
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT 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) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    }

    var __assign = function() {
        __assign = Object.assign || function __assign(t) {
            for (var s, i = 1, n = arguments.length; i < n; i++) {
                s = arguments[i];
                for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
            }
            return t;
        };
        return __assign.apply(this, arguments);
    };

    function __spreadArrays() {
        for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
        for (var r = Array(s), k = 0, i = 0; i < il; i++)
            for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
                r[k] = a[j];
        return r;
    }

    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.canvasSupported = false;
            this.svgSupported = false;
            this.touchEventsSupported = false;
            this.pointerEventsSupported = false;
            this.domSupported = false;
            this.transformSupported = false;
            this.transform3dSupported = false;
        }
        return Env;
    }());
    var env = new Env();
    if (typeof wx === 'object' && typeof wx.getSystemInfoSync === 'function') {
        env.wxa = true;
        env.canvasSupported = true;
        env.touchEventsSupported = true;
    }
    else if (typeof document === 'undefined' && typeof self !== 'undefined') {
        env.worker = true;
        env.canvasSupported = true;
    }
    else if (typeof navigator === 'undefined') {
        env.node = true;
        env.canvasSupported = 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.canvasSupported = !!document.createElement('canvas').getContext;
        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 BUILTIN_OBJECT = {
        '[object Function]': true,
        '[object RegExp]': true,
        '[object Date]': true,
        '[object Error]': true,
        '[object CanvasGradient]': true,
        '[object CanvasPattern]': true,
        '[object Image]': true,
        '[object Canvas]': true
    };
    var TYPED_ARRAY = {
        '[object Int8Array]': true,
        '[object Uint8Array]': true,
        '[object Uint8ClampedArray]': true,
        '[object Int16Array]': true,
        '[object Uint16Array]': true,
        '[object Int32Array]': true,
        '[object Uint32Array]': true,
        '[object Float32Array]': true,
        '[object Float64Array]': true
    };
    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 methods = {};
    function $override(name, fn) {
        methods[name] = fn;
    }
    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] = clone(source[i]);
                    }
                }
            }
        }
        else if (!BUILTIN_OBJECT[typeStr] && !isPrimitive(source) && !isDom(source)) {
            result = {};
            for (var key in source) {
                if (source.hasOwnProperty(key)) {
                    result[key] = clone(source[key]);
                }
            }
        }
        return result;
    }
    function merge(target, source, overwrite) {
        if (!isObject(source) || !isObject(target)) {
            return overwrite ? clone(source) : target;
        }
        for (var key in source) {
            if (source.hasOwnProperty(key)) {
                var targetProp = target[key];
                var sourceProp = source[key];
                if (isObject(sourceProp)
                    && isObject(targetProp)
                    && !isArray(sourceProp)
                    && !isArray(targetProp)
                    && !isDom(sourceProp)
                    && !isDom(targetProp)
                    && !isBuiltInObject(sourceProp)
                    && !isBuiltInObject(targetProp)
                    && !isPrimitive(sourceProp)
                    && !isPrimitive(targetProp)) {
                    merge(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)) {
                    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 = function () {
        return methods.createCanvas();
    };
    methods.createCanvas = function () {
        return document.createElement('canvas');
    };
    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 isPatternObject(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 HashMap = (function () {
        function HashMap(obj) {
            this.data = {};
            var isArr = isArray(obj);
            this.data = {};
            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.get = function (key) {
            return this.data.hasOwnProperty(key) ? this.data[key] : null;
        };
        HashMap.prototype.set = function (key, value) {
            return (this.data[key] = value);
        };
        HashMap.prototype.each = function (cb, context) {
            for (var key in this.data) {
                if (this.data.hasOwnProperty(key)) {
                    cb.call(context, this.data[key], key);
                }
            }
        };
        HashMap.prototype.keys = function () {
            return keys(this.data);
        };
        HashMap.prototype.removeKey = function (key) {
            delete this.data[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 hasOwn(own, prop) {
        return own.hasOwnProperty(prop);
    }
    function noop() { }

    var util = /*#__PURE__*/Object.freeze({
        __proto__: null,
        $override: $override,
        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,
        isPatternObject: isPatternObject,
        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,
        hasOwn: hasOwn,
        noop: noop
    });

    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;
            }
            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) {
            if (!this._$handlers) {
                return this;
            }
            var _h = this._$handlers[type];
            var eventProcessor = this._$eventProcessor;
            if (_h) {
                var args = arguments;
                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 isDomLevel2 = (typeof window !== 'undefined') && !!window.addEventListener;
    var MOUSE_EVENT_REG = /^(?:mouse|pointer|contextmenu|drag|drop)|click/;
    var _calcOut$1 = [];
    function clientToLocal(el, e, out, calculate) {
        out = out || {};
        if (calculate || !env.canvasSupported) {
            calculateZrXY(el, e, out);
        }
        else if (env.browser.firefox
            && 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) {
        if (isDomLevel2) {
            el.addEventListener(name, handler, opt);
        }
        else {
            el.attachEvent('on' + name, handler);
        }
    }
    function removeEventListener(el, name, handler, opt) {
        if (isDomLevel2) {
            el.removeEventListener(name, handler, opt);
        }
        else {
            el.detachEvent('on' + name, handler);
        }
    }
    var stop = isDomLevel2
        ? function (e) {
            e.preventDefault();
            e.stopPropagation();
            e.cancelBubble = true;
        }
        : function (e) {
            e.returnValue = false;
            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
                };
            }
        }
    };

    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 Handler = (function (_super) {
        __extends(Handler, _super);
        function Handler(storage, painter, proxy, painterRoot) {
            var _this = _super.call(this) || this;
            _this._hovered = new HoveredResult(0, 0);
            _this.storage = storage;
            _this.painter = painter;
            _this.painterRoot = painterRoot;
            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);
            for (var i = list.length - 1; i >= 0; i--) {
                var hoverCheckResult = void 0;
                if (list[i] !== exclude
                    && !list[i].ignore
                    && (hoverCheckResult = isHover(list[i], x, y))) {
                    !out.topTarget && (out.topTarget = list[i]);
                    if (hoverCheckResult !== SILENT) {
                        out.target = list[i];
                        break;
                    }
                }
            }
            return out;
        };
        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 isOutsideBoundary(handlerInstance, x, y) {
        var painter = handlerInstance.painter;
        return x < 0 || x > painter.getWidth() || y < 0 || y > painter.getHeight();
    }

    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 mIdentity = identity;
    var EPSILON = 5e-5;
    function isNotAroundZero(val) {
        return val > EPSILON || val < -EPSILON;
    }
    var scaleTmp = [];
    var tmpTransform = [];
    var originTransform = create$1();
    var abs = Math.abs;
    var Transformable = (function () {
        function Transformable() {
        }
        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.setOrigin = function (arr) {
            this.originX = arr[0];
            this.originY = arr[1];
        };
        Transformable.prototype.needLocalTransform = function () {
            return isNotAroundZero(this.rotation)
                || isNotAroundZero(this.x)
                || isNotAroundZero(this.y)
                || isNotAroundZero(this.scaleX - 1)
                || isNotAroundZero(this.scaleY - 1);
        };
        Transformable.prototype.updateTransform = function () {
            var parent = this.parent;
            var parentHasTransform = parent && parent.transform;
            var needLocalTransform = this.needLocalTransform();
            var m = this.transform;
            if (!(needLocalTransform || parentHasTransform)) {
                m && mIdentity(m);
                return;
            }
            m = m || create$1();
            if (needLocalTransform) {
                this.getLocalTransform(m);
            }
            else {
                mIdentity(m);
            }
            if (parentHasTransform) {
                if (needLocalTransform) {
                    mul$1(m, parent.transform, m);
                }
                else {
                    copy$1(m, parent.transform);
                }
            }
            this.transform = m;
            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.getLocalTransform = function (m) {
            return Transformable.getLocalTransform(this, 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];
            if (isNotAroundZero(sx - 1)) {
                sx = Math.sqrt(sx);
            }
            if (isNotAroundZero(sy - 1)) {
                sy = Math.sqrt(sy);
            }
            if (m[0] < 0) {
                sx = -sx;
            }
            if (m[3] < 0) {
                sy = -sy;
            }
            this.rotation = Math.atan2(-m[1] / sy, m[0] / sx);
            if (sx < 0 && sy < 0) {
                this.rotation += Math.PI;
                sx = -sx;
                sy = -sy;
            }
            this.x = m[4];
            this.y = m[5];
            this.scaleX = sx;
            this.scaleY = sy;
        };
        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.getLocalTransform = function (target, m) {
            m = m || [];
            mIdentity(m);
            var ox = target.originX || 0;
            var oy = target.originY || 0;
            var sx = target.scaleX;
            var sy = target.scaleY;
            var rotation = target.rotation || 0;
            var x = target.x;
            var y = target.y;
            m[4] -= ox;
            m[5] -= oy;
            m[0] *= sx;
            m[1] *= sy;
            m[2] *= sx;
            m[3] *= sy;
            m[4] *= sx;
            m[5] *= sy;
            if (rotation) {
                rotate(m, m, rotation);
            }
            m[4] += ox;
            m[5] += oy;
            m[4] += x;
            m[5] += y;
            return m;
        };
        Transformable.initDefaultProps = (function () {
            var proto = Transformable.prototype;
            proto.x = 0;
            proto.y = 0;
            proto.scaleX = 1;
            proto.scaleY = 1;
            proto.originX = 0;
            proto.originY = 0;
            proto.rotation = 0;
            proto.globalScaleRatio = 1;
        })();
        return Transformable;
    }());

    var easing = {
        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 - easing.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 easing.bounceIn(k * 2) * 0.5;
            }
            return easing.bounceOut(k * 2 - 1) * 0.5 + 0.5;
        }
    };

    var Clip = (function () {
        function Clip(opts) {
            this._initialized = false;
            this._startTime = 0;
            this._pausedTime = 0;
            this._paused = false;
            this._life = opts.life || 1000;
            this._delay = opts.delay || 0;
            this.loop = opts.loop == null ? false : opts.loop;
            this.gap = opts.gap || 0;
            this.easing = opts.easing || 'linear';
            this.onframe = opts.onframe;
            this.ondestroy = opts.ondestroy;
            this.onrestart = opts.onrestart;
        }
        Clip.prototype.step = function (globalTime, deltaTime) {
            if (!this._initialized) {
                this._startTime = globalTime + this._delay;
                this._initialized = true;
            }
            if (this._paused) {
                this._pausedTime += deltaTime;
                return;
            }
            var percent = (globalTime - this._startTime - this._pausedTime) / this._life;
            if (percent < 0) {
                percent = 0;
            }
            percent = Math.min(percent, 1);
            var easing$1 = this.easing;
            var easingFunc = typeof easing$1 === 'string'
                ? easing[easing$1] : easing$1;
            var schedule = typeof easingFunc === 'function'
                ? easingFunc(percent)
                : percent;
            this.onframe && this.onframe(schedule);
            if (percent === 1) {
                if (this.loop) {
                    this._restart(globalTime);
                    this.onrestart && this.onrestart();
                }
                else {
                    return true;
                }
            }
            return false;
        };
        Clip.prototype._restart = function (globalTime) {
            var remainder = (globalTime - this._startTime - this._pausedTime) % this._life;
            this._startTime = globalTime - remainder + this.gap;
            this._pausedTime = 0;
        };
        Clip.prototype.pause = function () {
            this._paused = true;
        };
        Clip.prototype.resume = function () {
            this._paused = false;
        };
        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, 0, 0, 0, 1);
                        return;
                    }
                    setRgba(rgbaArr, parseCssInt(params[0]), parseCssInt(params[1]), parseCssInt(params[2]), alpha);
                    putToCache(colorStr, rgbaArr);
                    return rgbaArr;
                case 'hsla':
                    if (params.length !== 4) {
                        setRgba(rgbaArr, 0, 0, 0, 1);
                        return;
                    }
                    params[3] = parseCssFloat(params[3]);
                    hsla2rgba(params, rgbaArr);
                    putToCache(colorStr, rgbaArr);
                    return rgbaArr;
                case 'hsl':
                    if (params.length !== 3) {
                        setRgba(rgbaArr, 0, 0, 0, 1);
                        return;
                    }
                    hsla2rgba(params, rgbaArr);
                    putToCache(colorStr, rgbaArr);
                    return rgbaArr;
                default:
                    return;
            }
        }
        setRgba(rgbaArr, 0, 0, 0, 1);
        return;
    }
    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() {
        var r = Math.round(Math.random() * 255);
        var g = Math.round(Math.random() * 255);
        var b = Math.round(Math.random() * 255);
        return 'rgb(' + r + ',' + g + ',' + b + ')';
    }

    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 arraySlice = Array.prototype.slice;
    function interpolateNumber(p0, p1, percent) {
        return (p1 - p0) * percent + p0;
    }
    function step(p0, p1, percent) {
        return percent > 0.5 ? p1 : 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);
        }
    }
    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);
            }
        }
    }
    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 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 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 catmullRomInterpolate(p0, p1, p2, p3, t, t2, t3) {
        var v0 = (p2 - p0) * 0.5;
        var v1 = (p3 - p1) * 0.5;
        return (2 * (p1 - p2) + v0 + v1) * t3
            + (-3 * (p1 - p2) - 2 * v0 - v1) * t2
            + v0 * t + p1;
    }
    function catmullRomInterpolate1DArray(out, p0, p1, p2, p3, t, t2, t3) {
        var len = p0.length;
        for (var i = 0; i < len; i++) {
            out[i] = catmullRomInterpolate(p0[i], p1[i], p2[i], p3[i], t, t2, t3);
        }
    }
    function catmullRomInterpolate2DArray(out, p0, p1, p2, p3, t, t2, t3) {
        var len = p0.length;
        var len2 = p0[0].length;
        for (var i = 0; i < len; i++) {
            if (!out[i]) {
                out[1] = [];
            }
            for (var j = 0; j < len2; j++) {
                out[i][j] = catmullRomInterpolate(p0[i][j], p1[i][j], p2[i][j], p3[i][j], t, t2, t3);
            }
        }
    }
    function cloneValue(value) {
        if (isArrayLike(value)) {
            var len = value.length;
            if (isArrayLike(value[0])) {
                var ret = [];
                for (var i = 0; i < len; i++) {
                    ret.push(arraySlice.call(value[i]));
                }
                return ret;
            }
            return arraySlice.call(value);
        }
        return value;
    }
    function rgba2String(rgba) {
        rgba[0] = Math.floor(rgba[0]);
        rgba[1] = Math.floor(rgba[1]);
        rgba[2] = Math.floor(rgba[2]);
        return 'rgba(' + rgba.join(',') + ')';
    }
    function guessArrayDim(value) {
        return isArrayLike(value && value[0]) ? 2 : 1;
    }
    var tmpRgba = [0, 0, 0, 0];
    var Track = (function () {
        function Track(propName) {
            this.keyframes = [];
            this.maxTime = 0;
            this.arrDim = 0;
            this.interpolable = true;
            this._needsSort = false;
            this._isAllValueEqual = true;
            this._lastFrame = 0;
            this._lastFramePercent = 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._isAllValueEqual && this.keyframes.length >= 2 && this.interpolable;
        };
        Track.prototype.getAdditiveTrack = function () {
            return this._additiveTrack;
        };
        Track.prototype.addKeyframe = function (time, value) {
            if (time >= this.maxTime) {
                this.maxTime = time;
            }
            else {
                this._needsSort = true;
            }
            var keyframes = this.keyframes;
            var len = keyframes.length;
            if (this.interpolable) {
                if (isArrayLike(value)) {
                    var arrayDim = guessArrayDim(value);
                    if (len > 0 && this.arrDim !== arrayDim) {
                        this.interpolable = false;
                        return;
                    }
                    if (arrayDim === 1 && typeof value[0] !== 'number'
                        || arrayDim === 2 && typeof value[0][0] !== 'number') {
                        this.interpolable = false;
                        return;
                    }
                    if (len > 0) {
                        var lastFrame = keyframes[len - 1];
                        if (this._isAllValueEqual) {
                            if (arrayDim === 1) {
                                if (!is1DArraySame(value, lastFrame.value)) {
                                    this._isAllValueEqual = false;
                                }
                            }
                            else {
                                this._isAllValueEqual = false;
                            }
                        }
                    }
                    this.arrDim = arrayDim;
                }
                else {
                    if (this.arrDim > 0) {
                        this.interpolable = false;
                        return;
                    }
                    if (typeof value === 'string') {
                        var colorArray = parse(value);
                        if (colorArray) {
                            value = colorArray;
                            this.isValueColor = true;
                        }
                        else {
                            this.interpolable = false;
                        }
                    }
                    else if (typeof value !== 'number' || isNaN(value)) {
                        this.interpolable = false;
                        return;
                    }
                    if (this._isAllValueEqual && len > 0) {
                        var lastFrame = keyframes[len - 1];
                        if (this.isValueColor && !is1DArraySame(lastFrame.value, value)) {
                            this._isAllValueEqual = false;
                        }
                        else if (lastFrame.value !== value) {
                            this._isAllValueEqual = false;
                        }
                    }
                }
            }
            var kf = {
                time: time,
                value: value,
                percent: 0
            };
            this.keyframes.push(kf);
            return kf;
        };
        Track.prototype.prepare = function (additiveTrack) {
            var kfs = this.keyframes;
            if (this._needsSort) {
                kfs.sort(function (a, b) {
                    return a.time - b.time;
                });
            }
            var arrDim = this.arrDim;
            var kfsLen = kfs.length;
            var lastKf = kfs[kfsLen - 1];
            for (var i = 0; i < kfsLen; i++) {
                kfs[i].percent = kfs[i].time / this.maxTime;
                if (arrDim > 0 && i !== kfsLen - 1) {
                    fillArray(kfs[i].value, lastKf.value, arrDim);
                }
            }
            if (additiveTrack
                && this.needsAnimate()
                && additiveTrack.needsAnimate()
                && arrDim === additiveTrack.arrDim
                && this.isValueColor === additiveTrack.isValueColor
                && !additiveTrack._finished) {
                this._additiveTrack = additiveTrack;
                var startValue = kfs[0].value;
                for (var i = 0; i < kfsLen; i++) {
                    if (arrDim === 0) {
                        if (this.isValueColor) {
                            kfs[i].additiveValue
                                = add1DArray([], kfs[i].value, startValue, -1);
                        }
                        else {
                            kfs[i].additiveValue = kfs[i].value - startValue;
                        }
                    }
                    else if (arrDim === 1) {
                        kfs[i].additiveValue = add1DArray([], kfs[i].value, startValue, -1);
                    }
                    else if (arrDim === 2) {
                        kfs[i].additiveValue = 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 keyframes = this.keyframes;
            var kfsNum = this.keyframes.length;
            var propName = this.propName;
            var arrDim = this.arrDim;
            var isValueColor = this.isValueColor;
            var frameIdx;
            if (percent < 0) {
                frameIdx = 0;
            }
            else if (percent < this._lastFramePercent) {
                var start = Math.min(this._lastFrame + 1, kfsNum - 1);
                for (frameIdx = start; frameIdx >= 0; frameIdx--) {
                    if (keyframes[frameIdx].percent <= percent) {
                        break;
                    }
                }
                frameIdx = Math.min(frameIdx, kfsNum - 2);
            }
            else {
                for (frameIdx = this._lastFrame; frameIdx < kfsNum; frameIdx++) {
                    if (keyframes[frameIdx].percent > percent) {
                        break;
                    }
                }
                frameIdx = Math.min(frameIdx - 1, kfsNum - 2);
            }
            var nextFrame = keyframes[frameIdx + 1];
            var frame = keyframes[frameIdx];
            if (!(frame && nextFrame)) {
                return;
            }
            this._lastFrame = frameIdx;
            this._lastFramePercent = percent;
            var range = (nextFrame.percent - frame.percent);
            if (range === 0) {
                return;
            }
            var w = (percent - frame.percent) / range;
            var targetArr = isAdditive ? this._additiveValue
                : (isValueColor ? tmpRgba : target[propName]);
            if ((arrDim > 0 || isValueColor) && !targetArr) {
                targetArr = this._additiveValue = [];
            }
            if (this.useSpline) {
                var p1 = keyframes[frameIdx][valueKey];
                var p0 = keyframes[frameIdx === 0 ? frameIdx : frameIdx - 1][valueKey];
                var p2 = keyframes[frameIdx > kfsNum - 2 ? kfsNum - 1 : frameIdx + 1][valueKey];
                var p3 = keyframes[frameIdx > kfsNum - 3 ? kfsNum - 1 : frameIdx + 2][valueKey];
                if (arrDim > 0) {
                    arrDim === 1
                        ? catmullRomInterpolate1DArray(targetArr, p0, p1, p2, p3, w, w * w, w * w * w)
                        : catmullRomInterpolate2DArray(targetArr, p0, p1, p2, p3, w, w * w, w * w * w);
                }
                else if (isValueColor) {
                    catmullRomInterpolate1DArray(targetArr, p0, p1, p2, p3, w, w * w, w * w * w);
                    if (!isAdditive) {
                        target[propName] = rgba2String(targetArr);
                    }
                }
                else {
                    var value = void 0;
                    if (!this.interpolable) {
                        value = p2;
                    }
                    else {
                        value = catmullRomInterpolate(p0, p1, p2, p3, w, w * w, w * w * w);
                    }
                    if (isAdditive) {
                        this._additiveValue = value;
                    }
                    else {
                        target[propName] = value;
                    }
                }
            }
            else {
                if (arrDim > 0) {
                    arrDim === 1
                        ? interpolate1DArray(targetArr, frame[valueKey], nextFrame[valueKey], w)
                        : interpolate2DArray(targetArr, frame[valueKey], nextFrame[valueKey], w);
                }
                else if (isValueColor) {
                    interpolate1DArray(targetArr, frame[valueKey], nextFrame[valueKey], w);
                    if (!isAdditive) {
                        target[propName] = rgba2String(targetArr);
                    }
                }
                else {
                    var value = void 0;
                    if (!this.interpolable) {
                        value = step(frame[valueKey], nextFrame[valueKey], w);
                    }
                    else {
                        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 arrDim = this.arrDim;
            var propName = this.propName;
            var additiveValue = this._additiveValue;
            if (arrDim === 0) {
                if (this.isValueColor) {
                    parse(target[propName], tmpRgba);
                    add1DArray(tmpRgba, tmpRgba, additiveValue, 1);
                    target[propName] = rgba2String(tmpRgba);
                }
                else {
                    target[propName] = target[propName] + additiveValue;
                }
            }
            else if (arrDim === 1) {
                add1DArray(target[propName], target[propName], additiveValue, 1);
            }
            else if (arrDim === 2) {
                add2DArray(target[propName], target[propName], additiveValue, 1);
            }
        };
        return Track;
    }());
    var Animator = (function () {
        function Animator(target, loop, additiveTo) {
            this._tracks = {};
            this._trackKeys = [];
            this._delay = 0;
            this._maxTime = 0;
            this._paused = false;
            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;
        }
        Animator.prototype.getTarget = function () {
            return this._target;
        };
        Animator.prototype.changeTarget = function (target) {
            this._target = target;
        };
        Animator.prototype.when = function (time, props) {
            return this.whenWithKeys(time, props, keys(props));
        };
        Animator.prototype.whenWithKeys = function (time, props, propNames) {
            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 lastFinalKf = additiveTrack.keyframes[additiveTrack.keyframes.length - 1];
                        initialValue = lastFinalKf && lastFinalKf.value;
                        if (additiveTrack.isValueColor && initialValue) {
                            initialValue = rgba2String(initialValue);
                        }
                    }
                    else {
                        initialValue = this._target[propName];
                    }
                    if (initialValue == null) {
                        continue;
                    }
                    if (time !== 0) {
                        track.addKeyframe(0, cloneValue(initialValue));
                    }
                    this._trackKeys.push(propName);
                }
                track.addKeyframe(time, cloneValue(props[propName]));
            }
            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._doneCallback = function () {
            this._setTracksFinished();
            this._clip = null;
            var doneList = this._doneList;
            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._abortedList;
            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, forceAnimate) {
            if (this._started > 0) {
                return;
            }
            this._started = 1;
            var self = this;
            var tracks = [];
            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;
                track.prepare(additiveTrack);
                if (track.needsAnimate()) {
                    tracks.push(track);
                }
                else if (!track.interpolable) {
                    var lastKf = kfs[kfs.length - 1];
                    if (lastKf) {
                        self._target[track.propName] = lastKf.value;
                    }
                }
            }
            if (tracks.length || forceAnimate) {
                var clip = new Clip({
                    life: this._maxTime,
                    loop: this._loop,
                    delay: this._delay,
                    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._onframeList;
                        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 && easing !== 'spline') {
                    clip.easing = 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._onframeList) {
                    this._onframeList = [];
                }
                this._onframeList.push(cb);
            }
            return this;
        };
        Animator.prototype.done = function (cb) {
            if (cb) {
                if (!this._doneList) {
                    this._doneList = [];
                }
                this._doneList.push(cb);
            }
            return this;
        };
        Animator.prototype.aborted = function (cb) {
            if (cb) {
                if (!this._abortedList) {
                    this._abortedList = [];
                }
                this._abortedList.push(cb);
            }
            return this;
        };
        Animator.prototype.getClip = function () {
            return this._clip;
        };
        Animator.prototype.getTrack = function (propName) {
            return this._tracks[propName];
        };
        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) {
                    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.saveFinalToTarget = function (target, trackKeys) {
            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 lastKf = kfs[kfs.length - 1];
                if (lastKf) {
                    var val = cloneValue(lastKf.value);
                    if (track.isValueColor) {
                        val = rgba2String(val);
                    }
                    target[propName] = val;
                }
            }
        };
        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(track.getAdditiveTrack());
                }
            }
        };
        return Animator;
    }());

    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 && isFinite(width)) {
                x = x + width;
                width = -width;
            }
            if (height < 0 && isFinite(height)) {
                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 textWidthCache = {};
    var DEFAULT_FONT = '12px sans-serif';
    var _ctx;
    var _cachedFont;
    function defaultMeasureText(text, font) {
        if (!_ctx) {
            _ctx = createCanvas().getContext('2d');
        }
        if (_cachedFont !== font) {
            _cachedFont = _ctx.font = font || DEFAULT_FONT;
        }
        return _ctx.measureText(text);
    }
    var methods$1 = {
        measureText: defaultMeasureText
    };
    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 = methods$1.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(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(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 dpr = 1;
    if (typeof window !== 'undefined') {
        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 PRESERVED_NORMAL_STATE = '__zr_normal__';
    var PRIMARY_STATES_KEYS = ['x', 'y', 'scaleX', 'scaleY', 'originX', 'originY', 'rotation', 'ignore'];
    var DEFAULT_ANIMATABLE_MAP = {
        x: true,
        y: true,
        scaleX: true,
        scaleY: true,
        originX: true,
        originY: true,
        rotation: true,
        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 attachedTransform = textEl.attachedTransform;
                var textAlign = void 0;
                var textVerticalAlign = void 0;
                var textStyleChanged = false;
                if (isLocal) {
                    attachedTransform.parent = this;
                }
                else {
                    attachedTransform.parent = null;
                }
                var innerOrigin = false;
                attachedTransform.x = textEl.x;
                attachedTransform.y = textEl.y;
                attachedTransform.originX = textEl.originX;
                attachedTransform.originY = textEl.originY;
                attachedTransform.rotation = textEl.rotation;
                attachedTransform.scaleX = textEl.scaleX;
                attachedTransform.scaleY = textEl.scaleY;
                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);
                    }
                    attachedTransform.x = tmpTextPosCalcRes.x;
                    attachedTransform.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;
                        attachedTransform.originX = -attachedTransform.x + relOriginX + (isLocal ? 0 : layoutRect.x);
                        attachedTransform.originY = -attachedTransform.y + relOriginY + (isLocal ? 0 : layoutRect.y);
                    }
                }
                if (textConfig.rotation != null) {
                    attachedTransform.rotation = textConfig.rotation;
                }
                var textOffset = textConfig.offset;
                if (textOffset) {
                    attachedTransform.x += textOffset[0];
                    attachedTransform.y += textOffset[1];
                    if (!innerOrigin) {
                        attachedTransform.originX = -textOffset[0];
                        attachedTransform.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);
                }
                if (textStyleChanged) {
                    textEl.dirtyStyle();
                }
                textEl.markRedraw();
            }
        };
        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 (fromStateTransition && fromStateTransition !== PRESERVED_NORMAL_STATE) {
                    continue;
                }
                var targetName = animator.targetName;
                var target = targetName
                    ? normalState[targetName] : normalState;
                animator.saveFinalToTarget(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) {
            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);
            if (useHoverLayer) {
                this._toggleHoverLayerFlag(true);
            }
            this._applyStateObj(stateName, state, this._normalState, keepCurrentStates, !noAnimation && !this.__inHover && animationCfg && animationCfg.duration > 0, animationCfg);
            if (this._textContent) {
                this._textContent.useState(stateName, keepCurrentStates);
            }
            if (this._textGuide) {
                this._textGuide.useState(stateName, keepCurrentStates);
            }
            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 &= ~Element.REDARAW_BIT;
            }
            return state;
        };
        Element.prototype.useStates = function (states, noAnimation) {
            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 useHoverLayer = !!(stateObjects[len - 1] && stateObjects[len - 1].hoverLayer);
                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);
                if (this._textContent) {
                    this._textContent.useStates(states);
                }
                if (this._textGuide) {
                    this._textGuide.useStates(states);
                }
                this._updateAnimationTargets();
                this.currentStates = states.slice();
                this.markRedraw();
                if (!useHoverLayer && this.__inHover) {
                    this._toggleHoverLayerFlag(false);
                    this.__dirty &= ~Element.REDARAW_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;
                    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) {
                throw new Error('Text element has been added to zrender.');
            }
            if (componentEl === this) {
                throw new Error('Recursive component attachment.');
            }
            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 (textEl.__zr && !textEl.__hostTarget) {
                throw new Error('Text element has been added to zrender.');
            }
            textEl.attachedTransform = 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.attachedTransform = 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 |= Element.REDARAW_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) {
            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) {
            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) {
            var target = key ? this[key] : this;
            if (!target) {
                logError('Property "'
                    + key
                    + '" is not existed in element '
                    + this.id);
                return;
            }
            var animator = new Animator(target, loop);
            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.REDARAW_BIT = 1;
        Element.initDefaultProps = (function () {
            var elProto = Element.prototype;
            elProto.type = 'element';
            elProto.name = '';
            elProto.ignore = false;
            elProto.silent = false;
            elProto.isGroup = false;
            elProto.draggable = false;
            elProto.dragging = false;
            elProto.ignoreClip = false;
            elProto.__inHover = false;
            elProto.__dirty = Element.REDARAW_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 () {
                        logDeprecatedError(key, xKey, yKey);
                        if (!this[privateKey]) {
                            var pos = this[privateKey] = [];
                            enhanceArray(this, pos);
                        }
                        return this[privateKey];
                    },
                    set: function (pos) {
                        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 && (!env.browser.ie || env.browser.version > 8)) {
                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);
            }
            animator.start(cfg.easing, cfg.force);
        }
        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 animateToShallow(animatable, topKey, source, target, cfg, animationProps, animators, reverse) {
        var animatableKeys = [];
        var changedKeys = [];
        var targetKeys = keys(target);
        var duration = cfg.duration;
        var delay = cfg.delay;
        var additive = cfg.additive;
        var setToFinal = cfg.setToFinal;
        var animateAll = !isObject(animationProps);
        for (var k = 0; k < targetKeys.length; k++) {
            var innerKey = targetKeys[k];
            if (source[innerKey] != null
                && target[innerKey] != null
                && (animateAll || animationProps[innerKey])) {
                if (isObject(target[innerKey]) && !isArrayLike(target[innerKey])) {
                    if (topKey) {
                        if (!reverse) {
                            source[innerKey] = target[innerKey];
                            animatable.updateDuringAnimation(topKey);
                        }
                        continue;
                    }
                    animateToShallow(animatable, innerKey, source[innerKey], target[innerKey], cfg, animationProps && animationProps[innerKey], animators, reverse);
                }
                else {
                    animatableKeys.push(innerKey);
                    changedKeys.push(innerKey);
                }
            }
            else if (!reverse) {
                source[innerKey] = target[innerKey];
                animatable.updateDuringAnimation(topKey);
                changedKeys.push(innerKey);
            }
        }
        var keyLen = animatableKeys.length;
        if (keyLen > 0
            || (cfg.force && !animators.length)) {
            var existsAnimators = animatable.animators;
            var existsAnimatorsOnSameTarget = [];
            for (var i = 0; i < existsAnimators.length; i++) {
                if (existsAnimators[i].targetName === topKey) {
                    existsAnimatorsOnSameTarget.push(existsAnimators[i]);
                }
            }
            if (!additive && existsAnimatorsOnSameTarget.length) {
                for (var i = 0; i < existsAnimatorsOnSameTarget.length; i++) {
                    var allAborted = existsAnimatorsOnSameTarget[i].stopTracks(changedKeys);
                    if (allAborted) {
                        var idx = indexOf(existsAnimators, existsAnimatorsOnSameTarget[i]);
                        existsAnimators.splice(idx, 1);
                    }
                }
            }
            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 = animatableKeys[i];
                    reversedTarget[innerKey] = source[innerKey];
                    if (setToFinal) {
                        revertedSource[innerKey] = target[innerKey];
                    }
                    else {
                        source[innerKey] = target[innerKey];
                    }
                }
            }
            else if (setToFinal) {
                sourceClone = {};
                for (var i = 0; i < keyLen; i++) {
                    var innerKey = animatableKeys[i];
                    sourceClone[innerKey] = cloneValue(source[innerKey]);
                    copyValue(source, target, innerKey);
                }
            }
            var animator = new Animator(source, false, additive ? existsAnimatorsOnSameTarget : null);
            animator.targetName = topKey;
            if (cfg.scope) {
                animator.scope = cfg.scope;
            }
            if (setToFinal && revertedSource) {
                animator.whenWithKeys(0, revertedSource, animatableKeys);
            }
            if (sourceClone) {
                animator.whenWithKeys(0, sourceClone, animatableKeys);
            }
            animator.whenWithKeys(duration == null ? 500 : duration, reverse ? reversedTarget : target, animatableKeys).delay(delay || 0);
            animatable.addAnimator(animator, topKey);
            animators.push(animator);
        }
    }

    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 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;
            env.canvasSupported && 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 |= Element.REDARAW_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 = (typeof window !== 'undefined'
        && ((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 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 || {};
            _this.onframe = opts.onframe || function () { };
            return _this;
        }
        Animation.prototype.addClip = function (clip) {
            if (clip.animation) {
                this.removeClip(clip);
            }
            if (!this._clipsHead) {
                this._clipsHead = this._clipsTail = clip;
            }
            else {
                this._clipsTail.next = clip;
                clip.prev = this._clipsTail;
                clip.next = null;
                this._clipsTail = 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._clipsHead = next;
            }
            if (next) {
                next.prev = prev;
            }
            else {
                this._clipsTail = 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 = new Date().getTime() - this._pausedTime;
            var delta = time - this._time;
            var clip = this._clipsHead;
            while (clip) {
                var nextClip = clip.next;
                var finished = clip.step(time, delta);
                if (finished) {
                    clip.ondestroy && clip.ondestroy();
                    this.removeClip(clip);
                    clip = nextClip;
                }
                else {
                    clip = nextClip;
                }
            }
            this._time = time;
            if (!notTriggerFrameAndStageUpdate) {
                this.onframe(delta);
                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 = new Date().getTime();
            this._pausedTime = 0;
            this._startLoop();
        };
        Animation.prototype.stop = function () {
            this._running = false;
        };
        Animation.prototype.pause = function () {
            if (!this._paused) {
                this._pauseStart = new Date().getTime();
                this._paused = true;
            }
        };
        Animation.prototype.resume = function () {
            if (this._paused) {
                this._pausedTime += (new Date().getTime()) - this._pauseStart;
                this._paused = false;
            }
        };
        Animation.prototype.clear = function () {
            var clip = this._clipsHead;
            while (clip) {
                var nextClip = clip.next;
                clip.prev = clip.next = clip.animation = null;
                clip = nextClip;
            }
            this._clipsHead = this._clipsTail = null;
        };
        Animation.prototype.isFinished = function () {
            return this._clipsHead == 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 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 (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.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 useVML = !env.canvasSupported;
    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 (useVML) {
                throw new Error('IE8 support has been dropped since 5.0');
            }
            if (!painterCtors[rendererType]) {
                rendererType = keys(painterCtors)[0];
            }
            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);
            this.storage = storage;
            this.painter = painter;
            var handerProxy = (!env.node && !env.worker)
                ? new HandlerDomProxy(painter.getViewportRoot(), painter.root)
                : null;
            this.handler = new Handler(storage, painter, handerProxy, painter.root);
            this.animation = new Animation({
                stage: {
                    update: function () { return _this._flush(true); }
                }
            });
            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 = new Date().getTime();
            if (this._needsRefresh) {
                triggerRendered = true;
                this.refreshImmediately(fromInside);
            }
            if (this._needsRefreshHover) {
                triggerRendered = true;
                this.refreshHoverImmediately();
            }
            var end = new Date().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.addHover = function (el) {
        };
        ZRender.prototype.removeHover = function (el) {
        };
        ZRender.prototype.clearHover = function () {
        };
        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.pathToImage = function (e, dpr) {
            if (this.painter.pathToImage) {
                return this.painter.pathToImage(e, dpr);
            }
        };
        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.1.0';

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

    var RADIAN_EPSILON = 1e-4;

    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 subDomain = domain[1] - domain[0];
      var subRange = range[1] - range[0];

      if (subDomain === 0) {
        return subRange === 0 ? range[0] : (range[0] + range[1]) / 2;
      } // Avoid accuracy problem in edge, such as
      // 146.39 - 62.83 === 83.55999999999999.
      // See echarts/test/ut/spec/util/number.js#linearMap#accuracyError
      // It is a little verbose for efficiency considering this method
      // is a hotspot.


      if (clamp) {
        if (subDomain > 0) {
          if (val <= domain[0]) {
            return range[0];
          } else if (val >= domain[1]) {
            return range[1];
          }
        } else {
          if (val >= domain[0]) {
            return range[0];
          } else if (val <= domain[1]) {
            return range[1];
          }
        }
      } else {
        if (val === domain[0]) {
          return range[0];
        }

        if (val === domain[1]) {
          return range[1];
        }
      }

      return (val - domain[0]) / subDomain * subRange + range[0];
    }
    /**
     * Convert a percent string to absolute number.
     * Returns NaN if percent is not a valid string or number
     */

    function parsePercent$1(percent, all) {
      switch (percent) {
        case 'center':
        case 'middle':
          percent = '50%';
          break;

        case 'left':
        case 'top':
          percent = '0%';
          break;

        case 'right':
        case 'bottom':
          percent = '100%';
          break;
      }

      if (typeof percent === 'string') {
        if (_trim(percent).match(/%$/)) {
          return parseFloat(percent) / 100 * all;
        }

        return parseFloat(percent);
      }

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


      precision = Math.min(Math.max(0, precision), 20);
      x = (+x).toFixed(precision);
      return returnStr ? x : +x;
    }
    /**
     * 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


      var e = 1;
      var count = 0;

      while (Math.round(val * e) / e !== val) {
        e *= 10;
        count++;
      }

      return count;
    }
    /**
     * Get precision with slow but safe method
     */

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

      var eIndex = str.indexOf('e');

      if (eIndex > 0) {
        var precision = +str.slice(eIndex + 1);
        return precision < 0 ? -precision : 0;
      } else {
        var dotIndex = str.indexOf('.');
        return dotIndex < 0 ? 0 : str.length - 1 - dotIndex;
      }
    }
    /**
     * Minimal dicernible data precisioin according to a single pixel.
     */

    function getPixelPrecision(dataExtent, pixelExtent) {
      var log = Math.log;
      var LN10 = Math.LN10;
      var dataQuantity = Math.floor(log(dataExtent[1] - dataExtent[0]) / LN10);
      var sizeQuantity = Math.round(log(Math.abs(pixelExtent[1] - pixelExtent[0])) / LN10); // toFixed() digits argument must be between 0 and 20.

      var precision = Math.min(Math.max(-dataQuantity + sizeQuantity, 0), 20);
      return !isFinite(precision) ? 20 : precision;
    }
    /**
     * Get a data of given precision, assuring the sum of percentages
     * in valueList is 1.
     * The largest remainer method is used.
     * https://en.wikipedia.org/wiki/Largest_remainder_method
     *
     * @param 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 sum = reduce(valueList, function (acc, val) {
        return acc + (isNaN(val) ? 0 : val);
      }, 0);

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

      var digits = Math.pow(10, precision);
      var votesPerQuota = map(valueList, function (val) {
        return (isNaN(val) ? 0 : val) / sum * digits * 100;
      });
      var targetSeats = digits * 100;
      var seats = map(votesPerQuota, function (votes) {
        // Assign automatic seats.
        return Math.floor(votes);
      });
      var currentSum = reduce(seats, function (acc, val) {
        return acc + val;
      }, 0);
      var remainder = map(votesPerQuota, function (votes, idx) {
        return votes - seats[idx];
      }); // Has remainding votes.

      while (currentSum < targetSeats) {
        // Find next largest remainder.
        var max = Number.NEGATIVE_INFINITY;
        var maxId = null;

        for (var i = 0, len = remainder.length; i < len; ++i) {
          if (remainder[i] > max) {
            max = remainder[i];
            maxId = i;
          }
        } // Add a vote to max remainder.


        ++seats[maxId];
        remainder[maxId] = 0;
        ++currentSum;
      }

      return seats[idx] / digits;
    } // Number.MAX_SAFE_INTEGER, ie do not support.

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

    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 loacal time):
     *     '2012', '2012-3-1', '2012/3/1', '2012/03/01',
     *     '2009/6/12 2:00', '2009/6/12 2:05:08', '2009/6/12 2:05:08.123'
     *   + a timestamp, which represent a time in UTC.
     * @return date Never be null/undefined. If invalid, return `new Date(NaN)`.
     */

    function parseDate(value) {
      if (value instanceof Date) {
        return value;
      } else if (typeof value === 'string') {
        // Different browsers parse date in different way, so we parse it manually.
        // Some other issues:
        // new Date('1970-01-01') is UTC,
        // new Date('1970/01/01') and new Date('1970-1-01') is local.
        // See issue #3623
        var match = TIME_REG.exec(value);

        if (!match) {
          // return Invalid Date.
          return new Date(NaN);
        } // Use local time when no timezone offset specifed.


        if (!match[8]) {
          // match[n] can only be string or undefined.
          // But take care of '12' + 1 => '121'.
          return new Date(+match[1], +(match[2] || 1) - 1, +match[3] || 1, +match[4] || 0, +(match[5] || 0), +match[6] || 0, +match[7] || 0);
        } // Timezoneoffset of Javascript Date has considered DST (Daylight Saving Time,
        // https://tc39.github.io/ecma262/#sec-daylight-saving-time-adjustment).
        // For example, system timezone is set as "Time Zone: America/Toronto",
        // then these code will get different result:
        // `new Date(1478411999999).getTimezoneOffset();  // get 240`
        // `new Date(1478412000000).getTimezoneOffset();  // get 300`
        // So we should not use `new Date`, but use `Date.UTC`.
        else {
            var hour = +match[4] || 0;

            if (match[8].toUpperCase() !== 'Z') {
              hour -= +match[8].slice(0, 3);
            }

            return new Date(Date.UTC(+match[1], +(match[2] || 1) - 1, +match[3] || 1, hour, +(match[5] || 0), +match[6] || 0, +match[7] || 0));
          }
      } else if (value == null) {
        return new Date(NaN);
      }

      return new Date(Math.round(value));
    }
    /**
     * Quantity of a number. e.g. 0.1, 1, 10, 100
     *
     * @param 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));
      }
    }
    /**
     * [Numberic 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 || typeof val !== 'string' || 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 dividor
     *
     * @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 warn(str) {
      if (hasConsole) {
        console.warn(ECHARTS_PREFIX + str);
      }
    }
    function error(str) {
      if (hasConsole) {
        console.error(ECHARTS_PREFIX + str);
      }
    }
    function deprecateLog(str) {
      if ("development" !== 'production') {
        if (storedLogs[str]) {
          // Not display duplicate message.
          return;
        }

        if (hasConsole) {
          storedLogs[str] = true;
          console.warn(ECHARTS_PREFIX + 'DEPRECATED: ' + str);
        }
      }
    }
    function deprecateReplaceLog(oldOpt, newOpt, scope) {
      if ("development" !== 'production') {
        deprecateLog((scope ? "[" + scope + "]" : '') + (oldOpt + " is deprecated, use " + newOpt + " instead."));
      }
    }
    function consoleLog() {
      var args = [];

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

      if ("development" !== 'production') {
        /* eslint-disable no-console */
        if (typeof console !== 'undefined' && console.log) {
          console.log.apply(console, args);
        }
        /* eslint-enable no-console */

      }
    }
    /**
     * If in __DEV__ environment, get console printable message for users hint.
     * Parameters are separated by ' '.
     * @usuage
     * 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);
    }

    /**
     * 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 do not ensure performance.
     * data could be [12, 2323, {value: 223}, [1221, 23], {value: [2, 23]}]
     * This helper method retieves 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 compoonets) will be removed.
     *     (3) Other new options will be used to create new component.
     *     (4) The index of the existing compoents 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 senario, the `result` index are exactly the consistent with the `newCmptOptions`,
     *     which ensures the compoennt 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 ommit 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 ommited.


      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 compoennt 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 overwitten. Consider case: axis.name = '20km'.
        // But id generated by name will not be changed, which affect
        // only in that case: setOption with 'not merge mode' and view
        // instance will be recreated, which can be accepted.


        keyInfo.name = opt.name != null ? makeComparableKey(opt.name) : existing ? existing.name // Avoid diffferent 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;
      }

      var type = typeof idOrName;
      return type === 'string' ? idOrName : type === 'number' || 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 (typeof targetValue === 'number') {
        var value = interpolateNumber(sourceValue || 0, targetValue, percent);
        return round(value, isAutoPrecision ? Math.max(getPrecisionSafe(sourceValue || 0), getPrecisionSafe(targetValue)) : precision);
      } else if (typeof targetValue === 'string') {
        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.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(leftVal, rightVal, percent);
            interpolated[i] = round(value, isAutoPrecision ? Math.max(getPrecisionSafe(leftVal), getPrecisionSafe(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; // 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.

        function ExtendedClass() {
          var args = [];

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

          if (!proto.$constructor) {
            if (!isESClass(superClass)) {
              // Will throw error if superClass is an es6 native class.
              superClass.apply(this, arguments);
            } else {
              var ins = createObject( // @ts-ignore
              ExtendedClass.prototype, new (superClass.bind.apply(superClass, __spreadArrays([void 0], args)))());
              return ins;
            }
          } else {
            proto.$constructor.apply(this, arguments);
          }
        }

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

    function isESClass(fn) {
      return typeof fn === 'function' && /^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 fetch from 'this'.
    // Consider this case:
    // class A has method f,
    // class B inherits class A, overrides method f, f call superApply('f'),
    // class C inherits class B, do not overrides method f,
    // then when method of class C is called, dead loop occured.

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

      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 'xxx'
       *     or Object.<subKey, componentClass>, when componentType is 'xxx.yy'
       */
      var storage = {};

      target.registerClass = function (clz) {
        // `type` should not be a "instance memeber".
        // 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 stil 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 = new Image();
                image.onload = image.onerror = imageOnLoad;
                globalImageCache.put(newImageOrSrc, image.__cachedImgObj = {
                    image: image,
                    pending: [pendingWrap]
                });
                image.src = image.__zrImageSrc = newImageOrSrc;
            }
            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 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);
        }
        var outerHeight = height;
        var outerWidth = width;
        if (padding) {
            outerHeight += padding[0] + padding[2];
            if (outerWidth != null) {
                outerWidth += padding[1] + padding[3];
            }
        }
        if (text && truncate && outerWidth != 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);
            }
        }
        if (width == null) {
            var maxWidth = 0;
            for (var i = 0; i < lines.length; i++) {
                maxWidth = Math.max(getWidth(lines[i], font), maxWidth);
            }
            width = maxWidth;
        }
        return {
            lines: lines,
            height: height,
            outerHeight: outerHeight,
            lineHeight: lineHeight,
            calculatedLineHeight: calculatedLineHeight,
            contentHeight: contentHeight,
            width: width
        };
    }
    var RichTextToken = (function () {
        function RichTextToken() {
        }
        return RichTextToken;
    }());
    var RichTextLine = (function () {
        function RichTextLine(tokens) {
            this.tokens = [];
            if (tokens) {
                this.tokens = tokens;
            }
        }
        return RichTextLine;
    }());
    var RichTextContentBlock = (function () {
        function RichTextContentBlock() {
            this.width = 0;
            this.height = 0;
            this.contentWidth = 0;
            this.contentHeight = 0;
            this.outerWidth = 0;
            this.outerHeight = 0;
            this.lines = [];
        }
        return RichTextContentBlock;
    }());
    function parseRichText(text, style) {
        var contentBlock = new RichTextContentBlock();
        text != null && (text += '');
        if (!text) {
            return contentBlock;
        }
        var topWidth = style.width;
        var topHeight = style.height;
        var overflow = style.overflow;
        var wrapInfo = (overflow === 'break' || overflow === 'breakAll') && topWidth != null
            ? { width: topWidth, accumWidth: 0, breakAll: overflow === 'breakAll' }
            : null;
        var lastIndex = STYLE_REG.lastIndex = 0;
        var result;
        while ((result = STYLE_REG.exec(text)) != null) {
            var matchedIndex = result.index;
            if (matchedIndex > lastIndex) {
                pushTokens(contentBlock, text.substring(lastIndex, matchedIndex), style, wrapInfo);
            }
            pushTokens(contentBlock, result[2], style, wrapInfo, result[1]);
            lastIndex = STYLE_REG.lastIndex;
        }
        if (lastIndex < text.length) {
            pushTokens(contentBlock, text.substring(lastIndex, text.length), style, wrapInfo);
        }
        var pendingList = [];
        var calculatedHeight = 0;
        var calculatedWidth = 0;
        var stlPadding = style.padding;
        var truncate = overflow === 'truncate';
        var truncateLine = style.lineOverflow === 'truncate';
        function finishLine(line, lineWidth, lineHeight) {
            line.width = lineWidth;
            line.lineHeight = lineHeight;
            calculatedHeight += lineHeight;
            calculatedWidth = Math.max(calculatedWidth, lineWidth);
        }
        outer: for (var i = 0; i < contentBlock.lines.length; i++) {
            var line = contentBlock.lines[i];
            var lineHeight = 0;
            var lineWidth = 0;
            for (var j = 0; j < line.tokens.length; j++) {
                var token = line.tokens[j];
                var tokenStyle = token.styleName && style.rich[token.styleName] || {};
                var textPadding = token.textPadding = tokenStyle.padding;
                var paddingH = textPadding ? textPadding[1] + textPadding[3] : 0;
                var font = token.font = tokenStyle.font || style.font;
                token.contentHeight = getLineHeight(font);
                var tokenHeight = retrieve2(tokenStyle.height, token.contentHeight);
                token.innerHeight = tokenHeight;
                textPadding && (tokenHeight += textPadding[0] + textPadding[2]);
                token.height = tokenHeight;
                token.lineHeight = retrieve3(tokenStyle.lineHeight, style.lineHeight, tokenHeight);
                token.align = tokenStyle && tokenStyle.align || style.align;
                token.verticalAlign = tokenStyle && tokenStyle.verticalAlign || 'middle';
                if (truncateLine && topHeight != null && calculatedHeight + token.lineHeight > topHeight) {
                    if (j > 0) {
                        line.tokens = line.tokens.slice(0, j);
                        finishLine(line, lineWidth, lineHeight);
                        contentBlock.lines = contentBlock.lines.slice(0, i + 1);
                    }
                    else {
                        contentBlock.lines = contentBlock.lines.slice(0, i);
                    }
                    break outer;
                }
                var styleTokenWidth = tokenStyle.width;
                var tokenWidthNotSpecified = styleTokenWidth == null || styleTokenWidth === 'auto';
                if (typeof styleTokenWidth === 'string' && styleTokenWidth.charAt(styleTokenWidth.length - 1) === '%') {
                    token.percentWidth = styleTokenWidth;
                    pendingList.push(token);
                    token.contentWidth = getWidth(token.text, font);
                }
                else {
                    if (tokenWidthNotSpecified) {
                        var textBackgroundColor = tokenStyle.backgroundColor;
                        var bgImg = textBackgroundColor && textBackgroundColor.image;
                        if (bgImg) {
                            bgImg = findExistImage(bgImg);
                            if (isImageReady(bgImg)) {
                                token.width = Math.max(token.width, bgImg.width * tokenHeight / bgImg.height);
                            }
                        }
                    }
                    var remainTruncWidth = truncate && topWidth != null
                        ? topWidth - lineWidth : null;
                    if (remainTruncWidth != null && remainTruncWidth < token.width) {
                        if (!tokenWidthNotSpecified || remainTruncWidth < paddingH) {
                            token.text = '';
                            token.width = token.contentWidth = 0;
                        }
                        else {
                            token.text = truncateText(token.text, remainTruncWidth - paddingH, font, style.ellipsis, { minChar: style.truncateMinChar });
                            token.width = token.contentWidth = getWidth(token.text, font);
                        }
                    }
                    else {
                        token.contentWidth = getWidth(token.text, font);
                    }
                }
                token.width += paddingH;
                lineWidth += token.width;
                tokenStyle && (lineHeight = Math.max(lineHeight, token.lineHeight));
            }
            finishLine(line, lineWidth, lineHeight);
        }
        contentBlock.outerWidth = contentBlock.width = retrieve2(topWidth, calculatedWidth);
        contentBlock.outerHeight = contentBlock.height = retrieve2(topHeight, calculatedHeight);
        contentBlock.contentHeight = calculatedHeight;
        contentBlock.contentWidth = calculatedWidth;
        if (stlPadding) {
            contentBlock.outerWidth += stlPadding[1] + stlPadding[3];
            contentBlock.outerHeight += stlPadding[0] + stlPadding[2];
        }
        for (var i = 0; i < pendingList.length; i++) {
            var token = pendingList[i];
            var percentWidth = token.percentWidth;
            token.width = parseInt(percentWidth, 10) / 100 * contentBlock.width;
        }
        return contentBlock;
    }
    function pushTokens(block, str, style, wrapInfo, styleName) {
        var isEmptyStr = str === '';
        var tokenStyle = styleName && style.rich[styleName] || {};
        var lines = block.lines;
        var font = tokenStyle.font || style.font;
        var newLine = false;
        var strLines;
        var linesWidths;
        if (wrapInfo) {
            var tokenPadding = tokenStyle.padding;
            var tokenPaddingH = tokenPadding ? tokenPadding[1] + tokenPadding[3] : 0;
            if (tokenStyle.width != null && tokenStyle.width !== 'auto') {
                var outerWidth_1 = parsePercent(tokenStyle.width, wrapInfo.width) + tokenPaddingH;
                if (lines.length > 0) {
                    if (outerWidth_1 + wrapInfo.accumWidth > wrapInfo.width) {
                        strLines = str.split('\n');
                        newLine = true;
                    }
                }
                wrapInfo.accumWidth = outerWidth_1;
            }
            else {
                var res = wrapText(str, font, wrapInfo.width, wrapInfo.breakAll, wrapInfo.accumWidth);
                wrapInfo.accumWidth = res.accumWidth + tokenPaddingH;
                linesWidths = res.linesWidths;
                strLines = res.lines;
            }
        }
        else {
            strLines = str.split('\n');
        }
        for (var i = 0; i < strLines.length; i++) {
            var text = strLines[i];
            var token = new RichTextToken();
            token.styleName = styleName;
            token.text = text;
            token.isLineHolder = !text && !isEmptyStr;
            if (typeof tokenStyle.width === 'number') {
                token.width = tokenStyle.width;
            }
            else {
                token.width = linesWidths
                    ? linesWidths[i]
                    : getWidth(text, font);
            }
            if (!i && !newLine) {
                var tokens = (lines[lines.length - 1] || (lines[0] = new RichTextLine())).tokens;
                var tokensLen = tokens.length;
                (tokensLen === 1 && tokens[0].isLineHolder)
                    ? (tokens[0] = token)
                    : ((text || !tokensLen || isEmptyStr) && tokens.push(token));
            }
            else {
                lines.push(new RichTextLine([token]));
            }
        }
    }
    function isLatin(ch) {
        var code = ch.charCodeAt(0);
        return code >= 0x21 && code <= 0xFF;
    }
    var breakCharMap = reduce(',&?/;] '.split(''), function (obj, ch) {
        obj[ch] = true;
        return obj;
    }, {});
    function isWordBreakChar(ch) {
        if (isLatin(ch)) {
            if (breakCharMap[ch]) {
                return true;
            }
            return false;
        }
        return true;
    }
    function wrapText(text, font, lineWidth, isBreakAll, lastAccumWidth) {
        var lines = [];
        var linesWidths = [];
        var line = '';
        var currentWord = '';
        var currentWordWidth = 0;
        var accumWidth = 0;
        for (var i = 0; i < text.length; i++) {
            var ch = text.charAt(i);
            if (ch === '\n') {
                if (currentWord) {
                    line += currentWord;
                    accumWidth += currentWordWidth;
                }
                lines.push(line);
                linesWidths.push(accumWidth);
                line = '';
                currentWord = '';
                currentWordWidth = 0;
                accumWidth = 0;
                continue;
            }
            var chWidth = getWidth(ch, font);
            var inWord = isBreakAll ? false : !isWordBreakChar(ch);
            if (!lines.length
                ? lastAccumWidth + accumWidth + chWidth > lineWidth
                : accumWidth + chWidth > lineWidth) {
                if (!accumWidth) {
                    if (inWord) {
                        lines.push(currentWord);
                        linesWidths.push(currentWordWidth);
                        currentWord = ch;
                        currentWordWidth = chWidth;
                    }
                    else {
                        lines.push(ch);
                        linesWidths.push(chWidth);
                    }
                }
                else if (line || currentWord) {
                    if (inWord) {
                        if (!line) {
                            line = currentWord;
                            currentWord = '';
                            currentWordWidth = 0;
                            accumWidth = currentWordWidth;
                        }
                        lines.push(line);
                        linesWidths.push(accumWidth - currentWordWidth);
                        currentWord += ch;
                        currentWordWidth += chWidth;
                        line = '';
                        accumWidth = currentWordWidth;
                    }
                    else {
                        if (currentWord) {
                            line += currentWord;
                            accumWidth += currentWordWidth;
                            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 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 () {
            this.markRedraw();
            this.__dirty |= Displayable.STYLE_CHANGED_BIT;
            if (this._rect) {
                this._rect = null;
            }
        };
        Displayable.prototype.dirty = function () {
            this.dirtyStyle();
        };
        Displayable.prototype.styleChanged = function () {
            return !!(this.__dirty & Displayable.STYLE_CHANGED_BIT);
        };
        Displayable.prototype.styleUpdated = function () {
            this.__dirty &= ~Displayable.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);
                }
            }
            for (var i = 0; i < PRIMARY_STATES_KEYS$1.length; i++) {
                var key = PRIMARY_STATES_KEYS$1[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.STYLE_CHANGED_BIT = 2;
        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 = Element.REDARAW_BIT | Displayable.STYLE_CHANGED_BIT;
        })();
        return Displayable;
    }(Element));
    var tmpRect = new BoundingRect(0, 0, 0, 0);
    var viewRect = new BoundingRect(0, 0, 0, 0);
    function isDisplayableCulled(el, width, height) {
        tmpRect.copy(el.getBoundingRect());
        if (el.transform) {
            tmpRect.applyTransform(el.transform);
        }
        viewRect.width = width;
        viewRect.height = height;
        return !tmpRect.intersect(viewRect);
    }

    var mathPow = Math.pow;
    var mathSqrt = Math.sqrt;
    var EPSILON$1 = 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$1 && val < EPSILON$1;
    }
    function isNotAroundZero$1(val) {
        return val > EPSILON$1 || val < -EPSILON$1;
    }
    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$1(b)) {
                var t1 = -c / b;
                if (t1 >= 0 && t1 <= 1) {
                    extrema[n++] = t1;
                }
            }
        }
        else {
            var disc = b * b - 4 * a * c;
            if (isAroundZero(disc)) {
                extrema[0] = -b / (2 * a);
            }
            else if (disc > 0) {
                var discSqrt = mathSqrt(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$1(b)) {
                var t1 = -c / b;
                if (t1 >= 0 && t1 <= 1) {
                    roots[n++] = t1;
                }
            }
        }
        else {
            var disc = b * b - 4 * a * c;
            if (isAroundZero(disc)) {
                var t1 = -b / (2 * a);
                if (t1 >= 0 && t1 <= 1) {
                    roots[n++] = t1;
                }
            }
            else if (disc > 0) {
                var discSqrt = mathSqrt(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 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 mathSqrt$1 = Math.sqrt;
    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._version = 0;
            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._lineDash) {
                this._lineDash = null;
                this._dashOffset = 0;
            }
            if (this._pathSegLen) {
                this._pathSegLen = null;
                this._pathLen = 0;
            }
            this._version++;
        };
        PathProxy.prototype.moveTo = function (x, y) {
            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 exceedUnit = mathAbs(x - this._xi) > this._ux
                || mathAbs(y - this._yi) > this._uy
                || this._len < 5;
            this.addData(CMD.L, x, y);
            if (this._ctx && exceedUnit) {
                this._needsDash ? this._dashedLineTo(x, y)
                    : this._ctx.lineTo(x, y);
            }
            if (exceedUnit) {
                this._xi = x;
                this._yi = y;
            }
            return this;
        };
        PathProxy.prototype.bezierCurveTo = function (x1, y1, x2, y2, x3, y3) {
            this.addData(CMD.C, x1, y1, x2, y2, x3, y3);
            if (this._ctx) {
                this._needsDash ? this._dashedBezierTo(x1, y1, x2, y2, x3, y3)
                    : this._ctx.bezierCurveTo(x1, y1, x2, y2, x3, y3);
            }
            this._xi = x3;
            this._yi = y3;
            return this;
        };
        PathProxy.prototype.quadraticCurveTo = function (x1, y1, x2, y2) {
            this.addData(CMD.Q, x1, y1, x2, y2);
            if (this._ctx) {
                this._needsDash ? this._dashedQuadraticTo(x1, y1, x2, y2)
                    : this._ctx.quadraticCurveTo(x1, y1, x2, y2);
            }
            this._xi = x2;
            this._yi = y2;
            return this;
        };
        PathProxy.prototype.arc = function (cx, cy, r, startAngle, endAngle, anticlockwise) {
            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) {
            if (this._ctx) {
                this._ctx.arcTo(x1, y1, x2, y2, radius);
            }
            return this;
        };
        PathProxy.prototype.rect = function (x, y, w, h) {
            this._ctx && this._ctx.rect(x, y, w, h);
            this.addData(CMD.R, x, y, w, h);
            return this;
        };
        PathProxy.prototype.closePath = function () {
            this.addData(CMD.Z);
            var ctx = this._ctx;
            var x0 = this._x0;
            var y0 = this._y0;
            if (ctx) {
                this._needsDash && this._dashedLineTo(x0, y0);
                ctx.closePath();
            }
            this._xi = x0;
            this._yi = y0;
            return this;
        };
        PathProxy.prototype.fill = function (ctx) {
            ctx && ctx.fill();
            this.toStatic();
        };
        PathProxy.prototype.stroke = function (ctx) {
            ctx && ctx.stroke();
            this.toStatic();
        };
        PathProxy.prototype.setLineDash = function (lineDash) {
            if (lineDash instanceof Array) {
                this._lineDash = lineDash;
                this._dashIdx = 0;
                var lineDashSum = 0;
                for (var i = 0; i < lineDash.length; i++) {
                    lineDashSum += lineDash[i];
                }
                this._dashSum = lineDashSum;
                this._needsDash = true;
            }
            else {
                this._lineDash = null;
                this._needsDash = false;
            }
            return this;
        };
        PathProxy.prototype.setLineDashOffset = function (offset) {
            this._dashOffset = offset;
            return this;
        };
        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._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._dashedLineTo = function (x1, y1) {
            var dashSum = this._dashSum;
            var lineDash = this._lineDash;
            var ctx = this._ctx;
            var offset = this._dashOffset;
            var x0 = this._xi;
            var y0 = this._yi;
            var dx = x1 - x0;
            var dy = y1 - y0;
            var dist = mathSqrt$1(dx * dx + dy * dy);
            var x = x0;
            var y = y0;
            var nDash = lineDash.length;
            var dash;
            var idx;
            dx /= dist;
            dy /= dist;
            if (offset < 0) {
                offset = dashSum + offset;
            }
            offset %= dashSum;
            x -= offset * dx;
            y -= offset * dy;
            while ((dx > 0 && x <= x1) || (dx < 0 && x >= x1)
                || (dx === 0 && ((dy > 0 && y <= y1) || (dy < 0 && y >= y1)))) {
                idx = this._dashIdx;
                dash = lineDash[idx];
                x += dx * dash;
                y += dy * dash;
                this._dashIdx = (idx + 1) % nDash;
                if ((dx > 0 && x < x0) || (dx < 0 && x > x0) || (dy > 0 && y < y0) || (dy < 0 && y > y0)) {
                    continue;
                }
                ctx[idx % 2 ? 'moveTo' : 'lineTo'](dx >= 0 ? mathMin$2(x, x1) : mathMax$2(x, x1), dy >= 0 ? mathMin$2(y, y1) : mathMax$2(y, y1));
            }
            dx = x - x1;
            dy = y - y1;
            this._dashOffset = -mathSqrt$1(dx * dx + dy * dy);
        };
        PathProxy.prototype._dashedBezierTo = function (x1, y1, x2, y2, x3, y3) {
            var ctx = this._ctx;
            var dashSum = this._dashSum;
            var offset = this._dashOffset;
            var lineDash = this._lineDash;
            var x0 = this._xi;
            var y0 = this._yi;
            var bezierLen = 0;
            var idx = this._dashIdx;
            var nDash = lineDash.length;
            var t;
            var dx;
            var dy;
            var x;
            var y;
            var tmpLen = 0;
            if (offset < 0) {
                offset = dashSum + offset;
            }
            offset %= dashSum;
            for (t = 0; t < 1; t += 0.1) {
                dx = cubicAt(x0, x1, x2, x3, t + 0.1)
                    - cubicAt(x0, x1, x2, x3, t);
                dy = cubicAt(y0, y1, y2, y3, t + 0.1)
                    - cubicAt(y0, y1, y2, y3, t);
                bezierLen += mathSqrt$1(dx * dx + dy * dy);
            }
            for (; idx < nDash; idx++) {
                tmpLen += lineDash[idx];
                if (tmpLen > offset) {
                    break;
                }
            }
            t = (tmpLen - offset) / bezierLen;
            while (t <= 1) {
                x = cubicAt(x0, x1, x2, x3, t);
                y = cubicAt(y0, y1, y2, y3, t);
                idx % 2 ? ctx.moveTo(x, y)
                    : ctx.lineTo(x, y);
                t += lineDash[idx] / bezierLen;
                idx = (idx + 1) % nDash;
            }
            (idx % 2 !== 0) && ctx.lineTo(x3, y3);
            dx = x3 - x;
            dy = y3 - y;
            this._dashOffset = -mathSqrt$1(dx * dx + dy * dy);
        };
        PathProxy.prototype._dashedQuadraticTo = function (x1, y1, x2, y2) {
            var x3 = x2;
            var y3 = y2;
            x2 = (x2 + 2 * x1) / 3;
            y2 = (y2 + 2 * y1) / 3;
            x1 = (this._xi + 2 * x1) / 3;
            y1 = (this._yi + 2 * y1) / 3;
            this._dashedBezierTo(x1, y1, x2, y2, x3, y3);
        };
        PathProxy.prototype.toStatic = function () {
            if (!this._saveData) {
                return;
            }
            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;
            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;
                }
                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++];
                        if (mathAbs(x - xi) > ux || mathAbs(y - yi) > uy || i === len - 1) {
                            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;
                        }
                        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.CMD = CMD;
        PathProxy.initDefaultProps = (function () {
            var proto = PathProxy.prototype;
            proto._saveData = true;
            proto._needsDash = false;
            proto._dashOffset = 0;
            proto._dashIdx = 0;
            proto._dashSum = 0;
            proto._ux = 0;
            proto._uy = 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$2 = 1e-4;
    function isAroundEqual(a, b) {
        return Math.abs(a - b) < EPSILON$2;
    }
    var roots = [-1, -1, -1];
    var extrema = [-1, -1];
    function swapExtrema() {
        var tmp = extrema[0];
        extrema[0] = extrema[1];
        extrema[1] = tmp;
    }
    function windingCubic(x0, y0, x1, y1, x2, y2, x3, y3, x, y) {
        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 = [
        'x', 'y', 'rotation', 'scaleX', 'scaleY', 'originX', 'originY', '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 |= Element.REDARAW_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, inBundle) { };
        Path.prototype.pathUpdated = function () {
            this.__dirty &= ~Path.SHAPE_CHANGED_BIT;
        };
        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 & Path.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 rectWithStroke = this._rectWithStroke || (this._rectWithStroke = rect.clone());
                if (this.__dirty || needsUpdateRect) {
                    rectWithStroke.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) {
                        rectWithStroke.width += w / lineScale;
                        rectWithStroke.height += w / lineScale;
                        rectWithStroke.x -= w / lineScale / 2;
                        rectWithStroke.y -= w / lineScale / 2;
                    }
                }
                return rectWithStroke;
            }
            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 |= Path.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 & Path.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.SHAPE_CHANGED_BIT = 4;
        Path.initDefaultProps = (function () {
            var pathProto = Path.prototype;
            pathProto.type = 'path';
            pathProto.strokeContainThreshold = 5;
            pathProto.segmentIgnoreThreshold = 0;
            pathProto.subPixelOptimize = false;
            pathProto.autoBatch = false;
            pathProto.__dirty = Element.REDARAW_BIT | Displayable.STYLE_CHANGED_BIT | Path.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 () {
            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;
            }
            var attachedTransform = this.attachedTransform;
            if (attachedTransform) {
                attachedTransform.updateTransform();
                var m = attachedTransform.transform;
                if (m) {
                    this.transform = this.transform || [];
                    copy$1(this.transform, m);
                }
                else {
                    this.transform = null;
                }
            }
            else {
                _super.prototype.update.call(this);
            }
        };
        ZRText.prototype.getComputedTransform = function () {
            if (this.__hostTarget) {
                this.__hostTarget.getComputedTransform();
                this.__hostTarget.updateInnerText(true);
            }
            return this.attachedTransform ? this.attachedTransform.getComputedTransform()
                : _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) {
            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 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(baseY, contentBlock.contentHeight, verticalAlign);
            if (needDrawBg || textPadding) {
                var outerWidth_1 = contentBlock.width;
                textPadding && (outerWidth_1 += textPadding[1] + textPadding[3]);
                var boxX = adjustTextX(baseX, outerWidth_1, textAlign);
                var boxY = adjustTextY(baseY, outerHeight, verticalAlign);
                needDrawBg && this._renderBackground(style, style, boxX, boxY, outerWidth_1, 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;
                }
                if (textStroke) {
                    subElStyle.stroke = textStroke;
                    subElStyle.lineWidth = style.lineWidth || defaultLineWidth;
                    subElStyle.lineDash = style.lineDash;
                    subElStyle.lineDashOffset = style.lineDashOffset || 0;
                }
                if (textFill) {
                    subElStyle.fill = textFill;
                }
                subElStyle.font = textFont;
                textY += lineHeight;
                if (fixedBoundingRect) {
                    el.setBoundingRect(new BoundingRect(adjustTextX(subElStyle.x, style.width, subElStyle.textAlign), adjustTextY(subElStyle.y, calculatedLineHeight, subElStyle.textBaseline), style.width, 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(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 = getStroke('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);
            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(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 isPlainBg = isString(textBackgroundColor);
            var textBorderRadius = style.borderRadius;
            var self = this;
            var rectEl;
            var imgEl;
            if (isPlainBg || (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 (isPlainBg) {
                var rectStyle = rectEl.style;
                rectStyle.fill = textBackgroundColor || null;
                rectStyle.fillOpacity = retrieve2(style.fillOpacity, 1);
            }
            else if (textBackgroundColor && textBackgroundColor.image) {
                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 (style.fontSize || style.fontFamily || style.fontWeight) {
                var fontSize = '';
                if (typeof style.fontSize === 'string'
                    && (style.fontSize.indexOf('px') !== -1
                        || style.fontSize.indexOf('rem') !== -1
                        || style.fontSize.indexOf('em') !== -1)) {
                    fontSize = style.fontSize;
                }
                else if (!isNaN(+style.fontSize)) {
                    fontSize = style.fontSize + 'px';
                }
                else {
                    fontSize = '12px';
                }
                font = [
                    style.fontStyle,
                    style.fontWeight,
                    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 };
    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.borderWidth && style.borderColor));
    }

    var getECData = makeInner();

    var _highlightNextDigit = 1;
    var _highlightKeyMap = {};
    var getSavedStates = 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 (typeof color$1 !== 'string') {
        return color$1;
      }

      var liftedColor = liftedColorCache.get(color$1);

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

      return liftedColor;
    }

    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 // Dont consider the animation to emphasis state.
        && animator.__fromStateTransition.indexOf(toStateName) < 0 && animator.targetName === 'style') {
          animator.saveFinalToTarget(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 || {}; // Apply default color lift

          var emphasisStyle = state.style || {};

          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;
    }
    /**FI
     * 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();
      model.eachComponent(function (componentType, componentModel) {
        var view = componentType === 'series' ? api.getViewOfSeriesModel(componentModel) : api.getViewOfComponentModel(componentModel); // Leave blur anyway

        view.group.traverse(function (child) {
          singleLeaveBlur(child);
        });
      });
    }
    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);
        }
      });
      ecModel.eachComponent(function (componentType, componentModel) {
        if (componentType === 'series') {
          return;
        }

        var view = api.getViewOfComponentModel(componentModel);

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

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

      if (!componentModel) {
        return;
      }

      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);
      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 handleGlboalMouseOutForHighDown(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 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]]();
      }
    }
    /**
     * @parame 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 hightlight/downplay record on each elements.
     * For the case: hover highlight/downplay (legend, visualMap, ...) and
     * user triggerred hightlight/downplay should not conflict.
     * Only all of the highlightDigit cleared, return to normal.
     * @param {string} highlightKey
     * @return {number} highlightDigit
     */

    function getHighlightDigit(highlightKey) {
      var highlightDigit = _highlightKeyMap[highlightKey];

      if (highlightDigit == null && _highlightNextDigit <= 32) {
        highlightDigit = _highlightKeyMap[highlightKey] = _highlightNextDigit++;
      }

      return highlightDigit;
    }
    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$2 = Math.sqrt;
    var mathAtan2 = Math.atan2;
    function transformPath(path, m) {
        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$2(m[0] * m[0] + m[1] * m[1]);
                    var sy = mathSqrt$2(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$3 = 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$3(lambda);
            ry *= mathSqrt$3(lambda);
        }
        var f = (fa === fs ? -1 : 1)
            * mathSqrt$3((((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];
            if (!pathEl.path) {
                pathEl.createPathProxy();
            }
            if (pathEl.shapeChanged()) {
                pathEl.buildPath(pathEl.path, pathEl.shape, true);
            }
            pathList.push(pathEl.path);
        }
        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;
    }

    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, inBundle) {
            if (inBundle) {
                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$4 = 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 x10 = x1 - x0;
        var y10 = y1 - y0;
        var x32 = x3 - x2;
        var y32 = y3 - y2;
        var t = y32 * x10 - x32 * y10;
        if (t * t < e) {
            return;
        }
        t = (x32 * (y0 - y2) - y32 * (x0 - x2)) / t;
        return [x0 + t * x10, y0 + t * y10];
    }
    function computeCornerTangents(x0, y0, x1, y1, radius, cr, clockwise) {
        var x01 = x0 - x1;
        var y01 = y0 - y1;
        var lo = (clockwise ? cr : -cr) / mathSqrt$4(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$4(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,
            x01: -ox,
            y01: -oy,
            x11: cx0 * (radius / r - 1),
            y11: cy0 * (radius / r - 1)
        };
    }
    function buildPath$1(ctx, shape) {
        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 clockwise = !!shape.clockwise;
        var startAngle = shape.startAngle;
        var endAngle = shape.endAngle;
        var arc;
        if (startAngle === endAngle) {
            arc = 0;
        }
        else {
            var tmpAngles = [startAngle, endAngle];
            normalizeArcAngles(tmpAngles, !clockwise);
            arc = mathAbs$1(tmpAngles[0] - tmpAngles[1]);
        }
        var x = shape.cx;
        var y = shape.cy;
        var cornerRadius = shape.cornerRadius || 0;
        var innerCornerRadius = shape.innerCornerRadius || 0;
        if (!(radius > e)) {
            ctx.moveTo(x, y);
        }
        else if (arc > PI2$5 - e) {
            ctx.moveTo(x + radius * mathCos$3(startAngle), y + radius * mathSin$3(startAngle));
            ctx.arc(x, y, radius, startAngle, endAngle, !clockwise);
            if (innerRadius > e) {
                ctx.moveTo(x + innerRadius * mathCos$3(endAngle), y + innerRadius * mathSin$3(endAngle));
                ctx.arc(x, y, innerRadius, endAngle, startAngle, clockwise);
            }
        }
        else {
            var halfRd = mathAbs$1(radius - innerRadius) / 2;
            var cr = mathMin$3(halfRd, cornerRadius);
            var icr = mathMin$3(halfRd, innerCornerRadius);
            var cr0 = icr;
            var cr1 = cr;
            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 xre = void 0;
            var yre = void 0;
            var xirs = void 0;
            var yirs = void 0;
            if (cr > e || icr > 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$4(x0 * x0 + y0 * y0) * mathSqrt$4(x1 * x1 + y1 * y1))) / 2);
                        var b = mathSqrt$4(it_1[0] * it_1[0] + it_1[1] * it_1[1]);
                        cr0 = mathMin$3(icr, (innerRadius - b) / (a - 1));
                        cr1 = mathMin$3(cr, (radius - b) / (a + 1));
                    }
                }
            }
            if (!(arc > e)) {
                ctx.moveTo(x + xrs, y + yrs);
            }
            else if (cr1 > e) {
                var ct0 = computeCornerTangents(xirs, yirs, xrs, yrs, radius, cr1, clockwise);
                var ct1 = computeCornerTangents(xre, yre, xire, yire, radius, cr1, clockwise);
                ctx.moveTo(x + ct0.cx + ct0.x01, y + ct0.cy + ct0.y01);
                if (cr1 < cr) {
                    ctx.arc(x + ct0.cx, y + ct0.cy, cr1, mathATan2(ct0.y01, ct0.x01), mathATan2(ct1.y01, ct1.x01), !clockwise);
                }
                else {
                    ctx.arc(x + ct0.cx, y + ct0.cy, cr1, mathATan2(ct0.y01, ct0.x01), mathATan2(ct0.y11, ct0.x11), !clockwise);
                    ctx.arc(x, y, radius, mathATan2(ct0.cy + ct0.y11, ct0.cx + ct0.x11), mathATan2(ct1.cy + ct1.y11, ct1.cx + ct1.x11), !clockwise);
                    ctx.arc(x + ct1.cx, y + ct1.cy, cr1, mathATan2(ct1.y11, ct1.x11), mathATan2(ct1.y01, ct1.x01), !clockwise);
                }
            }
            else {
                ctx.moveTo(x + xrs, y + yrs);
                ctx.arc(x, y, radius, startAngle, endAngle, !clockwise);
            }
            if (!(innerRadius > e) || !(arc > e)) {
                ctx.lineTo(x + xire, y + yire);
            }
            else if (cr0 > e) {
                var ct0 = computeCornerTangents(xire, yire, xre, yre, innerRadius, -cr0, clockwise);
                var ct1 = computeCornerTangents(xrs, yrs, xirs, yirs, innerRadius, -cr0, clockwise);
                ctx.lineTo(x + ct0.cx + ct0.x01, y + ct0.cy + ct0.y01);
                if (cr0 < icr) {
                    ctx.arc(x + ct0.cx, y + ct0.cy, cr0, mathATan2(ct0.y01, ct0.x01), mathATan2(ct1.y01, ct1.x01), !clockwise);
                }
                else {
                    ctx.arc(x + ct0.cx, y + ct0.cy, cr0, mathATan2(ct0.y01, ct0.x01), mathATan2(ct0.y11, ct0.x11), !clockwise);
                    ctx.arc(x, y, innerRadius, mathATan2(ct0.cy + ct0.y11, ct0.cx + ct0.x11), mathATan2(ct1.cy + ct1.y11, ct1.cx + ct1.x11), clockwise);
                    ctx.arc(x + ct1.cx, y + ct1.cy, cr0, mathATan2(ct1.y11, ct1.x11), mathATan2(ct1.y01, ct1.x01), !clockwise);
                }
            }
            else {
                ctx.lineTo(x + xire, y + yire);
                ctx.arc(x, y, 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;
            this.innerCornerRadius = 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 interpolate(p0, p1, p2, p3, t, t2, t3) {
        var v0 = (p2 - p0) * 0.5;
        var v1 = (p3 - p1) * 0.5;
        return (2 * (p1 - p2) + v0 + v1) * t3
            + (-3 * (p1 - p2) - 2 * v0 - v1) * t2
            + v0 * t + p1;
    }
    function smoothSpline(points, isLoop) {
        var len = points.length;
        var ret = [];
        var distance$1 = 0;
        for (var i = 1; i < len; i++) {
            distance$1 += distance(points[i - 1], points[i]);
        }
        var segs = distance$1 / 2;
        segs = segs < len ? len : segs;
        for (var i = 0; i < segs; i++) {
            var pos = i / (segs - 1) * (isLoop ? len : len - 1);
            var idx = Math.floor(pos);
            var w = pos - idx;
            var p0 = void 0;
            var p1 = points[idx % len];
            var p2 = void 0;
            var p3 = void 0;
            if (!isLoop) {
                p0 = points[idx === 0 ? idx : idx - 1];
                p2 = points[idx > len - 2 ? len - 1 : idx + 1];
                p3 = points[idx > len - 3 ? len - 1 : idx + 2];
            }
            else {
                p0 = points[(idx - 1 + len) % len];
                p2 = points[(idx + 1) % len];
                p3 = points[(idx + 2) % len];
            }
            var w2 = w * w;
            var w3 = w * w2;
            ret.push([
                interpolate(p0[0], p1[0], p2[0], p3[0], w, w2, w3),
                interpolate(p0[1], p1[1], p2[1], p3[1], w, w2, w3)
            ]);
        }
        return ret;
    }

    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 && smooth !== 'spline') {
                var controlPoints = smoothBezier(points, smooth, closePath, shape.smoothConstraint);
                ctx.moveTo(points[0][0], points[0][1]);
                var len = points.length;
                for (var i = 0; i < (closePath ? len : len - 1); i++) {
                    var cp1 = controlPoints[i * 2];
                    var cp2 = controlPoints[i * 2 + 1];
                    var p = points[(i + 1) % len];
                    ctx.bezierCurveTo(cp1[0], cp1[1], cp2[0], cp2[1], p[0], p[1]);
                }
            }
            else {
                if (smooth === 'spline') {
                    points = smoothSpline(points, closePath);
                }
                ctx.moveTo(points[0][0], points[0][1]);
                for (var i = 1, l = points.length; i < l; i++) {
                    ctx.lineTo(points[i][0], points[i][1]);
                }
            }
            closePath && ctx.closePath();
        }
    }

    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 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 register a shape named `'image'`,
     * the shape will not be used. If we intending to add some more reserved names
     * in feature, that might bring break changes (disable some existing user shape
     * names). But that case probably rearly happen. So we dont make more mechanism
     * to resolve this issue here.
     *
     * @param 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(param) {
      subPixelOptimizeLine(param.shape, param.shape, param.style);
      return param;
    }
    /**
     * 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;

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

      if (typeof dataIndex === 'function') {
        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 isUpdate = animationType === 'update';
      var isRemove = animationType === 'remove';
      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();

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

      if (animationEnabled) {
        var duration = void 0;
        var animationEasing = void 0;
        var animationDelay = void 0;

        if (animationPayload) {
          duration = animationPayload.duration || 0;
          animationEasing = animationPayload.easing || 'cubicOut';
          animationDelay = animationPayload.delay || 0;
        } else if (isRemove) {
          removeOpt = removeOpt || {};
          duration = retrieve2(removeOpt.duration, 200);
          animationEasing = retrieve2(removeOpt.easing, 'cubicOut');
          animationDelay = 0;
        } else {
          duration = animatableModel.getShallow(isUpdate ? 'animationDurationUpdate' : 'animationDuration');
          animationEasing = animatableModel.getShallow(isUpdate ? 'animationEasingUpdate' : 'animationEasing');
          animationDelay = animatableModel.getShallow(isUpdate ? 'animationDelayUpdate' : 'animationDelay');
        }

        if (typeof animationDelay === 'function') {
          animationDelay = animationDelay(dataIndex, animatableModel.getAnimationDelayParams ? animatableModel.getAnimationDelayParams(el, dataIndex) : null);
        }

        if (typeof duration === 'function') {
          duration = duration(dataIndex);
        }

        duration > 0 ? isFrom ? el.animateFrom(props, {
          duration: duration,
          delay: animationDelay || 0,
          easing: animationEasing,
          done: cb,
          force: !!cb || !!during,
          scope: animationType,
          during: during
        }) : el.animateTo(props, {
          duration: duration,
          delay: animationDelay || 0,
          easing: animationEasing,
          done: cb,
          force: !!cb || !!during,
          setToFinal: true,
          scope: animationType,
          during: during
        }) : ( // FIXME:
        // If `duration` is 0, only the animation on props
        // can be stoped, other animation should be continued?
        // But at present using duration 0 in `animateTo`, `animateFrom`
        // might cause unexpected behavior.
        el.stopAnimation(), // If `isFrom`, the props is the "from" props.
        !isFrom && el.attr(props), cb && cb());
      } else {
        el.stopAnimation();
        !isFrom && el.attr(props); // Call during 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('init', el, props, animatableModel, dataIndex, cb, during);
    }
    /**
     * Remove graphic element
     */

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

      animateOrSetProps('remove', 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);
          }
        });
      }
    }
    /**
     * 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 === 'remove') {
          return true;
        }
      }

      return false;
    }
    /**
     * 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 migth be incorrect when grpahic clipped by a corner.
      // and when element have border.
      return map(points, function (point) {
        var x = point[0];
        x = mathMax$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
      //     exising `k` such that `vec_m = k · vec_n`, equivalent to `vec_m X vec_n = 0`.

      var nmCrossProduct = crossProduct2d(nx, ny, mx, my);

      if (nearZero(nmCrossProduct)) {
        return false;
      } // `vec_m` and `vec_n` are intersect iff
      //     existing `p` and `q` in [0, 1] such that `vec_a1 + p * vec_m = vec_b1 + q * vec_n`,
      //     such that `q = ((vec_a1 - vec_b1) X vec_m) / (vec_n X vec_m)`
      //           and `p = ((vec_a1 - vec_b1) X vec_n) / (vec_n X vec_m)`.


      var b1a1x = a1x - b1x;
      var b1a1y = a1y - b1y;
      var q = crossProduct2d(b1a1x, b1a1y, mx, my) / nmCrossProduct;

      if (q < 0 || q > 1) {
        return false;
      }

      var p = crossProduct2d(b1a1x, b1a1y, nx, ny) / nmCrossProduct;

      if (p < 0 || p > 1) {
        return false;
      }

      return true;
    }
    /**
     * Cross product of 2-dimension vector.
     */

    function crossProduct2d(x1, y1, x2, y2) {
      return x1 * y2 - x2 * y1;
    }

    function nearZero(val) {
      return val <= 1e-6 && val >= -1e-6;
    }

    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)
      };
    } // Register built-in shapes. These shapes might be overwirtten
    // 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,
        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,
        updateProps: updateProps,
        initProps: initProps,
        removeElement: removeElement,
        removeElementWithFadeOut: removeElementWithFadeOut,
        isElementRemoved: isElementRemoved,
        getTransform: getTransform,
        applyTransform: applyTransform$1,
        transformDirection: transformDirection,
        groupTransition: groupTransition,
        clipPointsByRect: clipPointsByRect,
        clipRectByRect: clipRectByRect,
        createIcon: createIcon,
        linePolygonIntersect: linePolygonIntersect,
        lineLineIntersect: lineLineIntersect,
        setTooltipConfig: setTooltipConfig,
        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 slient 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) {
        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);
      }

      (currValue == null ? initProps : updateProps)(textEl, {}, animatableModel, dataIndex, null, during);
    }
    function enableLayoutLayoutFeatures(el, dataIndex, dataType) {
      getECData(el).dataIndex = dataIndex;
      getECData(el).dataType = dataType;
    }

    var PATH_COLOR = ['textStyle', 'color']; // TODO Performance improvement?

    var tmpRichText = 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) {
        tmpRichText.useStyle({
          text: text,
          fontStyle: this.getShallow('fontStyle'),
          fontWeight: this.getShallow('fontWeight'),
          fontSize: this.getShallow('fontSize'),
          fontFamily: this.getShallow('fontFamily'),
          verticalAlign: this.getShallow('verticalAlign') || this.getShallow('baseline'),
          padding: this.getShallow('padding'),
          lineHeight: this.getShallow('lineHeight'),
          rich: this.getShallow('rich')
        });
        tmpRichText.update();
        return tmpRichText.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 'xxx.yyy.zzz', 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 'xxx.yyy.zzz', so the return value type have to be `Model<ModelOption>`
      // getModel(path: string | string[], parentModel?: Model): Model;
      // TODO 'xxx.yyy.zzz' 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);
      };
      /**
       * Squash option stack into one.
       * parentModel will be removed after squashed.
       *
       * NOTE: resolveParentPath will not be applied here for simplicity. DON'T use this function
       * if resolveParentPath is modified.
       *
       * @param deepMerge If do deep merge. Default to be false.
       */
      // squash(
      //     deepMerge?: boolean,
      //     handleCallback?: (func: () => object) => object
      // ) {
      //     const optionStack = [];
      //     let model: Model = this;
      //     while (model) {
      //         if (model.option) {
      //             optionStack.push(model.option);
      //         }
      //         model = model.parentModel;
      //     }
      //     const newOption = {} as Opt;
      //     let option;
      //     while (option = optionStack.pop()) {    // Top down merge
      //         if (isFunction(option) && handleCallback) {
      //             option = handleCallback(option);
      //         }
      //         if (deepMerge) {
      //             merge(newOption, option);
      //         }
      //         else {
      //             extend(newOption, option);
      //         }
      //     }
      //     // Remove parentModel
      //     this.option = newOption;
      //     this.parentModel = null;
      // }

      /**
       * 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: 'Guage',
          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) / 4) + 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 (typeof formatter === 'string') {
        // Single formatter for all units at all levels
        template = formatter;
      } else if (typeof formatter === 'function') {
        // 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 = typeof value === 'number' ? 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 ? 'getUTCSeconds' : 'getSeconds';
    }
    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 ? 'setUTCSeconds' : 'setSeconds';
    }

    function getTextRect(text, font, align, verticalAlign, padding, rich, truncate, lineHeight) {
      deprecateLog('getTextRect is deprecated.');
      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;
    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];
      });
    }
    /**
     * 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) : '-';
    }
    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 repeatly 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 utc = isUTC ? 'UTC' : '';
      var y = date['get' + utc + 'FullYear']();
      var M = date['get' + utc + 'Month']() + 1;
      var d = date['get' + utc + 'Date']();
      var h = date['get' + utc + 'Hours']();
      var m = date['get' + utc + 'Minutes']();
      var s = date['get' + utc + 'Seconds']();
      var S = date['get' + utc + 'Milliseconds']();
      tpl = tpl.replace('MM', pad(M, 2)).replace('M', M).replace('yyyy', y).replace('yy', y % 100 + '').replace('dd', pad(d, 2)).replace('d', d).replace('hh', pad(h, 2)).replace('h', h).replace('mm', pad(m, 2)).replace('m', m).replace('ss', pad(s, 2)).replace('s', s).replace('SSS', pad(S, 3));
      return tpl;
    }
    /**
     * Capital first
     * @param {string} str
     * @return {string}
     */

    function capitalFirst(str) {
      return str ? str.charAt(0).toUpperCase() + str.substr(1) : str;
    }
    /**
     * @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. Traslate (with el.position by this method)
     * So this method only fixes the last step 'Traslate', which does not affect
     * scaling and rotating.
     *
     * If be called repeatly with the same input el, the same result will be gotten.
     *
     * @param 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) {
      var h = !opt || !opt.hv || opt.hv[0];
      var v = !opt || !opt.hv || opt.hv[1];
      var boundingMode = opt && opt.boundingMode || 'all';

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

      var rect;

      if (boundingMode === 'raw') {
        rect = el.type === 'group' ? new BoundingRect(0, 0, +positionInfo.width || 0, +positionInfo.height || 0) : el.getBoundingRect();
      } else {
        rect = el.getBoundingRect();

        if (el.needLocalTransform()) {
          var transform = el.getLocalTransform(); // Notice: raw rect may be inner object of el,
          // which should not be modified.

          rect = rect.clone();
          rect.applyTransform(transform);
        }
      } // The real width and height can not be specified but calculated by the given el.


      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') {
        el.x = dx;
        el.y = dy;
      } else {
        el.x += dx;
        el.y += dy;
      }

      el.markRedraw();
    }
    /**
     * @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';
       * 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';
       * import {XxxModel, XxxOption} from './XxxModel';
       * 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')
        };
      };

      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)',
      // https://dribbble.com/shots/1065960-Infographic-Pie-chart-visualization
      // color: ['#5793f3', '#d14a61', '#fd9c35', '#675bba', '#fec42c', '#dd4444', '#d4df5a', '#cd4870'],
      // Light colors:
      // color: ['#bcd3bb', '#e88f70', '#edc1a5', '#9dc5c8', '#e1e8c8', '#7b7c68', '#e5b5b5', '#f0b489', '#928ea8', '#bda29a'],
      // color: ['#cc5664', '#9bd6ec', '#ea946e', '#8acaaa', '#f1ec64', '#ee8686', '#a48dc1', '#5da6bc', '#b9dcae'],
      // Dark colors:
      // color: [
      //     '#c23531', '#2f4554', '#61a0a8', '#d48265', '#91c7ae', '#749f83',
      //     '#ca8622', '#bda29a', '#6e7074', '#546570', '#c4ccd3'
      // ],
      color: [// '#51689b', '#ce5c5c', '#fbc357', '#8fbf8f', '#659d84', '#fb8e6a', '#c77288', '#786090', '#91c4c5', '#6890ba'
      '#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', '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 mutiple series share one dimension
          // category axis, series name should better use
          // the other dimsion name. On the other hand, use
          // both dimensions name.
        } // In category way, the first category axis.
        else if (baseCategoryDimIndex === coordDimIdx) {
            pushDim(encode[coordDimName], 0, count);
            pushDim(encodeItemName, 0, count);
          } // In category way, the other axis.
          else {
              var start = datasetRecord.categoryWayDim;
              pushDim(encode[coordDimName], start, count);
              pushDim(encodeSeriesName, start, count);
              datasetRecord.categoryWayDim += count;
            }
      });

      function pushDim(dimIdxArr, idxFrom, idxCount) {
        for (var i = 0; i < idxCount; i++) {
          dimIdxArr.push(idxFrom + i);
        }
      }

      function getDataDimCountOnCoordDim(coordDimInfo) {
        var dimsDef = coordDimInfo.dimsDef;
        return dimsDef ? dimsDef.length : 1;
      }

      encodeItemName.length && (encode.itemName = encodeItemName);
      encodeSeriesName.length && (encode.seriesName = encodeSeriesName);
      return encode;
    }
    /**
     * Work for data like [{name: ..., value: ...}, ...].
     *
     * @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 use itemName in charts.
        // So we dont 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 = {};

    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 (!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']`.
        // Becuase 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)) {
            if ("development" !== 'production') {
              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;
              }
            } // 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;
          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("Unkown series " + subType);
                    }
                  }
                }

                return;
              }

              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.getLocale = function (localePosition) {
        var locale = this.getLocaleModel();
        return locale.get(localePosition);
      };

      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').slice(), function (oneSeries) {
          return !!oneSeries;
        });
      };
      /**
       * Count series before filtered.
       */


      GlobalModel.prototype.getSeriesCount = function () {
        return this._componentsCount.get('series');
      };
      /**
       * After filtering, series may be different
       * frome 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.
       * frome 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 can not be used outside,
          // i.e. `chart.setOption(chart.getModel().option);` is forbiden.
          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', '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 (creater, type) {
          var list = creater.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, becuase 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 opitons will not be merged to the formers, but just substitude 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 // lowser case for convenientce.

      };
      var applicatable = 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)) {
          applicatable = false;
        }
      });
      return applicatable;
    }

    function compare(real, expect, operator) {
      if (operator === 'min') {
        return real >= expect;
      } else if (operator === 'max') {
        return real <= expect;
      } else {
        // Equals
        return real === expect;
      }
    }

    function indicesEquals(indices1, indices2) {
      // indices is always order by asc and has only finite number.
      return indices1.join(',') === indices2.join(',');
    }

    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');
          }
        }
      });
      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 repeatly.
    //     Should be executed after series filtered and before stack calculation.

    function dataStack(ecModel) {
      var stackInfoMap = createHashMap();
      ecModel.eachSeries(function (seriesModel) {
        var stack = seriesModel.get('stack'); // Compatibal: when `stack` is set as '', do not stack.

        if (stack) {
          var stackInfoList = stackInfoMap.get(stack) || stackInfoMap.set(stack, []);
          var data = seriesModel.getData();
          var stackInfo = {
            // Used for calculate axis extent automatically.
            // 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; // Should not write on raw data, because stack series model list changes
        // depending on legend selection.

        var newData = targetData.map(dims, function (v0, v1, dataIndex) {
          var sum = targetData.get(targetStackInfo.stackedDimension, dataIndex); // Consider `connectNulls` of line area, if value is NaN, stackedOver
          // should also be NaN, to draw a appropriate belt area.

          if (isNaN(sum)) {
            return resultNaN;
          }

          var byValue;
          var stackedDataRawIndex;

          if (isStackedByIndex) {
            stackedDataRawIndex = targetData.getRawIndex(dataIndex);
          } else {
            byValue = targetData.get(targetStackInfo.stackedByDimension, dataIndex);
          } // If stackOver is NaN, chart view will render point on value start.


          var stackedOver = NaN;

          for (var j = idxInStack - 1; j >= 0; j--) {
            var stackInfo = stackInfoList[j]; // Has been optimized by inverted indices on `stackedByDimension`.

            if (!isStackedByIndex) {
              stackedDataRawIndex = stackInfo.data.rawIndexOf(stackInfo.stackedByDimension, byValue);
            }

            if (stackedDataRawIndex >= 0) {
              var val = stackInfo.data.getByRawIndex(stackInfo.stackResultDimension, stackedDataRawIndex); // Considering positive stack, negative stack and empty data

              if (sum >= 0 && val > 0 || // Positive stack
              sum <= 0 && val < 0 // Negative stack
              ) {
                  sum += val;
                  stackedOver = val;
                  break;
                }
            }
          }

          resultVal[0] = sum;
          resultVal[1] = stackedOver;
          return resultVal;
        });
        targetData.hostModel.setData(newData); // Update for consequent calculation

        targetStackInfo.data = newData;
      });
    }

    var SourceImpl =
    /** @class */
    function () {
      // readonly frozen: boolean;
      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.dimensionsDefine = fields.dimensionsDefine;
        this.dimensionsDetectedCount = fields.dimensionsDetectedCount;
        this.encodeDefine = fields.encodeDefine;
        this.metaRawOption = fields.metaRawOption;
      }

      return SourceImpl;
    }();

    function isSourceInstance(val) {
      return val instanceof SourceImpl;
    }
    function createSource(sourceData, thisMetaRawOption, // can be null. If not provided, auto detect it from `sourceData`.
    sourceFormat, encodeDefine // can be null
    ) {
      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,
        encodeDefine: makeEncodeDefine(encodeDefine),
        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,
        encodeDefine: makeEncodeDefine(source.encodeDefine)
      });
    }

    function makeEncodeDefine(encodeDefine) {
      // null means user not specify `series.encode`.
      return encodeDefine ? createHashMap(encodeDefine) : null;
    }
    /**
     * 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; // PEDING: could data be null/undefined here?
      // currently, if `dataset.source` not specified, error thrown.
      // if `series.data` not specified, nothing rendered without error thrown.
      // Should test these cases.

      if (!data) {
        return {
          dimensionsDefine: normalizeDimensionsOption(dimensionsDefine),
          startIndex: startIndex,
          dimensionsDetectedCount: dimensionsDetectedCount
        };
      }

      if (sourceFormat === SOURCE_FORMAT_ARRAY_ROWS) {
        var dataArrayRows = data; // Rule: Most of the first line are string: it is header.
        // Caution: consider a line with 5 string and 1 number,
        // it still can not be sure it is a head, because the
        // 5 string may be 5 values of category columns.

        if (sourceHeader === 'auto' || sourceHeader == null) {
          arrayRowsTravelFirst(function (val) {
            // '-' is regarded as null/undefined.
            if (val != null && val !== '-') {
              if (isString(val)) {
                startIndex == null && (startIndex = 1);
              } else {
                startIndex = 0;
              }
            } // 10 is an experience number, avoid long loop.

          }, seriesLayoutBy, dataArrayRows, 10);
        } else {
          startIndex = isNumber(sourceHeader) ? sourceHeader : sourceHeader ? 1 : 0;
        }

        if (!dimensionsDefine && startIndex === 1) {
          dimensionsDefine = [];
          arrayRowsTravelFirst(function (val, index) {
            dimensionsDefine[index] = val != null ? val + '' : '';
          }, seriesLayoutBy, dataArrayRows, Infinity);
        }

        dimensionsDetectedCount = dimensionsDefine ? dimensionsDefine.length : seriesLayoutBy === SERIES_LAYOUT_BY_ROW ? dataArrayRows.length : dataArrayRows[0] ? dataArrayRows[0].length : null;
      } else if (sourceFormat === SOURCE_FORMAT_OBJECT_ROWS) {
        if (!dimensionsDefine) {
          dimensionsDefine = objectRowsCollectDimensions(data);
        }
      } else if (sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS) {
        if (!dimensionsDefine) {
          dimensionsDefine = [];
          each(data, function (colArr, key) {
            dimensionsDefine.push(key);
          });
        }
      } else if (sourceFormat === SOURCE_FORMAT_ORIGINAL) {
        var value0 = getDataItemValue(data[0]);
        dimensionsDetectedCount = isArray(value0) && value0.length || 1;
      } else if (sourceFormat === SOURCE_FORMAT_TYPED_ARRAY) {
        if ("development" !== 'production') {
          assert(!!dimensionsDefine, 'dimensions must be given if data is TypedArray.');
        }
      }

      return {
        startIndex: startIndex,
        dimensionsDefine: normalizeDimensionsOption(dimensionsDefine),
        dimensionsDetectedCount: dimensionsDetectedCount
      };
    }

    function objectRowsCollectDimensions(data) {
      var firstIndex = 0;
      var obj;

      while (firstIndex < data.length && !(obj = data[firstIndex++])) {} // jshint ignore: line


      if (obj) {
        var dimensions_1 = [];
        each(obj, function (value, key) {
          dimensions_1.push(key);
        });
        return dimensions_1;
      }
    } // Consider dimensions defined like ['A', 'price', 'B', 'price', 'C', 'price'],
    // which is reasonable. But dimension name is duplicated.
    // Returns undefined or an array contains only object without null/undefiend 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 dont auto specify name, othewise a given name may
        // cause it be refered unexpectedly.

        if (item.name == null) {
          return item;
        } // Also consider number form like 2012.


        item.name += ''; // User may also specify displayName.
        // displayName will always exists except user not
        // specified or dim name is not specified or detected.
        // (A auto generated dim name will not be used as
        // displayName).

        if (item.displayName == null) {
          item.displayName = item.name;
        }

        var exist = nameMap.get(item.name);

        if (!exist) {
          nameMap.set(item.name, {
            count: 1
          });
        } else {
          item.name += '-' + exist.count++;
        }

        return item;
      });
    }

    function arrayRowsTravelFirst(cb, seriesLayoutBy, data, maxLoop) {
      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);
        }
      }
    }

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

      for (var i = 0; i < data.length; i++) {
        var row = data[i];
        item.push(row ? row[idx] : null);
      }

      return item;
    }, _a[SOURCE_FORMAT_OBJECT_ROWS] = getItemSimply, _a[SOURCE_FORMAT_KEYED_COLUMNS] = function (rawData, startIndex, dimsDef, idx) {
      var item = [];

      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.push(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 suppport 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 suppport count on "' + sourceFormat + '", "' + seriesLayoutBy + '".');
      }

      return method;
    }

    var getRawValueSimply = function (dataItem, dimIndex, dimName) {
      return dimIndex != null ? dataItem[dimIndex] : dataItem;
    };

    var rawSourceValueGetterMap = (_c = {}, _c[SOURCE_FORMAT_ARRAY_ROWS] = getRawValueSimply, _c[SOURCE_FORMAT_OBJECT_ROWS] = function (dataItem, dimIndex, dimName) {
      return dimIndex != null ? dataItem[dimName] : dataItem;
    }, _c[SOURCE_FORMAT_KEYED_COLUMNS] = getRawValueSimply, _c[SOURCE_FORMAT_ORIGINAL] = function (dataItem, dimIndex, dimName) {
      // FIXME: In some case (markpoint in geo (geo-map.html)),
      // dataItem is {coord: [...]}
      var value = getDataItemValue(dataItem);
      return dimIndex == null || !(value instanceof Array) ? value : value[dimIndex];
    }, _c[SOURCE_FORMAT_TYPED_ARRAY] = getRawValueSimply, _c);
    function getRawSourceValueGetter(sourceFormat) {
      var method = rawSourceValueGetterMap[sourceFormat];

      if ("development" !== 'production') {
        assert(method, 'Do not suppport 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, dim // If dimIndex is null/undefined, return OptionDataItem.
    // Otherwise, return OptionDataValue.
    ) {
      if (!data) {
        return;
      } // Consider data may be not persistent.


      var dataItem = data.getRawDataItem(dataIndex);

      if (dataItem == null) {
        return;
      }

      var sourceFormat = data.getProvider().getSource().sourceFormat;
      var dimName;
      var dimIndex;
      var dimInfo = data.getDimensionInfo(dim);

      if (dimInfo) {
        dimName = dimInfo.name;
        dimIndex = dimInfo.index;
      }

      return getRawSourceValueGetter(sourceFormat)(dataItem, dimIndex, dimName);
    }

    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;
        return {
          componentType: mainType,
          componentSubType: this.subType,
          componentIndex: this.componentIndex,
          seriesType: isSeries ? this.subType : null,
          seriesIndex: this.seriesIndex,
          seriesId: isSeries ? this.id : null,
          seriesName: isSeries ? this.name : null,
          name: name,
          dataIndex: rawDataIndex,
          data: itemOpt,
          dataType: dataType,
          value: rawValue,
          color: color,
          borderColor: borderColor,
          dimensionNames: userOutput ? userOutput.dimensionNames : null,
          encode: userOutput ? userOutput.encode : null,
          // 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 (typeof formatter === 'function') {
          params.status = status;
          params.dimensionIndex = labelDimIndex;
          return formatter(params);
        } else if (typeof formatter === 'string') {
          var str = formatTpl(formatter, params); // Support 'aaa{@[3]}bbb{@product}ccc'.
          // Do not support '}' in dim name util have to.

          return str.replace(DIMENSION_LABEL_REG, function (origin, dimStr) {
            var len = dimStr.length;
            var dimLoose = dimStr.charAt(0) === '[' && dimStr.charAt(len - 1) === ']' ? +dimStr.slice(1, len - 1) // Also support: '[]' => 0
            : dimStr;
            var val = retrieveRawValue(data, dataIndex, dimLoose);

            if (extendParams && isArray(extendParams.interpolatedValue)) {
              var dimInfo = data.getDimensionInfo(dimLoose);

              if (dimInfo) {
                val = extendParams.interpolatedValue[dimInfo.index];
              }
            }

            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 becuase in 'richText' it is not a HTML
    //     // string. But still support it for backward compat.
    //     html: string;
    //     markers: Dictionary<ColorString>;
    // };

    /**
     * For backward compat, normalize the return from `formatTooltip`.
     */

    function normalizeTooltipFormatResult(result // markersExisting: Dictionary<ColorString>
    ) {
      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 {
        markupText: markupText,
        // markers: markers || markersExisting,
        markupFragment: 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 happend in dataTask, dataZoom, map, currently.
        // where dataZoom do not set end each time, but only set
        // when reset. So we should record the setted end, in case
        // that the stub of dataZoom perform again and earse the
        // setted end by upstream.
        this._outputDueEnd = this._settedOutputEnd = end;
      };

      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 compatibiliy, do not modify it until 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
        var ordinalMeta = opt && opt.ordinalMeta;
        return ordinalMeta ? ordinalMeta.parseAndCollect(value) : value;
      }

      if (dimType === 'time' // spead up when using timestamp
      && typeof value !== 'number' && value != null && value !== '-') {
        value = +parseDate(value);
      } // dimType defaults 'number'.
      // If dimType is not ordinal and value is null or undefined or NaN or '-',
      // parse to NaN.
      // 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 by defualt `numericToNumber`.
        // 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 typeof val === 'string' ? 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 (typeof rval !== 'number') {
          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 typeof lval === 'number' ? this._opFn(lval, this._rvalFloat) : this._opFn(numericToNumber(lval), this._rvalFloat);
      };

      return FilterOrderComparator;
    }();

    var SortOrderComparator =
    /** @class */
    function () {
      /**
       * @param order by defualt: 'asc'
       * @param incomparable by defualt: 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 lvalTypeof = typeof lval;
        var rvalTypeof = typeof rval;
        var lvalFloat = lvalTypeof === 'number' ? lval : numericToNumber(lval);
        var rvalFloat = rvalTypeof === 'number' ? 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 = lvalTypeof === 'string';
          var rvalIsStr = rvalTypeof === 'string';

          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 make sence when 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
     *   void 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,
       * becuase 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.
      // Becuase the dimension is probably auto detected from data and not might reliable.
      // Should not lead the transformers to think that is relialbe 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 not sepcify dimension name. For simplicity, data transform
          // do not generate dimension name.

          if (name != null) {
            // Dimension name should not be duplicated.
            // For simplicity, data transform forbid 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 (typeof dim === 'number' // 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');
          consoleLog(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 becuase:
          // (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, null);
      });
    }

    function isSupportedSourceFormat(sourceFormat) {
      return sourceFormat === SOURCE_FORMAT_ARRAY_ROWS || sourceFormat === SOURCE_FORMAT_OBJECT_ROWS;
    }

    /**
     * [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 transfroms.
     * 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 = []; // version sign of each upstream source manager.

        this._upstreamSignList = [];
        this._versionSignBase = 0;
        this._sourceHost = sourceHost;
      }
      /**
       * Mark dirty.
       */


      SourceManager.prototype.dirty = function () {
        this._setLocalSource([], []);
      };

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

      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 : null;
          var seriesLayoutBy = retrieve2(newMetaRawOption.seriesLayoutBy, upMetaRawOption ? upMetaRawOption.seriesLayoutBy : null);
          var sourceHeader = retrieve2(newMetaRawOption.sourceHeader, upMetaRawOption ? upMetaRawOption.sourceHeader : null); // 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 ? upMetaRawOption.dimensions : null);
          resultSourceList = [createSource(data, {
            seriesLayoutBy: seriesLayoutBy,
            sourceHeader: sourceHeader,
            dimensions: dimensions
          }, sourceFormat, seriesModel.get('encode', true))];
        } 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, // Note: dataset option does not have `encode`.
              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 () {
        var sourceList = this._sourceList;

        if (!sourceList.length) {
          return true;
        } // All sourceList is from the some upsteam.


        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 defualt 0, means "main source".
       *                    Most cases there is only one source.
       */


      SourceManager.prototype.getSource = function (sourceIndex) {
        return this._sourceList[sourceIndex || 0];
      };
      /**
       * PEDING: 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
        // no need to update them when change happen.
        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 transfrom 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 getBuilder(fragment) {
      return hasOwn(builderMap, fragment.type) && builderMap[fragment.type];
    }

    var builderMap = {
      /**
       * A `section` block is like:
       * ```
       * header
       * subBlock
       * subBlock
       * ...
       * ```
       */
      section: {
        planLayout: function (fragment) {
          var subBlockLen = fragment.blocks.length;
          var thisBlockHasInnerGap = subBlockLen > 1 || subBlockLen > 0 && !fragment.noHeader;
          var thisGapLevelBetweenSubBlocks = 0;
          each(fragment.blocks, function (subBlock) {
            getBuilder(subBlock).planLayout(subBlock);
            var subGapLevel = subBlock.__gapLevelBetweenSubBlocks; // 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 >= thisGapLevelBetweenSubBlocks) {
              thisGapLevelBetweenSubBlocks = subGapLevel + (thisBlockHasInnerGap && ( // 0 always can not be readable gap level.
              !subGapLevel // If no header, always keep the sub gap level. Otherwise
              // look weird in case `multipleSeries`.
              || subBlock.type === 'section' && !subBlock.noHeader) ? 1 : 0);
            }
          });
          fragment.__gapLevelBetweenSubBlocks = thisGapLevelBetweenSubBlocks;
        },
        build: function (ctx, fragment, topMarginForOuterGap, toolTipTextStyle) {
          var noHeader = fragment.noHeader;
          var gaps = getGap(fragment);
          var subMarkupText = buildSubBlocks(ctx, fragment, noHeader ? topMarginForOuterGap : gaps.html, toolTipTextStyle);

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

      /**
       * A `nameValue` block is like:
       * ```
       * marker  name  value
       * ```
       */
      nameValue: {
        planLayout: function (fragment) {
          fragment.__gapLevelBetweenSubBlocks = 0;
        },
        build: function (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 value = fragment.value;
          var useUTC = ctx.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 ? [] : isArray(value) ? map(value, function (val, idx) {
            return makeValueReadable(val, isArray(valueTypeOption) ? valueTypeOption[idx] : valueTypeOption, useUTC);
          }) : [makeValueReadable(value, isArray(valueTypeOption) ? valueTypeOption[0] : valueTypeOption, useUTC)];
          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);
        }
      }
    };

    function buildSubBlocks(ctx, fragment, topMarginForOuterGap, tooltipTextStyle) {
      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();
          }
      }

      var gaps = getGap(fragment);
      each(subBlocks, function (subBlock, idx) {
        var subMarkupText = getBuilder(subBlock).build(ctx, subBlock, idx > 0 ? gaps.html : 0, tooltipTextStyle);
        subMarkupText != null && subMarkupTextList.push(subMarkupText);
      });

      if (!subMarkupTextList.length) {
        return;
      }

      return ctx.renderMode === 'richText' ? subMarkupTextList.join(gaps.richText) : wrapBlockHTML(subMarkupTextList.join(''), topMarginForOuterGap);
    }
    /**
     * @return markupText. null/undefined means no content.
     */


    function buildTooltipMarkup(fragment, markupStyleCreator, renderMode, orderMode, useUTC, toolTipTextStyle) {
      if (!fragment) {
        return;
      }

      var builder = getBuilder(fragment);
      builder.planLayout(fragment);
      var ctx = {
        useUTC: useUTC,
        renderMode: renderMode,
        orderMode: orderMode,
        markupStyleCreator: markupStyleCreator
      };
      return builder.build(ctx, fragment, 0, toolTipTextStyle);
    }

    function getGap(fragment) {
      var gapLevelBetweenSubBlocks = fragment.__gapLevelBetweenSubBlocks;
      return {
        html: HTML_GAPS[gapLevelBetweenSubBlocks],
        richText: RICH_TEXT_GAPS[gapLevelBetweenSubBlocks]
      };
    }

    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 : '';
      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, valueList, 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(valueList.join('  '), styles);
    }

    function retrieveVisualColorForTooltipMarker(series, dataIndex) {
      var style = series.getData().getItemVisual(dataIndex, 'style');
      var color = style[series.visualDrawType];
      return convertToColorString(color);
    }
    function getPaddingFromTooltipModel(model, renderMode) {
      var padding = model.get('padding');
      return padding != null ? padding // We give slightly different to look pretty.
      : renderMode === 'richText' ? [8, 10] : 10;
    }
    /**
     * The major feature is generate styles for `renderMode: 'richText'`.
     * But it also serves `renderMode: 'html'` to provide
     * "renderMode-independent" API.
     */

    var TooltipMarkupStyleCreator =
    /** @class */
    function () {
      function TooltipMarkupStyleCreator() {
        this.richTextStyles = {}; // Notice that "generate a style name" usuall happens repeatly when mouse moving and
        // displaying a tooltip. So we put the `_nextStyleNameId` as a member of each creator
        // rather than static shared by all creators (which will cause it increase to fast).

        this._nextStyleNameId = getRandomIdBase();
      }

      TooltipMarkupStyleCreator.prototype._generateStyleName = function () {
        return '__EC_aUTo_' + this._nextStyleNameId++;
      };

      TooltipMarkupStyleCreator.prototype.makeTooltipMarker = function (markerType, colorStr, renderMode) {
        var markerId = renderMode === 'richText' ? this._generateStyleName() : null;
        var marker = getTooltipMarker({
          color: colorStr,
          type: markerType,
          renderMode: renderMode,
          markerId: markerId
        });

        if (isString(marker)) {
          return marker;
        } else {
          if ("development" !== 'production') {
            assert(markerId);
          }

          this.richTextStyles[markerId] = marker.style;
          return marker.content;
        }
      };
      /**
       * @usage
       * ```ts
       * const styledText = markupStyleCreator.wrapRichTextStyle([
       *     // The styles will be auto merged.
       *     {
       *         fontSize: 12,
       *         color: 'blue'
       *     },
       *     {
       *         padding: 20
       *     }
       * ]);
       * ```
       */


      TooltipMarkupStyleCreator.prototype.wrapRichTextStyle = function (text, styles) {
        var finalStl = {};

        if (isArray(styles)) {
          each(styles, function (stl) {
            return extend(finalStl, stl);
          });
        } else {
          extend(finalStl, styles);
        }

        var styleName = this._generateStyleName();

        this.richTextStyles[styleName] = finalStl;
        return "{" + styleName + "|" + text + "}";
      };

      return TooltipMarkupStyleCreator;
    }();

    function defaultSeriesFormatTooltip(opt) {
      var series = opt.series;
      var dataIndex = opt.dataIndex;
      var multipleSeries = opt.multipleSeries;
      var data = series.getData();
      var tooltipDims = data.mapDimensionsAll('defaultedTooltip');
      var tooltipDimLen = tooltipDims.length;
      var value = series.getRawValue(dataIndex);
      var isValueArr = isArray(value);
      var markerColor = retrieveVisualColorForTooltipMarker(series, dataIndex); // Complicated rule for pretty tooltip.

      var inlineValue;
      var inlineValueType;
      var subBlocks;
      var sortParam;

      if (tooltipDimLen > 1 || isValueArr && !tooltipDimLen) {
        var formatArrResult = formatTooltipArrayValue(value, series, dataIndex, tooltipDims, markerColor);
        inlineValue = formatArrResult.inlineValues;
        inlineValueType = formatArrResult.inlineValueTypes;
        subBlocks = formatArrResult.blocks; // Only support tooltip sort by the first inline value. It's enough in most cases.

        sortParam = formatArrResult.inlineValues[0];
      } else if (tooltipDimLen) {
        var dimInfo = data.getDimensionInfo(tooltipDims[0]);
        sortParam = inlineValue = retrieveRawValue(data, dataIndex, tooltipDims[0]);
        inlineValueType = dimInfo.type;
      } else {
        sortParam = inlineValue = isValueArr ? value[0] : value;
      } // Do not show generated series name. It might not be readable.


      var seriesNameSpecified = isNameSpecified(series);
      var seriesName = seriesNameSpecified && series.name || '';
      var itemName = data.getName(dataIndex);
      var inlineName = multipleSeries ? seriesName : itemName;
      return createTooltipMarkup('section', {
        header: seriesName,
        // When series name not specified, do not show a header line with only '-'.
        // This case alway happen in tooltip.trigger: 'item'.
        noHeader: multipleSeries || !seriesNameSpecified,
        sortParam: sortParam,
        blocks: [createTooltipMarkup('nameValue', {
          markerType: 'item',
          markerColor: markerColor,
          // Do not mix display seriesName and itemName in one tooltip,
          // which might confuses users.
          name: inlineName,
          // name dimension might be auto assigned, where the name might
          // be not readable. So we check trim here.
          noName: !trim(inlineName),
          value: inlineValue,
          valueType: inlineValueType
        })].concat(subBlocks || [])
      });
    }

    function formatTooltipArrayValue(value, series, dataIndex, tooltipDims, colorStr) {
      // check: category-no-encode-has-axis-data in dataset.html
      var data = series.getData();
      var isValueMultipleLine = reduce(value, function (isValueMultipleLine, val, idx) {
        var dimItem = data.getDimensionInfo(idx);
        return isValueMultipleLine = isValueMultipleLine || dimItem && dimItem.tooltip !== false && dimItem.displayName != null;
      }, false);
      var inlineValues = [];
      var inlineValueTypes = [];
      var blocks = [];
      tooltipDims.length ? each(tooltipDims, function (dim) {
        setEachItem(retrieveRawValue(data, dataIndex, dim), dim);
      }) // By default, all dims is used on tooltip.
      : each(value, setEachItem);

      function setEachItem(val, dim) {
        var dimInfo = data.getDimensionInfo(dim); // If `dimInfo.tooltip` is not set, show tooltip.

        if (!dimInfo || dimInfo.otherDims.tooltip === false) {
          return;
        }

        if (isValueMultipleLine) {
          blocks.push(createTooltipMarkup('nameValue', {
            markerType: 'subItem',
            markerColor: colorStr,
            name: dimInfo.displayName,
            value: val,
            valueType: dimInfo.type
          }));
        } else {
          inlineValues.push(val);
          inlineValueTypes.push(dimInfo.type);
        }
      }

      return {
        inlineValues: inlineValues,
        inlineValueTypes: inlineValueTypes,
        blocks: blocks
      };
    }

    var inner$1 = makeInner();

    function getSelectionKey(data, dataIndex) {
      return data.getName(dataIndex) || data.getId(dataIndex);
    }

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

      function SeriesModel() {
        // [Caution]: Becuase 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/linkList
        // Theoretically, it is unreasonable to call `seriesModel.getData()` in the model
        // init or merge stage, because the data can be restored. So we do not `restoreData`
        // and `setData` here, which forbids calling `seriesModel.getData()` in this stage.
        // Call `seriesModel.getRawData()` instead.
        // this.restoreData();

        autoSeriesName(this);

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


      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.getSource = function () {
        return inner$1(this).sourceManager.getSource();
      };
      /**
       * Get data before processed
       */


      SeriesModel.prototype.getRawData = function () {
        return inner$1(this).dataBeforeProcessed;
      };
      /**
       * Get base axis if has coordinate system and has axis.
       * By default use coordSys.getBaseAxis();
       * Can be overrided for some chart.
       * @return {type} description
       */


      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 () {
        if (env.node) {
          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 data = this.getData(dataType);

        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 () {
        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);
        var nameOrId = getSelectionKey(data, dataIndex);
        return selectedMap[nameOrId] || false;
      };

      SeriesModel.prototype._innerSelect = function (data, innerDataIndices) {
        var _a, _b;

        var selectedMode = this.option.selectedMode;
        var len = innerDataIndices.length;

        if (!selectedMode || !len) {
          return;
        }

        if (selectedMode === 'multiple') {
          var selectedMap = this.option.selectedMap || (this.option.selectedMap = {});

          for (var i = 0; i < len; i++) {
            var dataIndex = innerDataIndices[i]; // TODO diffrent 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);
          this.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.useColorPaletteOnData = false;
        proto.ignoreStyleOnData = false;
        proto.hasSymbolVisual = false;
        proto.defaultSymbol = 'circle'; // Make sure the values can be accessed!

        proto.visualStyleAccessPath = 'itemStyle';
        proto.visualDrawType = 'fill';
      }();

      return SeriesModel;
    }(ComponentModel);

    mixin(SeriesModel, DataFormatMixin);
    mixin(SeriesModel, PaletteMixin);
    mountExtend(SeriesModel, ComponentModel);
    /**
     * MUST be called after `prepareSource` called
     * Here we need to make auto series, especially for auto legend. But we
     * do not modify series.name in option to avoid side effects.
     */

    function autoSeriesName(seriesModel) {
      // User specified name has higher priority, otherwise it may cause
      // series can not be queried unexpectedly.
      var name = seriesModel.name;

      if (!isNameSpecified(seriesModel)) {
        seriesModel.name = getSeriesAutoName(seriesModel) || name;
      }
    }

    function getSeriesAutoName(seriesModel) {
      var data = seriesModel.getRawData();
      var dataDims = data.mapDimensionsAll('seriesName');
      var nameArr = [];
      each(dataDims, function (dataDim) {
        var dimInfo = data.getDimensionInfo(dataDim);
        dimInfo.displayName && nameArr.push(dimInfo.displayName);
      });
      return nameArr.join(' ');
    }

    function dataTaskCount(context) {
      return context.model.getRawData().count();
    }

    function dataTaskReset(context) {
      var seriesModel = context.model;
      seriesModel.setData(seriesModel.getRawData().cloneShallow());
      return dataTaskProgress;
    }

    function dataTaskProgress(param, context) {
      // Avoid repead cloneShallow when data just created in reset.
      if (context.outputData && param.end > context.outputData.count()) {
        context.model.getRawData().cloneShallow(context.outputData);
      }
    } // TODO refactor


    function wrapData(data, seriesModel) {
      each(__spreadArrays(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 blur target series.
       * Can be used in marker for blur the markers
       */


      ComponentView.prototype.blurSeries = function (seriesModels, ecModel) {// Do nothing;
      };

      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) {};
      /**
       * Highlight series or specified data item.
       */


      ChartView.prototype.highlight = function (seriesModel, ecModel, api, payload) {
        toggleHighlight(seriesModel.getData(), payload, 'emphasis');
      };
      /**
       * Downplay series or specified data item.
       */


      ChartView.prototype.downplay = function (seriesModel, ecModel, api, payload) {
        toggleHighlight(seriesModel.getData(), 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);
      };

      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) {
        (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]) {
        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("Unkown 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("Unkown 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. Bacause 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' || typeof globalStyle.fill === 'function' ? colorPalette : globalStyle.fill;
          globalStyle.stroke = globalStyle.stroke === 'auto' || typeof globalStyle.stroke === 'function' ? 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 use one scope.
        // Pie and funnel are using diferrent scopes
        var paletteScopeGroupByType = createHashMap();
        ecModel.eachSeries(function (seriesModel) {
          if (!seriesModel.useColorPaletteOnData) {
            return;
          }

          var colorScope = paletteScopeGroupByType.get(seriesModel.type);

          if (!colorScope) {
            colorScope = {};
            paletteScopeGroupByType.set(seriesModel.type, colorScope);
          }

          inner$3(seriesModel).scope = colorScope;
        });
        ecModel.eachSeries(function (seriesModel) {
          if (!seriesModel.useColorPaletteOnData || 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 decalare `performRawSeries` in handlers, only
              // stream-independent (specifically, data item independent) operations can be
              // performed. Because is a series is filtered, most of the tasks will not
              // be performed. A stream-dependent operation probably cause wrong biz logic.
              // Perhaps we should not provide a separate callback for this case instead
              // of providing the config `performRawSeries`. The stream-dependent operaions
              // and stream-independent operations should better not be mixed.

              performArgs.skip = !stageHandler.performRawSeries && ecModel.isSeriesFiltered(task.context.model);
              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" do not supported for "overallReset", ' + 'becuase 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 legancy case), the overall task will only be
        // executed when upstream dirty. Otherwise the progressive rendering of all
        // pipelines will be disabled unexpectedly. But it still needs stubs to receive
        // dirty info from upsteam.
        else {
            overallProgress = false;
            each(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 wont be used in next trigger.
        this.eventInfo = null;
      };

      return ECEventProcessor;
    }();

    var seriesSymbolTask = {
      createOnAllSeries: true,
      // For legend.
      performRawSeries: true,
      reset: function (seriesModel, ecModel) {
        var data = seriesModel.getData();

        if (seriesModel.legendSymbol) {
          data.setVisual('legendSymbol', seriesModel.legendSymbol);
        }

        if (!seriesModel.hasSymbolVisual) {
          return;
        }

        var symbolType = seriesModel.get('symbol');
        var symbolSize = seriesModel.get('symbolSize');
        var keepAspect = seriesModel.get('symbolKeepAspect');
        var symbolRotate = seriesModel.get('symbolRotate');
        var symbolOffset = seriesModel.get('symbolOffset');
        var hasSymbolTypeCallback = isFunction(symbolType);
        var hasSymbolSizeCallback = isFunction(symbolSize);
        var hasSymbolRotateCallback = isFunction(symbolRotate);
        var hasSymbolOffsetCallback = isFunction(symbolOffset);
        var hasCallback = hasSymbolTypeCallback || hasSymbolSizeCallback || hasSymbolRotateCallback || hasSymbolOffsetCallback;
        var seriesSymbol = !hasSymbolTypeCallback && symbolType ? symbolType : seriesModel.defaultSymbol;
        var seriesSymbolSize = !hasSymbolSizeCallback ? symbolSize : null;
        var seriesSymbolRotate = !hasSymbolRotateCallback ? symbolRotate : null;
        var seriesSymbolOffset = !hasSymbolOffsetCallback ? symbolOffset : null;
        data.setVisual({
          legendSymbol: seriesModel.legendSymbol || seriesSymbol,
          // If seting callback functions on `symbol` or `symbolSize`, for simplicity and avoiding
          // to bring trouble, we do not pick a reuslt from one of its calling on data item here,
          // but just use the default value. Callback on `symbol` or `symbolSize` is convenient in
          // some cases but generally it is not recommanded.
          symbol: seriesSymbol,
          symbolSize: seriesSymbolSize,
          symbolKeepAspect: keepAspect,
          symbolRotate: seriesSymbolRotate,
          symbolOffset: seriesSymbolOffset
        }); // Only visible series has each data be visual encoded

        if (ecModel.isSeriesFiltered(seriesModel)) {
          return;
        }

        function dataEach(data, idx) {
          var rawValue = seriesModel.getRawValue(idx);
          var params = seriesModel.getDataParams(idx);
          hasSymbolTypeCallback && data.setItemVisual(idx, 'symbol', symbolType(rawValue, params));
          hasSymbolSizeCallback && data.setItemVisual(idx, 'symbolSize', symbolSize(rawValue, params));
          hasSymbolRotateCallback && data.setItemVisual(idx, 'symbolRotate', symbolRotate(rawValue, params));
          hasSymbolOffsetCallback && data.setItemVisual(idx, 'symbolOffset', symbolOffset(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);
          var itemSymbolType = itemModel.getShallow('symbol', true);
          var itemSymbolSize = itemModel.getShallow('symbolSize', true);
          var itemSymbolRotate = itemModel.getShallow('symbolRotate', true);
          var itemSymbolOffset = itemModel.getShallow('symbolOffset', true);
          var itemSymbolKeepAspect = itemModel.getShallow('symbolKeepAspect', true); // If has item symbol

          if (itemSymbolType != null) {
            data.setItemVisual(idx, 'symbol', itemSymbolType);
          }

          if (itemSymbolSize != null) {
            // PENDING Transform symbolSize ?
            data.setItemVisual(idx, 'symbolSize', itemSymbolSize);
          }

          if (itemSymbolRotate != null) {
            data.setItemVisual(idx, 'symbolRotate', itemSymbolRotate);
          }

          if (itemSymbolOffset != null) {
            data.setItemVisual(idx, 'symbolOffset', itemSymbolOffset);
          }

          if (itemSymbolKeepAspect != null) {
            data.setItemVisual(idx, 'symbolKeepAspect', itemSymbolKeepAspect);
          }
        }

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

      }
    }

    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 varible 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.normal;

              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 (typeof labelItem.layoutOption === 'function') {
            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) {
              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 && !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;
    }();

    // Inlucdes: pieSelect, pieUnSelect, pieToggleSelect, mapSelect, mapUnSelect, mapToggleSelect

    function createLegacyDataSelectAction(seriesType, ecRegisterAction) {
      function getSeriesIndices(ecModel, payload) {
        var seriesIndices = [];
        ecModel.eachComponent({
          mainType: 'series',
          subType: seriesType,
          query: payload
        }, function (seriesModel) {
          seriesIndices.push(seriesModel.seriesIndex);
        });
        return seriesIndices;
      }

      each([[seriesType + 'ToggleSelect', 'toggleSelect'], [seriesType + 'Select', 'select'], [seriesType + 'UnSelect', 'unselect']], function (eventsMap) {
        ecRegisterAction(eventsMap[0], function (payload, ecModel, api) {
          payload = extend({}, payload);

          if ("development" !== 'production') {
            deprecateReplaceLog(payload.type, eventsMap[1]);
          }

          api.dispatchAction(extend(payload, {
            type: eventsMap[1],
            seriesIndex: getSeriesIndices(ecModel, payload)
          }));
        });
      });
    }

    function handleSeriesLegacySelectEvents(type, eventPostfix, ecIns, ecModel, payload) {
      var legacyEventName = type + eventPostfix;

      if (!ecIns.isSilent(legacyEventName)) {
        if ("development" !== 'production') {
          deprecateLog("event " + legacyEventName + " is deprecated.");
        }

        ecModel.eachComponent({
          mainType: 'series',
          subType: 'pie'
        }, function (seriesModel) {
          var seriesIndex = seriesModel.seriesIndex;
          var 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: extend({}, seriesModel.option.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 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 (typeof Object.defineProperty === 'function') {
                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 contructors
     */
    // 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 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 = isNaN(x) ? 0 : x;
        x2 = isNaN(x2) ? 1 : x2;
        y = isNaN(y) ? 0 : y;
        y2 = isNaN(y2) ? 0 : y2;
        var canvasGradient = ctx.createLinearGradient(x, y, x2, y2);
        return canvasGradient;
    }
    function createRadialGradient(ctx, obj, rect) {
        var width = rect.width;
        var height = rect.height;
        var min = Math.min(width, height);
        var x = obj.x == null ? 0.5 : obj.x;
        var y = obj.y == null ? 0.5 : obj.y;
        var r = obj.r == null ? 0.5 : obj.r;
        if (!obj.global) {
            x = x * width + rect.x;
            y = y * height + rect.y;
            r = r * min;
        }
        var canvasGradient = ctx.createRadialGradient(x, y, 0, x, y, r);
        return canvasGradient;
    }
    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 normalizeLineDash(lineType, lineWidth) {
        if (!lineType || lineType === 'solid' || !(lineWidth > 0)) {
            return null;
        }
        lineWidth = lineWidth || 1;
        return lineType === 'dashed'
            ? [4 * lineWidth, 2 * lineWidth]
            : lineType === 'dotted'
                ? [lineWidth]
                : isNumber(lineType)
                    ? [lineType] : isArray(lineType) ? lineType : null;
    }

    var pathProxyForDraw = new PathProxy(true);
    function styleHasStroke(style) {
        var stroke = style.stroke;
        return !(stroke == null || stroke === 'none' || !(style.lineWidth > 0));
    }
    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.setTransform) {
                var matrix = new DOMMatrix();
                matrix.rotateSelf(0, 0, (pattern.rotation || 0) / Math.PI * 180);
                matrix.scaleSelf((pattern.scaleX || 1), (pattern.scaleY || 1));
                matrix.translateSelf((pattern.x || 0), (pattern.y || 0));
                canvasPattern.setTransform(matrix);
            }
            return canvasPattern;
        }
    }
    function brushPath(ctx, el, style, inBatch) {
        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;
        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 = el.__dirty
                    ? getCanvasGradient(ctx, fill, rect)
                    : el.__canvasFillGradient;
                el.__canvasFillGradient = fillGradient;
            }
            if (hasStrokeGradient) {
                strokeGradient = el.__dirty
                    ? getCanvasGradient(ctx, stroke, rect)
                    : el.__canvasStrokeGradient;
                el.__canvasStrokeGradient = strokeGradient;
            }
            if (hasFillPattern) {
                fillPattern = (el.__dirty || !el.__canvasFillPattern)
                    ? createCanvasPattern(ctx, fill, el)
                    : el.__canvasFillPattern;
                el.__canvasFillPattern = fillPattern;
            }
            if (hasStrokePattern) {
                strokePattern = (el.__dirty || !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 lineDash = style.lineDash && style.lineWidth > 0 && normalizeLineDash(style.lineDash, style.lineWidth);
        var lineDashOffset = style.lineDashOffset;
        var ctxLineDash = !!ctx.setLineDash;
        var scale = el.getGlobalScale();
        path.setScale(scale[0], scale[1], el.segmentIgnoreThreshold);
        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;
            }
        }
        var needsRebuild = true;
        if (firstDraw || (el.__dirty & Path.SHAPE_CHANGED_BIT)
            || (lineDash && !ctxLineDash && hasStroke)) {
            path.setDPR(ctx.dpr);
            if (strokePart) {
                path.setContext(null);
            }
            else {
                path.setContext(ctx);
                needsRebuild = false;
            }
            path.reset();
            if (lineDash && !ctxLineDash) {
                path.setLineDash(lineDash);
                path.setLineDashOffset(lineDashOffset);
            }
            el.buildPath(path, el.shape, inBatch);
            path.toStatic();
            el.pathUpdated();
        }
        if (needsRebuild) {
            path.rebuildPath(ctx, strokePart ? strokePercent : 1);
        }
        if (lineDash && ctxLineDash) {
            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 && ctxLineDash) {
            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 text = style.text;
        text != null && (text += '');
        if (text) {
            ctx.font = style.font || DEFAULT_FONT;
            ctx.textAlign = style.textAlign;
            ctx.textBaseline = style.textBaseline;
            var hasLineDash = void 0;
            if (ctx.setLineDash) {
                var lineDash = style.lineDash && style.lineWidth > 0 && normalizeLineDash(style.lineDash, style.lineWidth);
                var lineDashOffset = style.lineDashOffset;
                if (lineDash) {
                    var lineScale_2 = (style.strokeNoScale && el.getLineScale) ? el.getLineScale() : 1;
                    if (lineScale_2 && lineScale_2 !== 1) {
                        lineDash = map(lineDash, function (rawVal) {
                            return rawVal / lineScale_2;
                        });
                        lineDashOffset /= lineScale_2;
                    }
                    ctx.setLineDash(lineDash);
                    ctx.lineDashOffset = lineDashOffset;
                    hasLineDash = true;
                }
            }
            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 (hasLineDash) {
                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) {
            if (!styleChanged) {
                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;
            }
            ctx.fillStyle = style.fill;
        }
        if (forceSetAll || style.stroke !== prevStyle.stroke) {
            if (!styleChanged) {
                flushPathDrawn(ctx, scope);
                styleChanged = true;
            }
            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 && 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 &= ~Element.REDARAW_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 instanceof IncrementalDisplayable) {
                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]];
          var valueType = typeof value;

          if (value != null && !isArray(value) && valueType !== 'string' && valueType !== 'number' && valueType !== '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 && createCanvas();
        var svgRoot = isSVG && zr.painter.createSVGElement('g');
        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 minumum 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 minumum 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) {
              svgRoot.appendChild(zr.painter.paintOne(symbol));
            } 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 (typeof symbol === 'string') {
        return [[symbol]];
      }

      var isAllString = true;

      for (var i = 0; i < symbol.length; ++i) {
        if (typeof symbol[i] !== 'string') {
          isAllString = false;
          break;
        }
      }

      if (isAllString) {
        return normalizeSymbolArray([symbol]);
      }

      var result = [];

      for (var i = 0; i < symbol.length; ++i) {
        if (typeof symbol[i] === 'string') {
          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 (typeof dash === 'number') {
        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 (typeof dash[i] !== 'number') {
          isAllNumber = false;
          break;
        }
      }

      if (isAllNumber) {
        return normalizeDashArrayX([dash]);
      }

      var result = [];

      for (var i = 0; i < dash.length; ++i) {
        if (typeof dash[i] === 'number') {
          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 (typeof dash === 'number') {
        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 arrary 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);
        }
      });
    }

    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 (!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'),
                        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;
        }
        disp.z = -10000;
        disp.z2 = -1000;
    }
    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;
    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 = void 0;
                mt = mt || create$1();
                switch (type) {
                    case 'translate':
                        valueArr = splitNumberSequence(value);
                        translate(mt, mt, [parseFloat(valueArr[0]), parseFloat(valueArr[1] || '0')]);
                        break;
                    case 'scale':
                        valueArr = splitNumberSequence(value);
                        scale$1(mt, mt, [parseFloat(valueArr[0]), parseFloat(valueArr[1] || valueArr[0])]);
                        break;
                    case 'rotate':
                        valueArr = splitNumberSequence(value);
                        rotate(mt, mt, -parseFloat(valueArr[0]) / 180 * Math.PI);
                        break;
                    case 'skew':
                        valueArr = splitNumberSequence(value);
                        console.warn('Skew transform is not supported yet');
                        break;
                    case 'matrix':
                        valueArr = splitNumberSequence(value);
                        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);
    }

    var EPSILON$3 = 1e-8;
    function isAroundEqual$1(a, b) {
        return Math.abs(a - b) < EPSILON$3;
    }
    function contain$1(points, x, y) {
        var w = 0;
        var p = points[0];
        if (!p) {
            return false;
        }
        for (var i = 1; i < points.length; i++) {
            var p2 = points[i];
            w += windingLine(p[0], p[1], p2[0], p2[1], x, y);
            p = p2;
        }
        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 = [];

    var Region =
    /** @class */
    function () {
      function Region(name) {
        this.name = name;
      }
      /**
       * 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 () {
        return;
      };

      return Region;
    }();

    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;

        if (!cp) {
          var rect = _this.getBoundingRect();

          cp = [rect.x + rect.width / 2, rect.y + rect.height / 2];
        } else {
          cp = [cp[0], cp[1]];
        }

        _this._center = cp;
        return _this;
      }

      GeoJSONRegion.prototype.getBoundingRect = function () {
        var rect = this._rect;

        if (rect) {
          return rect;
        }

        var MAX_NUMBER = Number.MAX_VALUE;
        var min$1 = [MAX_NUMBER, MAX_NUMBER];
        var max$1 = [-MAX_NUMBER, -MAX_NUMBER];
        var min2 = [];
        var max2 = [];
        var geometries = this.geometries;
        var i = 0;

        for (; i < geometries.length; i++) {
          // Only support polygon
          if (geometries[i].type !== 'polygon') {
            continue;
          } // Doesn't consider hole


          var exterior = geometries[i].exterior;
          fromPoints(exterior, min2, max2);
          min(min$1, min$1, min2);
          max(max$1, max$1, max2);
        } // No data


        if (i === 0) {
          min$1[0] = min$1[1] = max$1[0] = max$1[1] = 0;
        }

        return this._rect = new BoundingRect(min$1[0], min$1[1], max$1[0] - min$1[0], max$1[1] - min$1[1]);
      };

      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++) {
          // Only support polygon.
          if (geometries[i].type !== 'polygon') {
            continue;
          }

          var exterior = geometries[i].exterior;
          var interiors = geometries[i].interiors;

          if (contain$1(exterior, coord[0], coord[1])) {
            // Not in the region if point is in the hole.
            for (var k = 0; k < (interiors ? interiors.length : 0); k++) {
              if (contain$1(interiors[k], coord[0], coord[1])) {
                continue loopGeo;
              }
            }

            return true;
          }
        }

        return false;
      };

      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++) {
          // Only support polygon.
          if (geometries[i].type !== 'polygon') {
            continue;
          }

          var exterior = geometries[i].exterior;
          var interiors = geometries[i].interiors;

          for (var p = 0; p < exterior.length; p++) {
            applyTransform(exterior[p], exterior[p], transform);
          }

          for (var h = 0; h < (interiors ? interiors.length : 0); h++) {
            for (var p = 0; p < interiors[h].length; p++) {
              applyTransform(interiors[h][p], interiors[h][p], transform);
            }
          }
        }

        rect = this._rect;
        rect.copy(target); // Update center

        this._center = [rect.x + rect.width / 2, rect.y + rect.height / 2];
      };

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

      GeoJSONRegion.prototype.getCenter = function () {
        return this._center;
      };

      GeoJSONRegion.prototype.setCenter = function (center) {
        this._center = center;
      };

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

        return center;
      };

      GeoSVGRegion.prototype._calculateCenter = 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);

    /**
     * "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 becuase 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 suport `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;
    // }

    function decode(json) {
      if (!json.UTF8Encoding) {
        return json;
      }

      var jsonCompressed = json;
      var encodeScale = jsonCompressed.UTF8Scale;

      if (encodeScale == null) {
        encodeScale = 1024;
      }

      var features = jsonCompressed.features;

      for (var f = 0; f < features.length; f++) {
        var feature = features[f];
        var geometry = feature.geometry;

        if (geometry.type === 'Polygon') {
          var coordinates = geometry.coordinates;

          for (var c = 0; c < coordinates.length; c++) {
            coordinates[c] = decodePolygon(coordinates[c], geometry.encodeOffsets[c], encodeScale);
          }
        } else if (geometry.type === 'MultiPolygon') {
          var coordinates = geometry.coordinates;

          for (var c = 0; c < coordinates.length; c++) {
            var coordinate = coordinates[c];

            for (var c2 = 0; c2 < coordinate.length; c2++) {
              coordinate[c2] = decodePolygon(coordinate[c2], geometry.encodeOffsets[c][c2], encodeScale);
            }
          }
        }
      } // Has been decoded


      jsonCompressed.UTF8Encoding = false;
      return jsonCompressed;
    }

    function decodePolygon(coordinate, encodeOffsets, encodeScale) {
      var result = [];
      var prevX = encodeOffsets[0];
      var prevY = encodeOffsets[1];

      for (var i = 0; i < coordinate.length; i += 2) {
        var x = coordinate.charCodeAt(i) - 64;
        var y = coordinate.charCodeAt(i + 1) - 64; // ZigZag decoding

        x = x >> 1 ^ -(x & 1);
        y = y >> 1 ^ -(y & 1); // Delta deocding

        x += prevX;
        y += prevY;
        prevX = x;
        prevY = y; // Dequantize

        result.push([x / encodeScale, y / encodeScale]);
      }

      return result;
    }

    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 = [];

        if (geo.type === 'Polygon') {
          var coordinates = geo.coordinates;
          geometries.push({
            type: 'polygon',
            // According to the GeoJSON specification.
            // First must be exterior, and the rest are all interior(holes).
            exterior: coordinates[0],
            interiors: coordinates.slice(1)
          });
        }

        if (geo.type === 'MultiPolygon') {
          var coordinates = geo.coordinates;
          each(coordinates, function (item) {
            if (item[0]) {
              geometries.push({
                type: 'polygon',
                exterior: item[0],
                interiors: item.slice(1)
              });
            }
          });
        }

        var region = new GeoJSONRegion(properties[nameProperty || 'name'], geometries, properties.cp);
        region.properties = properties;
        return region;
      });
    }

    var geoCoord = [126, 25];
    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') {
        regions.push(new GeoJSONRegion('南海诸岛', 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.
    */
    var geoCoordMap = {
      'Russia': [100, 60],
      'United States': [-99, 38],
      'United States of America': [-99, 38]
    };
    function fixGeoCoords(mapType, region) {
      if (mapType === 'world') {
        var geoCoord = geoCoordMap[region.name];

        if (geoCoord) {
          var cp = [geoCoord[0], geoCoord[1]];
          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 && nameMap.hasOwnProperty(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);
          fixGeoCoords(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);
      }
    };

    var assert$1 = assert;
    var each$3 = each;
    var isFunction$1 = isFunction;
    var isObject$2 = isObject;
    var indexOf$1 = indexOf;
    var hasWindow = typeof window !== 'undefined';
    var version$1 = '5.1.1';
    var dependencies = {
      zrender: '5.1.0'
    };
    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 begining 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 OPTION_UPDATED_KEY = '__optionUpdated';
    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 clearColorPalette;
    var render;
    var renderComponents;
    var renderSeries;
    var performPostUpdateFuncs;
    var createExtensionAPI;
    var enableConnect;
    var setTransitionOpt;
    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 (typeof theme === 'string') {
          theme = themeStorage[theme];
        }

        _this._dom = dom;
        var defaultRenderer = 'canvas';
        var defaultUseDirtyRect = false;

        if ("development" !== 'production') {
          var root =
          /* eslint-disable-next-line */
          hasWindow ? window : global;
          defaultRenderer = root.__ECHARTS__DEFAULT__RENDERER__ || defaultRenderer;
          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,
          useDirtyRect: opts.useDirtyRect == null ? defaultUseDirtyRect : opts.useDirtyRect
        }); // 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();
        _this._labelManager = new LabelManager(); // 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[OPTION_UPDATED_KEY]) {
          var silent = this[OPTION_UPDATED_KEY].silent;
          this[IN_MAIN_PROCESS_KEY] = true;
          prepare(this);
          updateMethods.update.call(this); // 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[OPTION_UPDATED_KEY] = false;
          flushPendingActions.call(this, silent);
          triggerUpdatedEvent.call(this, silent);
        } // Avoid do both lazy update and progress in one frame.
        else if (scheduler.unfinished) {
            // Stream progress.
            var remainTime = TEST_FRAME_REMAIN_TIME;
            var ecModel = this._model;
            var api = this._api;
            scheduler.unfinished = false;

            do {
              var startTime = +new Date();
              scheduler.performSeriesTasks(ecModel); // Currently dataProcessorFuncs do not check threshold.

              scheduler.performDataProcessorTasks(ecModel);
              updateStreamModes(this, ecModel); // Do not update coordinate system here. Because that coord system update in
              // each frame is not a good user experience. So we follow the rule that
              // the extent of the coordinate system is determin in the first frame (the
              // frame is executed immedietely after task reset.
              // this._coordSysMgr.update(ecModel, api);
              // console.log('--- ec frame visual ---', remainTime);

              scheduler.performVisualTasks(ecModel);
              renderSeries(this, this._model, api, 'remain');
              remainTime -= +new Date() - startTime;
            } while (remainTime > 0 && scheduler.unfinished); // Call flush explicitly for trigger finished event.


            if (!scheduler.unfinished) {
              this._zr.flush();
            } // Else, zr flushing be ensue within the same frame,
            // because zr flushing is after onframe event.

          }
      };

      ECharts.prototype.getDom = function () {
        return this._dom;
      };

      ECharts.prototype.getId = function () {
        return this.id;
      };

      ECharts.prototype.getZr = function () {
        return this._zr;
      };
      /* eslint-disable-next-line */


      ECharts.prototype.setOption = function (option, notMerge, lazyUpdate) {
        if ("development" !== 'production') {
          assert$1(!this[IN_MAIN_PROCESS_KEY], '`setOption` should not be called during main process.');
        }

        if (this._disposed) {
          disposedWarning(this.id);
          return;
        }

        var silent;
        var replaceMerge;
        var transitionOpt;

        if (isObject$2(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.init(null, null, null, theme, this._locale, optionManager);
        }

        this._model.setOption(option, {
          replaceMerge: replaceMerge
        }, optionPreprocessorFuncs);

        setTransitionOpt(this, transitionOpt);

        if (lazyUpdate) {
          this[OPTION_UPDATED_KEY] = {
            silent: silent
          };
          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 {
          prepare(this);
          updateMethods.update.call(this); // Ensure zr refresh sychronously, and then pixel in canvas can be
          // fetched after `setOption`.

          this._zr.flush();

          this[OPTION_UPDATED_KEY] = false;
          this[IN_MAIN_PROCESS_KEY] = false;
          flushPendingActions.call(this, silent);
          triggerUpdatedEvent.call(this, silent);
        }
      };
      /**
       * @DEPRECATED
       */


      ECharts.prototype.setTheme = function () {
        console.error('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 */
        || hasWindow && window.devicePixelRatio || 1;
      };
      /**
       * Get canvas which has all thing rendered
       */


      ECharts.prototype.getRenderedCanvas = function (opts) {
        if (!env.canvasSupported) {
          return;
        }

        opts = extend({}, opts || {});
        opts.pixelRatio = opts.pixelRatio || this.getDevicePixelRatio();
        opts.backgroundColor = opts.backgroundColor || this._model.get('backgroundColor');
        var zr = this._zr; // let list = zr.storage.getDisplayList();
        // Stop animations
        // Never works before in init animation, so remove it.
        // zrUtil.each(list, function (el) {
        //     el.stopAnimation(true);
        // });

        return zr.painter.getRenderedCanvas(opts);
      };
      /**
       * Get svg data url
       */


      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$3(excludeComponents, function (componentType) {
          ecModel.eachComponent({
            mainType: componentType
          }, function (component) {
            var view = self._componentsMap[component.__viewId];

            if (!view.group.ignore) {
              excludesComponentViews.push(view);
              view.group.ignore = true;
            }
          });
        });
        var url = this._zr.painter.getType() === 'svg' ? this.getSvgDataURL() : this.getRenderedCanvas(opts).toDataURL('image/' + (opts && opts.type || 'png'));
        each$3(excludesComponentViews, function (view) {
          view.group.ignore = false;
        });
        return url;
      };

      ECharts.prototype.getConnectedDataURL = function (opts) {
        if (this._disposed) {
          disposedWarning(this.id);
          return;
        }

        if (!env.canvasSupported) {
          return;
        }

        var isSvg = opts.type === 'svg';
        var groupId = this.group;
        var mathMin = Math.min;
        var mathMax = Math.max;
        var MAX_NUMBER = Infinity;

        if (connectedGroups[groupId]) {
          var left_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.getRenderedCanvas(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 = createCanvas();
          var zr_1 = init(targetCanvas, {
            renderer: isSvg ? 'svg' : 'canvas'
          });
          zr_1.resize({
            width: width,
            height: height
          });

          if (isSvg) {
            var content_1 = '';
            each$3(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$3(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') {
                  console.warn(key + ': ' + (view ? 'The found component do not support containPoint.' : 'No view mapping to the found component.'));
                }
              }
            } else {
              if ("development" !== 'production') {
                console.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) {
            console.warn('There is no specified seires 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$3(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)) {
                  console.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$3(eventActionMap, function (actionType, eventType) {
          _this._messageCenter.on(eventType, function (event) {
            this.trigger(eventType, event);
          }, _this);
        }); // Extra events
        // TODO register?

        each$3(['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;
        setAttribute(this.getDom(), DOM_ATTRIBUTE_KEY, '');
        var api = this._api;
        var ecModel = this._model;
        each$3(this._componentsViews, function (component) {
          component.dispose(ecModel, api);
        });
        each$3(this._chartsViews, function (chart) {
          chart.dispose(ecModel, api);
        }); // Dispose after all views disposed

        this._zr.dispose();

        delete instances$1[this.id];
      };
      /**
       * Resize the chart
       */


      ECharts.prototype.resize = function (opts) {
        if ("development" !== 'production') {
          assert$1(!this[IN_MAIN_PROCESS_KEY], '`resize` should not be called during main process.');
        }

        if (this._disposed) {
          disposedWarning(this.id);
          return;
        }

        this._zr.resize(opts);

        var ecModel = this._model; // Resize loading effect

        this._loadingFX && this._loadingFX.resize();

        if (!ecModel) {
          return;
        }

        var optionChanged = ecModel.resetOption('media');
        var silent = opts && opts.silent;
        this[IN_MAIN_PROCESS_KEY] = true;
        optionChanged && prepare(this);
        updateMethods.update.call(this, {
          type: 'resize',
          animation: extend({
            // Disable animation
            duration: 0
          }, opts && opts.animation)
        });
        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$2(name)) {
          cfg = name;
          name = '';
        }

        name = name || 'default';
        this.hideLoading();

        if (!loadingEffects[name]) {
          if ("development" !== 'production') {
            console.warn('Loading effects ' + name + ' not exists.');
          }

          return;
        }

        var el = loadingEffects[name](this._api, cfg);
        var zr = this._zr;
        this._loadingFX = el;
        zr.add(el);
      };
      /**
       * Hide loading effect
       */


      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$2(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 embeded browser, `requestAnimationFrame` and `setInterval`
          // hang when sliding page (on touch event), which cause that zr does not
          // refresh util user interaction finished, which is not expected.
          // But `dispatchAction` may be called too frequently when pan on touch
          // screen, which impacts performance if do not throttle them.
          this._throttledZrFlush();
        }

        flushPendingActions.call(this, silent);
        triggerUpdatedEvent.call(this, silent);
      };

      ECharts.prototype.updateLabelLayout = function () {
        var labelManager = this._labelManager;
        labelManager.updateLayoutConfig(this._api);
        labelManager.layout(this._api);
        labelManager.processLabelsOverall();
      };

      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$1(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 defaut 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$1(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$3([].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$3(normalizeToArray(excludeSeriesId), function (id) {
              var modelId = convertOptionIdName(id, null);

              if (modelId != null) {
                excludeSeriesIdMap.set(modelId, true);
              }
            });
          }

          if (isHighDownPayload(payload)) {
            allLeaveBlur(ecIns._api);
          } // If dispatchAction before setOption, do nothing.


          ecModel && ecModel.eachComponent(condition, function (model) {
            if (!excludeSeriesIdMap || excludeSeriesIdMap.get(model.id) == null) {
              if (isHighDownPayload(payload)) {
                if (model instanceof SeriesModel) {
                  if (payload.type === HIGHLIGHT_ACTION_TYPE && !payload.notBlur) {
                    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$3(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);
                }
              }

              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);
          },
          update: function (payload) {
            // console.profile && console.profile('update');
            var ecModel = this._model;
            var api = this._api;
            var zr = this._zr;
            var coordSysMgr = this._coordSysMgr;
            var scheduler = this._scheduler; // update before setOption

            if (!ecModel) {
              return;
            }

            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 orignal point

            coordSysMgr.create(ecModel, api);
            scheduler.performDataProcessorTasks(ecModel, payload); // Current stream render is not supported in data process. So we can update
            // stream modes after data processing, where the filtered data is used to
            // deteming whether use progressive rendering.

            updateStreamModes(this, ecModel); // We update stream modes before coordinate system updated, then the modes info
            // can be fetched when coord sys updating (consider the barGrid extent fix). But
            // the drawback is the full coord info can not be fetched. Fortunately this full
            // coord is not requied in stream mode updater currently.

            coordSysMgr.update(ecModel, api);
            clearColorPalette(ecModel);
            scheduler.performVisualTasks(ecModel, payload);
            render(this, ecModel, api, payload); // Set background

            var backgroundColor = ecModel.get('backgroundColor') || 'transparent';
            var darkMode = ecModel.get('darkMode'); // In IE8

            if (!env.canvasSupported) {
              var colorArr = parse(backgroundColor);
              backgroundColor = stringify(colorArr, 'rgb');

              if (colorArr[3] === 0) {
                backgroundColor = 'transparent';
              }
            } else {
              zr.setBackgroundColor(backgroundColor); // Force set dark mode.

              if (darkMode != null && darkMode !== 'auto') {
                zr.setDarkMode(darkMode);
              }
            }

            performPostUpdateFuncs(ecModel, api); // console.profile && console.profileEnd('update');
          },
          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);
            performPostUpdateFuncs(ecModel, this._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, this._model, this._api, payload);
            performPostUpdateFuncs(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);
            });
            performPostUpdateFuncs(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') {
            console.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);
          each$3(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) {
            // Still dirty
            if (this[OPTION_UPDATED_KEY]) {
              prepare(this);
              updateMethods.update.call(this, payload);
              this[OPTION_UPDATED_KEY] = false;
            } else {
              updateMethods[updateMethod].call(this, payload);
            }
          } // Follow the rule of action batch


          if (batched) {
            eventObj = {
              type: actionInfo.event || payloadType,
              escapeConnect: escapeConnect,
              batch: eventObjBatch
            };
          } else {
            eventObj = eventObjBatch[0];
          }

          this[IN_MAIN_PROCESS_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 repeatly,
            // so it should only be triggered when rendering indeed happend
            // in zrender. (Consider the case that dipatchAction is keep
            // triggering when mouse move).

            if ( // Although zr is dirty if initial animation is not finished
            // and this checking is called on frame, we also check
            // animation finished for robustness.
            zr.animation.isFinished() && !ecIns[OPTION_UPDATED_KEY] && !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) {
              handleGlboalMouseOutForHighDown(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
              });
            }
          });
        };

        clearColorPalette = function (ecModel) {
          ecModel.clearColorPalette();
          ecModel.eachSeries(function (seriesModel) {
            seriesModel.clearColorPalette();
          });
        };

        render = function (ecIns, ecModel, api, payload) {
          renderComponents(ecIns, ecModel, api, payload);
          each$3(ecIns._chartsViews, function (chart) {
            chart.__alive = false;
          });
          renderSeries(ecIns, ecModel, api, payload); // Remove groups of unrendered charts

          each$3(ecIns._chartsViews, function (chart) {
            if (!chart.__alive) {
              chart.remove(ecModel, api);
            }
          });
        };

        renderComponents = function (ecIns, ecModel, api, payload, dirtyList) {
          each$3(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, dirtyMap) {
          // Render all charts
          var scheduler = ecIns._scheduler;
          var labelManager = ecIns._labelManager;
          labelManager.clearLabels();
          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;
            }

            seriesModel.__transientTransitionOpt = null;
            chartView.group.silent = !!seriesModel.get('silent'); // Should not call markRedraw on group, because it will disable zrender
            // increamental render (alway render from the __startIndex each frame)
            // chartView.group.markRedraw();

            updateBlend(seriesModel, chartView);
            updateSeriesElementSelection(seriesModel); // Add labels.

            labelManager.addLabelsOfSeries(chartView);
          });
          scheduler.unfinished = unfinished || scheduler.unfinished;
          labelManager.updateLayoutConfig(api);
          labelManager.layout(api);
          labelManager.processLabelsOverall();
          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);
        };

        performPostUpdateFuncs = function (ecModel, api) {
          each$3(postUpdateFuncs, function (func) {
            func(ecModel, api);
          });
        };

        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.group.traverse(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;

          if ("development" !== 'production') {
            if (!env.canvasSupported && blendMode && blendMode !== 'source-over') {
              console.warn('Only canvas support blendMode');
            }
          }

          chartView.group.traverse(function (el) {
            // FIXME marker and other components
            if (!el.isGroup) {
              // DONT mark the element dirty. In case element is incremental and don't wan't to rerender.
              el.style.blend = blendMode;
            }

            if (el.eachPendingDisplayable) {
              el.eachPendingDisplayable(function (displayable) {
                displayable.style.blend = blendMode;
              });
            }
          });
        }

        function updateZ(model, view) {
          if (model.preventAutoZ) {
            return;
          } // Set z and zlevel


          _updateZ(view.group, model.get('z') || 0, model.get('zlevel') || 0, -Infinity);
        }

        function _updateZ(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
            // el.traverse((childEl: Element) => _updateZ(childEl, z, zlevel));
            var children = el.childrenRef();

            for (var i = 0; i < children.length; i++) {
              maxZ2 = Math.max(_updateZ(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.group.traverse(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.group.traverse(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 wan't 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;
                }
              } // The use higlighted 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$3(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$3(instances$1, function (otherChart) {
                  if (otherChart !== chart && otherChart.group === chart.group) {
                    otherCharts_1.push(otherChart);
                  }
                });
                updateConnectedChartsStatus(otherCharts_1, CONNECT_STATUS_PENDING);
                each$3(otherCharts_1, function (otherChart) {
                  if (otherChart[CONNECT_STATUS_KEY] !== CONNECT_STATUS_UPDATING) {
                    otherChart.dispatchAction(action_1);
                  }
                });
                updateConnectedChartsStatus(otherCharts_1, CONNECT_STATUS_UPDATED);
              }
            });
          });
        };

        setTransitionOpt = function (chart, transitionOpt) {
          var ecModel = chart._model;
          each(normalizeToArray(transitionOpt), function (transOpt) {
            var errMsg;
            var fromOpt = transOpt.from;
            var toOpt = transOpt.to;

            if (toOpt == null) {
              if ("development" !== 'production') {
                errMsg = '`transition.to` must be specified.';
              }

              throwError(errMsg);
            }

            var finderOpt = {
              includeMainTypes: ['series'],
              enableAll: false,
              enableNone: false
            };
            var fromResult = fromOpt ? parseFinder(ecModel, fromOpt, finderOpt) : null;
            var toResult = parseFinder(ecModel, toOpt, finderOpt);
            var toSeries = toResult.seriesModel;

            if (toSeries == null) {
              errMsg = '';

              if ("development" !== 'production') {
                errMsg = '`transition` is only supported on series.';
              }
            }

            if (fromResult && fromResult.seriesModel !== toSeries) {
              errMsg = '';

              if ("development" !== 'production') {
                errMsg = '`transition.from` and `transition.to` must be specified to the same series.';
              }
            }

            if (errMsg != null) {
              throwError(errMsg);
            } // Just a temp solution: mount them on series.


            toSeries.__transientTransitionOpt = {
              from: fromOpt ? fromOpt.dimension : null,
              to: toOpt.dimension,
              dividingMethod: transOpt.dividingMethod
            };
          });
        };
      }();

      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);
    }; // /**
    //  * Encode visual infomation from data after data processing
    //  *
    //  * @param {module:echarts/model/Global} ecModel
    //  * @param {object} layout
    //  * @param {boolean} [layoutFilter] `true`: only layout,
    //  *                                 `false`: only not layout,
    //  *                                 `null`/`undefined`: all.
    //  * @param {string} taskBaseTag
    //  * @private
    //  */
    // function startVisualEncoding(ecIns, ecModel, api, payload, layoutFilter) {
    //     each(visualFuncs, function (visual, index) {
    //         let isLayout = visual.isLayout;
    //         if (layoutFilter == null
    //             || (layoutFilter === false && !isLayout)
    //             || (layoutFilter === true && isLayout)
    //         ) {
    //             visual.func(ecModel, api, payload);
    //         }
    //     });
    // }


    var MOUSE_EVENT_NAMES = ['click', 'dblclick', 'mouseover', 'mouseout', 'mousemove', 'mousedown', 'mouseup', 'globalout', 'contextmenu'];

    function disposedWarning(id) {
      if ("development" !== 'production') {
        console.warn('Instance ' + id + ' has been disposed');
      }
    }

    var actions = {};
    /**
     * Map eventType to actionType
     */

    var eventActionMap = {};
    var dataProcessorFuncs = [];
    var optionPreprocessorFuncs = [];
    var postInitFuncs = [];
    var postUpdateFuncs = [];
    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)
     */

    function init$1(dom, theme, opts) {
      if ("development" !== 'production') {
        if (!dom) {
          throw new Error('Initialize failed: invalid dom.');
        }
      }

      var existInstance = getInstanceByDom(dom);

      if (existInstance) {
        if ("development" !== 'production') {
          console.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))) {
          console.warn('Can\'t get DOM width or height. Please check ' + 'dom.clientWidth and dom.clientHeight. They should not be 0.' + 'For example, you may need to call this in the callback ' + 'of window.onload.');
        }
      }

      var chart = new ECharts(dom, theme, opts);
      chart.id = 'ec_' + idBase++;
      instances$1[chart.id] = chart;
      setAttribute(dom, DOM_ATTRIBUTE_KEY, chart.id);
      enableConnect(chart);
      each$3(postInitFuncs, function (postInitFunc) {
        postInitFunc(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$3(charts, function (chart) {
          if (chart.group != null) {
            groupId = chart.group;
          }
        });
        groupId = groupId || 'g_' + groupIdBase++;
        each$3(charts, function (chart) {
          chart.group = groupId;
        });
      }

      connectedGroups[groupId] = true;
      return groupId;
    }
    /**
     * @deprecated
     */

    function disConnect(groupId) {
      connectedGroups[groupId] = false;
    }
    /**
     * Alias and backword compat
     */

    var disconnect = disConnect;
    /**
     * Dispose a chart instance
     */

    function dispose$1(chart) {
      if (typeof chart === 'string') {
        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$1(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) {
      if (indexOf$1(postInitFuncs, postInitFunc) < 0) {
        postInitFunc && postInitFuncs.push(postInitFunc);
      }
    }
    /**
     * Register postUpdater
     * @param {Function} postUpdateFunc
     */

    function registerPostUpdate(postUpdateFunc) {
      if (indexOf$1(postUpdateFuncs, postUpdateFunc) < 0) {
        postUpdateFunc && postUpdateFuncs.push(postUpdateFunc);
      }
    }
    function registerAction(actionInfo, eventName, action) {
      if (typeof eventName === 'function') {
        action = eventName;
        eventName = '';
      }

      var actionType = isObject$2(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$1(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$1(priority) || isObject$2(priority)) {
        fn = priority;
        priority = defaultPriority;
      }

      if ("development" !== 'production') {
        if (isNaN(priority) || priority == null) {
          throw new Error('Illegal priority');
        } // Check duplicate


        each$3(targetList, function (wrap) {
          assert$1(wrap.__raw !== fn);
        });
      } // Already registered


      if (indexOf$1(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')
     *
     * Be careful of using it in the browser.
     *
     * @example
     *     let Canvas = require('canvas');
     *     let echarts = require('echarts');
     *     echarts.setCanvasCreator(function () {
     *         // Small size is enough.
     *         return new Canvas(32, 32);
     *     });
     */

    function setCanvasCreator(creator) {
      $override('createCanvas', creator);
    }
    /**
     * The parameters and usage: see `geoSourceManager.registerMap`.
     * Compatible with previous `echarts.registerMap`.
     */

    function registerMap(mapName, geoJson, specialAreas) {
      geoSourceManager.registerMap(mapName, geoJson, specialAreas);
    }
    function getMap(mapName) {
      return geoSourceManager.getMapForUser(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);
    //     }
    // }
    // Buitlin 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,
      registerAction: registerAction,
      registerCoordinateSystem: registerCoordinateSystem,
      registerLayout: registerLayout,
      registerVisual: registerVisual,
      registerTransform: registerTransform,
      registerLoading: registerLoading,
      registerMap: registerMap,
      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 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) {
            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;
    }();

    function summarizeDimensions(data) {
      var summary = {};
      var encode = summary.encode = {};
      var notExtraCoordDimMap = createHashMap();
      var defaultedLabel = [];
      var defaultedTooltip = []; // See the comment of `List.js#userOutput`.

      var userOutput = summary.userOutput = {
        dimensionNames: data.dimensions.slice(),
        encode: {}
      };
      each(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(userOutput.encode, coordDim)[coordDimIndex] = dimItem.index;
          }

          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.encodeFirstDimNotExtra = encodeFirstDimNotExtra;
      var encodeLabel = encode.label; // FIXME `encode.label` is not recommanded, because formatter can not be set
      // in this way. Use label.formatter instead. May be remove this approach someday.

      if (encodeLabel && encodeLabel.length) {
        defaultedLabel = encodeLabel.slice();
      }

      var encodeTooltip = encode.tooltip;

      if (encodeTooltip && encodeTooltip.length) {
        defaultedTooltip = encodeTooltip.slice();
      } else if (!defaultedTooltip.length) {
        defaultedTooltip = defaultedLabel.slice();
      }

      encode.defaultedLabel = defaultedLabel;
      encode.defaultedTooltip = defaultedTooltip;
      return summary;
    }

    function getOrCreateEncodeArr(encode, dim) {
      if (!encode.hasOwnProperty(dim)) {
        encode[dim] = [];
      }

      return encode[dim];
    } // 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 DataDimensionInfo =
    /** @class */
    function () {
      /**
       * @param opt All of the fields will be shallow copied.
       */
      function DataDimensionInfo(opt) {
        /**
         * The format of `otherDims` is:
         * ```js
         * {
         *     tooltip: number optional,
         *     label: number optional,
         *     itemName: number optional,
         *     seriesName: number optional,
         * }
         * ```
         *
         * A `series.encode` can specified these fields:
         * ```js
         * encode: {
         *     // "3, 1, 5" is the index of data dimension.
         *     tooltip: [3, 1, 5],
         *     label: [0, 3],
         *     ...
         * }
         * ```
         * `otherDims` is the parse result of the `series.encode` above, like:
         * ```js
         * // Suppose the index of this data dimension is `3`.
         * this.otherDims = {
         *     // `3` is at the index `0` of the `encode.tooltip`
         *     tooltip: 0,
         *     // `3` is at the index `1` of the `encode.tooltip`
         *     label: 1
         * };
         * ```
         *
         * This prop should never be `null`/`undefined` after initialized.
         */
        this.otherDims = {};

        if (opt != null) {
          extend(this, opt);
        }
      }

      return DataDimensionInfo;
    }();

    var mathFloor = Math.floor;
    var isObject$3 = isObject;
    var map$1 = map;
    var UNDEFINED = 'undefined';
    var INDEX_NOT_FOUND = -1; // Use prefix to avoid index to be the same as otherIdList[idx],
    // which will cause weird udpate animation.

    var ID_PREFIX = 'e\0\0';
    var dataCtors = {
      'float': typeof Float64Array === UNDEFINED ? Array : Float64Array,
      'int': typeof Int32Array === UNDEFINED ? Array : Int32Array,
      // Ordinal data type can be string or int
      'ordinal': Array,
      'number': Array,
      'time': Array
    }; // Caution: MUST not use `new CtorUint32Array(arr, 0, len)`, because the Ctor of array is
    // different from the Ctor of typed array.

    var CtorUint32Array = typeof Uint32Array === UNDEFINED ? Array : Uint32Array;
    var CtorInt32Array = typeof Int32Array === UNDEFINED ? Array : Int32Array;
    var CtorUint16Array = typeof Uint16Array === UNDEFINED ? Array : Uint16Array;
    var TRANSFERABLE_PROPERTIES = ['hasItemOption', '_nameList', '_idList', '_invertedIndicesMap', '_rawData', '_dimValueGetter', '_count', '_rawCount', '_nameDimIdx', '_idDimIdx', '_nameRepeatCount'];
    var CLONE_PROPERTIES = ['_extent', '_approximateExtent', '_rawExtent']; // -----------------------------
    // Internal method declarations:
    // -----------------------------

    var defaultDimValueGetters;
    var prepareInvertedIndex;
    var getIndicesCtor;
    var prepareStorage;
    var getRawIndexWithoutIndices;
    var getRawIndexWithIndices;
    var getId;
    var getIdNameFromStore;
    var makeIdFromName;
    var normalizeDimensions;
    var validateDimensions;
    var cloneListForMapAndSample;
    var getInitialExtent;
    var setItemDataAndSeriesIndex;
    var transferProperties;

    var List =
    /** @class */
    function () {
      /**
       * @param dimensions
       *        For example, ['someDimName', {name: 'someDimName', type: 'someDimType'}, ...].
       *        Dimensions should be concrete names like x, y, z, lng, lat, angle, radius
       */
      function List(dimensions, hostModel) {
        this.type = 'list';
        this._count = 0;
        this._rawCount = 0;
        this._storage = {}; // We have an extra array store here. It's faster to be acessed than KV structured `_storage`.
        // We profile the code `storage[dim]` and it seems to be KeyedLoadIC_Megamorphic instead of fast property access.
        // Not sure why this happens. But using an extra array seems leads to faster `initData`
        // See https://github.com/apache/incubator-echarts/pull/13314 for more explanation.

        this._storageArr = [];
        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 = {}; // Globel layout properties.

        this._layout = {}; // Item visual properties after visual coding

        this._itemVisuals = []; // Item layout properties after layout

        this._itemLayouts = []; // Graphic elemnents

        this._graphicEls = []; // Raw extent will not be cloned, but only transfered.
        // It will not be calculated util needed.

        this._rawExtent = {};
        this._extent = {}; // 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 = true; // 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'];
        /**
         * Get raw data index.
         * Do not initialize.
         * Default `getRawIndex`. And it can be changed.
         */

        this.getRawIndex = getRawIndexWithoutIndices;
        dimensions = dimensions || ['x', 'y'];
        var dimensionInfos = {};
        var dimensionNames = [];
        var invertedIndicesMap = {};

        for (var i = 0; i < dimensions.length; i++) {
          // Use the original dimensions[i], where other flag props may exists.
          var dimInfoInput = dimensions[i];
          var dimensionInfo = isString(dimInfoInput) ? new DataDimensionInfo({
            name: dimInfoInput
          }) : !(dimInfoInput instanceof DataDimensionInfo) ? new DataDimensionInfo(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;
          dimensionInfo.index = i;

          if (dimensionInfo.createInvertedIndices) {
            invertedIndicesMap[dimensionName] = [];
          }

          if (otherDims.itemName === 0) {
            this._nameDimIdx = i;
            this._nameOrdinalMeta = dimensionInfo.ordinalMeta;
          }

          if (otherDims.itemId === 0) {
            this._idDimIdx = i;
            this._idOrdinalMeta = dimensionInfo.ordinalMeta;
          }
        }

        this.dimensions = dimensionNames;
        this._dimensionInfos = dimensionInfos;
        this.hostModel = hostModel; // Cache summary info for fast visit. See "dimensionHelper".

        this._dimensionsSummary = summarizeDimensions(this);
        this._invertedIndicesMap = invertedIndicesMap;
        this.userOutput = this._dimensionsSummary.userOutput;
      }
      /**
       * The meanings of the input parameter `dim`:
       *
       * + If dim is a number (e.g., `1`), it means the index of the dimension.
       *   For example, `getDimension(0)` will return 'x' or 'lng' or 'radius'.
       * + If dim is a number-like string (e.g., `"1"`):
       *     + If there is the same concrete dim name defined in `this.dimensions`, it means that concrete name.
       *     + If not, it will be converted to a number, which means the index of the dimension.
       *        (why? because of the backward compatbility. We have been tolerating number-like string in
       *        dimension setting, although now it seems that it is not a good idea.)
       *     For example, `visualMap[i].dimension: "1"` is the same meaning as `visualMap[i].dimension: 1`,
       *     if no dimension name is defined as `"1"`.
       * + If dim is a not-number-like string, it means the concrete dim name.
       *   For example, it can be be default name `"x"`, `"y"`, `"z"`, `"lng"`, `"lat"`, `"angle"`, `"radius"`,
       *   or customized in `dimensions` property of option like `"age"`.
       *
       * Get dimension name
       * @param dim See above.
       * @return Concrete dim name.
       */


      List.prototype.getDimension = function (dim) {
        if (typeof dim === 'number' // If being a number-like string but not being defined a dimension name.
        || !isNaN(dim) && !this._dimensionInfos.hasOwnProperty(dim)) {
          dim = this.dimensions[dim];
        }

        return dim;
      };
      /**
       * Get type and calculation info of particular dimension
       * @param 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'
       */


      List.prototype.getDimensionInfo = function (dim) {
        // Do not clone, because there may be categories in dimInfo.
        return this._dimensionInfos[this.getDimension(dim)];
      };
      /**
       * concrete dimension name list on coord.
       */


      List.prototype.getDimensionsOnCoord = function () {
        return this._dimensionsSummary.dataDimsOnCoord.slice();
      };

      List.prototype.mapDimension = function (coordDim, idx) {
        var dimensionsSummary = this._dimensionsSummary;

        if (idx == null) {
          return dimensionsSummary.encodeFirstDimNotExtra[coordDim];
        }

        var dims = dimensionsSummary.encode[coordDim];
        return dims ? dims[idx] : null;
      };

      List.prototype.mapDimensionsAll = function (coordDim) {
        var dimensionsSummary = this._dimensionsSummary;
        var dims = dimensionsSummary.encode[coordDim];
        return (dims || []).slice();
      };
      /**
       * Initialize from data
       * @param data source or data or data provider.
       * @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.
       */


      List.prototype.initData = function (data, nameList, dimValueGetter) {
        var notProvider = isSourceInstance(data) || isArrayLike(data);
        var provider = notProvider ? new DefaultDataProvider(data, this.dimensions.length) : data;

        if ("development" !== 'production') {
          assert(notProvider || isFunction(provider.getItem) && isFunction(provider.count), 'Inavlid data provider.');
        }

        this._rawData = provider;
        var sourceFormat = provider.getSource().sourceFormat; // Clear

        this._storage = {};
        this._indices = null;
        this._dontMakeIdFromName = this._idDimIdx != null || sourceFormat === SOURCE_FORMAT_TYPED_ARRAY // Cosndier performance.
        || !!provider.fillStorage;
        this._nameList = (nameList || []).slice();
        this._idList = [];
        this._nameRepeatCount = {};

        if (!dimValueGetter) {
          this.hasItemOption = false;
        }

        this.defaultDimValueGetter = defaultDimValueGetters[sourceFormat]; // Default dim value getter

        this._dimValueGetter = dimValueGetter = dimValueGetter || this.defaultDimValueGetter;
        this._dimValueGetterArrayRows = defaultDimValueGetters.arrayRows; // Reset raw extent.

        this._rawExtent = {};

        this._initDataFromProvider(0, provider.count()); // If data has no item option.


        if (provider.pure) {
          this.hasItemOption = false;
        }
      };

      List.prototype.getProvider = function () {
        return this._rawData;
      };
      /**
       * Caution: Can be only called on raw data (before `this._indices` created).
       */


      List.prototype.appendData = function (data) {
        if ("development" !== 'production') {
          assert(!this._indices, 'appendData can only be called on raw data.');
        }

        var rawData = this._rawData;
        var start = this.count();
        rawData.appendData(data);
        var end = rawData.count();

        if (!rawData.persistent) {
          end += start;
        }

        this._initDataFromProvider(start, end, true);
      };
      /**
       * Caution: Can be only called on raw data (before `this._indices` created).
       * This method does not modify `rawData` (`dataProvider`), but only
       * add values to storage.
       *
       * The final count will be increased by `Math.max(values.length, names.length)`.
       *
       * @param values That is the SourceType: 'arrayRows', like
       *        [
       *            [12, 33, 44],
       *            [NaN, 43, 1],
       *            ['-', 'asdf', 0]
       *        ]
       *        Each item is exaclty cooresponding to a dimension.
       */


      List.prototype.appendValues = function (values, names) {
        var storage = this._storage;
        var dimensions = this.dimensions;
        var dimLen = dimensions.length;
        var rawExtent = this._rawExtent;
        var start = this.count();
        var end = start + Math.max(values.length, names ? names.length : 0);

        for (var i = 0; i < dimLen; i++) {
          var dim = dimensions[i];

          if (!rawExtent[dim]) {
            rawExtent[dim] = getInitialExtent();
          }

          prepareStorage(storage, this._dimensionInfos[dim], end, true);
        }

        var rawExtentArr = map$1(dimensions, function (dim) {
          return rawExtent[dim];
        });
        var storageArr = this._storageArr = map$1(dimensions, function (dim) {
          return storage[dim];
        });
        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 = this._dimValueGetterArrayRows(values[sourceIdx] || emptyDataItem, dim, sourceIdx, dimIdx);

            storageArr[dimIdx][idx] = val;
            var dimRawExtent = rawExtentArr[dimIdx];
            val < dimRawExtent[0] && (dimRawExtent[0] = val);
            val > dimRawExtent[1] && (dimRawExtent[1] = val);
          }

          if (names) {
            this._nameList[idx] = names[sourceIdx];

            if (!this._dontMakeIdFromName) {
              makeIdFromName(this, idx);
            }
          }
        }

        this._rawCount = this._count = end; // Reset data extent

        this._extent = {};
        prepareInvertedIndex(this);
      };

      List.prototype._initDataFromProvider = function (start, end, append) {
        if (start >= end) {
          return;
        }

        var rawData = this._rawData;
        var storage = this._storage;
        var dimensions = this.dimensions;
        var dimLen = dimensions.length;
        var dimensionInfoMap = this._dimensionInfos;
        var nameList = this._nameList;
        var idList = this._idList;
        var rawExtent = this._rawExtent;
        var sourceFormat = rawData.getSource().sourceFormat;
        var isFormatOriginal = sourceFormat === SOURCE_FORMAT_ORIGINAL;

        for (var i = 0; i < dimLen; i++) {
          var dim = dimensions[i];

          if (!rawExtent[dim]) {
            rawExtent[dim] = getInitialExtent();
          }

          prepareStorage(storage, dimensionInfoMap[dim], end, append);
        }

        var storageArr = this._storageArr = map$1(dimensions, function (dim) {
          return storage[dim];
        });
        var rawExtentArr = map$1(dimensions, function (dim) {
          return rawExtent[dim];
        });

        if (rawData.fillStorage) {
          rawData.fillStorage(start, end, storageArr, rawExtentArr);
        } else {
          var dataItem = [];

          for (var idx = start; idx < end; idx++) {
            // NOTICE: Try not to write things into dataItem
            dataItem = rawData.getItem(idx, dataItem); // Each data item is value
            // [1, 2]
            // 2
            // Bar chart, line chart which uses category axis
            // only gives the 'y' value. 'x' value is the indices of category
            // Use a tempValue to normalize the value to be a (x, y) value
            // Store the data by dimensions

            for (var dimIdx = 0; dimIdx < dimLen; dimIdx++) {
              var dim = dimensions[dimIdx];
              var dimStorage = storageArr[dimIdx]; // PENDING NULL is empty or zero

              var val = this._dimValueGetter(dataItem, dim, idx, dimIdx);

              dimStorage[idx] = val;
              var dimRawExtent = rawExtentArr[dimIdx];
              val < dimRawExtent[0] && (dimRawExtent[0] = val);
              val > dimRawExtent[1] && (dimRawExtent[1] = val);
            } // If dataItem is {name: ...} or {id: ...}, it has highest priority.
            // This kind of ids and names are always stored `_nameList` and `_idList`.


            if (isFormatOriginal && !rawData.pure && 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._dontMakeIdFromName) {
              makeIdFromName(this, idx);
            }
          }
        }

        if (!rawData.persistent && rawData.clean) {
          // Clean unused data if data source is typed array.
          rawData.clean();
        }

        this._rawCount = this._count = end; // Reset data extent

        this._extent = {};
        prepareInvertedIndex(this);
      };

      List.prototype.count = function () {
        return this._count;
      };

      List.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);
          newIndices = new Ctor(this.count());

          for (var i = 0; i < newIndices.length; i++) {
            newIndices[i] = i;
          }
        }

        return newIndices;
      }; // Get data by index of dimension.
      // Because in v8 access array by number variable is faster than access object by string variable
      // Not sure why but the optimization just works.


      List.prototype.getByDimIdx = function (dimIdx, idx) {
        if (!(idx >= 0 && idx < this._count)) {
          return NaN;
        }

        var dimStore = this._storageArr[dimIdx];
        return dimStore ? dimStore[this.getRawIndex(idx)] : NaN;
      };
      /**
       * Get value. Return NaN if idx is out of range.
       * @param dim Dim must be concrete name.
       */


      List.prototype.get = function (dim, idx) {
        if (!(idx >= 0 && idx < this._count)) {
          return NaN;
        }

        var dimStore = this._storage[dim];
        return dimStore ? dimStore[this.getRawIndex(idx)] : NaN;
      };
      /**
       * @param dim concrete dim
       */


      List.prototype.getByRawIndex = function (dim, rawIdx) {
        if (!(rawIdx >= 0 && rawIdx < this._rawCount)) {
          return NaN;
        }

        var dimStore = this._storage[dim];
        return dimStore ? dimStore[rawIdx] : NaN;
      };

      List.prototype.getValues = function (dimensions, idx) {
        var values = [];

        if (!isArray(dimensions)) {
          // stack = idx;
          idx = dimensions;
          dimensions = this.dimensions;
        }

        for (var i = 0, len = dimensions.length; i < len; i++) {
          values.push(this.get(dimensions[i], idx
          /*, stack */
          ));
        }

        return values;
      };
      /**
       * If value is NaN. Inlcuding '-'
       * Only check the coord dimensions.
       */


      List.prototype.hasValue = function (idx) {
        var dataDimsOnCoord = this._dimensionsSummary.dataDimsOnCoord;

        for (var i = 0, len = dataDimsOnCoord.length; i < len; i++) {
          // Ordinal type originally can be string or number.
          // But when an ordinal type is used on coord, it can
          // not be string but only number. So we can also use isNaN.
          if (isNaN(this.get(dataDimsOnCoord[i], idx))) {
            return false;
          }
        }

        return true;
      };
      /**
       * Get extent of data in one dimension
       */


      List.prototype.getDataExtent = function (dim) {
        // Make sure use concrete dim as cache name.
        dim = this.getDimension(dim);
        var dimData = this._storage[dim];
        var initialExtent = getInitialExtent(); // stack = !!((stack || false) && this.getCalculationInfo(dim));

        if (!dimData) {
          return initialExtent;
        } // Make more strict checkings to ensure hitting cache.


        var currEnd = this.count(); // let cacheName = [dim, !!stack].join('_');
        // let cacheName = dim;
        // Consider the most cases when using data zoom, `getDataExtent`
        // happened before filtering. We cache raw extent, which is not
        // necessary to be cleared and recalculated when restore data.

        var useRaw = !this._indices; // && !stack;

        var dimExtent;

        if (useRaw) {
          return this._rawExtent[dim].slice();
        }

        dimExtent = this._extent[dim];

        if (dimExtent) {
          return dimExtent.slice();
        }

        dimExtent = initialExtent;
        var min = dimExtent[0];
        var max = dimExtent[1];

        for (var i = 0; i < currEnd; i++) {
          var 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;
      };
      /**
       * 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.
       */


      List.prototype.getApproximateExtent = function (dim) {
        dim = this.getDimension(dim);
        return this._approximateExtent[dim] || this.getDataExtent(dim);
      };
      /**
       * Calculate extent on a filtered data might be time consuming.
       * Approximate extent is only used for: calculte extent of filtered data outside.
       */


      List.prototype.setApproximateExtent = function (extent, dim) {
        dim = this.getDimension(dim);
        this._approximateExtent[dim] = extent.slice();
      };

      List.prototype.getCalculationInfo = function (key) {
        return this._calculationInfo[key];
      };

      List.prototype.setCalculationInfo = function (key, value) {
        isObject$3(key) ? extend(this._calculationInfo, key) : this._calculationInfo[key] = value;
      };
      /**
       * Get sum of data in one dimension
       */


      List.prototype.getSum = function (dim) {
        var dimData = this._storage[dim];
        var sum = 0;

        if (dimData) {
          for (var i = 0, len = this.count(); i < len; i++) {
            var value = this.get(dim, i);

            if (!isNaN(value)) {
              sum += value;
            }
          }
        }

        return sum;
      };
      /**
       * Get median of data in one dimension
       */


      List.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;
      }; // /**
      //  * Retreive the index with given value
      //  * @param {string} dim Concrete dimension.
      //  * @param {number} value
      //  * @return {number}
      //  */
      // Currently incorrect: should return dataIndex but not rawIndex.
      // Do not fix it until this method is to be used somewhere.
      // FIXME Precision of float value
      // indexOf(dim, value) {
      //     let storage = this._storage;
      //     let dimData = storage[dim];
      //     let chunkSize = this._chunkSize;
      //     if (dimData) {
      //         for (let i = 0, len = this.count(); i < len; i++) {
      //             let chunkIndex = mathFloor(i / chunkSize);
      //             let chunkOffset = i % chunkSize;
      //             if (dimData[chunkIndex][chunkOffset] === value) {
      //                 return i;
      //             }
      //         }
      //     }
      //     return -1;
      // }

      /**
       * Only support the dimension which inverted index created.
       * Do not support other cases until required.
       * @param dim concrete dim
       * @param value ordinal index
       * @return rawIndex
       */


      List.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;
      };
      /**
       * Retreive the index with given name
       */


      List.prototype.indexOfName = function (name) {
        for (var i = 0, len = this.count(); i < len; i++) {
          if (this.getName(i) === name) {
            return i;
          }
        }

        return -1;
      };
      /**
       * Retreive the index with given raw data index
       */


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


      List.prototype.indicesOfNearest = function (dim, value, maxDistance) {
        var storage = this._storage;
        var dimData = storage[dim];
        var nearestIndices = [];

        if (!dimData) {
          return nearestIndices;
        }

        if (maxDistance == null) {
          maxDistance = Infinity;
        }

        var minDist = Infinity;
        var minDiff = -1;
        var nearestIndicesLen = 0; // Check the test case of `test/ut/spec/data/List.js`.

        for (var i = 0, len = this.count(); i < len; i++) {
          var dataIndex = this.getRawIndex(i);
          var diff = value - dimData[dataIndex];
          var dist = Math.abs(diff);

          if (dist <= maxDistance) {
            // When the `value` is at the middle of `this.get(dim, i)` and `this.get(dim, i+1)`,
            // we'd better not push both of them to `nearestIndices`, otherwise it is easy to
            // get more than one item in `nearestIndices` (more specifically, in `tooltip`).
            // So we chose the one that `diff >= 0` in this csae.
            // But if `this.get(dim, i)` and `this.get(dim, j)` get the same value, both of them
            // should be push to `nearestIndices`.
            if (dist < minDist || dist === minDist && diff >= 0 && minDiff < 0) {
              minDist = dist;
              minDiff = diff;
              nearestIndicesLen = 0;
            }

            if (diff === minDiff) {
              nearestIndices[nearestIndicesLen++] = i;
            }
          }
        }

        nearestIndices.length = nearestIndicesLen;
        return nearestIndices;
      };
      /**
       * Get raw data item
       */


      List.prototype.getRawDataItem = function (idx) {
        if (!this._rawData.persistent) {
          var val = [];

          for (var i = 0; i < this.dimensions.length; i++) {
            var dim = this.dimensions[i];
            val.push(this.get(dim, idx));
          }

          return val;
        } else {
          return this._rawData.getItem(this.getRawIndex(idx));
        }
      };
      /**
       * @return Never be null/undefined. `number` will be converted to string. Becuase:
       * 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'`.
       */


      List.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, this._nameOrdinalMeta, rawIndex);
        }

        if (name == null) {
          name = '';
        }

        return name;
      };
      /**
       * @return Never null/undefined. `number` will be converted to string. Becuase:
       * 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.
       */


      List.prototype.getId = function (idx) {
        return getId(this, this.getRawIndex(idx));
      };

      List.prototype.each = function (dims, cb, ctx, ctxCompat) {

        var _this = this;

        if (!this._count) {
          return;
        }

        if (typeof dims === 'function') {
          ctxCompat = ctx;
          ctx = cb;
          cb = dims;
          dims = [];
        } // ctxCompat just for compat echarts3


        var fCtx = ctx || ctxCompat || this;
        var dimNames = map$1(normalizeDimensions(dims), this.getDimension, this);

        if ("development" !== 'production') {
          validateDimensions(this, dimNames);
        }

        var dimSize = dimNames.length;
        var dimIndices = map$1(dimNames, function (dimName) {
          return _this._dimensionInfos[dimName].index;
        });
        var storageArr = this._storageArr;

        for (var i = 0, len = this.count(); i < len; i++) {
          var rawIdx = this.getRawIndex(i); // Simple optimization

          switch (dimSize) {
            case 0:
              cb.call(fCtx, i);
              break;

            case 1:
              cb.call(fCtx, storageArr[dimIndices[0]][rawIdx], i);
              break;

            case 2:
              cb.call(fCtx, storageArr[dimIndices[0]][rawIdx], storageArr[dimIndices[1]][rawIdx], i);
              break;

            default:
              var k = 0;
              var value = [];

              for (; k < dimSize; k++) {
                value[k] = storageArr[dimIndices[k]][rawIdx];
              } // Index


              value[k] = i;
              cb.apply(fCtx, value);
          }
        }
      };

      List.prototype.filterSelf = function (dims, cb, ctx, ctxCompat) {

        var _this = this;

        if (!this._count) {
          return;
        }

        if (typeof dims === 'function') {
          ctxCompat = ctx;
          ctx = cb;
          cb = dims;
          dims = [];
        } // ctxCompat just for compat echarts3


        var fCtx = ctx || ctxCompat || this;
        var dimNames = map$1(normalizeDimensions(dims), this.getDimension, this);

        if ("development" !== 'production') {
          validateDimensions(this, dimNames);
        }

        var count = this.count();
        var Ctor = getIndicesCtor(this);
        var newIndices = new Ctor(count);
        var value = [];
        var dimSize = dimNames.length;
        var offset = 0;
        var dimIndices = map$1(dimNames, function (dimName) {
          return _this._dimensionInfos[dimName].index;
        });
        var dim0 = dimIndices[0];
        var storageArr = this._storageArr;

        for (var i = 0; i < count; i++) {
          var keep = void 0;
          var rawIdx = this.getRawIndex(i); // Simple optimization

          if (dimSize === 0) {
            keep = cb.call(fCtx, i);
          } else if (dimSize === 1) {
            var val = storageArr[dim0][rawIdx];
            keep = cb.call(fCtx, val, i);
          } else {
            var k = 0;

            for (; k < dimSize; k++) {
              value[k] = storageArr[dimIndices[k]][rawIdx];
            }

            value[k] = i;
            keep = cb.apply(fCtx, value);
          }

          if (keep) {
            newIndices[offset++] = rawIdx;
          }
        } // Set indices after filtered.


        if (offset < count) {
          this._indices = newIndices;
        }

        this._count = offset; // Reset data extent

        this._extent = {};
        this.getRawIndex = this._indices ? getRawIndexWithIndices : getRawIndexWithoutIndices;
        return this;
      };
      /**
       * Select data in range. (For optimization of filter)
       * (Manually inline code, support 5 million data filtering in data zoom.)
       */


      List.prototype.selectRange = function (range) {

        var _this = this;

        var len = this._count;

        if (!len) {
          return;
        }

        var dimensions = [];

        for (var dim in range) {
          if (range.hasOwnProperty(dim)) {
            dimensions.push(dim);
          }
        }

        if ("development" !== 'production') {
          validateDimensions(this, dimensions);
        }

        var dimSize = dimensions.length;

        if (!dimSize) {
          return;
        }

        var originalCount = this.count();
        var Ctor = getIndicesCtor(this);
        var newIndices = new Ctor(originalCount);
        var offset = 0;
        var dim0 = dimensions[0];
        var dimIndices = map$1(dimensions, function (dimName) {
          return _this._dimensionInfos[dimName].index;
        });
        var min = range[dim0][0];
        var max = range[dim0][1];
        var storageArr = this._storageArr;
        var quickFinished = false;

        if (!this._indices) {
          // Extreme optimization for common case. About 2x faster in chrome.
          var idx = 0;

          if (dimSize === 1) {
            var dimStorage = storageArr[dimIndices[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 = storageArr[dimIndices[0]];
            var dimStorage2 = storageArr[dimIndices[1]];
            var min2 = range[dimensions[1]][0];
            var max2 = range[dimensions[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 = this.getRawIndex(i);
              var val = storageArr[dimIndices[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 = this.getRawIndex(i);

              for (var k = 0; k < dimSize; k++) {
                var dimk = dimensions[k];
                var val = storageArr[dimIndices[k]][rawIndex]; // Do not filter NaN, see comment above.

                if (val < range[dimk][0] || val > range[dimk][1]) {
                  keep = false;
                }
              }

              if (keep) {
                newIndices[offset++] = this.getRawIndex(i);
              }
            }
          }
        } // Set indices after filtered.


        if (offset < originalCount) {
          this._indices = newIndices;
        }

        this._count = offset; // Reset data extent

        this._extent = {};
        this.getRawIndex = this._indices ? getRawIndexWithIndices : getRawIndexWithoutIndices;
        return this;
      };
      /* eslint-enable */


      List.prototype.mapArray = function (dims, cb, ctx, ctxCompat) {

        if (typeof dims === 'function') {
          ctxCompat = ctx;
          ctx = cb;
          cb = dims;
          dims = [];
        } // ctxCompat just for compat echarts3


        ctx = ctx || ctxCompat || this;
        var result = [];
        this.each(dims, function () {
          result.push(cb && cb.apply(this, arguments));
        }, ctx);
        return result;
      };

      List.prototype.map = function (dims, cb, ctx, ctxCompat) {

        var fCtx = ctx || ctxCompat || this;
        var dimNames = map$1(normalizeDimensions(dims), this.getDimension, this);

        if ("development" !== 'production') {
          validateDimensions(this, dimNames);
        }

        var list = cloneListForMapAndSample(this, dimNames);
        var storage = list._storage; // Following properties are all immutable.
        // So we can reference to the same value

        list._indices = this._indices;
        list.getRawIndex = list._indices ? getRawIndexWithIndices : getRawIndexWithoutIndices;
        var tmpRetValue = [];
        var dimSize = dimNames.length;
        var dataCount = this.count();
        var values = [];
        var rawExtent = list._rawExtent;

        for (var dataIndex = 0; dataIndex < dataCount; dataIndex++) {
          for (var dimIndex = 0; dimIndex < dimSize; dimIndex++) {
            values[dimIndex] = this.get(dimNames[dimIndex], dataIndex);
          }

          values[dimSize] = dataIndex;
          var retValue = cb && cb.apply(fCtx, values);

          if (retValue != null) {
            // a number or string (in oridinal dimension)?
            if (typeof retValue !== 'object') {
              tmpRetValue[0] = retValue;
              retValue = tmpRetValue;
            }

            var rawIndex = this.getRawIndex(dataIndex);

            for (var i = 0; i < retValue.length; i++) {
              var dim = dimNames[i];
              var val = retValue[i];
              var rawExtentOnDim = rawExtent[dim];
              var dimStore = storage[dim];

              if (dimStore) {
                dimStore[rawIndex] = val;
              }

              if (val < rawExtentOnDim[0]) {
                rawExtentOnDim[0] = val;
              }

              if (val > rawExtentOnDim[1]) {
                rawExtentOnDim[1] = val;
              }
            }
          }
        }

        return list;
      };
      /**
       * Large data down sampling on given dimension
       * @param sampleIndex Sample index for name and id
       */


      List.prototype.downSample = function (dimension, rate, sampleValue, sampleIndex) {
        var list = cloneListForMapAndSample(this, [dimension]);
        var targetStorage = list._storage;
        var frameValues = [];
        var frameSize = mathFloor(1 / rate);
        var dimStore = targetStorage[dimension];
        var len = this.count();
        var rawExtentOnDim = list._rawExtent[dimension];
        var newIndices = new (getIndicesCtor(this))(len);
        var offset = 0;

        for (var i = 0; i < len; i += frameSize) {
          // Last frame
          if (frameSize > len - i) {
            frameSize = len - i;
            frameValues.length = frameSize;
          }

          for (var k = 0; k < frameSize; k++) {
            var dataIdx = this.getRawIndex(i + k);
            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;
        }

        list._count = offset;
        list._indices = newIndices;
        list.getRawIndex = getRawIndexWithIndices;
        return list;
      };
      /**
       * Large data down sampling using largest-triangle-three-buckets
       * @param {string} valueDimension
       * @param {number} targetCount
       */


      List.prototype.lttbDownSample = function (valueDimension, rate) {
        var list = cloneListForMapAndSample(this, []);
        var targetStorage = list._storage;
        var dimStore = targetStorage[valueDimension];
        var len = this.count();
        var newIndices = new (getIndicesCtor(this))(len);
        var sampledIndex = 0;
        var frameSize = mathFloor(1 / rate);
        var currentRawIndex = this.getRawIndex(0);
        var maxArea;
        var area;
        var nextRawIndex; // 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; // Find a point from current frame that construct a triangel with largest area with previous selected point
          // And the average of next frame.

          for (var idx = frameStart; idx < frameEnd; idx++) {
            var rawIndex = this.getRawIndex(idx);
            var y = dimStore[rawIndex];

            if (isNaN(y)) {
              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
            }
          }

          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);
        list._count = sampledIndex;
        list._indices = newIndices;
        list.getRawIndex = getRawIndexWithIndices;
        return list;
      };
      /**
       * Get model of one data item.
       */
      // TODO: Type of data item


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


      List.prototype.diff = function (otherList) {
        var thisList = this;
        return new DataDiffer(otherList ? otherList.getIndices() : [], this.getIndices(), function (idx) {
          return getId(otherList, idx);
        }, function (idx) {
          return getId(thisList, idx);
        });
      };
      /**
       * Get visual property.
       */


      List.prototype.getVisual = function (key) {
        var visual = this._visual;
        return visual && visual[key];
      };

      List.prototype.setVisual = function (kvObj, val) {
        this._visual = this._visual || {};

        if (isObject$3(kvObj)) {
          extend(this._visual, kvObj);
        } else {
          this._visual[kvObj] = val;
        }
      };
      /**
       * Get visual property of single data item
       */
      // eslint-disable-next-line


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


      List.prototype.hasItemVisual = function () {
        return this._itemVisuals.length > 0;
      };
      /**
       * Make sure itemVisual property is unique
       */
      // TODO: use key to save visual to reduce memory.


      List.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$3(val)) {
            val = extend({}, val);
          }

          itemVisual[key] = val;
        }

        return val;
      }; // eslint-disable-next-line


      List.prototype.setItemVisual = function (idx, key, value) {
        var itemVisual = this._itemVisuals[idx] || {};
        this._itemVisuals[idx] = itemVisual;

        if (isObject$3(key)) {
          extend(itemVisual, key);
        } else {
          itemVisual[key] = value;
        }
      };
      /**
       * Clear itemVisuals and list visual.
       */


      List.prototype.clearAllVisual = function () {
        this._visual = {};
        this._itemVisuals = [];
      };

      List.prototype.setLayout = function (key, val) {
        if (isObject$3(key)) {
          for (var name_1 in key) {
            if (key.hasOwnProperty(name_1)) {
              this.setLayout(name_1, key[name_1]);
            }
          }

          return;
        }

        this._layout[key] = val;
      };
      /**
       * Get layout property.
       */


      List.prototype.getLayout = function (key) {
        return this._layout[key];
      };
      /**
       * Get layout of single data item
       */


      List.prototype.getItemLayout = function (idx) {
        return this._itemLayouts[idx];
      };
      /**
       * Set layout of single data item
       */


      List.prototype.setItemLayout = function (idx, layout, merge) {
        this._itemLayouts[idx] = merge ? extend(this._itemLayouts[idx] || {}, layout) : layout;
      };
      /**
       * Clear all layout of single data item
       */


      List.prototype.clearItemLayouts = function () {
        this._itemLayouts.length = 0;
      };
      /**
       * Set graphic element relative to data. It can be set as null
       */


      List.prototype.setItemGraphicEl = function (idx, el) {
        var hostModel = this.hostModel;

        if (el) {
          var ecData = getECData(el); // Add data index and series index for indexing the data by element
          // Useful in tooltip

          ecData.dataIndex = idx;
          ecData.dataType = this.dataType;
          ecData.seriesIndex = hostModel && hostModel.seriesIndex; // TODO: not store dataIndex on children.

          if (el.type === 'group') {
            el.traverse(setItemDataAndSeriesIndex, el);
          }
        }

        this._graphicEls[idx] = el;
      };

      List.prototype.getItemGraphicEl = function (idx) {
        return this._graphicEls[idx];
      };

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


      List.prototype.cloneShallow = function (list) {
        if (!list) {
          var dimensionInfoList = map$1(this.dimensions, this.getDimensionInfo, this);
          list = new List(dimensionInfoList, this.hostModel);
        } // FIXME


        list._storage = this._storage;
        list._storageArr = this._storageArr;
        transferProperties(list, this); // Clone will not change the data extent and indices

        if (this._indices) {
          var Ctor = this._indices.constructor;

          if (Ctor === Array) {
            var thisCount = this._indices.length;
            list._indices = new Ctor(thisCount);

            for (var i = 0; i < thisCount; i++) {
              list._indices[i] = this._indices[i];
            }
          } else {
            list._indices = new Ctor(this._indices);
          }
        } else {
          list._indices = null;
        }

        list.getRawIndex = list._indices ? getRawIndexWithIndices : getRawIndexWithoutIndices;
        return list;
      };
      /**
       * Wrap some method to add more feature
       */


      List.prototype.wrapMethod = function (methodName, injectFunction) {
        var originalMethod = this[methodName];

        if (typeof originalMethod !== 'function') {
          return;
        }

        this.__wrappedMethods = this.__wrappedMethods || [];

        this.__wrappedMethods.push(methodName);

        this[methodName] = function () {
          var res = originalMethod.apply(this, arguments);
          return injectFunction.apply(this, [res].concat(slice(arguments)));
        };
      }; // ----------------------------------------------------------
      // A work around for internal method visiting private member.
      // ----------------------------------------------------------


      List.internalField = function () {
        defaultDimValueGetters = {
          arrayRows: getDimValueSimply,
          objectRows: function (dataItem, dimName, dataIndex, dimIndex) {
            return parseDataValue(dataItem[dimName], this._dimensionInfos[dimName]);
          },
          keyedColumns: getDimValueSimply,
          original: function (dataItem, dimName, dataIndex, dimIndex) {
            // Performance sensitive, do not use modelUtil.getDataItemValue.
            // If dataItem is an plain object with no value field, the 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); // If any dataItem is like { value: 10 }

            if (!this._rawData.pure && isDataItemOption(dataItem)) {
              this.hasItemOption = true;
            }

            return parseDataValue(value instanceof Array ? value[dimIndex] // If value is a single number or something else not array.
            : value, this._dimensionInfos[dimName]);
          },
          typedArray: function (dataItem, dimName, dataIndex, dimIndex) {
            return dataItem[dimIndex];
          }
        };

        function getDimValueSimply(dataItem, dimName, dataIndex, dimIndex) {
          return parseDataValue(dataItem[dimIndex], this._dimensionInfos[dimName]);
        }

        prepareInvertedIndex = function (list) {
          var invertedIndicesMap = list._invertedIndicesMap;
          each(invertedIndicesMap, function (invertedIndices, dim) {
            var dimInfo = list._dimensionInfos[dim]; // Currently, only dimensions that has ordinalMeta can create inverted indices.

            var ordinalMeta = dimInfo.ordinalMeta;

            if (ordinalMeta) {
              invertedIndices = invertedIndicesMap[dim] = new CtorInt32Array(ordinalMeta.categories.length); // The default value of TypedArray is 0. To avoid miss
              // mapping to 0, we should set it as INDEX_NOT_FOUND.

              for (var i = 0; i < invertedIndices.length; i++) {
                invertedIndices[i] = INDEX_NOT_FOUND;
              }

              for (var i = 0; i < list._count; i++) {
                // Only support the case that all values are distinct.
                invertedIndices[list.get(dim, i)] = i;
              }
            }
          });
        };

        getIdNameFromStore = function (list, dimIdx, ordinalMeta, rawIndex) {
          var val;
          var chunk = list._storageArr[dimIdx];

          if (chunk) {
            val = chunk[rawIndex];

            if (ordinalMeta && ordinalMeta.categories.length) {
              val = ordinalMeta.categories[val];
            }
          }

          return convertOptionIdName(val, null);
        };

        getIndicesCtor = function (list) {
          // The possible max value in this._indicies is always this._rawCount despite of filtering.
          return list._rawCount > 65535 ? CtorUint32Array : CtorUint16Array;
        };

        prepareStorage = function (storage, dimInfo, end, append) {
          var DataCtor = dataCtors[dimInfo.type];
          var dim = dimInfo.name;

          if (append) {
            var oldStore = storage[dim];
            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];
              }

              storage[dim] = newStore;
            }
          } else {
            storage[dim] = new DataCtor(end);
          }
        };

        getRawIndexWithoutIndices = function (idx) {
          return idx;
        };

        getRawIndexWithIndices = function (idx) {
          if (idx < this._count && idx >= 0) {
            return this._indices[idx];
          }

          return -1;
        };
        /**
         * @see the comment of `List['getId']`.
         */


        getId = function (list, rawIndex) {
          var id = list._idList[rawIndex];

          if (id == null && list._idDimIdx != null) {
            id = getIdNameFromStore(list, list._idDimIdx, list._idOrdinalMeta, rawIndex);
          }

          if (id == null) {
            id = ID_PREFIX + rawIndex;
          }

          return id;
        };

        normalizeDimensions = function (dimensions) {
          if (!isArray(dimensions)) {
            dimensions = dimensions != null ? [dimensions] : [];
          }

          return dimensions;
        };

        validateDimensions = function (list, dims) {
          for (var i = 0; i < dims.length; i++) {
            // stroage may be empty when no data, so use
            // dimensionInfos to check.
            if (!list._dimensionInfos[dims[i]]) {
              console.error('Unkown dimension ' + dims[i]);
            }
          }
        }; // Data in excludeDimensions is copied, otherwise transfered.


        cloneListForMapAndSample = function (original, excludeDimensions) {
          var allDimensions = original.dimensions;
          var list = new List(map$1(allDimensions, original.getDimensionInfo, original), original.hostModel); // FIXME If needs stackedOn, value may already been stacked

          transferProperties(list, original);
          var storage = list._storage = {};
          var originalStorage = original._storage;
          var storageArr = list._storageArr = []; // Init storage

          for (var i = 0; i < allDimensions.length; i++) {
            var dim = allDimensions[i];

            if (originalStorage[dim]) {
              // Notice that we do not reset invertedIndicesMap here, becuase
              // there is no scenario of mapping or sampling ordinal dimension.
              if (indexOf(excludeDimensions, dim) >= 0) {
                storage[dim] = cloneChunk(originalStorage[dim]);
                list._rawExtent[dim] = getInitialExtent();
                list._extent[dim] = null;
              } else {
                // Direct reference for other dimensions
                storage[dim] = originalStorage[dim];
              }

              storageArr.push(storage[dim]);
            }
          }

          return list;
        };

        function cloneChunk(originalChunk) {
          var Ctor = originalChunk.constructor; // Only shallow clone is enough when Array.

          return Ctor === Array ? originalChunk.slice() : new Ctor(originalChunk);
        }

        getInitialExtent = function () {
          return [Infinity, -Infinity];
        };

        setItemDataAndSeriesIndex = function (child) {
          var childECData = getECData(child);
          var thisECData = getECData(this);
          childECData.seriesIndex = thisECData.seriesIndex;
          childECData.dataIndex = thisECData.dataIndex;
          childECData.dataType = thisECData.dataType;
        };

        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 (list, idx) {
          var nameList = list._nameList;
          var idList = list._idList;
          var nameDimIdx = list._nameDimIdx;
          var idDimIdx = list._idDimIdx;
          var name = nameList[idx];
          var id = idList[idx];

          if (name == null && nameDimIdx != null) {
            nameList[idx] = name = getIdNameFromStore(list, nameDimIdx, list._nameOrdinalMeta, idx);
          }

          if (id == null && idDimIdx != null) {
            idList[idx] = id = getIdNameFromStore(list, idDimIdx, list._idOrdinalMeta, idx);
          }

          if (id == null && name != null) {
            var nameRepeatCount = list._nameRepeatCount;
            var nmCnt = nameRepeatCount[name] = (nameRepeatCount[name] || 0) + 1;
            id = name;

            if (nmCnt > 1) {
              id += '__ec__' + nmCnt;
            }

            idList[idx] = id;
          }
        };
      }();

      return List;
    }();

    /**
     * @see {module:echarts/test/ut/spec/data/completeDimensions}
     *
     * This method builds the relationship between:
     * + "what the coord sys or series requires (see `sysDims`)",
     * + "what the user defines (in `encode` and `dimensions`, see `opt.dimsDef` and `opt.encodeDef`)"
     * + "what the data source provids (see `source`)".
     *
     * Some guess strategy will be adapted if user does not define something.
     * If no 'value' dimension specified, the first no-named dimension will be
     * named as 'value'.
     *
     * @param {Array.<string>} sysDims Necessary dimensions, like ['x', 'y'], which
     *      provides not only dim template, but also default order.
     *      properties: 'name', 'type', 'displayName'.
     *      `name` of each item provides default coord name.
     *      [{dimsDef: [string|Object, ...]}, ...] dimsDef of sysDim item provides default dim name, and
     *                                    provide dims count that the sysDim required.
     *      [{ordinalMeta}] can be specified.
     * @param {module:echarts/data/Source|Array|Object} source or data (for compatibal with pervious)
     * @param {Object} [opt]
     * @param {Array.<Object|string>} [opt.dimsDef] option.series.dimensions User defined dimensions
     *      For example: ['asdf', {name, type}, ...].
     * @param {Object|HashMap} [opt.encodeDef] option.series.encode {x: 2, y: [3, 1], tooltip: [1, 2], label: 3}
     * @param {Function} [opt.encodeDefaulter] Called if no `opt.encodeDef` exists.
     *      If not specified, auto find the next available data dim.
     *      param source {module:data/Source}
     *      param dimCount {number}
     *      return {Object} encode Never be `null/undefined`.
     * @param {string} [opt.generateCoord] Generate coord dim with the given name.
     *      If not specified, extra dim names will be:
     *      'value', 'value0', 'value1', ...
     * @param {number} [opt.generateCoordCount] By default, the generated dim name is `generateCoord`.
     *      If `generateCoordCount` specified, the generated dim names will be:
     *      `generateCoord` + 0, `generateCoord` + 1, ...
     *      can be Infinity, indicate that use all of the remain columns.
     * @param {number} [opt.dimCount] If not specified, guess by the first data item.
     * @return {Array.<module:data/DataDimensionInfo>}
     */

    function completeDimensions(sysDims, source, opt) {
      if (!isSourceInstance(source)) {
        source = createSourceFromSeriesDataOption(source);
      }

      opt = opt || {};
      sysDims = (sysDims || []).slice();
      var dimsDef = (opt.dimsDef || []).slice();
      var dataDimNameMap = createHashMap();
      var coordDimNameMap = createHashMap(); // let valueCandidate;

      var result = [];
      var dimCount = getDimCount(source, sysDims, dimsDef, opt.dimCount); // Apply user defined dims (`name` and `type`) and init result.

      for (var i = 0; i < dimCount; i++) {
        var dimDefItemRaw = dimsDef[i];
        var dimDefItem = dimsDef[i] = extend({}, isObject(dimDefItemRaw) ? dimDefItemRaw : {
          name: dimDefItemRaw
        });
        var userDimName = dimDefItem.name;
        var resultItem = result[i] = new DataDimensionInfo(); // Name will be applied later for avoiding duplication.

        if (userDimName != null && dataDimNameMap.get(userDimName) == null) {
          // Only if `series.dimensions` is defined in option
          // displayName, will be set, and dimension will be diplayed vertically in
          // tooltip by default.
          resultItem.name = resultItem.displayName = userDimName;
          dataDimNameMap.set(userDimName, i);
        }

        dimDefItem.type != null && (resultItem.type = dimDefItem.type);
        dimDefItem.displayName != null && (resultItem.displayName = dimDefItem.displayName);
      }

      var encodeDef = opt.encodeDef;

      if (!encodeDef && opt.encodeDefaulter) {
        encodeDef = opt.encodeDefaulter(source, dimCount);
      }

      var encodeDefMap = createHashMap(encodeDef); // 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(result[resultDimIdx], coordDim, idx);
          }
        });
      }); // Apply templetes 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 = clone(sysDimItem);
          sysDimItem.ordinalMeta = ordinalMeta; // `coordDimIndex` should not be set directly.

          sysDimItemDimsDef = sysDimItem.dimsDef;
          sysDimItemOtherDims = sysDimItem.otherDims;
          sysDimItem.name = sysDimItem.coordDim = sysDimItem.coordDimIndex = sysDimItem.dimsDef = sysDimItem.otherDims = null;
        }

        var dataDims = 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 < result.length && result[availDimIdx].coordDim != null) {
              availDimIdx++;
            }

            availDimIdx < result.length && dataDims.push(availDimIdx++);
          }
        } // Apply templates.


        each(dataDims, function (resultDimIdx, coordDimIndex) {
          var resultItem = result[resultDimIdx];
          applyDim(defaults(resultItem, sysDimItem), coordDim, coordDimIndex);

          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'; // Set dim `name` and other `coordDim` and other props.

      for (var resultDimIdx = 0; resultDimIdx < dimCount; resultDimIdx++) {
        var resultItem = result[resultDimIdx] = result[resultDimIdx] || new DataDimensionInfo();
        var coordDim = resultItem.coordDim;

        if (coordDim == null) {
          resultItem.coordDim = genName(extra, coordDimNameMap, fromZero);
          resultItem.coordDimIndex = 0;

          if (!generateCoord || generateCoordCount <= 0) {
            resultItem.isExtraCoord = true;
          }

          generateCoordCount--;
        }

        resultItem.name == null && (resultItem.name = genName(resultItem.coordDim, dataDimNameMap, false));

        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 colum should better be treated as a "ordinal" although it
        // might not able to be detected as an "ordinal" by `guessOrdinal`.
        || resultItem.isExtraCoord && (resultItem.otherDims.itemName != null || resultItem.otherDims.seriesName != null))) {
          resultItem.type = 'ordinal';
        }
      }

      return result;
    } // ??? TODO
    // Originally detect dimCount by data[0]. Should we
    // optimize it to only by sysDims and dimensions and encode.
    // So only necessary dims will be initialized.
    // But
    // (1) custom series should be considered. where other dims
    // may be visited.
    // (2) sometimes user need to calcualte bubble size or use visualMap
    // on other dimensions besides coordSys needed.
    // So, dims that is not used by system, should be shared in storage?


    function getDimCount(source, sysDims, dimsDef, optDimCount) {
      // Note that the result dimCount should not small than columns count
      // of data, otherwise `dataDimNameMap` checking will be incorrect.
      var dimCount = Math.max(source.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 genName(name, map, fromZero) {
      if (fromZero || map.get(name) != null) {
        var i = 0;

        while (map.get(name + i) != null) {
          i++;
        }

        name += i;
      }

      map.set(name, true);
      return name;
    }

    /**
     * @param opt.coordDimensions
     * @param opt.dimensionsDefine By default `source.dimensionsDefine` Overwrite source define.
     * @param opt.encodeDefine By default `source.encodeDefine` Overwrite source define.
     * @param opt.encodeDefaulter Make default encode if user not specified.
     */

    function createDimensions( // TODO: TYPE completeDimensions type
    source, opt) {
      opt = opt || {};
      return completeDimensions(opt.coordDimensions || [], source, {
        // FIXME:TS detect whether source then call `.dimensionsDefine` and `.encodeDefine`?
        dimsDef: opt.dimensionsDefine || source.dimensionsDefine,
        encodeDef: opt.encodeDefine || source.encodeDefine,
        dimCount: opt.dimensionsCount,
        encodeDefaulter: opt.encodeDefaulter,
        generateCoord: opt.generateCoord,
        generateCoordCount: opt.generateCoordCount
      });
    }

    /**
     * @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 dimensionInfoList The same as the input of <module:echarts/data/List>.
     *        The input dimensionInfoList 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, dimensionInfoList, opt) {
      opt = opt || {};
      var byIndex = opt.byIndex;
      var stackedCoordDimension = opt.stackedCoordDimension; // Compatibal: when `stack` is set as '', do not stack.

      var mayStack = !!(seriesModel && seriesModel.get('stack'));
      var stackedByDimInfo;
      var stackedDimInfo;
      var stackResultDimension;
      var stackedOverDimension;
      each(dimensionInfoList, function (dimensionInfo, index) {
        if (isString(dimensionInfo)) {
          dimensionInfoList[index] = dimensionInfo = {
            name: dimensionInfo
          };
        }

        if (mayStack && !dimensionInfo.isExtraCoord) {
          // Find the first ordinal dimension as the stackedByDimInfo.
          if (!byIndex && !stackedByDimInfo && dimensionInfo.ordinalMeta) {
            stackedByDimInfo = dimensionInfo;
          } // Find the first stackable dimension as the stackedDimInfo.


          if (!stackedDimInfo && dimensionInfo.type !== 'ordinal' && dimensionInfo.type !== 'time' && (!stackedCoordDimension || stackedCoordDimension === dimensionInfo.coordDim)) {
            stackedDimInfo = dimensionInfo;
          }
        }
      });

      if (stackedDimInfo && !byIndex && !stackedByDimInfo) {
        // Compatible with previous design, value axis (time axis) only stack by index.
        // It may make sense if the user provides elaborately constructed data.
        byIndex = true;
      } // Add stack dimension, they can be both calculated by coordinate system in `unionExtent`.
      // That put stack logic in List is for using conveniently in echarts extensions, but it
      // might not be a good way.


      if (stackedDimInfo) {
        // Use a weird name that not duplicated with other names.
        stackResultDimension = '__\0ecstackresult';
        stackedOverDimension = '__\0ecstackedover'; // Create inverted index to fast query index by value.

        if (stackedByDimInfo) {
          stackedByDimInfo.createInvertedIndices = true;
        }

        var stackedDimCoordDim_1 = stackedDimInfo.coordDim;
        var stackedDimType = stackedDimInfo.type;
        var stackedDimCoordIndex_1 = 0;
        each(dimensionInfoList, function (dimensionInfo) {
          if (dimensionInfo.coordDim === stackedDimCoordDim_1) {
            stackedDimCoordIndex_1++;
          }
        });
        dimensionInfoList.push({
          name: stackResultDimension,
          coordDim: stackedDimCoordDim_1,
          coordDimIndex: stackedDimCoordIndex_1,
          type: stackedDimType,
          isExtraCoord: true,
          isCalculationCoord: true
        });
        stackedDimCoordIndex_1++;
        dimensionInfoList.push({
          name: stackedOverDimension,
          // This dimension contains stack base (generally, 0), so do not set it as
          // `stackedDimCoordDim` to avoid extent calculation, consider log scale.
          coordDim: stackedOverDimension,
          coordDimIndex: stackedDimCoordIndex_1,
          type: stackedDimType,
          isExtraCoord: true,
          isCalculationCoord: true
        });
      }

      return {
        stackedDimension: stackedDimInfo && stackedDimInfo.name,
        stackedByDimension: stackedByDimInfo && stackedByDimInfo.name,
        isStackedByIndex: byIndex,
        stackedOverDimension: stackedOverDimension,
        stackResultDimension: stackResultDimension
      };
    }
    function isDimensionStacked(data, stackedDim
    /*, stackedByDim*/
    ) {
      // Each single series only maps to one pair of axis. So we do not need to
      // check stackByDim, whatever stacked by a dimension or stacked by index.
      return !!stackedDim && stackedDim === data.getCalculationInfo('stackedDimension'); // && (
      //     stackedByDim != null
      //         ? stackedByDim === data.getCalculationInfo('stackedByDimension')
      //         : data.getCalculationInfo('isStackedByIndex')
      // );
    }
    function getStackedDimension(data, targetDim) {
      return isDimensionStacked(data, targetDim) ? data.getCalculationInfo('stackResultDimension') : targetDim;
    }

    function createListFromArray(source, seriesModel, opt) {
      opt = opt || {};

      if (!isSourceInstance(source)) {
        source = createSourceFromSeriesDataOption(source);
      }

      var coordSysName = seriesModel.get('coordinateSystem');
      var registeredCoordSys = CoordinateSystemManager.get(coordSysName);
      var coordSysInfo = getCoordSysInfoBySeries(seriesModel);
      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); // dimInfo.stackable = isStackable(axisType);
          }

          return dimInfo;
        });
      }

      if (!coordSysDimDefs) {
        // Get dimensions from registered coordinate system
        coordSysDimDefs = registeredCoordSys && (registeredCoordSys.getDimensionsInfo ? registeredCoordSys.getDimensionsInfo() : registeredCoordSys.dimensions.slice()) || ['x', 'y'];
      }

      var useEncodeDefaulter = opt.useEncodeDefaulter;
      var dimInfoList = createDimensions(source, {
        coordDimensions: coordSysDimDefs,
        generateCoord: opt.generateCoord,
        encodeDefaulter: isFunction(useEncodeDefaulter) ? useEncodeDefaulter : useEncodeDefaulter ? curry(makeSeriesEncodeForAxisCoordSys, coordSysDimDefs, seriesModel) : null
      });
      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 (opt.createInvertedIndices) {
            dimInfo.createInvertedIndices = true;
          }
        }

        if (dimInfo.otherDims.itemName != null) {
          hasNameEncode = true;
        }
      });

      if (!hasNameEncode && firstCategoryDimIndex != null) {
        dimInfoList[firstCategoryDimIndex].otherDims.itemName = 0;
      }

      var stackCalculationInfo = enableDataStack(seriesModel, dimInfoList);
      var list = new List(dimInfoList, seriesModel);
      list.setCalculationInfo(stackCalculationInfo);
      var dimValueGetter = firstCategoryDimIndex != null && isNeedCompleteOrdinalData(source) ? function (itemOpt, dimName, dataIndex, dimIndex) {
        // Use dataIndex as ordinal value in categoryAxis
        return dimIndex === firstCategoryDimIndex ? dataIndex : this.defaultDimValueGetter(itemOpt, dimName, dataIndex, dimIndex);
      } : null;
      list.hasItemOption = false;
      list.initData(source, null, dimValueGetter);
      return list;
    }

    function isNeedCompleteOrdinalData(source) {
      if (source.sourceFormat === SOURCE_FORMAT_ORIGINAL) {
        var sampleItem = firstDataNotNull(source.data || []);
        return sampleItem != null && !isArray(getDataItemValue(sampleItem));
      }
    }

    function firstDataNotNull(data) {
      var i = 0;

      while (i < data.length && data[i] == null) {
        i++;
      }

      return data[i];
    }

    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 OrdinalMeta =
    /** @class */
    function () {
      function OrdinalMeta(opt) {
        this.categories = opt.categories || [];
        this._needCollect = opt.needCollect;
        this._deduplication = opt.deduplication;
      }

      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 (typeof category !== 'string' && !needCollect) {
          return category;
        } // Optimize for the scenario:
        // category is ['2012-01-01', '2012-01-02', ...], where the input
        // data has been ensured not duplicate and is large data.
        // Notice, if a dataset dimension provide categroies, usually echarts
        // should remove duplication except user tell echarts dont do that
        // (set axis.deduplication = false), because echarts do not know whether
        // the values in the category dimension has duplication (consider the
        // parallel-aqi example)


        if (needCollect && !this._deduplication) {
          index = this.categories.length;
          this.categories[index] = category;
          return index;
        }

        var map = 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 + '';
      }
    }

    var roundNumber = round;
    /**
     * @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 = [roundNumber(Math.ceil(extent[0] / interval) * interval, precision), roundNumber(Math.floor(extent[1] / interval) * interval, precision)];
      fixExtent(niceTickExtent, extent);
      return result;
    }
    /**
     * @return interval precision
     */

    function getIntervalPrecision(interval) {
      // Tow more digital for tick.
      return getPrecisionSafe(interval) + 2;
    }

    function clamp(niceTickExtent, idx, extent) {
      niceTickExtent[idx] = Math.max(Math.min(niceTickExtent[idx], extent[1]), extent[0]);
    } // In some cases (e.g., splitNumber is 1), niceTickExtent may be out of extent.


    function fixExtent(niceTickExtent, extent) {
      !isFinite(niceTickExtent[0]) && (niceTickExtent[0] = extent[0]);
      !isFinite(niceTickExtent[1]) && (niceTickExtent[1] = extent[1]);
      clamp(niceTickExtent, 0, extent);
      clamp(niceTickExtent, 1, extent);

      if (niceTickExtent[0] > niceTickExtent[1]) {
        niceTickExtent[0] = niceTickExtent[1];
      }
    }
    function contain$2(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) {
        return typeof val === 'string' ? this._ordinalMeta.getOrdinal(val) // val might be float.
        : Math.round(val);
      };

      OrdinalScale.prototype.contain = function (rank) {
        rank = this.parse(rank);
        return contain$2(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.niceTicks = function () {};

      OrdinalScale.prototype.niceExtent = function () {};

      OrdinalScale.type = 'ordinal';
      return OrdinalScale;
    }(Scale);

    Scale.registerClass(OrdinalScale);

    var roundNumber$1 = 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$2(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 setted extent
        // We assume user wan't to set both interval, min, max to get a better result

        this._niceExtent = this._extent.slice();
        this._intervalPrecision = getIntervalPrecision(interval);
      };
      /**
       * @param 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$1(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$1(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$1(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$1(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 = getPrecisionSafe(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$1(data.value, precision, true);
        return addCommas(dataNum);
      };
      /**
       * @param splitNumber By default `5`.
       */


      IntervalScale.prototype.niceTicks = function (splitNumber, minInterval, maxInterval) {
        splitNumber = splitNumber || 5;
        var extent = this._extent;
        var span = extent[1] - extent[0];

        if (!isFinite(span)) {
          return;
        } // User may set axis min 0 and data are all negative
        // FIXME If it needs to reverse ?


        if (span < 0) {
          span = -span;
          extent.reverse();
        }

        var result = intervalScaleNiceTicks(extent, splitNumber, minInterval, maxInterval);
        this._intervalPrecision = result.intervalPrecision;
        this._interval = result.interval;
        this._niceExtent = result.niceTickExtent;
      };

      IntervalScale.prototype.niceExtent = function (opt) {
        var extent = this._extent; // If extent start and end are same, expand them

        if (extent[0] === extent[1]) {
          if (extent[0] !== 0) {
            // Expand extent
            var expandSize = extent[0]; // In the fowllowing case
            //      Axis has been fixed max 100
            //      Plus data are all 100 and axis extent are [100, 100].
            // Extend to the both side will cause expanded max is larger than fixed max.
            // So only expand to the smaller side.

            if (!opt.fixMax) {
              extent[1] += expandSize / 2;
              extent[0] -= expandSize / 2;
            } else {
              extent[0] -= expandSize / 2;
            }
          } else {
            extent[1] = 1;
          }
        }

        var span = extent[1] - extent[0]; // If there are no data and extent are [Infinity, -Infinity]

        if (!isFinite(span)) {
          extent[0] = 0;
          extent[1] = 1;
        }

        this.niceTicks(opt.splitNumber, opt.minInterval, opt.maxInterval); // let extent = this._extent;

        var interval = this._interval;

        if (!opt.fixMin) {
          extent[0] = roundNumber$1(Math.floor(extent[0] / interval) * interval);
        }

        if (!opt.fixMax) {
          extent[1] = roundNumber$1(Math.ceil(extent[1] / interval) * interval);
        }
      };

      IntervalScale.type = 'interval';
      return IntervalScale;
    }(Scale);

    Scale.registerClass(IntervalScale);

    var STACK_PREFIX = '__ec_stack_';
    var LARGE_BAR_MIN_WIDTH = 0.5;
    var LargeArr = typeof Float32Array !== 'undefined' ? Float32Array : Array;

    function getSeriesStackId(seriesModel) {
      return seriesModel.get('stack') || STACK_PREFIX + seriesModel.seriesIndex;
    }

    function getAxisKey(axis) {
      return axis.dim + axis.index;
    }
    /**
     * @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) && !isInLargeMode(seriesModel)) {
          seriesModels.push(seriesModel);
        }
      });
      return seriesModels;
    }
    /**
     * Map from (baseAxis.dim + '_' + baseAxis.index) to min gap of two adjacent
     * values.
     * This works for time axes, value axes, and log axes.
     * For a single time axis, return value is in the form like
     * {'x_0': [1000000]}.
     * The value of 1000000 is in milliseconds.
     */

    function getValueAxesMinGaps(barSeries) {
      /**
       * Map from axis.index to values.
       * For a single time axis, axisValues is in the form like
       * {'x_0': [1495555200000, 1495641600000, 1495728000000]}.
       * Items in axisValues[x], e.g. 1495555200000, are time values of all
       * series.
       */
      var axisValues = {};
      each(barSeries, function (seriesModel) {
        var cartesian = seriesModel.coordinateSystem;
        var baseAxis = cartesian.getBaseAxis();

        if (baseAxis.type !== 'time' && baseAxis.type !== 'value') {
          return;
        }

        var data = seriesModel.getData();
        var key = baseAxis.dim + '_' + baseAxis.index;
        var dim = data.mapDimension(baseAxis.dim);

        for (var i = 0, cnt = data.count(); i < cnt; ++i) {
          var value = data.get(dim, i);

          if (!axisValues[key]) {
            // No previous data for the axis
            axisValues[key] = [value];
          } else {
            // No value in previous series
            axisValues[key].push(value);
          } // Ignore duplicated time values in the same axis

        }
      });
      var axisMinGaps = {};

      for (var key in axisValues) {
        if (axisValues.hasOwnProperty(key)) {
          var valuesInAxis = axisValues[key];

          if (valuesInAxis) {
            // Sort axis values into ascending order to calculate gaps
            valuesInAxis.sort(function (a, b) {
              return a - b;
            });
            var min = null;

            for (var j = 1; j < valuesInAxis.length; ++j) {
              var delta = valuesInAxis[j] - valuesInAxis[j - 1];

              if (delta > 0) {
                // Ignore 0 delta because they are of the same axis value
                min = min === null ? delta : Math.min(min, delta);
              }
            } // Set to null if only have one data


            axisMinGaps[key] = min;
          }
        }
      }

      return axisMinGaps;
    }

    function makeColumnLayout(barSeries) {
      var axisMinGaps = getValueAxesMinGaps(barSeries);
      var seriesInfoList = [];
      each(barSeries, function (seriesModel) {
        var cartesian = seriesModel.coordinateSystem;
        var baseAxis = cartesian.getBaseAxis();
        var axisExtent = baseAxis.getExtent();
        var bandWidth;

        if (baseAxis.type === 'category') {
          bandWidth = baseAxis.getBandWidth();
        } else if (baseAxis.type === 'value' || baseAxis.type === 'time') {
          var key = baseAxis.dim + '_' + baseAxis.index;
          var minGap = axisMinGaps[key];
          var extentSpan = Math.abs(axisExtent[1] - axisExtent[0]);
          var scale = baseAxis.scale.getExtent();
          var scaleSpan = Math.abs(scale[1] - scale[0]);
          bandWidth = minGap ? extentSpan / scaleSpan * minGap : extentSpan; // When there is only one data value
        } else {
          var data = seriesModel.getData();
          bandWidth = Math.abs(axisExtent[1] - axisExtent[0]) / data.count();
        }

        var barWidth = parsePercent$1(seriesModel.get('barWidth'), bandWidth);
        var barMaxWidth = parsePercent$1(seriesModel.get('barMaxWidth'), bandWidth);
        var barMinWidth = parsePercent$1( // barMinWidth by default is 1 in cartesian. Because in value axis,
        // the auto-calculated bar width might be less than 1.
        seriesModel.get('barMinWidth') || 1, bandWidth);
        var barGap = seriesModel.get('barGap');
        var barCategoryGap = seriesModel.get('barCategoryGap');
        seriesInfoList.push({
          bandWidth: bandWidth,
          barWidth: barWidth,
          barMaxWidth: barMaxWidth,
          barMinWidth: barMinWidth,
          barGap: barGap,
          barCategoryGap: barCategoryGap,
          axisKey: getAxisKey(baseAxis),
          stackId: getSeriesStackId(seriesModel)
        });
      });
      return doCalBarWidthAndOffset(seriesInfoList);
    }

    function doCalBarWidthAndOffset(seriesInfoList) {
      // Columns info on each category axis. Key is cartesian name
      var columnsMap = {};
      each(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 wheter the
            // bar is able to be visible. So `minWidth` should not be restricted
            // by `maxWidth` or `remainedWidth` (which is from `bandWidth`). In
            // the extreme cases for `value` axis, bars are allowed to overlap
            // with each other if `minWidth` specified.


            if (minWidth && minWidth > finalWidth) {
              finalWidth = minWidth;
            }

            if (finalWidth !== autoWidth) {
              column.width = finalWidth;
              remainedWidth -= finalWidth + barGapPercent * finalWidth;
              autoWidthCount--;
            }
          } else {
            // `barMinWidth/barMaxWidth` has higher priority than `barWidth`, as
            // CSS does. Becuase barWidth can be a percent value, where
            // `barMaxWidth` can be used to restrict the final width.
            var finalWidth = column.width;

            if (maxWidth) {
              finalWidth = Math.min(finalWidth, maxWidth);
            } // `minWidth` has higher priority, as described above


            if (minWidth) {
              finalWidth = Math.max(finalWidth, minWidth);
            }

            column.width = finalWidth;
            remainedWidth -= finalWidth + barGapPercent * finalWidth;
            autoWidthCount--;
          }
        }); // Recalculate width again

        autoWidth = (remainedWidth - categoryGap) / (autoWidthCount + (autoWidthCount - 1) * barGapPercent);
        autoWidth = Math.max(autoWidth, 0);
        var widthSum = 0;
        var lastColumn;
        each(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);
      var lastStackCoords = {};
      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;
        var valueAxis = cartesian.getOtherAxis(baseAxis);
        var barMinHeight = seriesModel.get('barMinHeight') || 0;
        lastStackCoords[stackId] = lastStackCoords[stackId] || [];
        data.setLayout({
          bandWidth: columnLayoutInfo.bandWidth,
          offset: columnOffset,
          size: columnWidth
        });
        var valueDim = data.mapDimension(valueAxis.dim);
        var baseDim = data.mapDimension(baseAxis.dim);
        var stacked = isDimensionStacked(data, valueDim
        /*, baseDim*/
        );
        var isValueAxisH = valueAxis.isHorizontal();
        var valueAxisStart = getValueAxisStart(baseAxis, valueAxis);

        for (var idx = 0, len = data.count(); idx < len; idx++) {
          var value = data.get(valueDim, idx);
          var baseValue = data.get(baseDim, idx);
          var sign = value >= 0 ? 'p' : 'n';
          var baseCoord = valueAxisStart; // Because of the barMinHeight, we can not use the value in
          // stackResultDimension directly.

          if (stacked) {
            // Only ordinal axis can be stacked.
            if (!lastStackCoords[stackId][baseValue]) {
              lastStackCoords[stackId][baseValue] = {
                p: valueAxisStart,
                n: valueAxisStart // Negative stack

              };
            } // Should also consider #4243


            baseCoord = lastStackCoords[stackId][baseValue][sign];
          }

          var x = void 0;
          var y = void 0;
          var width = void 0;
          var height = void 0;

          if (isValueAxisH) {
            var coord = cartesian.dataToPoint([value, baseValue]);
            x = baseCoord;
            y = coord[1] + columnOffset;
            width = coord[0] - valueAxisStart;
            height = columnWidth;

            if (Math.abs(width) < barMinHeight) {
              width = (width < 0 ? -1 : 1) * barMinHeight;
            } // Ignore stack from NaN value


            if (!isNaN(width)) {
              stacked && (lastStackCoords[stackId][baseValue][sign] += width);
            }
          } else {
            var coord = cartesian.dataToPoint([baseValue, value]);
            x = coord[0] + columnOffset;
            y = baseCoord;
            width = columnWidth;
            height = coord[1] - valueAxisStart;

            if (Math.abs(height) < barMinHeight) {
              // Include zero to has a positive bar
              height = (height <= 0 ? -1 : 1) * barMinHeight;
            } // Ignore stack from NaN value


            if (!isNaN(height)) {
              stacked && (lastStackCoords[stackId][baseValue][sign] += height);
            }
          }

          data.setItemLayout(idx, {
            x: x,
            y: y,
            width: width,
            height: height
          });
        }
      });
    } // TODO: Do not support stack in large mode yet.

    var largeLayout = {
      seriesType: 'bar',
      plan: createRenderPlanner(),
      reset: function (seriesModel) {
        if (!isOnCartesian(seriesModel) || !isInLargeMode(seriesModel)) {
          return;
        }

        var data = seriesModel.getData();
        var cartesian = seriesModel.coordinateSystem;
        var coordLayout = cartesian.master.getRect();
        var baseAxis = cartesian.getBaseAxis();
        var valueAxis = cartesian.getOtherAxis(baseAxis);
        var valueDim = data.mapDimension(valueAxis.dim);
        var baseDim = data.mapDimension(baseAxis.dim);
        var valueAxisHorizontal = valueAxis.isHorizontal();
        var valueDimIdx = valueAxisHorizontal ? 0 : 1;
        var barWidth = retrieveColumnLayout(makeColumnLayout([seriesModel]), baseAxis, seriesModel).width;

        if (!(barWidth > LARGE_BAR_MIN_WIDTH)) {
          // jshint ignore:line
          barWidth = LARGE_BAR_MIN_WIDTH;
        }

        return {
          progress: function (params, data) {
            var count = params.count;
            var largePoints = new LargeArr(count * 2);
            var largeBackgroundPoints = new LargeArr(count * 2);
            var largeDataIndices = new LargeArr(count);
            var dataIndex;
            var coord = [];
            var valuePair = [];
            var pointsOffset = 0;
            var idxOffset = 0;

            while ((dataIndex = params.next()) != null) {
              valuePair[valueDimIdx] = data.get(valueDim, dataIndex);
              valuePair[1 - valueDimIdx] = data.get(baseDim, dataIndex);
              coord = cartesian.dataToPoint(valuePair, null, coord); // Data index might not be in order, depends on `progressiveChunkMode`.

              largeBackgroundPoints[pointsOffset] = valueAxisHorizontal ? coordLayout.x + coordLayout.width : coord[0];
              largePoints[pointsOffset++] = coord[0];
              largeBackgroundPoints[pointsOffset] = valueAxisHorizontal ? coord[1] : coordLayout.y + coordLayout.height;
              largePoints[pointsOffset++] = coord[1];
              largeDataIndices[idxOffset++] = dataIndex;
            }

            data.setLayout({
              largePoints: largePoints,
              largeDataIndices: largeDataIndices,
              largeBackgroundPoints: largeBackgroundPoints,
              barWidth: barWidth,
              valueAxisStart: getValueAxisStart(baseAxis, valueAxis),
              backgroundStart: valueAxisHorizontal ? coordLayout.x : coordLayout.y,
              valueAxisHorizontal: valueAxisHorizontal
            });
          }
        };
      }
    };

    function isOnCartesian(seriesModel) {
      return seriesModel.coordinateSystem && seriesModel.coordinateSystem.type === 'cartesian2d';
    }

    function isInLargeMode(seriesModel) {
      return seriesModel.pipelineContext && seriesModel.pipelineContext.large;
    } // See cases in `test/bar-start.html` and `#7412`, `#8747`.


    function getValueAxisStart(baseAxis, valueAxis, stacked) {
      return valueAxis.toGlobalCoord(valueAxis.dataToCoord(valueAxis.type === 'log' ? 1 : 0));
    }

    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
       * @param expandToNicedExtent Whether expand the ticks to niced extent.
       */


      TimeScale.prototype.getTicks = function (expandToNicedExtent) {
        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.niceExtent = function (opt) {
        var extent = this._extent; // If extent start and end are same, expand them

        if (extent[0] === extent[1]) {
          // Expand extent
          extent[0] -= ONE_DAY;
          extent[1] += ONE_DAY;
        } // If there are no data and extent are [Infinity, -Infinity]


        if (extent[1] === -Infinity && extent[0] === Infinity) {
          var d = new Date();
          extent[1] = +new Date(d.getFullYear(), d.getMonth(), d.getDate());
          extent[0] = extent[1] - ONE_DAY;
        }

        this.niceTicks(opt.splitNumber, opt.minInterval, opt.maxInterval);
      };

      TimeScale.prototype.niceTicks = 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 typeof val === 'number' ? val : +parseDate(val);
      };

      TimeScale.prototype.contain = function (val) {
        return contain$2(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 betwen two month.
      : 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 getPrecisionSafe$1 = getPrecisionSafe;
    var roundingErrorFix = round;
    var mathFloor$1 = 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 = this.base;
        start = mathLog(start) / mathLog(base);
        end = mathLog(end) / mathLog(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.niceTicks = function (approxTickNum) {
        approxTickNum = approxTickNum || 10;
        var extent = this._extent;
        var span = extent[1] - extent[0];

        if (span === Infinity || span <= 0) {
          return;
        }

        var interval = quantity(span);
        var err = approxTickNum / span * interval; // Filter ticks to get closer to the desired count.

        if (err <= 0.5) {
          interval *= 10;
        } // Interval should be integer


        while (!isNaN(interval) && Math.abs(interval) < 1 && Math.abs(interval) > 0) {
          interval *= 10;
        }

        var niceExtent = [round(mathCeil(extent[0] / interval) * interval), round(mathFloor$1(extent[1] / interval) * interval)];
        this._interval = interval;
        this._niceExtent = niceExtent;
      };

      LogScale.prototype.niceExtent = function (opt) {
        intervalScaleProto.niceExtent.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$2(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, getPrecisionSafe$1(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 ouside (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 = model.getNeedCrossZero && model.getNeedCrossZero();
        var modelMinRaw = this._modelMinRaw = model.get('min', true);

        if (isFunction(modelMinRaw)) {
          // This callback alway provide users the full data extent (before data 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 alway provide users the full data extent (before data 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);

        if (min > max) {
          min = NaN;
          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 begining
     * 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 initailized using series data extent via
    // `scale.setExtent` or `scale.unionExtentFromData`;


    function niceScaleExtent(scale, model) {
      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;
      scale.setExtent(extent[0], extent[1]);
      scale.niceExtent({
        splitNumber: splitNumber,
        fixMin: extentInfo.fixMin,
        fixMax: extentInfo.fixMax,
        minInterval: scaleType === 'interval' || scaleType === 'time' ? model.get('minInterval') : null,
        maxInterval: scaleType === 'interval' || scaleType === 'time' ? model.get('maxInterval') : null
      }); // If some one specified the min, max. And the default calculated interval
      // is not good enough. He can specify the interval. It is often appeared
      // in angle axis with angle 0 - 360. Interval calculated in interval scale is hard
      // to be 60.
      // FIXME

      var interval = model.get('interval');

      if (interval != null) {
        scale.setInterval && scale.setInterval(interval);
      }
    }
    /**
     * @param 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 (typeof labelFormatter === 'string') {
        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 (typeof labelFormatter === 'function') {
        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 reguardless 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.
    */
    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 muti dimension List structure from seriesModel.
     */

    function createList(seriesModel) {
      return createListFromArray(seriesModel.getSource(), 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 method `getCategories` and `getOrdinalMeta`
        // are required for `'category'` axis, and ecModel are required
        // for `'time'` axis. But occationally 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,
     *
     * Inlcude 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 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$4 = 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 repeatly.


      return listCacheSet(labelsCache, optionLabelInterval, {
        labels: labels,
        labelCategoryInterval: numericLabelInterval
      });
    }

    function makeCategoryTicks(axis, tickModel) {
      var ticksCache = getListCache(axis, 'ticks');
      var optionTickInterval = getOptionCategoryInterval(tickModel);
      var result = listCacheGet(ticksCache, optionTickInterval);

      if (result) {
        return result;
      }

      var ticks;
      var tickCategoryInterval; // Optimize for the case that large category data and no label displayed,
      // we should not return all ticks.

      if (!tickModel.get('show') || axis.scale.isBlank()) {
        ticks = [];
      }

      if (isFunction(optionTickInterval)) {
        ticks = makeLabelsByCustomizedCategoryInterval(axis, optionTickInterval, true);
      } // Always use label interval by default despite label show. Consider this
      // scenario, Use multiple grid with the xAxis sync, and only one xAxis shows
      // labels. `splitLine` and `axisTick` should be consistent in this case.
      else if (optionTickInterval === 'auto') {
          var labelsResult = makeCategoryLabelsActually(axis, axis.getLabelModel());
          tickCategoryInterval = labelsResult.labelCategoryInterval;
          ticks = map(labelsResult.labels, function (labelItem) {
            return labelItem.tickValue;
          });
        } else {
          tickCategoryInterval = optionTickInterval;
          ticks = makeLabelsByNumericCategoryInterval(axis, tickCategoryInterval, true);
        } // Cache to avoid calling interval function repeatly.


      return listCacheSet(ticksCache, optionTickInterval, {
        ticks: ticks,
        tickCategoryInterval: tickCategoryInterval
      });
    }

    function makeRealNumberLabels(axis) {
      var ticks = axis.scale.getTicks();
      var labelFormatter = makeLabelFormatter(axis);
      return {
        labels: map(ticks, function (tick, idx) {
          return {
            formattedLabel: labelFormatter(tick, idx),
            rawLabel: axis.scale.getLabel(tick),
            tickValue: tick.value
          };
        })
      };
    }

    function getListCache(axis, prop) {
      // Because key can be funciton, and cache size always be small, we use array cache.
      return inner$4(axis)[prop] || (inner$4(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$4(axis).autoInterval;
      return result != null ? result : inner$4(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$4(axis.model);
      var axisExtent = axis.getExtent();
      var lastAutoInterval = cache.lastAutoInterval;
      var lastTickCount = cache.lastTickCount; // Use cache to keep interval stable while moving zoom window,
      // otherwise the calculated interval might jitter when the zoom
      // window size is close to the interval-changing size.
      // For example, if all of the axis labels are `a, b, c, d, e, f, g`.
      // The jitter will cause that sometimes the displayed labels are
      // `a, d, g` (interval: 2) sometimes `a, c, e`(interval: 1).

      if (lastAutoInterval != null && lastTickCount != null && Math.abs(lastAutoInterval - interval) <= 1 && Math.abs(lastTickCount - tickCount) <= 1 // Always choose the bigger one, otherwise the critical
      // point is not the same when zooming in or zooming out.
      && lastAutoInterval > interval // If the axis change is caused by chart resize, the cache should not
      // be used. Otherwise some hiden labels might not be shown again.
      && cache.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 overrided 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 overrided, 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 unecessary 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) { regsiters.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;
    }

    function createElement(name) {
        return document.createElementNS('http://www.w3.org/2000/svg', name);
    }

    function diff(oldArr, newArr, equals) {
        if (!equals) {
            equals = function (a, b) {
                return a === b;
            };
        }
        oldArr = oldArr.slice();
        newArr = newArr.slice();
        var newLen = newArr.length;
        var oldLen = oldArr.length;
        var editLength = 1;
        var maxEditLength = newLen + oldLen;
        var bestPath = [{ newPos: -1, components: [] }];
        var oldPos = extractCommon(bestPath[0], newArr, oldArr, 0, equals);
        if (bestPath[0].newPos + 1 >= newLen && oldPos + 1 >= oldLen) {
            var indices = [];
            for (var i = 0; i < newArr.length; i++) {
                indices.push(i);
            }
            return [{
                    indices: indices,
                    count: newArr.length,
                    added: false,
                    removed: false
                }];
        }
        function execEditLength() {
            for (var diagonalPath = -1 * editLength; diagonalPath <= editLength; diagonalPath += 2) {
                var basePath;
                var addPath = bestPath[diagonalPath - 1];
                var removePath = bestPath[diagonalPath + 1];
                var oldPos = (removePath ? removePath.newPos : 0) - diagonalPath;
                if (addPath) {
                    bestPath[diagonalPath - 1] = undefined;
                }
                var canAdd = addPath && addPath.newPos + 1 < newLen;
                var canRemove = removePath && 0 <= oldPos && oldPos < oldLen;
                if (!canAdd && !canRemove) {
                    bestPath[diagonalPath] = undefined;
                    continue;
                }
                if (!canAdd || (canRemove && addPath.newPos < removePath.newPos)) {
                    basePath = clonePath(removePath);
                    pushComponent(basePath.components, false, true);
                }
                else {
                    basePath = addPath;
                    basePath.newPos++;
                    pushComponent(basePath.components, true, false);
                }
                oldPos = extractCommon(basePath, newArr, oldArr, diagonalPath, equals);
                if (basePath.newPos + 1 >= newLen && oldPos + 1 >= oldLen) {
                    return buildValues(basePath.components);
                }
                else {
                    bestPath[diagonalPath] = basePath;
                }
            }
            editLength++;
        }
        while (editLength <= maxEditLength) {
            var ret = execEditLength();
            if (ret) {
                return ret;
            }
        }
    }
    function extractCommon(basePath, newArr, oldArr, diagonalPath, equals) {
        var newLen = newArr.length;
        var oldLen = oldArr.length;
        var newPos = basePath.newPos;
        var oldPos = newPos - diagonalPath;
        var commonCount = 0;
        while (newPos + 1 < newLen && oldPos + 1 < oldLen && equals(newArr[newPos + 1], oldArr[oldPos + 1])) {
            newPos++;
            oldPos++;
            commonCount++;
        }
        if (commonCount) {
            basePath.components.push({
                count: commonCount,
                added: false,
                removed: false,
                indices: []
            });
        }
        basePath.newPos = newPos;
        return oldPos;
    }
    function pushComponent(components, added, removed) {
        var last = components[components.length - 1];
        if (last && last.added === added && last.removed === removed) {
            components[components.length - 1] = {
                count: last.count + 1,
                added: added,
                removed: removed,
                indices: []
            };
        }
        else {
            components.push({
                count: 1,
                added: added,
                removed: removed,
                indices: []
            });
        }
    }
    function buildValues(components) {
        var componentPos = 0;
        var componentLen = components.length;
        var newPos = 0;
        var oldPos = 0;
        for (; componentPos < componentLen; componentPos++) {
            var component = components[componentPos];
            if (!component.removed) {
                var indices = [];
                for (var i = newPos; i < newPos + component.count; i++) {
                    indices.push(i);
                }
                component.indices = indices;
                newPos += component.count;
                if (!component.added) {
                    oldPos += component.count;
                }
            }
            else {
                for (var i = oldPos; i < oldPos + component.count; i++) {
                    component.indices.push(i);
                }
                oldPos += component.count;
            }
        }
        return components;
    }
    function clonePath(path) {
        return { newPos: path.newPos, components: path.components.slice(0) };
    }
    function arrayDiff(oldArr, newArr, equal) {
        return diff(oldArr, newArr, equal);
    }

    var NONE = 'none';
    var mathRound = Math.round;
    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 EPSILON$4 = 1e-4;
    function round3(val) {
        return mathRound(val * 1e3) / 1e3;
    }
    function round4(val) {
        return mathRound(val * 1e4) / 1e4;
    }
    function isAroundZero$1(val) {
        return val < EPSILON$4 && val > -EPSILON$4;
    }
    function pathHasFill(style) {
        var fill = style.fill;
        return fill != null && fill !== NONE;
    }
    function pathHasStroke(style) {
        var stroke = style.stroke;
        return stroke != null && stroke !== NONE;
    }
    function setTransform(svgEl, m) {
        if (m) {
            attr(svgEl, 'transform', 'matrix('
                + round3(m[0]) + ','
                + round3(m[1]) + ','
                + round3(m[2]) + ','
                + round3(m[3]) + ','
                + round4(m[4]) + ','
                + round4(m[5])
                + ')');
        }
    }
    function attr(el, key, val) {
        if (!val || val.type !== 'linear' && val.type !== 'radial') {
            el.setAttribute(key, val);
        }
    }
    function attrXLink(el, key, val) {
        el.setAttributeNS('http://www.w3.org/1999/xlink', key, val);
    }
    function attrXML(el, key, val) {
        el.setAttributeNS('http://www.w3.org/XML/1998/namespace', key, val);
    }
    function bindStyle(svgEl, style, el) {
        var opacity = style.opacity == null ? 1 : style.opacity;
        if (el instanceof ZRImage) {
            svgEl.style.opacity = opacity + '';
            return;
        }
        if (pathHasFill(style)) {
            var fill = style.fill;
            fill = fill === 'transparent' ? NONE : fill;
            attr(svgEl, 'fill', fill);
            attr(svgEl, 'fill-opacity', (style.fillOpacity != null ? style.fillOpacity * opacity : opacity) + '');
        }
        else {
            attr(svgEl, 'fill', NONE);
        }
        if (pathHasStroke(style)) {
            var stroke = style.stroke;
            stroke = stroke === 'transparent' ? NONE : stroke;
            attr(svgEl, 'stroke', stroke);
            var strokeWidth = style.lineWidth;
            var strokeScale_1 = style.strokeNoScale
                ? el.getLineScale()
                : 1;
            attr(svgEl, 'stroke-width', (strokeScale_1 ? strokeWidth / strokeScale_1 : 0) + '');
            attr(svgEl, 'paint-order', style.strokeFirst ? 'stroke' : 'fill');
            attr(svgEl, 'stroke-opacity', (style.strokeOpacity != null ? style.strokeOpacity * opacity : opacity) + '');
            var lineDash = style.lineDash && strokeWidth > 0 && normalizeLineDash(style.lineDash, strokeWidth);
            if (lineDash) {
                var lineDashOffset = style.lineDashOffset;
                if (strokeScale_1 && strokeScale_1 !== 1) {
                    lineDash = map(lineDash, function (rawVal) {
                        return rawVal / strokeScale_1;
                    });
                    if (lineDashOffset) {
                        lineDashOffset /= strokeScale_1;
                        lineDashOffset = mathRound(lineDashOffset);
                    }
                }
                attr(svgEl, 'stroke-dasharray', lineDash.join(','));
                attr(svgEl, 'stroke-dashoffset', (lineDashOffset || 0) + '');
            }
            else {
                attr(svgEl, 'stroke-dasharray', '');
            }
            style.lineCap && attr(svgEl, 'stroke-linecap', style.lineCap);
            style.lineJoin && attr(svgEl, 'stroke-linejoin', style.lineJoin);
            style.miterLimit && attr(svgEl, 'stroke-miterlimit', style.miterLimit + '');
        }
        else {
            attr(svgEl, 'stroke', NONE);
        }
    }
    var SVGPathRebuilder = (function () {
        function SVGPathRebuilder() {
        }
        SVGPathRebuilder.prototype.reset = function () {
            this._d = [];
            this._str = '';
        };
        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 firstCmd = this._d.length === 0;
            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 = round4(cx + rx * mathCos$4(startAngle));
            var y0 = round4(cy + ry * mathSin$4(startAngle));
            if (isCircle) {
                if (clockwise) {
                    dTheta = PI2$7 - 1e-4;
                }
                else {
                    dTheta = -PI2$7 + 1e-4;
                }
                large = true;
                if (firstCmd) {
                    this._d.push('M', x0, y0);
                }
            }
            var x = round4(cx + rx * mathCos$4(startAngle + dTheta));
            var y = round4(cy + ry * mathSin$4(startAngle + dTheta));
            if (isNaN(x0) || isNaN(y0) || isNaN(rx) || isNaN(ry) || isNaN(psi) || isNaN(degree) || isNaN(x) || isNaN(y)) {
                return '';
            }
            this._d.push('A', round4(rx), round4(ry), mathRound(psi * degree), +large, +clockwise, x, y);
        };
        SVGPathRebuilder.prototype.rect = function (x, y, w, h) {
            this._add('M', x, y);
            this._add('L', x + w, y);
            this._add('L', x + w, y + h);
            this._add('L', x, y + h);
            this._add('L', x, y);
        };
        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) {
            this._d.push(cmd);
            for (var i = 1; i < arguments.length; i++) {
                var val = arguments[i];
                if (isNaN(val)) {
                    this._invalid = true;
                    return;
                }
                this._d.push(round4(val));
            }
        };
        SVGPathRebuilder.prototype.generateStr = function () {
            this._str = this._invalid ? '' : this._d.join(' ');
            this._d = [];
        };
        SVGPathRebuilder.prototype.getStr = function () {
            return this._str;
        };
        return SVGPathRebuilder;
    }());
    var svgPath = {
        brush: function (el) {
            var style = el.style;
            var svgEl = el.__svgEl;
            if (!svgEl) {
                svgEl = createElement('path');
                el.__svgEl = svgEl;
            }
            if (!el.path) {
                el.createPathProxy();
            }
            var path = el.path;
            if (el.shapeChanged()) {
                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 || el.style.strokePercent < 1) {
                if (!svgPathBuilder) {
                    svgPathBuilder = elExt.__svgPathBuilder = new SVGPathRebuilder();
                }
                svgPathBuilder.reset();
                path.rebuildPath(svgPathBuilder, el.style.strokePercent);
                svgPathBuilder.generateStr();
                elExt.__svgPathVersion = pathVersion;
            }
            attr(svgEl, 'd', svgPathBuilder.getStr());
            bindStyle(svgEl, style, el);
            setTransform(svgEl, el.transform);
        }
    };
    var svgImage = {
        brush: function (el) {
            var style = el.style;
            var image = style.image;
            if (image instanceof HTMLImageElement) {
                image = image.src;
            }
            else if (image instanceof HTMLCanvasElement) {
                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 svgEl = el.__svgEl;
            if (!svgEl) {
                svgEl = createElement('image');
                el.__svgEl = svgEl;
            }
            if (image !== el.__imageSrc) {
                attrXLink(svgEl, 'href', image);
                el.__imageSrc = image;
            }
            attr(svgEl, 'width', dw + '');
            attr(svgEl, 'height', dh + '');
            attr(svgEl, 'x', x + '');
            attr(svgEl, 'y', y + '');
            bindStyle(svgEl, style, el);
            setTransform(svgEl, el.transform);
        }
    };
    var TEXT_ALIGN_TO_ANCHOR = {
        left: 'start',
        right: 'end',
        center: 'middle',
        middle: 'middle'
    };
    function adjustTextY$1(y, lineHeight, textBaseline) {
        if (textBaseline === 'top') {
            y += lineHeight / 2;
        }
        else if (textBaseline === 'bottom') {
            y -= lineHeight / 2;
        }
        return y;
    }
    var svgText = {
        brush: function (el) {
            var style = el.style;
            var text = style.text;
            text != null && (text += '');
            if (!text || isNaN(style.x) || isNaN(style.y)) {
                return;
            }
            var textSvgEl = el.__svgEl;
            if (!textSvgEl) {
                textSvgEl = createElement('text');
                attrXML(textSvgEl, 'xml:space', 'preserve');
                el.__svgEl = textSvgEl;
            }
            var font = style.font || DEFAULT_FONT;
            var textSvgElStyle = textSvgEl.style;
            textSvgElStyle.font = font;
            textSvgEl.textContent = text;
            bindStyle(textSvgEl, style, el);
            setTransform(textSvgEl, el.transform);
            var x = style.x || 0;
            var y = adjustTextY$1(style.y || 0, getLineHeight(font), style.textBaseline);
            var textAlign = TEXT_ALIGN_TO_ANCHOR[style.textAlign]
                || style.textAlign;
            attr(textSvgEl, 'dominant-baseline', 'central');
            attr(textSvgEl, 'text-anchor', textAlign);
            attr(textSvgEl, 'x', x + '');
            attr(textSvgEl, 'y', y + '');
        }
    };

    var MARK_UNUSED = '0';
    var MARK_USED = '1';
    var Definable = (function () {
        function Definable(zrId, svgRoot, tagNames, markLabel, domName) {
            this.nextId = 0;
            this._domName = '_dom';
            this.createElement = createElement;
            this._zrId = zrId;
            this._svgRoot = svgRoot;
            this._tagNames = typeof tagNames === 'string' ? [tagNames] : tagNames;
            this._markLabel = markLabel;
            if (domName) {
                this._domName = domName;
            }
        }
        Definable.prototype.getDefs = function (isForceCreating) {
            var svgRoot = this._svgRoot;
            var defs = this._svgRoot.getElementsByTagName('defs');
            if (defs.length === 0) {
                if (isForceCreating) {
                    var defs_1 = svgRoot.insertBefore(this.createElement('defs'), svgRoot.firstChild);
                    if (!defs_1.contains) {
                        defs_1.contains = function (el) {
                            var children = defs_1.children;
                            if (!children) {
                                return false;
                            }
                            for (var i = children.length - 1; i >= 0; --i) {
                                if (children[i] === el) {
                                    return true;
                                }
                            }
                            return false;
                        };
                    }
                    return defs_1;
                }
                else {
                    return null;
                }
            }
            else {
                return defs[0];
            }
        };
        Definable.prototype.doUpdate = function (target, onUpdate) {
            if (!target) {
                return;
            }
            var defs = this.getDefs(false);
            if (target[this._domName] && defs.contains(target[this._domName])) {
                if (typeof onUpdate === 'function') {
                    onUpdate(target);
                }
            }
            else {
                var dom = this.add(target);
                if (dom) {
                    target[this._domName] = dom;
                }
            }
        };
        Definable.prototype.add = function (target) {
            return null;
        };
        Definable.prototype.addDom = function (dom) {
            var defs = this.getDefs(true);
            if (dom.parentNode !== defs) {
                defs.appendChild(dom);
            }
        };
        Definable.prototype.removeDom = function (target) {
            var defs = this.getDefs(false);
            if (defs && target[this._domName]) {
                defs.removeChild(target[this._domName]);
                target[this._domName] = null;
            }
        };
        Definable.prototype.getDoms = function () {
            var defs = this.getDefs(false);
            if (!defs) {
                return [];
            }
            var doms = [];
            each(this._tagNames, function (tagName) {
                var tags = defs.getElementsByTagName(tagName);
                for (var i = 0; i < tags.length; i++) {
                    doms.push(tags[i]);
                }
            });
            return doms;
        };
        Definable.prototype.markAllUnused = function () {
            var doms = this.getDoms();
            var that = this;
            each(doms, function (dom) {
                dom[that._markLabel] = MARK_UNUSED;
            });
        };
        Definable.prototype.markDomUsed = function (dom) {
            dom && (dom[this._markLabel] = MARK_USED);
        };
        Definable.prototype.markDomUnused = function (dom) {
            dom && (dom[this._markLabel] = MARK_UNUSED);
        };
        Definable.prototype.isDomUnused = function (dom) {
            return dom && dom[this._markLabel] !== MARK_USED;
        };
        Definable.prototype.removeUnused = function () {
            var _this = this;
            var defs = this.getDefs(false);
            if (!defs) {
                return;
            }
            var doms = this.getDoms();
            each(doms, function (dom) {
                if (_this.isDomUnused(dom)) {
                    defs.removeChild(dom);
                }
            });
        };
        Definable.prototype.getSvgProxy = function (displayable) {
            if (displayable instanceof Path) {
                return svgPath;
            }
            else if (displayable instanceof ZRImage) {
                return svgImage;
            }
            else if (displayable instanceof TSpan) {
                return svgText;
            }
            else {
                return svgPath;
            }
        };
        Definable.prototype.getSvgElement = function (displayable) {
            return displayable.__svgEl;
        };
        return Definable;
    }());

    function isLinearGradient(value) {
        return value.type === 'linear';
    }
    function isRadialGradient(value) {
        return value.type === 'radial';
    }
    function isGradient(value) {
        return value && (value.type === 'linear'
            || value.type === 'radial');
    }
    var GradientManager = (function (_super) {
        __extends(GradientManager, _super);
        function GradientManager(zrId, svgRoot) {
            return _super.call(this, zrId, svgRoot, ['linearGradient', 'radialGradient'], '__gradient_in_use__') || this;
        }
        GradientManager.prototype.addWithoutUpdate = function (svgElement, displayable) {
            if (displayable && displayable.style) {
                var that_1 = this;
                each(['fill', 'stroke'], function (fillOrStroke) {
                    var value = displayable.style[fillOrStroke];
                    if (isGradient(value)) {
                        var gradient = value;
                        var defs = that_1.getDefs(true);
                        var dom = void 0;
                        if (gradient.__dom) {
                            dom = gradient.__dom;
                            if (!defs.contains(gradient.__dom)) {
                                that_1.addDom(dom);
                            }
                        }
                        else {
                            dom = that_1.add(gradient);
                        }
                        that_1.markUsed(displayable);
                        var id = dom.getAttribute('id');
                        svgElement.setAttribute(fillOrStroke, 'url(#' + id + ')');
                    }
                });
            }
        };
        GradientManager.prototype.add = function (gradient) {
            var dom;
            if (isLinearGradient(gradient)) {
                dom = this.createElement('linearGradient');
            }
            else if (isRadialGradient(gradient)) {
                dom = this.createElement('radialGradient');
            }
            else {
                logError('Illegal gradient type.');
                return null;
            }
            gradient.id = gradient.id || this.nextId++;
            dom.setAttribute('id', 'zr' + this._zrId
                + '-gradient-' + gradient.id);
            this.updateDom(gradient, dom);
            this.addDom(dom);
            return dom;
        };
        GradientManager.prototype.update = function (gradient) {
            if (!isGradient(gradient)) {
                return;
            }
            var that = this;
            this.doUpdate(gradient, function () {
                var dom = gradient.__dom;
                if (!dom) {
                    return;
                }
                var tagName = dom.tagName;
                var type = gradient.type;
                if (type === 'linear' && tagName === 'linearGradient'
                    || type === 'radial' && tagName === 'radialGradient') {
                    that.updateDom(gradient, gradient.__dom);
                }
                else {
                    that.removeDom(gradient);
                    that.add(gradient);
                }
            });
        };
        GradientManager.prototype.updateDom = function (gradient, dom) {
            if (isLinearGradient(gradient)) {
                dom.setAttribute('x1', gradient.x + '');
                dom.setAttribute('y1', gradient.y + '');
                dom.setAttribute('x2', gradient.x2 + '');
                dom.setAttribute('y2', gradient.y2 + '');
            }
            else if (isRadialGradient(gradient)) {
                dom.setAttribute('cx', gradient.x + '');
                dom.setAttribute('cy', gradient.y + '');
                dom.setAttribute('r', gradient.r + '');
            }
            else {
                logError('Illegal gradient type.');
                return;
            }
            if (gradient.global) {
                dom.setAttribute('gradientUnits', 'userSpaceOnUse');
            }
            else {
                dom.setAttribute('gradientUnits', 'objectBoundingBox');
            }
            dom.innerHTML = '';
            var colors = gradient.colorStops;
            for (var i = 0, len = colors.length; i < len; ++i) {
                var stop_1 = this.createElement('stop');
                stop_1.setAttribute('offset', colors[i].offset * 100 + '%');
                var color$1 = colors[i].color;
                if (color$1.indexOf('rgba') > -1) {
                    var opacity = parse(color$1)[3];
                    var hex = toHex(color$1);
                    stop_1.setAttribute('stop-color', '#' + hex);
                    stop_1.setAttribute('stop-opacity', opacity + '');
                }
                else {
                    stop_1.setAttribute('stop-color', colors[i].color);
                }
                dom.appendChild(stop_1);
            }
            gradient.__dom = dom;
        };
        GradientManager.prototype.markUsed = function (displayable) {
            if (displayable.style) {
                var gradient = displayable.style.fill;
                if (gradient && gradient.__dom) {
                    _super.prototype.markDomUsed.call(this, gradient.__dom);
                }
                gradient = displayable.style.stroke;
                if (gradient && gradient.__dom) {
                    _super.prototype.markDomUsed.call(this, gradient.__dom);
                }
            }
        };
        return GradientManager;
    }(Definable));

    function isPattern(value) {
        return value && (!!value.image || !!value.svgElement);
    }
    var patternDomMap = new WeakMap();
    var PatternManager = (function (_super) {
        __extends(PatternManager, _super);
        function PatternManager(zrId, svgRoot) {
            return _super.call(this, zrId, svgRoot, ['pattern'], '__pattern_in_use__') || this;
        }
        PatternManager.prototype.addWithoutUpdate = function (svgElement, displayable) {
            if (displayable && displayable.style) {
                var that_1 = this;
                each(['fill', 'stroke'], function (fillOrStroke) {
                    var pattern = displayable.style[fillOrStroke];
                    if (isPattern(pattern)) {
                        var defs = that_1.getDefs(true);
                        var dom = patternDomMap.get(pattern);
                        if (dom) {
                            if (!defs.contains(dom)) {
                                that_1.addDom(dom);
                            }
                        }
                        else {
                            dom = that_1.add(pattern);
                        }
                        that_1.markUsed(displayable);
                        var id = dom.getAttribute('id');
                        svgElement.setAttribute(fillOrStroke, 'url(#' + id + ')');
                    }
                });
            }
        };
        PatternManager.prototype.add = function (pattern) {
            if (!isPattern(pattern)) {
                return;
            }
            var dom = this.createElement('pattern');
            pattern.id = pattern.id == null ? this.nextId++ : pattern.id;
            dom.setAttribute('id', 'zr' + this._zrId
                + '-pattern-' + pattern.id);
            dom.setAttribute('x', '0');
            dom.setAttribute('y', '0');
            dom.setAttribute('patternUnits', 'userSpaceOnUse');
            this.updateDom(pattern, dom);
            this.addDom(dom);
            return dom;
        };
        PatternManager.prototype.update = function (pattern) {
            if (!isPattern(pattern)) {
                return;
            }
            var that = this;
            this.doUpdate(pattern, function () {
                var dom = patternDomMap.get(pattern);
                that.updateDom(pattern, dom);
            });
        };
        PatternManager.prototype.updateDom = function (pattern, patternDom) {
            var svgElement = pattern.svgElement;
            if (svgElement instanceof SVGElement) {
                if (svgElement.parentNode !== patternDom) {
                    patternDom.innerHTML = '';
                    patternDom.appendChild(svgElement);
                    patternDom.setAttribute('width', pattern.svgWidth + '');
                    patternDom.setAttribute('height', pattern.svgHeight + '');
                }
            }
            else {
                var img = void 0;
                var prevImage = patternDom.getElementsByTagName('image');
                if (prevImage.length) {
                    if (pattern.image) {
                        img = prevImage[0];
                    }
                    else {
                        patternDom.removeChild(prevImage[0]);
                        return;
                    }
                }
                else if (pattern.image) {
                    img = this.createElement('image');
                }
                if (img) {
                    var imageSrc = void 0;
                    if (typeof pattern.image === 'string') {
                        imageSrc = pattern.image;
                    }
                    else if (pattern.image instanceof HTMLImageElement) {
                        imageSrc = pattern.image.src;
                    }
                    else if (pattern.image instanceof HTMLCanvasElement) {
                        imageSrc = pattern.image.toDataURL();
                    }
                    if (imageSrc) {
                        img.setAttribute('href', imageSrc);
                        img.setAttribute('x', '0');
                        img.setAttribute('y', '0');
                        var hostEl = {
                            dirty: function () { }
                        };
                        var createdImage = createOrUpdateImage(imageSrc, img, hostEl, function (img) {
                            patternDom.setAttribute('width', img.width + '');
                            patternDom.setAttribute('height', img.height + '');
                        });
                        if (createdImage && createdImage.width && createdImage.height) {
                            patternDom.setAttribute('width', createdImage.width + '');
                            patternDom.setAttribute('height', createdImage.height + '');
                        }
                        patternDom.appendChild(img);
                    }
                }
            }
            var x = pattern.x || 0;
            var y = pattern.y || 0;
            var rotation = (pattern.rotation || 0) / Math.PI * 180;
            var scaleX = pattern.scaleX || 1;
            var scaleY = pattern.scaleY || 1;
            var transform = "translate(" + x + ", " + y + ") rotate(" + rotation + ") scale(" + scaleX + ", " + scaleY + ")";
            patternDom.setAttribute('patternTransform', transform);
            patternDomMap.set(pattern, patternDom);
        };
        PatternManager.prototype.markUsed = function (displayable) {
            if (displayable.style) {
                if (isPattern(displayable.style.fill)) {
                    _super.prototype.markDomUsed.call(this, patternDomMap.get(displayable.style.fill));
                }
                if (isPattern(displayable.style.stroke)) {
                    _super.prototype.markDomUsed.call(this, patternDomMap.get(displayable.style.stroke));
                }
            }
        };
        return PatternManager;
    }(Definable));

    function generateClipPathsKey(clipPaths) {
        var key = [];
        if (clipPaths) {
            for (var i = 0; i < clipPaths.length; i++) {
                var clipPath = clipPaths[i];
                key.push(clipPath.id);
            }
        }
        return key.join(',');
    }
    function hasClipPath(displayable) {
        var clipPaths = displayable.__clipPaths;
        return clipPaths && clipPaths.length > 0;
    }
    var ClippathManager = (function (_super) {
        __extends(ClippathManager, _super);
        function ClippathManager(zrId, svgRoot) {
            var _this = _super.call(this, zrId, svgRoot, 'clipPath', '__clippath_in_use__') || this;
            _this._refGroups = {};
            _this._keyDuplicateCount = {};
            return _this;
        }
        ClippathManager.prototype.markAllUnused = function () {
            _super.prototype.markAllUnused.call(this);
            for (var key in this._refGroups) {
                this.markDomUnused(this._refGroups[key]);
            }
            this._keyDuplicateCount = {};
        };
        ClippathManager.prototype._getClipPathGroup = function (displayable, prevDisplayable) {
            if (!hasClipPath(displayable)) {
                return;
            }
            var clipPaths = displayable.__clipPaths;
            var keyDuplicateCount = this._keyDuplicateCount;
            var clipPathKey = generateClipPathsKey(clipPaths);
            if (isClipPathChanged(clipPaths, prevDisplayable && prevDisplayable.__clipPaths)) {
                keyDuplicateCount[clipPathKey] = keyDuplicateCount[clipPathKey] || 0;
                keyDuplicateCount[clipPathKey] && (clipPathKey += '-' + keyDuplicateCount[clipPathKey]);
                keyDuplicateCount[clipPathKey]++;
            }
            return this._refGroups[clipPathKey]
                || (this._refGroups[clipPathKey] = this.createElement('g'));
        };
        ClippathManager.prototype.update = function (displayable, prevDisplayable) {
            var clipGroup = this._getClipPathGroup(displayable, prevDisplayable);
            if (clipGroup) {
                this.markDomUsed(clipGroup);
                this.updateDom(clipGroup, displayable.__clipPaths);
            }
            return clipGroup;
        };
        ClippathManager.prototype.updateDom = function (parentEl, clipPaths) {
            if (clipPaths && clipPaths.length > 0) {
                var defs = this.getDefs(true);
                var clipPath = clipPaths[0];
                var clipPathEl = void 0;
                var id = void 0;
                if (clipPath._dom) {
                    id = clipPath._dom.getAttribute('id');
                    clipPathEl = clipPath._dom;
                    if (!defs.contains(clipPathEl)) {
                        defs.appendChild(clipPathEl);
                    }
                }
                else {
                    id = 'zr' + this._zrId + '-clip-' + this.nextId;
                    ++this.nextId;
                    clipPathEl = this.createElement('clipPath');
                    clipPathEl.setAttribute('id', id);
                    defs.appendChild(clipPathEl);
                    clipPath._dom = clipPathEl;
                }
                var svgProxy = this.getSvgProxy(clipPath);
                svgProxy.brush(clipPath);
                var pathEl = this.getSvgElement(clipPath);
                clipPathEl.innerHTML = '';
                clipPathEl.appendChild(pathEl);
                parentEl.setAttribute('clip-path', 'url(#' + id + ')');
                if (clipPaths.length > 1) {
                    this.updateDom(clipPathEl, clipPaths.slice(1));
                }
            }
            else {
                if (parentEl) {
                    parentEl.setAttribute('clip-path', 'none');
                }
            }
        };
        ClippathManager.prototype.markUsed = function (displayable) {
            var _this = this;
            if (displayable.__clipPaths) {
                each(displayable.__clipPaths, function (clipPath) {
                    if (clipPath._dom) {
                        _super.prototype.markDomUsed.call(_this, clipPath._dom);
                    }
                });
            }
        };
        ClippathManager.prototype.removeUnused = function () {
            _super.prototype.removeUnused.call(this);
            var newRefGroupsMap = {};
            for (var key in this._refGroups) {
                var group = this._refGroups[key];
                if (!this.isDomUnused(group)) {
                    newRefGroupsMap[key] = group;
                }
                else if (group.parentNode) {
                    group.parentNode.removeChild(group);
                }
            }
            this._refGroups = newRefGroupsMap;
        };
        return ClippathManager;
    }(Definable));

    var ShadowManager = (function (_super) {
        __extends(ShadowManager, _super);
        function ShadowManager(zrId, svgRoot) {
            var _this = _super.call(this, zrId, svgRoot, ['filter'], '__filter_in_use__', '_shadowDom') || this;
            _this._shadowDomMap = {};
            _this._shadowDomPool = [];
            return _this;
        }
        ShadowManager.prototype._getFromPool = function () {
            var shadowDom = this._shadowDomPool.pop();
            if (!shadowDom) {
                shadowDom = this.createElement('filter');
                shadowDom.setAttribute('id', 'zr' + this._zrId + '-shadow-' + this.nextId++);
                var domChild = this.createElement('feDropShadow');
                shadowDom.appendChild(domChild);
                this.addDom(shadowDom);
            }
            return shadowDom;
        };
        ShadowManager.prototype.update = function (svgElement, displayable) {
            var style = displayable.style;
            if (hasShadow(style)) {
                var shadowKey = getShadowKey(displayable);
                var shadowDom = displayable._shadowDom = this._shadowDomMap[shadowKey];
                if (!shadowDom) {
                    shadowDom = this._getFromPool();
                    this._shadowDomMap[shadowKey] = shadowDom;
                }
                this.updateDom(svgElement, displayable, shadowDom);
            }
            else {
                this.remove(svgElement, displayable);
            }
        };
        ShadowManager.prototype.remove = function (svgElement, displayable) {
            if (displayable._shadowDom != null) {
                displayable._shadowDom = null;
                svgElement.style.filter = '';
            }
        };
        ShadowManager.prototype.updateDom = function (svgElement, displayable, shadowDom) {
            var domChild = shadowDom.children[0];
            var style = displayable.style;
            var globalScale = displayable.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 = style.shadowBlur;
            var color = style.shadowColor;
            domChild.setAttribute('dx', offsetX / scaleX + '');
            domChild.setAttribute('dy', offsetY / scaleY + '');
            domChild.setAttribute('flood-color', color);
            var stdDx = blur / 2 / scaleX;
            var stdDy = blur / 2 / scaleY;
            var stdDeviation = stdDx + ' ' + stdDy;
            domChild.setAttribute('stdDeviation', stdDeviation);
            shadowDom.setAttribute('x', '-100%');
            shadowDom.setAttribute('y', '-100%');
            shadowDom.setAttribute('width', '300%');
            shadowDom.setAttribute('height', '300%');
            displayable._shadowDom = shadowDom;
            var id = shadowDom.getAttribute('id');
            svgElement.style.filter = 'url(#' + id + ')';
        };
        ShadowManager.prototype.removeUnused = function () {
            var defs = this.getDefs(false);
            if (!defs) {
                return;
            }
            var shadowDomsPool = this._shadowDomPool;
            for (var key in this._shadowDomMap) {
                var dom = this._shadowDomMap[key];
                shadowDomsPool.push(dom);
            }
            this._shadowDomMap = {};
        };
        return ShadowManager;
    }(Definable));
    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 parseInt10(val) {
        return parseInt(val, 10);
    }
    function getSvgProxy(el) {
        if (el instanceof Path) {
            return svgPath;
        }
        else if (el instanceof ZRImage) {
            return svgImage;
        }
        else if (el instanceof TSpan) {
            return svgText;
        }
        else {
            return svgPath;
        }
    }
    function checkParentAvailable(parent, child) {
        return child && parent && child.parentNode !== parent;
    }
    function insertAfter(parent, child, prevSibling) {
        if (checkParentAvailable(parent, child) && prevSibling) {
            var nextSibling = prevSibling.nextSibling;
            nextSibling ? parent.insertBefore(child, nextSibling)
                : parent.appendChild(child);
        }
    }
    function prepend(parent, child) {
        if (checkParentAvailable(parent, child)) {
            var firstChild = parent.firstChild;
            firstChild ? parent.insertBefore(child, firstChild)
                : parent.appendChild(child);
        }
    }
    function remove(parent, child) {
        if (child && parent && child.parentNode === parent) {
            parent.removeChild(child);
        }
    }
    function removeFromMyParent(child) {
        if (child && child.parentNode) {
            child.parentNode.removeChild(child);
        }
    }
    function getSvgElement(displayable) {
        return displayable.__svgEl;
    }
    var SVGPainter = (function () {
        function SVGPainter(root, storage, opts, zrId) {
            this.type = 'svg';
            this.refreshHover = createMethodNotSupport('refreshHover');
            this.pathToImage = createMethodNotSupport('pathToImage');
            this.configLayer = createMethodNotSupport('configLayer');
            this.root = root;
            this.storage = storage;
            this._opts = opts = extend({}, opts || {});
            var svgDom = createElement('svg');
            svgDom.setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns', 'http://www.w3.org/2000/svg');
            svgDom.setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xlink', 'http://www.w3.org/1999/xlink');
            svgDom.setAttribute('version', '1.1');
            svgDom.setAttribute('baseProfile', 'full');
            svgDom.style.cssText = 'user-select:none;position:absolute;left:0;top:0;';
            var bgRoot = createElement('g');
            svgDom.appendChild(bgRoot);
            var svgRoot = createElement('g');
            svgDom.appendChild(svgRoot);
            this._gradientManager = new GradientManager(zrId, svgRoot);
            this._patternManager = new PatternManager(zrId, svgRoot);
            this._clipPathManager = new ClippathManager(zrId, svgRoot);
            this._shadowManager = new ShadowManager(zrId, svgRoot);
            var viewport = document.createElement('div');
            viewport.style.cssText = 'overflow:hidden;position:relative';
            this._svgDom = svgDom;
            this._svgRoot = svgRoot;
            this._backgroundRoot = bgRoot;
            this._viewport = viewport;
            root.appendChild(viewport);
            viewport.appendChild(svgDom);
            this.resize(opts.width, opts.height);
            this._visibleList = [];
        }
        SVGPainter.prototype.getType = function () {
            return 'svg';
        };
        SVGPainter.prototype.getViewportRoot = function () {
            return this._viewport;
        };
        SVGPainter.prototype.getSvgDom = function () {
            return this._svgDom;
        };
        SVGPainter.prototype.getSvgRoot = function () {
            return this._svgRoot;
        };
        SVGPainter.prototype.getViewportRootOffset = function () {
            var viewportRoot = this.getViewportRoot();
            if (viewportRoot) {
                return {
                    offsetLeft: viewportRoot.offsetLeft || 0,
                    offsetTop: viewportRoot.offsetTop || 0
                };
            }
        };
        SVGPainter.prototype.refresh = function () {
            var list = this.storage.getDisplayList(true);
            this._paintList(list);
        };
        SVGPainter.prototype.setBackgroundColor = function (backgroundColor) {
            if (this._backgroundRoot && this._backgroundNode) {
                this._backgroundRoot.removeChild(this._backgroundNode);
            }
            var bgNode = createElement('rect');
            bgNode.setAttribute('width', this.getWidth());
            bgNode.setAttribute('height', this.getHeight());
            bgNode.setAttribute('x', 0);
            bgNode.setAttribute('y', 0);
            bgNode.setAttribute('id', 0);
            bgNode.style.fill = backgroundColor;
            this._backgroundRoot.appendChild(bgNode);
            this._backgroundNode = bgNode;
        };
        SVGPainter.prototype.createSVGElement = function (tag) {
            return createElement(tag);
        };
        SVGPainter.prototype.paintOne = function (el) {
            var svgProxy = getSvgProxy(el);
            svgProxy && svgProxy.brush(el);
            return getSvgElement(el);
        };
        SVGPainter.prototype._paintList = function (list) {
            var gradientManager = this._gradientManager;
            var patternManager = this._patternManager;
            var clipPathManager = this._clipPathManager;
            var shadowManager = this._shadowManager;
            gradientManager.markAllUnused();
            patternManager.markAllUnused();
            clipPathManager.markAllUnused();
            shadowManager.markAllUnused();
            var svgRoot = this._svgRoot;
            var visibleList = this._visibleList;
            var listLen = list.length;
            var newVisibleList = [];
            for (var i = 0; i < listLen; i++) {
                var displayable = list[i];
                var svgProxy = getSvgProxy(displayable);
                var svgElement = getSvgElement(displayable);
                if (!displayable.invisible) {
                    if (displayable.__dirty || !svgElement) {
                        svgProxy && svgProxy.brush(displayable);
                        svgElement = getSvgElement(displayable);
                        if (svgElement && displayable.style) {
                            gradientManager.update(displayable.style.fill);
                            gradientManager.update(displayable.style.stroke);
                            patternManager.update(displayable.style.fill);
                            patternManager.update(displayable.style.stroke);
                            shadowManager.update(svgElement, displayable);
                        }
                        displayable.__dirty = 0;
                    }
                    if (svgElement) {
                        newVisibleList.push(displayable);
                    }
                }
            }
            var diff = arrayDiff(visibleList, newVisibleList);
            var prevSvgElement;
            var topPrevSvgElement;
            for (var i = 0; i < diff.length; i++) {
                var item = diff[i];
                if (item.removed) {
                    for (var k = 0; k < item.count; k++) {
                        var displayable = visibleList[item.indices[k]];
                        var svgElement = getSvgElement(displayable);
                        hasClipPath(displayable) ? removeFromMyParent(svgElement)
                            : remove(svgRoot, svgElement);
                    }
                }
            }
            var prevDisplayable;
            var currentClipGroup;
            for (var i = 0; i < diff.length; i++) {
                var item = diff[i];
                if (item.removed) {
                    continue;
                }
                for (var k = 0; k < item.count; k++) {
                    var displayable = newVisibleList[item.indices[k]];
                    var clipGroup = clipPathManager.update(displayable, prevDisplayable);
                    if (clipGroup !== currentClipGroup) {
                        prevSvgElement = topPrevSvgElement;
                        if (clipGroup) {
                            prevSvgElement ? insertAfter(svgRoot, clipGroup, prevSvgElement)
                                : prepend(svgRoot, clipGroup);
                            topPrevSvgElement = clipGroup;
                            prevSvgElement = null;
                        }
                        currentClipGroup = clipGroup;
                    }
                    var svgElement = getSvgElement(displayable);
                    prevSvgElement
                        ? insertAfter(currentClipGroup || svgRoot, svgElement, prevSvgElement)
                        : prepend(currentClipGroup || svgRoot, svgElement);
                    prevSvgElement = svgElement || prevSvgElement;
                    if (!currentClipGroup) {
                        topPrevSvgElement = prevSvgElement;
                    }
                    gradientManager.markUsed(displayable);
                    gradientManager.addWithoutUpdate(svgElement, displayable);
                    patternManager.markUsed(displayable);
                    patternManager.addWithoutUpdate(svgElement, displayable);
                    clipPathManager.markUsed(displayable);
                    prevDisplayable = displayable;
                }
            }
            gradientManager.removeUnused();
            patternManager.removeUnused();
            clipPathManager.removeUnused();
            shadowManager.removeUnused();
            this._visibleList = newVisibleList;
        };
        SVGPainter.prototype.resize = function (width, height) {
            var viewport = this._viewport;
            viewport.style.display = 'none';
            var opts = this._opts;
            width != null && (opts.width = width);
            height != null && (opts.height = height);
            width = this._getSize(0);
            height = this._getSize(1);
            viewport.style.display = '';
            if (this._width !== width || this._height !== height) {
                this._width = width;
                this._height = height;
                var viewportStyle = viewport.style;
                viewportStyle.width = width + 'px';
                viewportStyle.height = height + 'px';
                var svgRoot = this._svgDom;
                svgRoot.setAttribute('width', width + '');
                svgRoot.setAttribute('height', height + '');
            }
            if (this._backgroundNode) {
                this._backgroundNode.setAttribute('width', width);
                this._backgroundNode.setAttribute('height', height);
            }
        };
        SVGPainter.prototype.getWidth = function () {
            return this._width;
        };
        SVGPainter.prototype.getHeight = function () {
            return this._height;
        };
        SVGPainter.prototype._getSize = function (whIdx) {
            var opts = this._opts;
            var wh = ['width', 'height'][whIdx];
            var cwh = ['clientWidth', 'clientHeight'][whIdx];
            var plt = ['paddingLeft', 'paddingTop'][whIdx];
            var prb = ['paddingRight', 'paddingBottom'][whIdx];
            if (opts[wh] != null && opts[wh] !== 'auto') {
                return parseFloat(opts[wh]);
            }
            var root = this.root;
            var stl = document.defaultView.getComputedStyle(root);
            return ((root[cwh] || parseInt10(stl[wh]) || parseInt10(root.style[wh]))
                - (parseInt10(stl[plt]) || 0)
                - (parseInt10(stl[prb]) || 0)) | 0;
        };
        SVGPainter.prototype.dispose = function () {
            this.root.innerHTML = '';
            this._svgRoot
                = this._backgroundRoot
                    = this._svgDom
                        = this._backgroundNode
                            = this._viewport
                                = this.storage
                                    = null;
        };
        SVGPainter.prototype.clear = function () {
            var viewportNode = this._viewport;
            if (viewportNode && viewportNode.parentNode) {
                viewportNode.parentNode.removeChild(viewportNode);
            }
        };
        SVGPainter.prototype.toDataURL = function () {
            this.refresh();
            var svgDom = this._svgDom;
            var outerHTML = svgDom.outerHTML
                || (svgDom.parentNode && svgDom.parentNode).innerHTML;
            var html = encodeURIComponent(outerHTML.replace(/></g, '>\n\r<'));
            return 'data:image/svg+xml;charset=UTF-8,' + html;
        };
        return SVGPainter;
    }());
    function createMethodNotSupport(method) {
        return function () {
            logError('In SVG mode painter not support method "' + method + '"');
        };
    }

    function install(registers) {
      registers.registerPainter('svg', SVGPainter);
    }

    function returnFalse() {
        return false;
    }
    function createDom(id, painter, dpr) {
        var newDom = 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) {
                dom.onselectstart = returnFalse;
                domStyle.webkitUserSelect = 'none';
                domStyle.userSelect = 'none';
                domStyle.webkitTapHighlightColor = 'rgba(0,0,0,0)';
                domStyle['-webkit-touch-callout'] = 'none';
                domStyle.padding = '0';
                domStyle.margin = '0';
                domStyle.borderWidth = '0';
            }
            _this.domBack = null;
            _this.ctxBack = null;
            _this.painter = painter;
            _this.config = null;
            _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 & Element.REDARAW_BIT) || !shouldPaint)
                        ? el.getPrevPaintRect()
                        : null;
                    if (prevRect) {
                        addRectToMergePool(prevRect);
                    }
                    var curRect = shouldPaint && ((el.__dirty & Element.REDARAW_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)) {
                        clearColorGradientOrPattern = clearColor.__canvasGradient
                            || getCanvasGradient(ctx, clearColor, {
                                x: 0,
                                y: 0,
                                width: width,
                                height: height
                            });
                        clearColor.__canvasGradient = clearColorGradientOrPattern;
                    }
                    else if (isPatternObject(clearColor)) {
                        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 parseInt10$1(val) {
        return parseInt(val, 10);
    }
    function isLayerValid(layer) {
        if (!layer) {
            return false;
        }
        if (layer.__builtin__) {
            return true;
        }
        if (typeof (layer.resize) !== 'function'
            || typeof (layer.refresh) !== 'function') {
            return false;
        }
        return true;
    }
    function 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) {
                rootStyle.webkitTapHighlightColor = 'transparent';
                rootStyle.webkitUserSelect = 'none';
                rootStyle.userSelect = 'none';
                rootStyle['-webkit-touch-callout'] = 'none';
                root.innerHTML = '';
            }
            this.storage = storage;
            var zlevelList = this._zlevelList;
            this._prevDisplayList = [];
            var layers = this._layers;
            if (!singleCanvas) {
                this._width = this._getSize(0);
                this._height = this._getSize(1);
                var domRoot = this._domRoot = createRoot(this._width, this._height);
                root.appendChild(domRoot);
            }
            else {
                var 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);
                ctx.save();
                var start = paintAll ? layer.__startIndex : layer.__drawIndex;
                var useTimer = !paintAll && layer.incremental && Date.now;
                var startTime = useTimer && Date.now();
                var clearColor = layer.zlevel === this_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]) {
                logError('ZLevel ' + zlevel + ' has been used already');
                return;
            }
            if (!isLayerValid(layer)) {
                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 & Element.REDARAW_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;
                width != null && (opts.width = width);
                height != null && (opts.height = height);
                width = this._getSize(0);
                height = this._getSize(1);
                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;
        };
        CanvasPainter.prototype._getSize = function (whIdx) {
            var opts = this._opts;
            var wh = ['width', 'height'][whIdx];
            var cwh = ['clientWidth', 'clientHeight'][whIdx];
            var plt = ['paddingLeft', 'paddingTop'][whIdx];
            var prb = ['paddingRight', 'paddingBottom'][whIdx];
            if (opts[wh] != null && opts[wh] !== 'auto') {
                return parseFloat(opts[wh]);
            }
            var root = this.root;
            var stl = document.defaultView.getComputedStyle(root);
            return ((root[cwh] || parseInt10$1(stl[wh]) || parseInt10$1(root.style[wh]))
                - (parseInt10$1(stl[plt]) || 0)
                - (parseInt10$1(stl[prb]) || 0)) | 0;
        };
        CanvasPainter.prototype.pathToImage = function (path, dpr) {
            dpr = dpr || this.dpr;
            var canvas = document.createElement('canvas');
            var ctx = canvas.getContext('2d');
            var rect = path.getBoundingRect();
            var style = path.style;
            var shadowBlurSize = style.shadowBlur * dpr;
            var shadowOffsetX = style.shadowOffsetX * dpr;
            var shadowOffsetY = style.shadowOffsetY * dpr;
            var lineWidth = path.hasStroke() ? style.lineWidth : 0;
            var leftMargin = Math.max(lineWidth / 2, -shadowOffsetX + shadowBlurSize);
            var rightMargin = Math.max(lineWidth / 2, shadowOffsetX + shadowBlurSize);
            var topMargin = Math.max(lineWidth / 2, -shadowOffsetY + shadowBlurSize);
            var bottomMargin = Math.max(lineWidth / 2, shadowOffsetY + shadowBlurSize);
            var width = rect.width + leftMargin + rightMargin;
            var height = rect.height + topMargin + bottomMargin;
            canvas.width = width * dpr;
            canvas.height = height * dpr;
            ctx.scale(dpr, dpr);
            ctx.clearRect(0, 0, width, height);
            ctx.dpr = dpr;
            var pathTransform = {
                x: path.x,
                y: path.y,
                scaleX: path.scaleX,
                scaleY: path.scaleY,
                rotation: path.rotation,
                originX: path.originX,
                originY: path.originY
            };
            path.x = leftMargin - rect.x;
            path.y = topMargin - rect.y;
            path.rotation = 0;
            path.scaleX = 1;
            path.scaleY = 1;
            path.updateTransform();
            if (path) {
                brush(ctx, path, {
                    inHover: false,
                    viewWidth: this._width,
                    viewHeight: this._height
                }, true);
            }
            var imgShape = new ZRImage({
                style: {
                    x: 0,
                    y: 0,
                    image: canvas
                }
            });
            extend(path, pathTransform);
            return imgShape;
        };
        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 createListFromArray(this.getSource(), 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 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, opt.symbolKeepAspect);
        group.add(symbol);
        symbol.setStyle(opt.itemStyle);

        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,
          lineStyle: {
            width: 'bolder'
          }
        },
        // 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
      };
      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 dimInfo = data.getDimensionInfo(labelDims[i]);

        if (dimInfo) {
          vals.push(interpolatedValue[dimInfo.index]);
        }
      }

      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);
      };
      /**
       * 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) {
        var symbolPath = this.childAt(0);
        symbolPath.draggable = draggable;
        symbolPath.cursor = 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);
        }

        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 remove animation manually if don't call initProps or updateProps.
          this.childAt(0).stopAnimation('remove');
        }

        this._seriesModel = seriesModel;
      };

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

        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');
          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 = data.getItemVisual(idx, 'symbolOffset') || 0;

        if (symbolOffset) {
          if (!isArray(symbolOffset)) {
            symbolOffset = [symbolOffset, symbolOffset];
          }

          symbolPath.x = parsePercent$1(symbolOffset[0], symbolSize[0]);
          symbolPath.y = parsePercent$1(retrieve2(symbolOffset[1], symbolOffset[0]) || 0, symbolSize[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;

        if (hoverScale) {
          var scaleRatio = Math.max(1.1, 3 / this._sizeY);
          emphasisState.scaleX = this._sizeX * scaleRatio;
          emphasisState.scaleY = this._sizeY * scaleRatio;
        }

        this.setSymbolScale(1);
        enableHoverEmphasis(this, focus, blurScope);
      };

      Symbol.prototype.setSymbolScale = function (scale) {
        this.scaleX = this.scaleY = scale;
      };

      Symbol.prototype.fadeOut = function (cb, opt) {
        var symbolPath = this.childAt(0);
        var seriesModel = this._seriesModel;
        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) {
        var symbolSize = data.getItemVisual(idx, 'symbolSize');
        return isArray(symbolSize) ? symbolSize.slice() : [+symbolSize, +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'),
        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) {
        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;
          }

          if (!symbolEl) {
            symbolEl = new SymbolCtor(data, newIdx);
            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);
          });
        }).execute();
        this._getSymbolPoint = getSymbolPoint;
        this._data = data;
      };

      SymbolDraw.prototype.isPersistent = function () {
        return true;
      };

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

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

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

    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);
      var 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];
            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);
                cpx1 = x - lenPrevSeg * smooth;
                cpy1 = y;
                nextCpx0 = x + lenPrevSeg * smooth;
                nextCpy0 = y;
              } else if (smoothMonotone === 'y') {
                lenPrevSeg = Math.abs(dy0);
                lenNextSeg = Math.abs(dy1);
                cpx1 = x;
                cpy1 = y - lenPrevSeg * smooth;
                nextCpx0 = x;
                nextCpy0 = y + lenPrevSeg * 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 = typeof during === 'function' ? 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 typeof smooth === 'number' ? 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) {
      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 = [];

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

    function getVisualGradient(data, coordSys) {
      var visualMetaList = data.getVisual('visualMeta');

      if (!visualMetaList || !visualMetaList.length || !data.count()) {
        // When data.count() is 0, gradient range can not be calculated.
        return;
      }

      if (coordSys.type !== 'cartesian2d') {
        if ("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 dimIndex = visualMetaList[i].dimension;
        var dimName = data.dimensions[dimIndex];
        var dimInfo = data.getDimensionInfo(dimName);
        coordDim = dimInfo && dimInfo.coordDim; // Can only be x or y

        if (coordDim === 'x' || coordDim === 'y') {
          visualMeta = visualMetaList[i];
          break;
        }
      }

      if (!visualMeta) {
        if ("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); // dataToCoor mapping may not be linear, but must be monotonic.

      var colorStops = map(visualMeta.stops, function (stop) {
        return {
          offset: 0,
          coord: axis.toGlobalCoord(axis.dataToCoord(stop.value)),
          color: stop.color
        };
      });
      var stopLen = colorStops.length;
      var outerColors = visualMeta.outerColors.slice();

      if (stopLen && colorStops[0].coord > colorStops[stopLen - 1].coord) {
        colorStops.reverse();
        outerColors.reverse();
      }

      var tinyExtent = 10; // Arbitrary value: 10px

      var minCoord = colorStops[0].coord - tinyExtent;
      var maxCoord = colorStops[stopLen - 1].coord + tinyExtent;
      var coordSpan = maxCoord - minCoord;

      if (coordSpan < 1e-3) {
        return 'transparent';
      }

      each(colorStops, function (stop) {
        stop.offset = (stop.coord - minCoord) / coordSpan;
      });
      colorStops.push({
        offset: stopLen ? colorStops[stopLen - 1].offset : 0.5,
        color: outerColors[1] || 'transparent'
      });
      colorStops.unshift({
        offset: stopLen ? colorStops[0].offset : 0.5,
        color: outerColors[0] || 'transparent'
      }); // zrUtil.each(colorStops, function (colorStop) {
      //     // Make sure each offset has rounded px to avoid not sharp edge
      //     colorStop.offset = (Math.round(colorStop.offset * (end - start) + start) - start) / (end - start);
      // });

      var gradient = new LinearGradient(0, 0, 0, 0, colorStops, true);
      gradient[coordDim] = minCoord;
      gradient[coordDim + '2'] = maxCoord;
      return gradient;
    }

    function getIsIgnoreFunc(seriesModel, data, coordSys) {
      var showAllSymbol = seriesModel.get('showAllSymbol');
      var isAuto = showAllSymbol === 'auto';

      if (showAllSymbol && !isAuto) {
        return;
      }

      var categoryAxis = coordSys.getAxesByScale('ordinal')[0];

      if (!categoryAxis) {
        return;
      } // Note that category label interval strategy might bring some weird effect
      // in some scenario: users may wonder why some of the symbols are not
      // displayed. So we show all symbols as possible as we can.


      if (isAuto // Simplify the logic, do not determine label overlap here.
      && canShowAllSymbolForCategory(categoryAxis, data)) {
        return;
      } // Otherwise follow the label interval strategy on category axis.


      var categoryDataDim = data.mapDimension(categoryAxis.dim);
      var labelMap = {};
      each(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 mose cases, line is monotonous on category axis, and the label size
      // is close with each other. So we check the symbol size and some of the
      // label size alone with the category axis to estimate whether all symbol
      // can be shown without overlap.
      var axisExtent = categoryAxis.getExtent();
      var availSize = Math.abs(axisExtent[1] - axisExtent[0]) / categoryAxis.scale.count();
      isNaN(availSize) && (availSize = 0); // 0/0 is NaN.
      // Sampling some points, max 5.

      var dataLen = data.count();
      var step = Math.max(1, Math.round(dataLen / 5));

      for (var dataIndex = 0; dataIndex < dataLen; dataIndex += step) {
        if (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 createLineClipPath(lineView, coordSys, hasAnimation, seriesModel) {
      if (isCoordinateSystemType(coordSys, 'cartesian2d')) {
        var endLabelModel_1 = seriesModel.getModel('endLabel');
        var showEndLabel = endLabelModel_1.get('show');
        var valueAnimation_1 = endLabelModel_1.get('valueAnimation');
        var data_1 = seriesModel.getData();
        var labelAnimationRecord_1 = {
          lastFrameIndex: 0
        };
        var during = showEndLabel ? function (percent, clipRect) {
          lineView._endLabelOnDuring(percent, clipRect, data_1, labelAnimationRecord_1, valueAnimation_1, endLabelModel_1, coordSys);
        } : null;
        var isHorizontal = coordSys.getBaseAxis().isHorizontal();
        var clipPath = createGridClipPath(coordSys, hasAnimation, seriesModel, function () {
          var endLabel = lineView._endLabel;

          if (endLabel && hasAnimation) {
            if (labelAnimationRecord_1.originalX != null) {
              endLabel.attr({
                x: labelAnimationRecord_1.originalX,
                y: labelAnimationRecord_1.originalY
              });
            }
          }
        }, during); // Expand clip shape to avoid clipping when line value exceeds axis

        if (!seriesModel.get('clip', true)) {
          var rectShape = clipPath.shape;
          var expandSize = Math.max(rectShape.width, rectShape.height);

          if (isHorizontal) {
            rectShape.y -= expandSize;
            rectShape.height += expandSize * 2;
          } else {
            rectShape.x -= expandSize;
            rectShape.width += expandSize * 2;
          }
        } // Set to the final frame. To make sure label layout is right.


        if (during) {
          during(1, clipPath);
        }

        return clipPath;
      } else {
        if ("development" !== 'production') {
          if (seriesModel.get(['endLabel', 'show'])) {
            console.warn('endLabel is not supported for lines in polar systems.');
          }
        }

        return createPolarClipPath(coordSys, hasAnimation, seriesModel);
      }
    }

    function getEndLabelStateSpecified(endLabelModel, coordSys) {
      var baseAxis = coordSys.getBaseAxis();
      var isHorizontal = baseAxis.isHorizontal();
      var isBaseInversed = baseAxis.inverse;
      var align = isHorizontal ? isBaseInversed ? 'right' : 'left' : 'center';
      var verticalAlign = isHorizontal ? 'middle' : isBaseInversed ? 'top' : 'bottom';
      return {
        normal: {
          align: endLabelModel.get('align') || align,
          verticalAlign: endLabelModel.get('verticalAlign') || verticalAlign
        }
      };
    }

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

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

      LineView.prototype.init = function () {
        var lineGroup = new Group();
        var symbolDraw = new SymbolDraw();
        this.group.add(symbolDraw.group);
        this._symbolDraw = symbolDraw;
        this._lineGroup = lineGroup;
      };

      LineView.prototype.render = function (seriesModel, ecModel, api) {
        var _this = this;

        var coordSys = seriesModel.coordinateSystem;
        var group = this.group;
        var data = seriesModel.getData();
        var lineStyleModel = seriesModel.getModel('lineStyle');
        var areaStyleModel = seriesModel.getModel('areaStyle');
        var points = data.getLayout('points') || [];
        var isCoordSysPolar = coordSys.type === 'polar';
        var prevCoordSys = this._coordSys;
        var symbolDraw = this._symbolDraw;
        var polyline = this._polyline;
        var polygon = this._polygon;
        var lineGroup = this._lineGroup;
        var hasAnimation = seriesModel.get('animation');
        var isAreaChart = !areaStyleModel.isEmpty();
        var valueOrigin = areaStyleModel.get('origin');
        var dataCoordInfo = prepareDataCoordInfo(coordSys, data, valueOrigin);
        var stackedOnPoints = isAreaChart && getStackedOnPoints(coordSys, data, dataCoordInfo);
        var showSymbol = seriesModel.get('showSymbol');
        var 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) || 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);

            if (stackedOnPoints) {
              stackedOnPoints = turnPointsIntoStep(stackedOnPoints, coordSys, step);
            }
          }

          polyline = this._newPolyline(points);

          if (isAreaChart) {
            polygon = this._newPolygon(points, stackedOnPoints);
          } // 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


          lineGroup.setClipPath(createLineClipPath(this, coordSys, false, seriesModel)); // Always update, or it is wrong in the case turning on legend
          // because points are not changed

          showSymbol && symbolDraw.updateData(data, {
            isIgnore: isIgnoreFunc,
            clipShape: clipShapeForSymbol,
            disableAnimation: true,
            getSymbolPoint: function (idx) {
              return [points[idx * 2], points[idx * 2 + 1]];
            }
          }); // In the case data zoom triggerred refreshing frequently
          // Data may not change if line has a category axis. So it should animate nothing

          if (!isPointsSame(this._stackedOnPoints, stackedOnPoints) || !isPointsSame(this._points, points)) {
            if (hasAnimation) {
              this._doUpdateAnimation(data, stackedOnPoints, coordSys, api, step, valueOrigin);
            } else {
              // Not do it in update with animation
              if (step) {
                // TODO If stacked series is not step
                points = turnPointsIntoStep(points, coordSys, step);

                if (stackedOnPoints) {
                  stackedOnPoints = turnPointsIntoStep(stackedOnPoints, coordSys, step);
                }
              }

              polyline.setShape({
                points: points
              });
              polygon && polygon.setShape({
                points: points,
                stackedOnPoints: stackedOnPoints
              });
            }
          }
        }

        var focus = seriesModel.get(['emphasis', 'focus']);
        var blurScope = seriesModel.get(['emphasis', 'blurScope']);
        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;
        enableHoverEmphasis(polyline, focus, blurScope);
        var smooth = getSmooth(seriesModel.get('smooth'));
        var smoothMonotone = seriesModel.get('smoothMonotone');
        var connectNulls = seriesModel.get('connectNulls');
        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;
          enableHoverEmphasis(polygon, focus, blurScope);
        }

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

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

      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: should't draw symbol outside clipShapeForSymbol


            if (this._clipShapeForSymbol && !this._clipShapeForSymbol.contain(x, y)) {
              return;
            }

            symbol = new Symbol(data, dataIndex);
            symbol.x = x;
            symbol.y = y;
            symbol.setZ(seriesModel.get('zlevel'), seriesModel.get('z')); // ensure label text of the temporal symbol is on the top of line and area polygon

            var symbolLabel = symbol.getSymbolPath().getTextContent();
            symbolLabel && (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 (typeof seriesDuration === 'function') {
          seriesDuration = seriesDuration(null);
        }

        var seriesDalay = seriesModel.get('animationDelay') || 0;
        var seriesDalayValue = typeof seriesDalay === 'function' ? seriesDalay(null) : seriesDalay;
        data.eachItemGraphicEl(function (symbol, idx) {
          var el = symbol;

          if (el) {
            var point = [symbol.x, symbol.y];
            var start = void 0;
            var end = void 0;
            var current = void 0;

            if (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 = typeof seriesDalay === 'function' ? seriesDalay(idx) : seriesDuration * ratio + seriesDalayValue;
            var symbolPath = el.getSymbolPath();
            var text = symbolPath.getTextContent();
            el.attr({
              scaleX: 0,
              scaleY: 0
            });
            el.animateTo({
              scaleX: 1,
              scaleY: 1
            }, {
              duration: 200,
              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 (endLabelModel.get('show')) {
          var data_2 = seriesModel.getData();
          var polyline = this._polyline;
          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(data_2.getLayout('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) {
        var polyline = this._polyline;
        var polygon = this._polygon;
        var seriesModel = data.hostModel;
        var diff = lineAnimationDiff(this._data, data, this._stackedOnPoints, stackedOnPoints, this._coordSys, coordSys, this._valueOrigin, valueOrigin);
        var current = diff.current;
        var stackedOnCurrent = diff.stackedOnCurrent;
        var next = diff.next;
        var stackedOnNext = diff.stackedOnNext;

        if (step) {
          // TODO If stacked series is not step
          current = turnPointsIntoStep(diff.current, coordSys, step);
          stackedOnCurrent = turnPointsIntoStep(diff.stackedOnCurrent, coordSys, step);
          next = turnPointsIntoStep(diff.next, coordSys, step);
          stackedOnNext = turnPointsIntoStep(diff.stackedOnNext, coordSys, step);
        } // Don't apply animation if diff is large.
        // For better result and avoid memory explosion problems like
        // https://github.com/apache/incubator-echarts/issues/12229


        if (getBoundingDiff(current, next) > 3000 || polygon && getBoundingDiff(stackedOnCurrent, stackedOnNext) > 3000) {
          polyline.setShape({
            points: next
          });

          if (polygon) {
            polygon.setShape({
              points: next,
              stackedOnPoints: stackedOnNext
            });
          }

          return;
        }

        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[1]*/
          )) {
            dims[0] = stackResultDim;
          }

          if (isDimensionStacked(data, dims[1]
          /*, dims[0]*/
          )) {
            dims[1] = stackResultDim;
          }

          var dimInfo0 = data.getDimensionInfo(dims[0]);
          var dimInfo1 = data.getDimensionInfo(dims[1]);
          var dimIdx0 = dimInfo0 && dimInfo0.index;
          var dimIdx1 = dimInfo1 && dimInfo1.index;
          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 = data.getByDimIdx(dimIdx0, i); // NOTE: Make sure the second parameter is null to use default strategy.

                  point = coordSys.dataToPoint(x, null, tmpOut);
                } else {
                  tmpIn[0] = data.getByDimIdx(dimIdx0, i);
                  tmpIn[1] = data.getByDimIdx(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);
            }
          };
        }
      };
    }

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

              var sampler = void 0;

              if (typeof sampling === 'string') {
                sampler = samplers[sampling];
              } else if (typeof sampling === 'function') {
                sampler = sampling;
              }

              if (sampler) {
                // Only support sample the first dim mapped from value axis.
                seriesModel.setData(data.downSample(data.mapDimension(valueAxis.dim), 1 / rate, sampler, indexSampler));
              }
            }
          }
        }
      };
    }

    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 createListFromArray(this.getSource(), this, {
          useEncodeDefaulter: true
        });
      };

      BaseBarSeriesModel.prototype.getMarkerPosition = function (value) {
        var coordSys = this.coordinateSystem;

        if (coordSys) {
          // PENDING if clamp ?
          var pt = coordSys.dataToPoint(coordSys.clampData(value));
          var data = this.getData();
          var offset = data.getLayout('offset');
          var size = data.getLayout('size');
          var offsetIndex = coordSys.getBaseAxis().isHorizontal() ? 0 : 1;
          pt[offsetIndex] += offset + size / 2;
          return pt;
        }

        return [NaN, NaN];
      };

      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 createListFromArray(this.getSource(), 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 x = shape.cx;
        var y = shape.cy;
        var r0 = Math.max(shape.r0 || 0, 0);
        var r = Math.max(shape.r, 0);
        var dr = (r - r0) * 0.5;
        var rCenter = r0 + dr;
        var startAngle = shape.startAngle;
        var endAngle = shape.endAngle;
        var clockwise = shape.clockwise;
        var unitStartX = Math.cos(startAngle);
        var unitStartY = Math.sin(startAngle);
        var unitEndX = Math.cos(endAngle);
        var unitEndY = Math.sin(endAngle);
        var lessThanCircle = clockwise ? endAngle - startAngle < Math.PI * 2 : startAngle - endAngle < Math.PI * 2;

        if (lessThanCircle) {
          ctx.moveTo(unitStartX * r0 + x, unitStartY * r0 + y);
          ctx.arc(unitStartX * rCenter + x, unitStartY * rCenter + y, dr, -Math.PI + startAngle, startAngle, !clockwise);
        }

        ctx.arc(x, y, r, startAngle, endAngle, !clockwise);
        ctx.moveTo(unitEndX * r + x, unitEndY * r + y);
        ctx.arc(unitEndX * rCenter + x, unitEndY * rCenter + y, dr, endAngle - Math.PI * 2, endAngle - Math.PI, !clockwise);

        if (r0 !== 0) {
          ctx.arc(x, y, r0, endAngle, startAngle, clockwise);
          ctx.moveTo(unitStartX * r0 + x, unitEndY * r0 + y);
        }

        ctx.closePath();
      };

      return SausagePath;
    }(Path);

    var _eventPos = [0, 0];
    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') {
          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) {
        // Do not support progressive in normal mode.
        this._incrementalRenderLarge(params, seriesModel);
      };

      BarView.prototype._updateDrawMode = function (seriesModel) {
        var isLargeDraw = seriesModel.pipelineContext.large;

        if (this._isLargeDraw == null || isLargeDraw !== this._isLargeDraw) {
          this._isLargeDraw = isLargeDraw;

          this._clear();
        }
      };

      BarView.prototype._renderNormal = function (seriesModel, ecModel, api, payload) {
        var group = this.group;
        var data = seriesModel.getData();
        var oldData = this._data;
        var coord = seriesModel.coordinateSystem;
        var baseAxis = coord.getBaseAxis();
        var isHorizontalOrRadial;

        if (coord.type === 'cartesian2d') {
          isHorizontalOrRadial = baseAxis.isHorizontal();
        } else if (coord.type === 'polar') {
          isHorizontalOrRadial = baseAxis.dim === 'angle';
        }

        var animationModel = seriesModel.isAnimationEnabled() ? seriesModel : null;
        var realtimeSortCfg = shouldRealtimeSort(seriesModel, coord);

        if (realtimeSortCfg) {
          this._enableRealtimeSort(realtimeSortCfg, data, api);
        }

        var needsClip = seriesModel.get('clip', true) || realtimeSortCfg;
        var coordSysClipArea = getClipArea(coord, data); // If there is clipPath created in large mode. Remove it.

        group.removeClipPath(); // We don't use clipPath in normal mode because we needs a perfect animation
        // And don't want the label are clipped.

        var roundCap = seriesModel.get('roundCap', true);
        var drawBackground = seriesModel.get('showBackground', true);
        var backgroundModel = seriesModel.getModel('backgroundStyle');
        var barBorderRadius = backgroundModel.get('borderRadius') || 0;
        var bgEls = [];
        var oldBgEls = this._backgroundEls;
        var isInitSort = payload && payload.isInitSort;
        var isChangeOrder = payload && payload.type === 'changeAxisOrder';

        function createBackground(dataIndex) {
          var bgLayout = getLayout[coord.type](data, dataIndex);
          var bgEl = createBackgroundEl(coord, isHorizontalOrRadial, bgLayout);
          bgEl.useStyle(backgroundModel.getItemStyle()); // Only cartesian2d support borderRadius.

          if (coord.type === 'cartesian2d') {
            bgEl.setShape('r', barBorderRadius);
          }

          bgEls[dataIndex] = bgEl;
          return bgEl;
        }
        data.diff(oldData).add(function (dataIndex) {
          var itemModel = data.getItemModel(dataIndex);
          var layout = getLayout[coord.type](data, dataIndex, itemModel);

          if (drawBackground) {
            createBackground(dataIndex);
          } // If dataZoom in filteMode: 'empty', the baseValue can be set as NaN in "axisProxy".


          if (!data.hasValue(dataIndex)) {
            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);
          updateStyle(el, data, dataIndex, itemModel, layout, seriesModel, isHorizontalOrRadial, coord.type === 'polar');

          if (isInitSort) {
            el.attr({
              shape: layout
            });
          } else if (realtimeSortCfg) {
            updateRealtimeAnimation(realtimeSortCfg, animationModel, el, layout, dataIndex, isHorizontalOrRadial, false, false);
          } else {
            initProps(el, {
              shape: layout
            }, seriesModel, dataIndex);
          }

          data.setItemGraphicEl(dataIndex, el);
          group.add(el);
          el.ignore = isClipped;
        }).update(function (newIndex, oldIndex) {
          var itemModel = data.getItemModel(newIndex);
          var layout = getLayout[coord.type](data, newIndex, itemModel);

          if (drawBackground) {
            var bgEl = void 0;

            if (oldBgEls.length === 0) {
              bgEl = createBackground(oldIndex);
            } else {
              bgEl = oldBgEls[oldIndex];
              bgEl.useStyle(backgroundModel.getItemStyle()); // Only cartesian2d support borderRadius.

              if (coord.type === 'cartesian2d') {
                bgEl.setShape('r', barBorderRadius);
              }

              bgEls[newIndex] = bgEl;
            }

            var bgLayout = getLayout[coord.type](data, newIndex);
            var shape = createBackgroundShape(isHorizontalOrRadial, bgLayout, coord);
            updateProps(bgEl, {
              shape: shape
            }, animationModel, newIndex);
          }

          var el = oldData.getItemGraphicEl(oldIndex);

          if (!data.hasValue(newIndex)) {
            group.remove(el);
            el = null;
            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);
          } // Not change anything if only order changed.
          // Especially not change label.


          if (!isChangeOrder) {
            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, true);
      };

      BarView.prototype._updateLargeClip = function (seriesModel) {
        // Use clipPath in large mode.
        var clipPath = seriesModel.get('clip', true) ? createClipPath(seriesModel.coordinateSystem, false, seriesModel) : null;

        if (clipPath) {
          this.group.setClipPath(clipPath);
        } else {
          this.group.removeClipPath();
        }
      };

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

            if (el) {
              var shape = el.shape; // If data is NaN, shape.xxx may be NaN, so use || 0 here in case

              return (baseAxis.isHorizontal() // 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(shape.height) : Math.abs(shape.width)) || 0;
            } else {
              return 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,
          animation: {
            // Update the axis label from the natural initial layout to
            // sorted layout should has no animation.
            duration: 0
          }
        });
      };

      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.
        // Beause if data changed and the bar show again, its transition animaiton
        // 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) {
        // Keep the same logic with bar in catesion: use end value to control
        // direction. Notice that if clockwise is true (by default), the sector
        // will always draw clockwisely, no matter whether endAngle is greater
        // or less than startAngle.
        var clockwise = layout.startAngle < layout.endAngle;
        var ShapeClass = !isRadial && roundCap ? SausagePath : Sector;
        var sector = new ShapeClass({
          shape: defaults({
            clockwise: clockwise
          }, layout),
          z2: 1
        });
        sector.name = 'item'; // Animation

        if (animationModel) {
          var sectorShape = sector.shape;
          var animateProperty = isRadial ? 'r' : 'endAngle';
          var animateTarget = {};
          sectorShape[animateProperty] = isRadial ? 0 : layout.startAngle;
          animateTarget[animateProperty] = layout[animateProperty];
          (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);
    }

    var getLayout = {
      // itemModel is only used to get borderWidth, which is not needed
      // when calculating bar background layout.
      cartesian2d: function (data, dataIndex, itemModel) {
        var layout = data.getItemLayout(dataIndex);
        var fixedLineWidth = itemModel ? getLineWidth(itemModel, layout) : 0; // fix layout with lineWidth

        var signX = layout.width > 0 ? 1 : -1;
        var signY = layout.height > 0 ? 1 : -1;
        return {
          x: layout.x + signX * fixedLineWidth / 2,
          y: layout.y + signY * fixedLineWidth / 2,
          width: layout.width - signX * fixedLineWidth,
          height: layout.height - signY * fixedLineWidth
        };
      },
      polar: function (data, dataIndex, itemModel) {
        var layout = data.getItemLayout(dataIndex);
        return {
          cx: layout.cx,
          cy: layout.cy,
          r0: layout.r0,
          r: layout.r,
          startAngle: layout.startAngle,
          endAngle: layout.endAngle
        };
      }
    };

    function isZeroOnPolar(layout) {
      return layout.startAngle != null && layout.endAngle != null && layout.startAngle === layout.endAngle;
    }

    function updateStyle(el, data, dataIndex, itemModel, layout, seriesModel, isHorizontal, isPolar) {
      var style = data.getItemVisual(dataIndex, 'style');

      if (!isPolar) {
        el.setShape('r', itemModel.get(['itemStyle', 'borderRadius']) || 0);
      }

      el.useStyle(style);
      var cursorStyle = itemModel.getShallow('cursor');
      cursorStyle && el.attr('cursor', cursorStyle);

      if (!isPolar) {
        var labelPositionOutside = isHorizontal ? layout.height > 0 ? 'bottom' : 'top' : layout.width > 0 ? 'left' : 'right';
        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();
        setLabelValueAnimation(label, labelStatesModels, seriesModel.getRawValue(dataIndex), function (value) {
          return getDefaultInterpolatedLabel(data, value);
        });
      }

      var emphasisModel = itemModel.getModel(['emphasis']);
      enableHoverEmphasis(el, emphasisModel.get('focus'), emphasisModel.get('blurScope'));
      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 startPoint = this.__startPoint;
        var baseDimIdx = this.__baseDimIdx;

        for (var i = 0; i < points.length; i += 2) {
          startPoint[baseDimIdx] = points[i + baseDimIdx];
          ctx.moveTo(startPoint[0], startPoint[1]);
          ctx.lineTo(points[i], points[i + 1]);
        }
      };

      return LargePath;
    }(Path);

    function createLarge(seriesModel, group, incremental) {
      // TODO support polar
      var data = seriesModel.getData();
      var startPoint = [];
      var baseDimIdx = data.getLayout('valueAxisHorizontal') ? 1 : 0;
      startPoint[1 - baseDimIdx] = data.getLayout('valueAxisStart');
      var largeDataIndices = data.getLayout('largeDataIndices');
      var barWidth = data.getLayout('barWidth');
      var backgroundModel = seriesModel.getModel('backgroundStyle');
      var drawBackground = seriesModel.get('showBackground', true);

      if (drawBackground) {
        var points = data.getLayout('largeBackgroundPoints');
        var backgroundStartPoint = [];
        backgroundStartPoint[1 - baseDimIdx] = data.getLayout('backgroundStart');
        var bgEl = new LargePath({
          shape: {
            points: points
          },
          incremental: !!incremental,
          silent: true,
          z2: 0
        });
        bgEl.__startPoint = backgroundStartPoint;
        bgEl.__baseDimIdx = baseDimIdx;
        bgEl.__largeDataIndices = largeDataIndices;
        bgEl.__barWidth = barWidth;
        setLargeBackgroundStyle(bgEl, backgroundModel, data);
        group.add(bgEl);
      }

      var el = new LargePath({
        shape: {
          points: data.getLayout('largePoints')
        },
        incremental: !!incremental
      });
      el.__startPoint = startPoint;
      el.__baseDimIdx = baseDimIdx;
      el.__largeDataIndices = largeDataIndices;
      el.__barWidth = barWidth;
      group.add(el);
      setLargeStyle(el, seriesModel, data); // 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);
      }
    } // 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 barWidthHalf = Math.abs(largePath.__barWidth / 2);
      var startValueVal = largePath.__startPoint[valueDimIdx];
      _eventPos[0] = x;
      _eventPos[1] = y;
      var pointerBaseVal = _eventPos[baseDimIdx];
      var pointerValueVal = _eventPos[1 - baseDimIdx];
      var baseLowerBound = pointerBaseVal - barWidthHalf;
      var baseUpperBound = pointerBaseVal + barWidthHalf;

      for (var i = 0, len = points.length / 2; i < len; i++) {
        var ii = i * 2;
        var barBaseVal = points[ii + baseDimIdx];
        var barValueVal = points[ii + valueDimIdx];

        if (barBaseVal >= baseLowerBound && barBaseVal <= baseUpperBound && (startValueVal <= barValueVal ? pointerValueVal >= startValueVal && pointerValueVal <= barValueVal : pointerValueVal >= barValueVal && pointerValueVal <= startValueVal)) {
          return largeDataIndices[i];
        }
      }

      return -1;
    }

    function setLargeStyle(el, seriesModel, data) {
      var globalStyle = data.getVisual('style');
      el.useStyle(extend({}, globalStyle)); // Use stroke instead of fill.

      el.style.fill = null;
      el.style.stroke = globalStyle.fill;
      el.style.lineWidth = data.getLayout('barWidth');
    }

    function setLargeBackgroundStyle(el, backgroundModel, data) {
      var borderColor = backgroundModel.get('borderColor') || backgroundModel.get('color');
      var itemStyle = backgroundModel.getItemStyle();
      el.useStyle(itemStyle);
      el.style.fill = null;
      el.style.stroke = borderColor;
      el.style.lineWidth = data.getLayout('barWidth');
    }

    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')); // Use higher prority to avoid to be blocked by other overall layout, which do not
      // only exist in this module, but probably also exist in other modules, like `barPolar`.

      registers.registerLayout(registers.PRIORITY.VISUAL.PROGRESSIVE_LAYOUT, largeLayout); // 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 pieLayout(seriesType, ecModel, api) {
      ecModel.eachSeriesByType(seriesType, function (seriesModel) {
        var data = seriesModel.getData();
        var valueDim = data.mapDimension('value');
        var viewRect = getViewRect(seriesModel, api);
        var center = seriesModel.get('center');
        var radius = seriesModel.get('radius');

        if (!isArray(radius)) {
          radius = [0, radius];
        }

        if (!isArray(center)) {
          center = [center, center];
        }

        var width = parsePercent$1(viewRect.width, api.getWidth());
        var height = parsePercent$1(viewRect.height, api.getHeight());
        var size = Math.min(width, height);
        var cx = parsePercent$1(center[0], width) + viewRect.x;
        var cy = parsePercent$1(center[1], height) + viewRect.y;
        var r0 = parsePercent$1(radius[0], size / 2);
        var r = parsePercent$1(radius[1], size / 2);
        var startAngle = -seriesModel.get('startAngle') * RADIAN;
        var minAngle = seriesModel.get('minAngle') * RADIAN;
        var validDataCount = 0;
        data.each(valueDim, function (value) {
          !isNaN(value) && validDataCount++;
        });
        var sum = data.getSum(valueDim); // Sum may be 0

        var unitRadian = Math.PI / (sum || validDataCount) * 2;
        var clockwise = seriesModel.get('clockwise');
        var roseType = seriesModel.get('roseType');
        var stillShowZeroSum = seriesModel.get('stillShowZeroSum'); // [0...max]

        var extent = data.getDataExtent(valueDim);
        extent[0] = 0; // In the case some sector angle is smaller than minAngle

        var restAngle = PI2$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);
          item.label.x = cx + (dx + item.len2) * dir;
        }
      } // 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]);
        }
      }

      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];
        var label = layout.label;

        if (isPositionCenter(layout)) {
          continue;
        }

        var linePoints = layout.linePoints;

        if (linePoints) {
          var isAlignToEdge = layout.labelAlignTo === 'edge';
          var realTextWidth = layout.rect.width;
          var targetTextWidth = void 0;

          if (isAlignToEdge) {
            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 (label.x < cx) {
              targetTextWidth = label.x - viewLeft - layout.bleedMargin;
            } else {
              targetTextWidth = viewLeft + viewWidth - label.x - layout.bleedMargin;
            }
          }

          if (targetTextWidth < layout.rect.width) {
            // TODOTODO
            // layout.text = textContain.truncateText(layout.text, targetTextWidth, layout.font);
            layout.label.style.width = targetTextWidth;

            if (layout.labelAlignTo === 'edge') {
              realTextWidth = targetTextWidth; // realTextWidth = textContain.getWidth(layout.text, layout.font);
            }
          }

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

    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;
          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 labelRotate;
        var rotate = labelModel.get('rotate');

        if (typeof rotate === 'number') {
          labelRotate = rotate * (Math.PI / 180);
        } else {
          labelRotate = rotate ? nx < 0 ? -midAngle + Math.PI : -midAngle : 0;
        }

        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
          });
        } else {
          label.setStyle({
            align: textAlign
          });
          var selectState = label.states.select;

          if (selectState) {
            selectState.x += label.x;
            selectState.y += label.y;
          }
        }

        sector.setTextConfig({
          inside: isLabelInside
        });
      });

      if (!hasLabelRotate && seriesModel.get('avoidLabelOverlap')) {
        avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight, viewLeft, viewTop);
      }

      for (var i = 0; i < labelLayoutList.length; i++) {
        var layout = labelLayoutList[i];
        var label = layout.label;
        var labelLine = layout.labelLine;
        var notShowLabel = isNaN(label.x) || isNaN(label.y);

        if (label) {
          label.setStyle({
            align: layout.textAlign
          });

          if (notShowLabel) {
            each(label.states, setNotShow);
            label.ignore = true;
          }

          var selectState = label.states.select;

          if (selectState) {
            selectState.x += label.x;
            selectState.y += label.y;
          }
        }

        if (labelLine) {
          var linePoints = layout.linePoints;

          if (notShowLabel || !linePoints) {
            each(labelLine.states, setNotShow);
            labelLine.ignore = true;
          } else {
            limitTurnAngle(linePoints, layout.minTurnAngle);
            limitSurfaceAngle(linePoints, layout.surfaceNormal, layout.maxSurfaceAngle);
            labelLine.setShape({
              points: linePoints
            }); // Set the anchor to the midpoint of sector

            label.__hostTarget.textGuideLineConfig = {
              anchor: new Point(linePoints[0][0], linePoints[0][1])
            };
          }
        }
      }
    }

    function getSectorCornerRadius(model, shape) {
      var cornerRadius = model.get('borderRadius');

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

      if (!isArray(cornerRadius)) {
        cornerRadius = [cornerRadius, cornerRadius];
      }

      return {
        innerCornerRadius: parsePercent(cornerRadius[0], shape.r0),
        cornerRadius: parsePercent(cornerRadius[1], shape.r)
      };
    }

    /**
     * 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);
        var sectorShape = extend(getSectorCornerRadius(itemModel.getModel('itemStyle'), layout) || {}, 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 (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 {
          // 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 = __assign({
          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
        });
        enableHoverEmphasis(this, emphasisModel.get('focus'), emphasisModel.get('blurScope'));
      };

      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.init = function () {
        var sectorGroup = new Group();
        this._sectorGroup = sectorGroup;
      };

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

        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 createListSimply(seriesModel, opt, nameList) {
      opt = isArray(opt) && {
        coordDimensions: opt
      } || extend({}, opt);
      var source = seriesModel.getSource();
      var dimensionsInfo = createDimensions(source, opt);
      var list = new List(dimensionsInfo, seriesModel);
      list.initData(source, nameList);
      return list;
    }

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


    /**
     * 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 PieSeriesModel =
    /** @class */
    function (_super) {
      __extends(PieSeriesModel, _super);

      function PieSeriesModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.useColorPaletteOnData = true;
        return _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 createListSimply(this, {
          coordDimensions: ['value'],
          encodeDefaulter: curry(makeSeriesEncodeForNameBased, this)
        });
      };
      /**
       * @overwrite
       */


      PieSeriesModel.prototype.getDataParams = function (dataIndex) {
        var data = this.getData();

        var params = _super.prototype.getDataParams.call(this, dataIndex); // FIXME toFixed?


        var valueList = [];
        data.each(data.mapDimension('value'), function (value) {
          valueList.push(value);
        });
        params.percent = getPercentWithPrecision(valueList, dataIndex, data.hostModel.get('percentPrecision'));
        params.$vars.push('percent');
        return params;
      };

      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,
        // 默认全局居中
        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
        },
        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 install$4(registers) {
      registers.registerChartView(PieView);
      registers.registerSeriesModel(PieSeriesModel);
      createLegacyDataSelectAction('pie', registers.registerAction);
      registers.registerLayout(curry(pieLayout, 'pie'));
      registers.registerProcessor(dataFilter('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 createListFromArray(this.getSource(), 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.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'
          }
        } // 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) {
        return _super.call(this, opts) || this;
      }

      LargeSymbolPath.prototype.getDefaultShape = function () {
        return new LargeSymbolPathShape();
      };

      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; // Do draw in afterBrush.

        if (canBoost) {
          this._ctx = ctx;
          return;
        }

        this._ctx = null;

        for (var i = 0; i < points.length;) {
          var x = points[i++];
          var y = points[i++];

          if (isNaN(x) || isNaN(y)) {
            continue;
          }

          if (this.softClipShape && !this.softClipShape.contain(x, y)) {
            continue;
          }

          symbolProxyShape.x = x - size[0] / 2;
          symbolProxyShape.y = y - size[1] / 2;
          symbolProxyShape.width = size[0];
          symbolProxyShape.height = size[1];
          symbolProxy.buildPath(path, symbolProxyShape, true);
        }
      };

      LargeSymbolPath.prototype.afterBrush = function () {
        var shape = this.shape;
        var points = shape.points;
        var size = shape.size;
        var ctx = this._ctx;

        if (!ctx) {
          return;
        } // PENDING If style or other canvas status changed?


        for (var i = 0; i < points.length;) {
          var x = points[i++];
          var y = points[i++];

          if (isNaN(x) || isNaN(y)) {
            continue;
          }

          if (this.softClipShape && !this.softClipShape.contain(x, y)) {
            continue;
          } // fillRect is faster than building a rect path and draw.
          // And it support light globalCompositeOperation.


          ctx.fillRect(x - size[0] / 2, y - size[1] / 2, size[0], size[1]);
        }
      };

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

      return LargeSymbolPath;
    }(Path);

    var LargeSymbolDraw =
    /** @class */
    function () {
      function LargeSymbolDraw() {
        this.group = new Group();
      }

      LargeSymbolDraw.prototype.isPersistent = function () {
        return !this._incremental;
      };
      /**
       * Update symbols draw by new data
       */

      LargeSymbolDraw.prototype.updateData = function (data, opt) {
        this.group.removeAll();
        var symbolEl = new LargeSymbolPath({
          rectHover: true,
          cursor: 'default'
        });
        symbolEl.setShape({
          points: data.getLayout('points')
        });

        this._setCommon(symbolEl, data, false, opt);

        this.group.add(symbolEl);
        this._incremental = null;
      };

      LargeSymbolDraw.prototype.updateLayout = function (data) {
        if (this._incremental) {
          return;
        }

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

      LargeSymbolDraw.prototype.incrementalPrepareUpdate = function (data) {
        this.group.removeAll();

        this._clearIncremental(); // Only use incremental displayables when data amount is larger than 2 million.
        // PENDING Incremental data?


        if (data.count() > 2e6) {
          if (!this._incremental) {
            this._incremental = new IncrementalDisplayable({
              silent: true
            });
          }

          this.group.add(this._incremental);
        } else {
          this._incremental = null;
        }
      };

      LargeSymbolDraw.prototype.incrementalUpdate = function (taskParams, data, opt) {
        var symbolEl;

        if (this._incremental) {
          symbolEl = new LargeSymbolPath();

          this._incremental.addDisplayable(symbolEl, true);
        } else {
          symbolEl = new LargeSymbolPath({
            rectHover: true,
            cursor: 'default',
            startIndex: taskParams.start,
            endIndex: taskParams.end
          });
          symbolEl.incremental = true;
          this.group.add(symbolEl);
        }

        symbolEl.setShape({
          points: data.getLayout('points')
        });

        this._setCommon(symbolEl, data, !!this._incremental, opt);
      };

      LargeSymbolDraw.prototype._setCommon = function (symbolEl, data, isIncremental, 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);
        }

        if (!isIncremental) {
          var ecData_1 = getECData(symbolEl); // Enable tooltip
          // PENDING May have performance issue when path is extremely large

          ecData_1.seriesIndex = hostModel.seriesIndex;
          symbolEl.on('mousemove', function (e) {
            ecData_1.dataIndex = null;
            var dataIndex = symbolEl.findDataIndex(e.offsetX, e.offsetY);

            if (dataIndex >= 0) {
              // Provide dataIndex for tooltip
              ecData_1.dataIndex = dataIndex + (symbolEl.startIndex || 0);
            }
          });
        }
      };

      LargeSymbolDraw.prototype.remove = function () {
        this._clearIncremental();

        this._incremental = null;
        this.group.removeAll();
      };

      LargeSymbolDraw.prototype._clearIncremental = function () {
        var incremental = this._incremental;

        if (incremental) {
          incremental.clearDisplaybles();
        }
      };

      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 || !this._symbolDraw.isPersistent()) {
          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._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,
        // Lenght 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({
      scale: true,
      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({
      scale: true,
      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 args = [];

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

            var _this = _super.apply(this, args) || 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.dataToPoint = function (data, reserved, 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));
        out[1] = yAxis.toGlobalCoord(yAxis.dataToCoord(yVal));
        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, out) {
        out = 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]));
        out[1] = yAxis.coordToData(yAxis.toLocalCoord(point[1]));
        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 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);

        each(axesMap.x, function (xAxis) {
          niceScaleExtent(xAxis.scale, xAxis.model);
        });
        each(axesMap.y, function (yAxis) {
          niceScaleExtent(yAxis.scale, yAxis.model);
        }); // 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]; // if (axisIndex == null) {
          //     Find first axis
          //     for (let name in axesMapOnDim) {
          //         if (axesMapOnDim.hasOwnProperty(name)) {
          //             return axesMapOnDim[name];
          //         }
          //     }
          // }
          // return axesMapOnDim[axisIndex];
        }
      };

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

            if (data.type === 'list') {
              unionExtent(data, xAxis);
              unionExtent(data, yAxis);
            }
          }
        }, this);

        function unionExtent(data, axis) {
          each(getDataDimensionsOnAxis(data, axis.dim), function (dim) {
            axis.scale.unionExtentFromData(data, dim);
          });
        }
      };
      /**
       * @param dim 'x' or 'y' or 'auto' or null/undefined
       */


      Grid.prototype.getTooltipAxes = function (dim) {
        var baseAxes = [];
        var otherAxes = [];
        each(this.getCartesians(), function (cartesian) {
          var baseAxis = dim != null && dim !== 'auto' ? cartesian.getAxis(dim) : cartesian.getBaseAxis();
          var otherAxis = cartesian.getOtherAxis(baseAxis);
          indexOf(baseAxes, baseAxis) < 0 && baseAxes.push(baseAxis);
          indexOf(otherAxes, otherAxis) < 0 && otherAxes.push(otherAxis);
        });
        return {
          baseAxes: baseAxes,
          otherAxes: otherAxes
        };
      };

      Grid.create = function (ecModel, api) {
        var grids = [];
        ecModel.eachComponent('grid', function (gridModel, idx) {
          var grid = new Grid(gridModel, ecModel, api);
          grid.name = 'grid_' + idx; // dataSampling requires axis extent, so resize
          // should be performed in create stage.

          grid.resize(gridModel, api, true);
          gridModel.coordinateSystem = grid;
          grids.push(grid);
        }); // Inject the coordinateSystems into seriesModel

        ecModel.eachSeries(function (seriesModel) {
          if (!isCartesian2DSeries(seriesModel)) {
            return;
          }

          var axesModelMap = findAxisModels(seriesModel);
          var xAxisModel = axesModelMap.xAxisModel;
          var yAxisModel = axesModelMap.yAxisModel;
          var gridModel = xAxisModel.getCoordSysModel();

          if ("development" !== 'production') {
            if (!gridModel) {
              throw new Error('Grid "' + retrieve3(xAxisModel.get('gridIndex'), xAxisModel.get('gridId'), 0) + '" not found');
            }

            if (xAxisModel.getCoordSysModel() !== yAxisModel.getCoordSysModel()) {
              throw new Error('xAxis and yAxis must use the same grid');
            }
          }

          var grid = gridModel.coordinateSystem;
          seriesModel.coordinateSystem = grid.getCartesian(xAxisModel.componentIndex, yAxisModel.componentIndex);
        });
        return grids;
      }; // For deciding which dimensions to use when creating list data


      Grid.dimensions = cartesian2DDimensions;
      return Grid;
    }();
    /**
     * Check if the axis is used in the specified grid.
     */


    function isAxisUsedInTheGrid(axisModel, gridModel) {
      return axisModel.getCoordSysModel() === gridModel;
    }

    function fixAxisOnZero(axesMap, otherAxisDim, axis, // Key: see `getOnZeroRecordKey`
    onZeroRecords) {
      axis.getAxesOnZeroOf = function () {
        // TODO: onZero of multiple axes.
        return otherAxisOnZeroOf ? [otherAxisOnZeroOf] : [];
      }; // onZero can not be enabled in these two situations:
      // 1. When any other axis is a category axis.
      // 2. When no axis is cross 0 point.


      var otherAxes = axesMap[otherAxisDim];
      var otherAxisOnZeroOf;
      var axisModel = axis.model;
      var onZero = axisModel.get(['axisLine', 'onZero']);
      var onZeroAxisIndex = axisModel.get(['axisLine', 'onZeroAxisIndex']);

      if (!onZero) {
        return;
      } // If target axis is specified.


      if (onZeroAxisIndex != null) {
        if (canOnZeroToAxis(otherAxes[onZeroAxisIndex])) {
          otherAxisOnZeroOf = otherAxes[onZeroAxisIndex];
        }
      } else {
        // Find the first available other axis.
        for (var idx in otherAxes) {
          if (otherAxes.hasOwnProperty(idx) && canOnZeroToAxis(otherAxes[idx]) // Consider that two Y axes on one value axis,
          // if both onZero, the two Y axes overlap.
          && !onZeroRecords[getOnZeroRecordKey(otherAxes[idx])]) {
            otherAxisOnZeroOf = otherAxes[idx];
            break;
          }
        }
      }

      if (otherAxisOnZeroOf) {
        onZeroRecords[getOnZeroRecordKey(otherAxisOnZeroOf)] = true;
      }

      function getOnZeroRecordKey(axis) {
        return axis.dim + '_' + axis.index;
      }
    }

    function canOnZeroToAxis(axis) {
      return axis && axis.type !== 'category' && axis.type !== 'time' && ifAxisCrossZero(axis);
    }

    function updateAxisTransform(axis, coordBase) {
      var axisExtent = axis.getExtent();
      var axisExtentSum = axisExtent[0] + axisExtent[1]; // Fast transform

      axis.toGlobalCoord = axis.dim === 'x' ? function (coord) {
        return coord + coordBase;
      } : function (coord) {
        return axisExtentSum - coord + coordBase;
      };
      axis.toLocalCoord = axis.dim === 'x' ? function (coord) {
        return coord - coordBase;
      } : function (coord) {
        return axisExtentSum - coord + coordBase;
      };
    }

    var PI$5 = Math.PI;
    /**
     * A final axis is translated and rotated from a "standard axis".
     * So opt.position and opt.rotation is required.
     *
     * A standard axis is and axis from [0, 0] to [0, axisExtent[1]],
     * for example: (0, 0) ------------> (0, 50)
     *
     * nameDirection or tickDirection or labelDirection is 1 means tick
     * or label is below the standard axis, whereas is -1 means above
     * the standard axis. labelOffset means offset between label and axis,
     * which is useful when 'onZero', where axisLabel is in the grid and
     * label in outside grid.
     *
     * Tips: like always,
     * positive rotation represents anticlockwise, and negative rotation
     * represents clockwise.
     * The direction of position coordinate is the same as the direction
     * of screen coordinate.
     *
     * Do not need to consider axis 'inverse', which is auto processed by
     * axis extent.
     */

    var AxisBuilder =
    /** @class */
    function () {
      function AxisBuilder(axisModel, opt) {
        this.group = new Group();
        this.opt = opt;
        this.axisModel = axisModel; // Default value

        defaults(opt, {
          labelOffset: 0,
          nameDirection: 1,
          tickDirection: 1,
          labelDirection: 1,
          silent: true,
          handleAutoShown: function () {
            return true;
          }
        }); // FIXME Not use a seperate text group?

        var transformGroup = new Group({
          x: opt.position[0],
          y: opt.position[1],
          rotation: opt.rotation
        }); // this.group.add(transformGroup);
        // this._transformGroup = transformGroup;

        transformGroup.updateTransform();
        this._transformGroup = transformGroup;
      }

      AxisBuilder.prototype.hasBuilder = function (name) {
        return !!builders[name];
      };

      AxisBuilder.prototype.add = function (name) {
        builders[name](this.opt, this.axisModel, this.group, this._transformGroup);
      };

      AxisBuilder.prototype.getGroup = function () {
        return this.group;
      };

      AxisBuilder.innerTextLayout = function (axisRotation, textRotation, direction) {
        var rotationDiff = remRadian(textRotation - axisRotation);
        var textAlign;
        var textVerticalAlign;

        if (isRadianAroundZero(rotationDiff)) {
          // Label is parallel with axis line.
          textVerticalAlign = direction > 0 ? 'top' : 'bottom';
          textAlign = 'center';
        } else if (isRadianAroundZero(rotationDiff - PI$5)) {
          // Label is inverse parallel with axis line.
          textVerticalAlign = direction > 0 ? 'bottom' : 'top';
          textAlign = 'center';
        } else {
          textVerticalAlign = 'middle';

          if (rotationDiff > 0 && rotationDiff < PI$5) {
            textAlign = direction > 0 ? 'right' : 'left';
          } else {
            textAlign = direction > 0 ? 'left' : 'right';
          }
        }

        return {
          rotation: rotationDiff,
          textAlign: textAlign,
          textVerticalAlign: textVerticalAlign
        };
      };

      AxisBuilder.makeAxisEventDataBase = function (axisModel) {
        var eventData = {
          componentType: axisModel.mainType,
          componentIndex: axisModel.componentIndex
        };
        eventData[axisModel.mainType + 'Index'] = axisModel.componentIndex;
        return eventData;
      };

      AxisBuilder.isLabelSilent = function (axisModel) {
        var tooltipOpt = axisModel.get('tooltip');
        return axisModel.get('silent') // Consider mouse cursor, add these restrictions.
        || !(axisModel.get('triggerEvent') || tooltipOpt && tooltipOpt.show);
      };

      return AxisBuilder;
    }();
    var builders = {
      axisLine: function (opt, axisModel, group, transformGroup) {
        var shown = axisModel.get(['axisLine', 'show']);

        if (shown === 'auto' && opt.handleAutoShown) {
          shown = opt.handleAutoShown('axisLine');
        }

        if (!shown) {
          return;
        }

        var extent = axisModel.axis.getExtent();
        var matrix = transformGroup.transform;
        var pt1 = [extent[0], 0];
        var pt2 = [extent[1], 0];

        if (matrix) {
          applyTransform(pt1, pt1, matrix);
          applyTransform(pt2, pt2, matrix);
        }

        var lineStyle = extend({
          lineCap: 'round'
        }, axisModel.getModel(['axisLine', 'lineStyle']).getLineStyle());
        var line = new Line({
          // Id for animation
          subPixelOptimize: true,
          shape: {
            x1: pt1[0],
            y1: pt1[1],
            x2: pt2[0],
            y2: pt2[1]
          },
          style: lineStyle,
          strokeContainThreshold: opt.strokeContainThreshold || 5,
          silent: true,
          z2: 1
        });
        line.anid = 'line';
        group.add(line);
        var arrows = axisModel.get(['axisLine', 'symbol']);
        var arrowSize = axisModel.get(['axisLine', 'symbolSize']);
        var arrowOffset = axisModel.get(['axisLine', 'symbolOffset']) || 0;

        if (typeof arrowOffset === 'number') {
          arrowOffset = [arrowOffset, arrowOffset];
        }

        if (arrows != null) {
          if (typeof arrows === 'string') {
            // Use the same arrow for start and end point
            arrows = [arrows, arrows];
          }

          if (typeof arrowSize === 'string' || typeof arrowSize === 'number') {
            // Use the same size for width and height
            arrowSize = [arrowSize, arrowSize];
          }

          var symbolWidth_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;
              symbol.attr({
                rotation: point.rotate,
                x: pt1[0] + r * Math.cos(opt.rotation),
                y: pt1[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);
      },
      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({
          subPixelOptimize: true,
          shape: {
            x1: pt1[0],
            y1: pt1[1],
            x2: pt2[0],
            y2: pt2[1]
          },
          style: tickLineStyle,
          z2: 2,
          autoBatch: true,
          silent: true
        });
        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,
          style: createTextStyle(itemLabelModel, {
            text: formattedLabel,
            align: itemLabelModel.getShallow('align', true) || labelLayout.textAlign,
            verticalAlign: itemLabelModel.getShallow('verticalAlign', true) || itemLabelModel.getShallow('baseline', true) || labelLayout.textVerticalAlign,
            fill: typeof textColor === 'function' ? textColor( // (1) In category axis with data zoom, tick is not the original
            // index of axis.data. So tick should not be exposed to user
            // in category axis.
            // (2) Compatible with previous version, which always use formatted label as
            // input. But in interval scale the formatted label is like '223,445', which
            // maked user repalce ','. So we modify it to return original val but remain
            // it as 'string' to avoid error in replacing.
            axis.type === 'category' ? rawLabel : axis.type === 'value' ? tickValue + '' : tickValue, index) : textColor
          })
        });
        textEl.anid = 'label_' + tickValue; // Pack data for mouse event

        if (triggerEvent) {
          var eventData = AxisBuilder.makeAxisEventDataBase(axisModel);
          eventData.targetType = 'axisLabel';
          eventData.value = rawLabel;
          getECData(textEl).eventData = eventData;
        } // FIXME


        transformGroup.add(textEl);
        textEl.updateTransform();
        labelEls.push(textEl);
        group.add(textEl);
        textEl.decomposeTransform();
      });
      return labelEls;
    }

    // allAxesInfo should be updated when setOption performed.

    function collect(ecModel, api) {
      var result = {
        /**
         * key: makeKey(axis.model)
         * value: {
         *      axis,
         *      coordSys,
         *      axisPointerModel,
         *      triggerTooltip,
         *      involveSeries,
         *      snap,
         *      seriesModels,
         *      seriesDataCount
         * }
         */
        axesInfo: {},
        seriesInvolved: false,

        /**
         * key: makeKey(coordSys.model)
         * value: Object: key makeKey(axis.model), value: axisInfo
         */
        coordSysAxesInfo: {},
        coordSysMap: {}
      };
      collectAxesInfo(result, ecModel, api); // Check seriesInvolved for performance, in case too many series in some chart.

      result.seriesInvolved && collectSeriesInfo(result, ecModel);
      return result;
    }

    function collectAxesInfo(result, ecModel, api) {
      var globalTooltipModel = ecModel.getComponent('tooltip');
      var globalAxisPointerModel = ecModel.getComponent('axisPointer'); // links can only be set on global.

      var linksOption = globalAxisPointerModel.get('link', true) || [];
      var linkGroups = []; // Collect axes info.

      each(api.getCoordinateSystems(), function (coordSys) {
        // Some coordinate system do not support axes, like geo.
        if (!coordSys.axisPointerEnabled) {
          return;
        }

        var coordSysKey = makeKey(coordSys.model);
        var axesInfoInCoordSys = result.coordSysAxesInfo[coordSysKey] = {};
        result.coordSysMap[coordSysKey] = coordSys; // Set tooltip (like 'cross') is a convienent way to show axisPointer
        // for user. So we enable seting tooltip on coordSys model.

        var coordSysModel = coordSys.model;
        var baseTooltipModel = coordSysModel.getModel('tooltip', globalTooltipModel);
        each(coordSys.getAxes(), curry(saveTooltipAxisInfo, false, null)); // If axis tooltip used, choose tooltip axis for each coordSys.
        // Notice this case: coordSys is `grid` but not `cartesian2D` here.

        if (coordSys.getTooltipAxes && globalTooltipModel // If tooltip.showContent is set as false, tooltip will not
        // show but axisPointer will show as normal.
        && baseTooltipModel.get('show')) {
          // Compatible with previous logic. But series.tooltip.trigger: 'axis'
          // or series.data[n].tooltip.trigger: 'axis' are not support any more.
          var triggerAxis = baseTooltipModel.get('trigger') === 'axis';
          var cross = baseTooltipModel.get(['axisPointer', 'type']) === 'cross';
          var tooltipAxes = coordSys.getTooltipAxes(baseTooltipModel.get(['axisPointer', 'axis']));

          if (triggerAxis || cross) {
            each(tooltipAxes.baseAxes, curry(saveTooltipAxisInfo, cross ? 'cross' : true, triggerAxis));
          }

          if (cross) {
            each(tooltipAxes.otherAxes, curry(saveTooltipAxisInfo, 'cross', false));
          }
        } // fromTooltip: true | false | 'cross'
        // triggerTooltip: true | false | null


        function saveTooltipAxisInfo(fromTooltip, triggerTooltip, axis) {
          var axisPointerModel = axis.model.getModel('axisPointer', globalAxisPointerModel);
          var axisPointerShow = axisPointerModel.get('show');

          if (!axisPointerShow || axisPointerShow === 'auto' && !fromTooltip && !isHandleTrigger(axisPointerModel)) {
            return;
          }

          if (triggerTooltip == null) {
            triggerTooltip = axisPointerModel.get('triggerTooltip');
          }

          axisPointerModel = fromTooltip ? makeAxisPointerModel(axis, baseTooltipModel, globalAxisPointerModel, ecModel, fromTooltip, triggerTooltip) : axisPointerModel;
          var snap = axisPointerModel.get('snap');
          var axisKey = makeKey(axis.model);
          var involveSeries = triggerTooltip || snap || axis.type === 'category'; // If result.axesInfo[key] exist, override it (tooltip has higher priority).

          var axisInfo = result.axesInfo[axisKey] = {
            key: axisKey,
            axis: axis,
            coordSys: coordSys,
            axisPointerModel: axisPointerModel,
            triggerTooltip: triggerTooltip,
            involveSeries: involveSeries,
            snap: snap,
            useHandle: isHandleTrigger(axisPointerModel),
            seriesModels: [],
            linkGroup: null
          };
          axesInfoInCoordSys[axisKey] = axisInfo;
          result.seriesInvolved = result.seriesInvolved || involveSeries;
          var groupIndex = getLinkGroupIndex(linksOption, axis);

          if (groupIndex != null) {
            var linkGroup = linkGroups[groupIndex] || (linkGroups[groupIndex] = {
              axesInfo: {}
            });
            linkGroup.axesInfo[axisKey] = axisInfo;
            linkGroup.mapper = linksOption[groupIndex].mapper;
            axisInfo.linkGroup = linkGroup;
          }
        }
      });
    }

    function makeAxisPointerModel(axis, baseTooltipModel, globalAxisPointerModel, ecModel, fromTooltip, triggerTooltip) {
      var tooltipAxisPointerModel = baseTooltipModel.getModel('axisPointer');
      var fields = ['type', 'snap', 'lineStyle', 'shadowStyle', 'label', 'animation', 'animationDurationUpdate', 'animationEasingUpdate', 'z'];
      var volatileOption = {};
      each(fields, function (field) {
        volatileOption[field] = clone(tooltipAxisPointerModel.get(field));
      }); // category axis do not auto snap, otherwise some tick that do not
      // has value can not be hovered. value/time/log axis default snap if
      // triggered from tooltip and trigger tooltip.

      volatileOption.snap = axis.type !== 'category' && !!triggerTooltip; // Compatibel with previous behavior, tooltip axis do not show label by default.
      // Only these properties can be overrided from tooltip to axisPointer.

      if (tooltipAxisPointerModel.get('type') === 'cross') {
        volatileOption.type = 'line';
      }

      var labelOption = volatileOption.label || (volatileOption.label = {}); // Follow the convention, do not show label when triggered by tooltip by default.

      labelOption.show == null && (labelOption.show = false);

      if (fromTooltip === 'cross') {
        // When 'cross', both axes show labels.
        var tooltipAxisPointerLabelShow = tooltipAxisPointerModel.get(['label', 'show']);
        labelOption.show = tooltipAxisPointerLabelShow != null ? tooltipAxisPointerLabelShow : true; // If triggerTooltip, this is a base axis, which should better not use cross style
        // (cross style is dashed by default)

        if (!triggerTooltip) {
          var crossStyle = volatileOption.lineStyle = tooltipAxisPointerModel.get('crossStyle');
          crossStyle && defaults(labelOption, crossStyle.textStyle);
        }
      }

      return axis.model.getModel('axisPointer', new Model(volatileOption, globalAxisPointerModel, ecModel));
    }

    function collectSeriesInfo(result, ecModel) {
      // Prepare data for axis trigger
      ecModel.eachSeries(function (seriesModel) {
        // Notice this case: this coordSys is `cartesian2D` but not `grid`.
        var coordSys = seriesModel.coordinateSystem;
        var seriesTooltipTrigger = seriesModel.get(['tooltip', 'trigger'], true);
        var seriesTooltipShow = seriesModel.get(['tooltip', 'show'], true);

        if (!coordSys || seriesTooltipTrigger === 'none' || seriesTooltipTrigger === false || seriesTooltipTrigger === 'item' || seriesTooltipShow === false || seriesModel.get(['axisPointer', 'show'], true) === false) {
          return;
        }

        each(result.coordSysAxesInfo[makeKey(coordSys.model)], function (axisInfo) {
          var axis = axisInfo.axis;

          if (coordSys.getAxis(axis.dim) === axis) {
            axisInfo.seriesModels.push(seriesModel);
            axisInfo.seriesDataCount == null && (axisInfo.seriesDataCount = 0);
            axisInfo.seriesDataCount += seriesModel.getData().count();
          }
        });
      });
    }
    /**
     * For example:
     * {
     *     axisPointer: {
     *         links: [{
     *             xAxisIndex: [2, 4],
     *             yAxisIndex: 'all'
     *         }, {
     *             xAxisId: ['a5', 'a7'],
     *             xAxisName: 'xxx'
     *         }]
     *     }
     * }
     */


    function getLinkGroupIndex(linksOption, axis) {
      var axisModel = axis.model;
      var dim = axis.dim;

      for (var i = 0; i < linksOption.length; i++) {
        var linkOption = linksOption[i] || {};

        if (checkPropInLink(linkOption[dim + 'AxisId'], axisModel.id) || checkPropInLink(linkOption[dim + 'AxisIndex'], axisModel.componentIndex) || checkPropInLink(linkOption[dim + 'AxisName'], axisModel.name)) {
          return i;
        }
      }
    }

    function checkPropInLink(linkPropValue, axisPropValue) {
      return linkPropValue === 'all' || isArray(linkPropValue) && indexOf(linkPropValue, axisPropValue) >= 0 || linkPropValue === axisPropValue;
    }

    function fixValue(axisModel) {
      var axisInfo = getAxisInfo(axisModel);

      if (!axisInfo) {
        return;
      }

      var axisPointerModel = axisInfo.axisPointerModel;
      var scale = axisInfo.axis.scale;
      var option = axisPointerModel.option;
      var status = axisPointerModel.get('status');
      var value = axisPointerModel.get('value'); // Parse init value for category and time axis.

      if (value != null) {
        value = scale.parse(value);
      }

      var useHandle = isHandleTrigger(axisPointerModel); // If `handle` used, `axisPointer` will always be displayed, so value
      // and status should be initialized.

      if (status == null) {
        option.status = useHandle ? 'show' : 'hide';
      }

      var extent = scale.getExtent().slice();
      extent[0] > extent[1] && extent.reverse();

      if ( // Pick a value on axis when initializing.
      value == null // If both `handle` and `dataZoom` are used, value may be out of axis extent,
      // where we should re-pick a value to keep `handle` displaying normally.
      || value > extent[1]) {
        // Make handle displayed on the end of the axis when init, which looks better.
        value = extent[1];
      }

      if (value < extent[0]) {
        value = extent[0];
      }

      option.value = value;

      if (useHandle) {
        option.status = axisInfo.axis.scale.isBlank() ? 'hide' : 'show';
      }
    }
    function getAxisInfo(axisModel) {
      var coordSysAxesInfo = (axisModel.ecModel.getComponent('axisPointer') || {}).coordSysAxesInfo;
      return coordSysAxesInfo && coordSysAxesInfo.axesInfo[makeKey(axisModel)];
    }
    function getAxisPointerModel(axisModel) {
      var axisInfo = getAxisInfo(axisModel);
      return axisInfo && axisInfo.axisPointerModel;
    }

    function isHandleTrigger(axisPointerModel) {
      return !!axisPointerModel.get(['handle', 'show']);
    }
    /**
     * @param {module:echarts/model/Model} model
     * @return {string} unique key
     */


    function makeKey(model) {
      return model.type + '||' + model.id;
    }

    var axisPointerClazz = {};
    /**
     * Base class of AxisView.
     */

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

      function AxisView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = AxisView.type;
        return _this;
      }
      /**
       * @override
       */


      AxisView.prototype.render = function (axisModel, ecModel, api, payload) {
        // FIXME
        // This process should proformed after coordinate systems updated
        // (axis scale updated), and should be performed each time update.
        // So put it here temporarily, although it is not appropriate to
        // put a model-writing procedure in `view`.
        this.axisPointerClass && fixValue(axisModel);

        _super.prototype.render.apply(this, arguments);

        this._doUpdateAxisPointerClass(axisModel, api, true);
      };
      /**
       * Action handler.
       */


      AxisView.prototype.updateAxisPointer = function (axisModel, ecModel, api, payload) {
        this._doUpdateAxisPointerClass(axisModel, api, false);
      };
      /**
       * @override
       */


      AxisView.prototype.remove = function (ecModel, api) {
        var axisPointer = this._axisPointer;
        axisPointer && axisPointer.remove(api);
      };
      /**
       * @override
       */


      AxisView.prototype.dispose = function (ecModel, api) {
        this._disposeAxisPointer(api);

        _super.prototype.dispose.apply(this, arguments);
      };

      AxisView.prototype._doUpdateAxisPointerClass = function (axisModel, api, forceRender) {
        var Clazz = AxisView.getAxisPointerClass(this.axisPointerClass);

        if (!Clazz) {
          return;
        }

        var axisPointerModel = getAxisPointerModel(axisModel);
        axisPointerModel ? (this._axisPointer || (this._axisPointer = new Clazz())).render(axisModel, axisPointerModel, api, forceRender) : this._disposeAxisPointer(api);
      };

      AxisView.prototype._disposeAxisPointer = function (api) {
        this._axisPointer && this._axisPointer.dispose(api);
        this._axisPointer = null;
      };

      AxisView.registerAxisPointerClass = function (type, clazz) {
        if ("development" !== 'production') {
          if (axisPointerClazz[type]) {
            throw new Error('axisPointer ' + type + ' exists');
          }
        }

        axisPointerClazz[type] = clazz;
      };

      AxisView.getAxisPointerClass = function (type) {
        return type && axisPointerClazz[type];
      };
      AxisView.type = 'axis';
      return AxisView;
    }(ComponentView);

    var inner$5 = 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$5(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$5(axisView).splitAreaColors = newSplitAreaColors;
    }
    function rectCoordAxisHandleRemove(axisView) {
      inner$5(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++) {
              var otherAxisType = cartesians[i].getOtherAxis(axisModel.axis).type;

              if (otherAxisType === 'value' || otherAxisType === 'log') {
                // 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);
        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;
          axisGroup.add(new Line({
            anid: tickValue != null ? 'line_' + ticksCoords[i].tickValue : null,
            subPixelOptimize: true,
            autoBatch: true,
            shape: {
              x1: p1[0],
              y1: p1[1],
              x2: p2[0],
              y2: p2[1]
            },
            style: defaults({
              stroke: lineColors[colorIndex]
            }, lineStyle),
            silent: true
          }));
        }
      },
      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;
            }

            axisGroup.add(new Line({
              anid: 'minor_line_' + minorTicksCoords[i][k].tickValue,
              subPixelOptimize: true,
              autoBatch: true,
              shape: {
                x1: p1[0],
                y1: p1[1],
                x2: p2[0],
                y2: p2[1]
              },
              style: lineStyle,
              silent: true
            }));
          }
        }
      },
      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;
        }
      });
    }

    function normalizeSymbolSize(symbolSize) {
      if (!isArray(symbolSize)) {
        symbolSize = [+symbolSize, +symbolSize];
      }

      return symbolSize;
    }

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

            var pathEmphasisState = symbolPath.ensureState('emphasis');
            pathEmphasisState.style = clone(itemHoverStyle);
            var defaultText = data.get(data.dimensions[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
            });
          });
          enableHoverEmphasis(itemGroup, emphasisModel.get('focus'), emphasisModel.get('blurScope'));
        });
        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.useColorPaletteOnData = true;
        _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 createListSimply(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,
        coordinateSystem: 'radar',
        legendHoverLink: true,
        radarIndex: 0,
        lineStyle: {
          width: 2,
          type: 'solid'
        },
        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,
            nameLocation: 'end',
            nameGap: nameGap,
            // min: 0,
            nameTextStyle: iNameTextStyle,
            triggerEvent: triggerEvent
          }, false);

          if (!showName) {
            innerIndicatorOpt.name = '';
          }

          if (typeof nameFormatter === 'string') {
            var indName = innerIndicatorOpt.name;
            innerIndicatorOpt.name = nameFormatter.replace('{value}', indName != null ? indName : '');
          } else if (typeof nameFormatter === 'function') {
            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 axisBuilder = new AxisBuilder(indicatorAxis.model, {
            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 (typeof radius === 'string' || typeof radius === 'number') {
          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');

        function increaseInterval(interval) {
          var exp10 = Math.pow(10, Math.floor(Math.log(interval) / Math.LN10)); // Increase interval

          var f = interval / exp10;

          if (f === 2) {
            f = 5;
          } else {
            // f is 2 or 5
            f *= 2;
          }

          return f * exp10;
        } // Force all the axis fixing the maxSplitNumber.


        each(indicatorAxes, function (indicatorAxis, idx) {
          var rawExtent = getScaleExtent(indicatorAxis.scale, indicatorAxis.model).extent;
          niceScaleExtent(indicatorAxis.scale, indicatorAxis.model);
          var axisModel = indicatorAxis.model;
          var scale = indicatorAxis.scale;
          var fixedMin = parseAxisModelMinMax(scale, axisModel.get('min', true));
          var fixedMax = parseAxisModelMinMax(scale, axisModel.get('max', true));
          var interval = scale.getInterval();

          if (fixedMin != null && fixedMax != null) {
            // User set min, max, divide to get new interval
            scale.setExtent(+fixedMin, +fixedMax);
            scale.setInterval((fixedMax - fixedMin) / splitNumber);
          } else if (fixedMin != null) {
            var max = void 0; // User set min, expand extent on the other side

            do {
              max = fixedMin + interval * splitNumber;
              scale.setExtent(+fixedMin, max); // Interval must been set after extent
              // FIXME

              scale.setInterval(interval);
              interval = increaseInterval(interval);
            } while (max < rawExtent[1] && isFinite(max) && isFinite(rawExtent[1]));
          } else if (fixedMax != null) {
            var min = void 0; // User set min, expand extent on the other side

            do {
              min = fixedMax - interval * splitNumber;
              scale.setExtent(min, +fixedMax);
              scale.setInterval(interval);
              interval = increaseInterval(interval);
            } while (min > rawExtent[0] && isFinite(min) && isFinite(rawExtent[0]));
          } else {
            var nicedSplitNumber = scale.getTicks().length - 1;

            if (nicedSplitNumber > splitNumber) {
              interval = increaseInterval(interval);
            } // TODO


            var max = Math.ceil(rawExtent[1] / interval) * interval;
            var min = round(max - interval * splitNumber);
            scale.setExtent(min, max);
            scale.setInterval(interval);
          }
        });
      };

      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, 'legendSymbol', 'roundRect');
          }); // visual is for unselected data

          data.setVisual('legendSymbol', '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'
    }, function () {});

    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) || e.target && e.target.draggable) {
          return;
        }

        var x = e.offsetX;
        var y = e.offsetY; // Only check on mosedown, but not mousemove.
        // Mouse can be out of target when mouse moving.

        if (this.pointerChecker && this.pointerChecker(e, x, y)) {
          this._x = x;
          this._y = y;
          this._dragging = true;
        }
      };

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

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

    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 nameMap = this._regionsGroupByName = createHashMap();
        var regionsGroup = this._regionsGroup;
        var transformInfoRaw = viewBuildCtx.transformInfoRaw;
        var mapOrGeoModel = viewBuildCtx.mapOrGeoModel;
        var data = viewBuildCtx.data;

        var transformPoint = function (point) {
          return [point[0] * transformInfoRaw.scaleX + transformInfoRaw.x, point[1] * transformInfoRaw.scaleY + transformInfoRaw.y];
        };

        regionsGroup.removeAll(); // Only when the resource is GeoJSON, there is `geo.regions`.

        each(viewBuildCtx.geo.regions, function (region) {
          var regionName = region.name;
          var regionModel = mapOrGeoModel.getRegionModel(regionName);
          var dataIdx = data ? data.indexOfName(regionName) : null; // Consider in GeoJson properties.name may be duplicated, for example,
          // there is multiple region named "United Kindom" or "France" (so many
          // colonies). And it is not appropriate to merge them in geo, which
          // will make them share the same label and bring trouble in label
          // location calculation.

          var regionGroup = nameMap.get(regionName);
          var hasRegionGroup = !!regionGroup;

          if (!hasRegionGroup) {
            regionGroup = nameMap.set(regionName, new Group());
            regionsGroup.add(regionGroup);
          }

          var compoundPath = new CompoundPath({
            segmentIgnoreThreshold: 1,
            shape: {
              paths: []
            }
          });
          regionGroup.add(compoundPath);

          if (!hasRegionGroup) {
            // ensure children have been added to group before calling resetEventTriggerForRegion
            resetEventTriggerForRegion(viewBuildCtx, regionGroup, regionName, regionModel, mapOrGeoModel, dataIdx);
            resetTooltipForRegion(viewBuildCtx, regionGroup, regionName, regionModel, mapOrGeoModel);
            resetStateTriggerForRegion(viewBuildCtx, regionGroup, regionName, regionModel, mapOrGeoModel);
          }

          each(region.geometries, function (geometry) {
            if (geometry.type !== 'polygon') {
              return;
            }

            var points = [];

            for (var i = 0; i < geometry.exterior.length; ++i) {
              points.push(transformPoint(geometry.exterior[i]));
            }

            compoundPath.shape.paths.push(new Polygon({
              segmentIgnoreThreshold: 1,
              shape: {
                points: points
              }
            }));

            for (var i = 0; i < (geometry.interiors ? geometry.interiors.length : 0); ++i) {
              var interior = geometry.interiors[i];
              var points_1 = [];

              for (var j = 0; j < interior.length; ++j) {
                points_1.push(transformPoint(interior[j]));
              }

              compoundPath.shape.paths.push(new Polygon({
                segmentIgnoreThreshold: 1,
                shape: {
                  points: points_1
                }
              }));
            }
          });
          applyOptionStyleForRegion(viewBuildCtx, compoundPath, dataIdx, regionModel);

          if (compoundPath instanceof Displayable) {
            compoundPath.culling = true;
          }

          var centerPt = transformPoint(region.getCenter());
          resetLabelForRegion(viewBuildCtx, compoundPath, regionName, regionModel, mapOrGeoModel, dataIdx, centerPt);
        }, 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, that is, if tag is inside a named <g> (where `namedFrom` does not exists):

          if (!namedItem.namedFrom) {
            // label should batter to be displayed based on the center of <g>
            // if it is named rather than displayed on each child.
            if (LABEL_HOST_MAP.get(svgNodeTagLower) != null) {
              resetLabelForRegion(viewBuildCtx, el, regionName, regionModel, mapOrGeoModel, dataIdx, null);
            }

            resetEventTriggerForRegion(viewBuildCtx, el, regionName, regionModel, mapOrGeoModel, dataIdx);
            resetTooltipForRegion(viewBuildCtx, el, regionName, regionModel, mapOrGeoModel);

            if (STATE_TRIGGER_TAG_MAP.get(svgNodeTagLower) != null) {
              var focus_1 = resetStateTriggerForRegion(viewBuildCtx, el, regionName, regionModel, mapOrGeoModel);

              if (focus_1 === 'self') {
                focusSelf = true;
              }

              var els = svgDispatcherMap.get(regionName) || svgDispatcherMap.set(regionName, []);
              els.push(el);
            }
          }
        }, this);

        this._enableBlurEntireSVG(focusSelf, viewBuildCtx);
      };

      MapDraw.prototype._enableBlurEntireSVG = function (focusSelf, viewBuildCtx) {
        // It's a little complicated to support blurring the entire geoSVG in series-map.
        // So do not suport it until some requirements come.
        // At present, in series-map, only regions can be blurred.
        if (focusSelf && viewBuildCtx.isGeo) {
          var blurStyle = viewBuildCtx.mapOrGeoModel.getModel(['blur', 'itemStyle']).getItemStyle(); // Only suport `opacity` here. Because not sure that other props are suitable for
          // all of the elements generated by SVG (especially for Text/TSpan/Image/... ).

          var opacity_1 = blurStyle.opacity;

          this._svgGraphicRecord.root.traverse(function (el) {
            if (!el.isGroup) {
              // PENDING: clear those settings to SVG elements when `_freeSVG`.
              // (Currently it happen not to be needed.)
              setDefaultStateProxy(el);
              var style = el.ensureState('blur').style || {}; // Do not overwrite the region style that already set from region option.

              if (style.opacity == null && opacity_1 != null) {
                style.opacity = opacity_1;
              } // If `ensureState('blur').style = {}`, there will be default opacity.
              // Enable `stateTransition` (animation).


              el.ensureState('emphasis');
            }
          });
        }
      };

      MapDraw.prototype.remove = function () {
        this._regionsGroup.removeAll();

        this._regionsGroupByName = null;

        this._svgGroup.removeAll();

        this._freeSVG();

        this._controller.dispose();

        this._controllerHost = null;
      };

      MapDraw.prototype.findHighDownDispatchers = function (name, geoModel) {
        if (name == null) {
          return [];
        }

        var geo = geoModel.coordinateSystem;

        if (geo.resourceType === 'geoJSON') {
          var regionsGroupByName = this._regionsGroupByName;

          if (regionsGroupByName) {
            var regionGroup = regionsGroupByName.get(name);
            return regionGroup ? [regionGroup] : [];
          }
        } else if (geo.resourceType === 'geoSVG') {
          return this._svgDispatcherMap && this._svgDispatcherMap.get(name) || [];
        }
      };

      MapDraw.prototype._svgResourceChanged = function (mapName) {
        return this._svgMapName !== mapName;
      };

      MapDraw.prototype._useSVG = function (mapName) {
        var resource = geoSourceManager.getGeoResource(mapName);

        if (resource && resource.type === 'geoSVG') {
          var svgGraphic = resource.useGraphic(this.uid);

          this._svgGroup.add(svgGraphic.root);

          this._svgGraphicRecord = svgGraphic;
          this._svgMapName = mapName;
        }
      };

      MapDraw.prototype._freeSVG = function () {
        var mapName = this._svgMapName;

        if (mapName == null) {
          return;
        }

        var resource = geoSourceManager.getGeoResource(mapName);

        if (resource && resource.type === 'geoSVG') {
          resource.freeGraphic(this.uid);
        }

        this._svgGraphicRecord = null;
        this._svgDispatcherMap = null;

        this._svgGroup.removeAll();

        this._svgMapName = null;
      };

      MapDraw.prototype._updateController = function (mapOrGeoModel, ecModel, api) {
        var geo = mapOrGeoModel.coordinateSystem;
        var controller = this._controller;
        var controllerHost = this._controllerHost; // @ts-ignore FIXME:TS

        controllerHost.zoomLimit = mapOrGeoModel.get('scaleLimit');
        controllerHost.zoom = geo.getZoom(); // roamType is will be set default true if it is null
        // @ts-ignore FIXME:TS

        controller.enable(mapOrGeoModel.get('roam') || false);
        var mainType = mapOrGeoModel.mainType;

        function makeActionBase() {
          var action = {
            type: 'geoRoam',
            componentType: mainType
          };
          action[mainType + 'Id'] = mapOrGeoModel.id;
          return action;
        }

        controller.off('pan').on('pan', function (e) {
          this._mouseDownFlag = false;
          updateViewOnPan(controllerHost, e.dx, e.dy);
          api.dispatchAction(extend(makeActionBase(), {
            dx: e.dx,
            dy: e.dy
          }));
        }, 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
          }));
        }, 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` becuase `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`, becuase
      // (1) Some SVG also use fill on polyline (The different between
      // polyline and polygon is "open" or "close" but not fill or not).
      // (2) For the common props like opacity, if some use itemStyle
      // and some use `lineStyle`, it might confuse users.
      // (3) Most SVG use <path>, where can not detect wether draw a "line"
      // or a filled shape, so use `itemStyle` for <path>.
      var normalStyleModel = regionModel.getModel('itemStyle');
      var emphasisStyleModel = regionModel.getModel(['emphasis', 'itemStyle']);
      var blurStyleModel = regionModel.getModel(['blur', 'itemStyle']);
      var selectStyleModel = regionModel.getModel(['select', 'itemStyle']); // NOTE: DONT use 'style' in visual when drawing map.
      // This component is used for drawing underlying map for both geo component and map series.

      var normalStyle = getFixedItemStyle(normalStyleModel);
      var emphasisStyle = getFixedItemStyle(emphasisStyleModel);
      var selectStyle = getFixedItemStyle(selectStyleModel);
      var blurStyle = getFixedItemStyle(blurStyleModel); // Update the itemStyle if has data visual

      var data = viewBuildCtx.data;

      if (data) {
        // Only visual color of each item will be used. It can be encoded by visualMap
        // But visual color of series is used in symbol drawing
        // Visual color for each series is for the symbol draw
        var style = data.getItemVisual(dataIndex, 'style');
        var decal = data.getItemVisual(dataIndex, 'decal');

        if (viewBuildCtx.isVisualEncodedByVisualMap && style.fill) {
          normalStyle.fill = style.fill;
        }

        if (decal) {
          normalStyle.decal = createOrUpdatePatternFromDecal(decal, viewBuildCtx.api);
        }
      } // SVG text, tspan and image can be named but not supporeted
      // to be styled by region option yet.


      el.setStyle(normalStyle);
      el.style.strokeNoScale = true;
      el.ensureState('emphasis').style = emphasisStyle;
      el.ensureState('select').style = selectStyle;
      el.ensureState('blur').style = blurStyle; // Enable blur

      setDefaultStateProxy(el);
    }

    function resetLabelForRegion(viewBuildCtx, el, regionName, regionModel, mapOrGeoModel, // Exist only if `viewBuildCtx.data` exists.
    dataIdx, // If labelXY not provided, use `textConfig.position: 'inside'`
    labelXY) {
      var data = viewBuildCtx.data;
      var isGeo = viewBuildCtx.isGeo;
      var isDataNaN = data && isNaN(data.get(data.mapDimension('value'), dataIdx));
      var itemLayout = data && data.getItemLayout(dataIdx); // In the following cases label will be drawn
      // 1. In map series and data value is NaN
      // 2. In geo component
      // 3. Region has no series legendSymbol, 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) {
            if (labelXY) {
              // Compute a relative offset based on the el bounding rect.
              var rect = el.getBoundingRect().clone();
              el.textConfig.position = [(labelXY[0] - rect.x) / rect.width * 100 + '%', (labelXY[1] - rect.y) / rect.height * 100 + '%'];
            }
          }
        }

        enableLayoutLayoutFeatures(el, dataIdx, null);
        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 rigionGroup
      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. Becuause 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');
      enableHoverEmphasis(el, focus, emphasisModel.get('blurScope'));

      if (viewBuildCtx.isGeo) {
        enableComponentHighDownFeatures(el, mapOrGeoModel, regionName);
      }

      return focus;
    }
     // @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 drawed map
            this._mapDraw && this._mapDraw.remove();
            this._mapDraw = null;
          }
        } else {
          var mapDraw = this._mapDraw;
          mapDraw && group.add(mapDraw.group);
        }

        mapModel.get('showLegendSymbol') && ecModel.getComponent('legend') && this._renderSymbols(mapModel, ecModel, api);
      };

      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 begining, and this scenario is rarely encountered.
            // So it won't be fixed until have to.

            setLabelStyle(circle, getLabelStatesModels(itemModel), {
              labelFetcher: {
                getFormattedLabel: function (idx, state) {
                  return mapModel.getFormattedLabel(fullIndex_1, state);
                }
              }
            });
            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 = createListSimply(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 symbolType = opt.symbolType || 'roundRect';
        var symbol = createSymbol(symbolType, 0, 0, opt.itemWidth, opt.itemHeight, opt.itemStyle.fill, opt.symbolKeepAspect);
        symbol.setStyle(opt.itemStyle); // Map do not use itemStyle.borderWidth as border width

        symbol.style.stroke = 'none';

        if (symbolType.indexOf('empty') > -1) {
          symbol.style.stroke = symbol.style.fill;
          symbol.style.fill = '#fff';
          symbol.style.lineWidth = 2;
        }

        return symbol;
      };

      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 wan't to put map in a fixed size box with right aspect ratio
        // This two properties may more conveninet
        // layoutCenter: [50%, 50%]
        // layoutSize: 100
        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 legendSymbol(which is offset 0)

        var data = mapSeries.getData();
        data.each(function (idx) {
          var name = data.getName(idx);
          var layout = data.getItemLayout(idx) || {};
          layout.showLabel = !mapSymbolOffsets[name];
          data.setItemLayout(idx, layout);
        });
        processedMapType[mapType] = true;
      });
    }

    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) {
        if (!centerCoord) {
          return;
        }

        this._center = centerCoord;

        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; // Becuase roamTransformabel has `originX/originY` modified,
        // but the caller of `getTransformInfo` can not handle `originX/originY`,
        // so need to recalcualte 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 Geo =
    /** @class */
    function (_super) {
      __extends(Geo, _super);

      function Geo(name, map, opt) {
        var _this = _super.call(this, name) || this;

        _this.dimensions = ['lng', 'lat'];
        _this.type = 'geo'; // Only store specified name coord via `addGeoCoord`.

        _this._nameCoordMap = createHashMap();
        _this.map = map;
        var source = geoSourceManager.load(map, opt.nameMap, opt.nameProperty);
        var resource = geoSourceManager.getGeoResource(map);
        _this.resourceType = resource ? resource.type : null;
        var defaultParmas = GEO_DEFAULT_PARAMS[resource.type];
        _this._regionsMap = source.regionsMap;
        _this._invertLongitute = defaultParmas.invertLongitute;
        _this.regions = source.regions;
        _this.aspectScale = retrieve2(opt.aspectScale, defaultParmas.aspectScale);
        var boundingRect = source.boundingRect;

        _this.setBoundingRect(boundingRect.x, boundingRect.y, boundingRect.width, boundingRect.height);

        return _this;
      }
      /**
       * Whether contain the given [lng, lat] coord.
       */
      // Never used yet.
      // containCoord(coord: number[]) {
      //     const regions = this.regions;
      //     for (let i = 0; i < regions.length; i++) {
      //         const region = regions[i];
      //         if (region.type === 'geoJSON' && (region as GeoJSONRegion).contain(coord)) {
      //             return true;
      //         }
      //     }
      //     return false;
      // }


      Geo.prototype._transformTo = function (x, y, width, height) {
        var rect = this.getBoundingRect();
        var invertLongitute = this._invertLongitute;
        rect = rect.clone();

        if (invertLongitute) {
          // Longitute 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); // calcualte center only on demand.


        return this._nameCoordMap.get(name) || region && region.getCenter();
      };

      Geo.prototype.dataToPoint = function (data, noRoam, out) {
        if (typeof data === 'string') {
          // Map area name to geoCoord
          data = this.getGeoCoord(data);
        }

        if (data) {
          return View.prototype.dataToPoint.call(this, data, 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 = boundingCoords[0];
        var rightBottom = boundingCoords[1];

        if (isNaN(leftTop[0]) || isNaN(leftTop[1]) || isNaN(rightBottom[0]) || isNaN(rightBottom[1])) {
          if ("development" !== 'production') {
            console.error('Invalid boundingCoords');
          }
        } else {
          this.setBoundingRect(leftTop[0], leftTop[1], rightBottom[0] - leftTop[0], rightBottom[1] - leftTop[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'));
      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 = Geo.prototype.dimensions;
      }

      GeoCreator.prototype.create = function (ecModel, api) {
        var geoList = []; // FIXME Create each time may be slow

        ecModel.eachComponent('geo', function (geoModel, idx) {
          var name = geoModel.get('map');
          var geo = new Geo(name + idx, name, {
            nameMap: geoModel.get('nameMap'),
            nameProperty: geoModel.get('nameProperty'),
            aspectScale: geoModel.get('aspectScale')
          });
          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, {
            nameMap: mergeAll(nameMapList),
            nameProperty: mapSeries[0].get('nameProperty'),
            aspectScale: mapSeries[0].get('aspectScale')
          });
          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 (typeof formatter === 'function') {
          params.status = status;
          return formatter(params);
        } else if (typeof formatter === 'string') {
          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 wan't to put map in a fixed size box with right aspect ratio
        // This two properties may more conveninet
        // layoutCenter: [50%, 50%]
        // layoutSize: 100
        silent: false,
        // Map type
        map: '',
        // Define left-top, right-bottom coords to control view
        // For example, [ [180, 90], [-180, -90] ]
        boundingCoords: null,
        // Default on center of map
        center: null,
        zoom: 1,
        scaleLimit: null,
        // selectedMode: false
        label: {
          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 updateCenterAndZoom(view, payload, zoomLimit) {
      var previousZoom = view.getZoom();
      var center = view.getCenter();
      var zoom = payload.zoom;
      var point = view.dataToPoint(center);

      if (payload.dx != null && payload.dy != null) {
        point[0] -= payload.dx;
        point[1] -= payload.dy;
        view.setCenter(view.pointToData(point));
      }

      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(view.pointToData(point));
        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) {
        var mapDraw = new MapDraw(api);
        this._mapDraw = mapDraw;
        this.group.add(mapDraw.group);
        this._api = api;
      };

      GeoView.prototype.render = function (geoModel, ecModel, api, payload) {
        var mapDraw = this._mapDraw;

        if (geoModel.get('show')) {
          mapDraw.draw(geoModel, ecModel, api, this, payload);
        } else {
          this._mapDraw.group.removeAll();
        }

        mapDraw.group.on('click', this._handleRegionClick, this);
        mapDraw.group.silent = geoModel.get('silent');
        this._model = geoModel;
        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 install$9(registers) {
      registers.registerCoordinateSystem('geo', geoCreator);
      registers.registerComponentModel(GeoModel);
      registers.registerComponentView(GeoView);

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

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

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

      if (edge) {
        edge.useStyle(defaults({
          strokeNoScale: true,
          fill: null
        }, lineStyle));
        setStatesStylesFromModel(edge, itemModel, 'lineStyle');
        setDefaultStateProxy(edge);
        group.add(edge);
      }
    }

    function removeNode(data, dataIndex, symbolEl, group, seriesModel) {
      var node = data.tree.getNodeByDataIndex(dataIndex);
      var virtualRoot = data.tree.root;
      var source = node.parentNode === virtualRoot ? node : node.parentNode || node; // let edgeShape = seriesScope.edgeShape;

      var sourceLayout;

      while (sourceLayout = source.getLayout(), sourceLayout == null) {
        source = source.parentNode === virtualRoot ? source : source.parentNode || source;
      } // 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, {
        fadeLabel: true,
        animation: removeAnimationOpt
      });
      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 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$6 = makeInner();

    function linkList(opt) {
      var mainData = opt.mainData;
      var datas = opt.datas;

      if (!datas) {
        datas = {
          main: mainData
        };
        opt.datasAttr = {
          main: 'data'
        };
      }

      opt.datas = opt.mainData = null;
      linkAll(mainData, datas, opt); // Porxy data original methods.

      each(datas, function (data) {
        each(mainData.TRANSFERABLE_METHODS, function (methodName) {
          data.wrapMethod(methodName, 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$6(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$6(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$6(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$6(this).mainData;
      return dataType == null || mainData == null ? mainData : inner$6(mainData).datas[dataType];
    }
    /**
     * Get list of all linked data
     */


    function getLinkedDataAll() {
      var mainData = inner$6(this).mainData;
      return mainData == null ? [{
        data: mainData
      }] : map(keys(inner$6(mainData).datas), function (type) {
        return {
          type: type,
          data: inner$6(mainData).datas[type]
        };
      });
    }

    function isMainData(data) {
      return inner$6(data).mainData === data;
    }

    function linkAll(mainData, datas, opt) {
      inner$6(mainData).datas = {};
      each(datas, function (data, dataType) {
        linkSingle(data, dataType, mainData, opt);
      });
    }

    function linkSingle(data, dataType, mainData, opt) {
      inner$6(mainData).datas[dataType] = data;
      inner$6(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 (typeof options === 'function') {
          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.get(data.getDimension(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]>


      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);
      };
      /**
       * 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 dimensionsInfo = createDimensions(listData, {
          coordDimensions: ['value'],
          dimensionsCount: dimMax
        });
        var list = new List(dimensionsInfo, hostModel);
        list.initData(listData);
        beforeLink && beforeLink(list);
        linkList({
          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;
    }

    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
       * @param  option  the object used to config echarts view
       * @return storage initial data
       */


      TreeSeriesModel.prototype.getInitialData = function (option) {
        //create an 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.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
        });
      };

      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) {
        ecModel.eachComponent({
          mainType: 'series',
          subType: 'tree',
          query: payload
        }, function (seriesModel) {
          var coordSys = seriesModel.coordinateSystem;
          var res = updateCenterAndZoom(coordSys, payload);
          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);
    }

    function retrieveTargetInfo(payload, validPayloadTypes, seriesModel) {
      if (payload && indexOf(validPayloadTypes, payload.type) >= 0) {
        var root = seriesModel.getData().tree.root;
        var targetNode = payload.targetNode;

        if (typeof targetNode === 'string') {
          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 noop$1 = function () {};

    var actionTypes = ['treemapZoomToNode', 'treemapRender', 'treemapMove'];
    function installTreemapAction(registers) {
      for (var i = 0; i < actionTypes.length; i++) {
        registers.registerAction({
          type: actionTypes[i],
          update: 'updateView'
        }, noop$1);
      }

      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 = levelModels[node.depth]; // 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.treePathInfo = wrapTreePathInfo(node, this);
        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'
            }
          }
        },
        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%'],
            ellipsis: true,
            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
        // }
        // data: {
        //      value: [],
        //      children: [],
        //      link: 'http://xxx.xxx.xxx',
        //      target: 'blank' or 'self'
        // }

      };
      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'); // let emphasisStyleModel = model.getModel('emphasis.itemStyle');

        var textStyleModel = normalStyleModel.getModel('textStyle');
        var layoutParam = {
          pos: {
            left: model.get('left'),
            right: model.get('right'),
            top: model.get('top'),
            bottom: model.get('bottom')
          },
          box: {
            width: api.getWidth(),
            height: api.getHeight()
          },
          emptyItemWidth: model.get('emptyItemWidth'),
          totalWidth: 0,
          renderList: []
        };

        this._prepare(targetNode, layoutParam, textStyleModel);

        this._renderContent(seriesModel, layoutParam, normalStyleModel, textStyleModel, onSelect);

        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, textStyleModel, 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;

        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: {
                text: text,
                fill: textStyleModel.getTextColor(),
                font: textStyleModel.getFont()
              }
            }),
            textConfig: {
              position: 'inside'
            },
            z2: Z2_EMPHASIS_LIFT * 1e4,
            onclick: curry(onSelect, itemNode)
          });
          el.disableLabelAnimation = true;
          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.componentIndex,
        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$7 = 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 renderResult = this._doRender(containerGroup, seriesModel, reRoot);

        !isInit && (!payloadType || payloadType === 'treemapZoomToNode' || payloadType === 'treemapRootToNode') ? this._doAnimation(containerGroup, renderResult, seriesModel, reRoot) : renderResult.renderFinally();

        this._resetController(api);

        this._renderBreadcrumb(seriesModel, api, targetInfo);
      };

      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 can not find all of the old graphic
        // elements from tree. So we use this stragegy: make element storage, move
        // from old storage to new storage, clear old storage.


        dualTravel(thisTree.root ? [thisTree.root] : [], oldTree && oldTree.root ? [oldTree.root] : [], containerGroup, thisTree === oldTree || !oldTree, 0); // Process all removing.

        var willDeleteEls = clearStorage(oldStorage);
        this._oldTree = thisTree;
        this._storage = thisStorage;
        return {
          lastsForAnimation: lastsForAnimation,
          willDeleteEls: willDeleteEls,
          renderFinally: renderFinally
        };

        function dualTravel(thisViewChildren, oldViewChildren, parentGroup, sameTree, depth) {
          // When 'render' is triggered by action,
          // 'this' and 'old' may be the same tree,
          // we use rawIndex in that case.
          if (sameTree) {
            oldViewChildren = thisViewChildren;
            each(thisViewChildren, function (child, index) {
              !child.isRemoved() && processNode(index, index);
            });
          } // Diff hierarchically (diff only in each subtree, but not whole).
          // because, consistency of view is important.
          else {
              new DataDiffer(oldViewChildren, thisViewChildren, getKey, getKey).add(processNode).update(processNode).remove(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$7(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) {
        if (!seriesModel.get('animation')) {
          return;
        }

        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$7(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, dont use 'getBoundingRect'.

            if (shape.x <= point[0] && point[0] <= shape.x + shape.width && shape.y <= point[1] && point[1] <= shape.y + shape.height) {
              targetInfo = {
                node: node,
                offsetX: point[0],
                offsetY: point[1]
              };
            } else {
              return false; // Suppress visit subtree.
            }
          }
        }, this);
        return targetInfo;
      };

      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$7(group).nodeWidth = thisWidth;
      inner$7(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 focus = nodeModel.get(['emphasis', 'focus']);
      var blurScope = nodeModel.get(['emphasis', 'blurScope']);
      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, true); // 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);

        if (bg && isHighDownDispatcher(bg)) {
          setAsHighDownDispatcher(bg, false);
        }

        setAsHighDownDispatcher(group, true); // 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();
        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 can not set all backgroud with the same z, Because the behaviour of
    // drill down and roll up differ background creation sequence from tree
    // hierarchy sequence, which cause that lowser background element overlap
    // upper ones. So we calculate z based on depth.
    // Moreover, we try to shrink down z interval to [0, 1] to avoid that
    // treemap with large z overlaps other components.


    function calculateZ2(depth, z2InLevel) {
      return depth * Z2_BASE + z2InLevel;
    }

    var each$4 = each;
    var isObject$4 = 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);
      };
      /**
       * Convinent 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$4(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$4(visualTypes)) {
          var types_1 = [];
          each$4(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'].
            || typeof pieceValue === 'string' && pieceValue === value + '') {
              return i;
            }

            findClosestWhenOutside && updatePossible(pieceValue, i);
          }
        }

        for (var i = 0, len = pieceList.length; i < len; i++) {
          var piece = pieceList[i];
          var interval = piece.interval;
          var close_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$4(categories, function (cate, index) {
        categoryMap[cate] = index;
      }); // Process visual map input.

      if (!isArray(visual)) {
        var visualArr_1 = [];

        if (isObject(visual)) {
          each$4(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$4(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) {
          return parse(item);
        });
      }

      return visualArr;
    }
    /**
     * Normalizers by mapping methods.
     */


    var normalizers = {
      linear: function (value) {
        return linearMap(value, this.option.dataExtent, [0, 1], true);
      },
      piecewise: function (value) {
        var pieceList = this.option.pieceList;
        var pieceIndex = VisualMapping.findPieceIndex(value, pieceList, true);

        if (pieceIndex != null) {
          return linearMap(pieceIndex, [0, pieceList.length - 1], [0, 1], true);
        }
      },
      category: function (value) {
        var index = this.option.categories ? this.option.categoryMap[value] : value; // ordinal 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$8 = 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$8(mapping).drColorMappingBy = colorMappingBy;
      return mapping;
    } // Notice: If we dont have the attribute 'colorRange', but only use
    // attribute 'color' to represent both concepts of 'colorRange' and 'color',
    // (It means 'colorRange' when 'color' is Array, means 'color' when not array),
    // this problem will be encountered:
    // If a level-1 node dont have children, and its siblings has children,
    // and colorRange is set on level-1, then the node can not be colored.
    // So we separate 'colorRange' and 'color' to different attributes.


    function getRangeVisual(nodeModel, name) {
      // 'colorRange', 'colorARange', 'colorSRange'.
      // If not exsits on this node, fetch from levels and series.
      var range = nodeModel.get(name);
      return isArray(range) && range.length ? {
        name: name,
        range: range
      } : null;
    }

    function mapVisual(nodeModel, visuals, child, index, mapping, seriesModel) {
      var childVisuals = extend({}, visuals);

      if (mapping) {
        // Only support color, colorAlpha, colorSaturation.
        var mappingType = mapping.type;
        var colorMappingBy = mappingType === 'color' && inner$8(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$5 = 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$5(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$5(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 whold width and heigth by target node.
      var currNode = (targetInfo || {}).node;
      var defaultSize = [containerWidth, containerHeight];

      if (!currNode || currNode === viewRoot) {
        return defaultSize;
      }

      var parent;
      var viewArea = containerWidth * containerHeight;
      var area = viewArea * seriesModel.option.zoomToNodeRatio;

      while (parent = currNode.parentNode) {
        // jshint ignore:line
        var sum = 0;
        var siblings = parent.children;

        for (var i = 0, len = siblings.length; i < len; i++) {
          sum += siblings[i].getValue();
        }

        var currNodeValue = currNode.getValue();

        if (currNodeValue === 0) {
          return defaultSize;
        }

        area *= sum / currNodeValue; // 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 postion base on coord of containerGroup


    function calculateRootPosition(layoutInfo, rootRect, targetInfo) {
      if (rootRect) {
        return {
          x: rootRect.x,
          y: rootRect.y
        };
      }

      var defaultPosition = {
        x: 0,
        y: 0
      };

      if (!targetInfo) {
        return defaultPosition;
      } // If targetInfo is fetched by 'retrieveTargetInfo',
      // old tree and new tree are the same tree,
      // so the node still exists and we can visit it.


      var targetNode = targetInfo.node;
      var layout = targetNode.getLayout();

      if (!layout) {
        return defaultPosition;
      } // Transform coord from local to container.


      var targetCenter = [layout.width / 2, layout.height / 2];
      var node = targetNode;

      while (node) {
        var nodeLayout = node.getLayout();
        targetCenter[0] += nodeLayout.x;
        targetCenter[1] += nodeLayout.y;
        node = node.parentNode;
      }

      return {
        x: layoutInfo.width / 2 - targetCenter[0],
        y: layoutInfo.height / 2 - targetCenter[1]
      };
    } // Mark nodes visible for prunning when visual coding and rendering.
    // Prunning depends on layout and root position, so we have to do it after layout.


    function prunning(node, clipRect, viewAbovePath, viewRoot, depth) {
      var nodeLayout = node.getLayout();
      var nodeInViewAbovePath = viewAbovePath[depth];
      var isAboveViewRoot = nodeInViewAbovePath && nodeInViewAbovePath === node;

      if (nodeInViewAbovePath && !isAboveViewRoot || depth === viewAbovePath.length && node !== viewRoot) {
        return;
      }

      node.setLayout({
        // isInView means: viewRoot sub tree + viewAbovePath
        isInView: true,
        // invisible only means: outside view clip so that the node can not
        // see but still layout for animation preparation but not render.
        invisible: !isAboveViewRoot && !clipRect.intersect(nodeLayout),
        isAboveViewRoot: isAboveViewRoot
      }, true); // Transform to child coordinate.

      var childClipRect = new BoundingRect(clipRect.x - nodeLayout.x, clipRect.y - nodeLayout.y, clipRect.width, clipRect.height);
      each$5(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);
    }

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


            for (var i = 0; i < legendModels.length; i++) {
              if (!legendModels[i].isSelected(category)) {
                return false;
              }
            }
          }

          return true;
        });
      });
    }

    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 (typeof categoryIdx === 'string') {
                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 (typeof autoCurvenessParmas === 'number') {
        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) {
      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;
      }

      _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;
          node.setLayout([r * Math.cos(angle) + cx, r * Math.sin(angle) + cy]);
          angle += radianHalf;
        });
      }
    };

    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'));
          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') || 0;
      var symbolKeepAspect = lineData.getItemVisual(idx, name + 'KeepAspect');
      var symbolSizeArr = isArray(symbolSize) ? symbolSize : [symbolSize, symbolSize];
      var symbolOffsetArr = isArray(symbolOffset) ? symbolOffset : [symbolOffset, symbolOffset];
      symbolOffsetArr[0] = parsePercent$1(symbolOffsetArr[0], symbolSizeArr[0]);
      symbolOffsetArr[1] = parsePercent$1(retrieve2(symbolOffsetArr[1], symbolOffsetArr[0]), symbolSizeArr[1]);
      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; // Optimization for large dataset

        if (!seriesScope || lineData.hasItemOption) {
          var itemModel = lineData.getItemModel(idx);
          emphasisLineStyle = itemModel.getModel(['emphasis', 'lineStyle']).getLineStyle();
          blurLineStyle = itemModel.getModel(['blur', 'lineStyle']).getLineStyle();
          selectLineStyle = itemModel.getModel(['select', 'lineStyle']).getLineStyle();
          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.

        });
        enableHoverEmphasis(this);
      };

      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.isPersistent = function () {
        return true;
      };

      LineDraw.prototype.updateData = function (lineData) {
        var _this = this;

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

      LineDraw.prototype.remove = function () {
        this.group.removeAll();
      };

      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;
      return {
        lineStyle: hostModel.getModel('lineStyle').getLineStyle(),
        emphasisLineStyle: hostModel.getModel(['emphasis', 'lineStyle']).getLineStyle(),
        blurLineStyle: hostModel.getModel(['blur', 'lineStyle']).getLineStyle(),
        selectLineStyle: hostModel.getModel(['select', 'lineStyle']).getLineStyle(),
        labelStatesModels: getLabelStatesModels(hostModel)
      };
    }

    function isPointNaN(pt) {
      return isNaN(pt[0]) || isNaN(pt[1]);
    }

    function lineNeedsDraw(pts) {
      return !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);
        }

        data.graph.eachNode(function (node) {
          var idx = node.dataIndex;
          var el = node.getGraphicEl();
          var itemModel = node.getModel(); // Update draggable

          el.off('drag').off('dragend');
          var draggable = itemModel.get('draggable');

          if (draggable) {
            el.on('drag', function () {
              if (forceLayout) {
                forceLayout.warmUp();
                !_this._layouting && _this._startForceLayoutIteration(forceLayout, layoutAnimation);
                forceLayout.setFixed(idx); // Write position back to layout

                data.setItemLayout(idx, [el.x, el.y]);
              }
            }).on('dragend', function () {
              if (forceLayout) {
                forceLayout.setUnfixed(idx);
              }
            });
          }

          el.setDraggable(draggable && !!forceLayout);
          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 (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.eachItemGraphicEl(function (el, idx) {
          var itemModel = data.getItemModel(idx);
          var labelRotate = itemModel.get(['label', 'rotate']) || 0;
          var symbolPath = el.getSymbolPath();

          if (circularRotateLabel) {
            var pos = data.getItemLayout(idx);
            var rad = Math.atan2(pos[1] - cy, pos[0] - cx);

            if (rad < 0) {
              rad = Math.PI * 2 + rad;
            }

            var isLeft = pos[0] < cx;

            if (isLeft) {
              rad = rad - Math.PI;
            }

            var textPosition = isLeft ? 'left' : 'right';
            symbolPath.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
            });
          }
        });
        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.setSymbolScale(nodeScale);
        });
      };

      GraphView.prototype.updateLayout = function (seriesModel) {
        adjustEdge(seriesModel.getGraph(), getNodeGlobalScale(seriesModel));

        this._symbolDraw.updateLayout();

        this._lineDraw.updateLayout();
      };

      GraphView.prototype.remove = function (ecModel, api) {
        this._symbolDraw && this._symbolDraw.remove();
        this._lineDraw && this._lineDraw.remove();
      };

      GraphView.type = 'graph';
      return GraphView;
    }(ChartView);

    function generateNodeKey(id) {
      return '_EC_' + id;
    }

    var Graph =
    /** @class */
    function () {
      function Graph(directed) {
        this.type = 'graph';
        this.nodes = [];
        this.edges = [];
        this._nodesMap = {};
        /**
         * @type {Object.<string, module:echarts/data/Graph.Edge>}
         * @private
         */

        this._edgesMap = {};
        this._directed = directed || false;
      }
      /**
       * If is directed graph
       */


      Graph.prototype.isDirected = function () {
        return this._directed;
      };
      /**
       * Add a new node
       */

      Graph.prototype.addNode = function (id, dataIndex) {
        id = id == null ? '' + dataIndex : '' + id;
        var nodesMap = this._nodesMap;

        if (nodesMap[generateNodeKey(id)]) {
          if ("development" !== 'production') {
            console.error('Graph nodes have duplicate name or id');
          }

          return;
        }

        var node = new GraphNode(id, dataIndex);
        node.hostGraph = this;
        this.nodes.push(node);
        nodesMap[generateNodeKey(id)] = node;
        return node;
      };
      /**
       * Get node by data index
       */

      Graph.prototype.getNodeByIndex = function (dataIndex) {
        var rawIdx = this.data.getRawIndex(dataIndex);
        return this.nodes[rawIdx];
      };
      /**
       * Get node by id
       */

      Graph.prototype.getNodeById = function (id) {
        return this._nodesMap[generateNodeKey(id)];
      };
      /**
       * Add a new edge
       */

      Graph.prototype.addEdge = function (n1, n2, dataIndex) {
        var nodesMap = this._nodesMap;
        var edgesMap = this._edgesMap; // PNEDING

        if (typeof n1 === 'number') {
          n1 = this.nodes[n1];
        }

        if (typeof n2 === 'number') {
          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;
      }

      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.get(data.getDimension(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 = createListFromArray(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 dimensionNames = createDimensions(nodes, {
          coordDimensions: coordDimensions
        });
        nodeData = new List(dimensionNames, seriesModel);
        nodeData.initData(nodes);
      }

      var edgeData = new List(['value'], seriesModel);
      edgeData.initData(validEdges, linkNameList);
      beforeLink && beforeLink(nodeData, edgeData);
      linkList({
        mainData: nodeData,
        struct: graph,
        structAttr: 'graph',
        datas: {
          node: nodeData,
          edge: edgeData
        },
        datasAttr: {
          node: 'data',
          edge: 'edgeData'
        }
      }); // Update dataIndex of nodes and edges because invalid edge may be removed

      graph.update();
      return graph;
    }

    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 List(['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'
      }, function () {});
      registers.registerAction({
        type: 'unfocusNodeAdjacency',
        event: 'unfocusNodeAdjacency',
        update: 'series:unfocusNodeAdjacency'
      }, function () {}); // Register roam action.

      registers.registerAction(actionInfo, function (payload, ecModel) {
        ecModel.eachComponent({
          mainType: 'series',
          query: payload
        }, function (seriesModel) {
          var coordSys = seriesModel.coordinateSystem;
          var res = updateCenterAndZoom(coordSys, payload);
          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 (typeof labelFormatter === 'string') {
          label = labelFormatter.replace('{value}', label);
        } else if (typeof labelFormatter === 'function') {
          label = labelFormatter(value);
        }
      }

      return label;
    }

    var PI2$9 = Math.PI * 2;

    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 angleRangeSpan = !((endAngle - startAngle) % PI2$9) && endAngle !== startAngle ? PI2$9 : (endAngle - startAngle) % PI2$9;
        var prevEndAngle = startAngle;

        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']));
          group.add(sector);
          prevEndAngle = endAngle;
        }

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

        if (!clockwise) {
          var tmp = startAngle;
          startAngle = endAngle;
          endAngle = tmp;
        }

        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);
            group.add(new ZRText({
              style: createTextStyle(labelModel, {
                text: label,
                x: unitX * (r - splitLineLen - distance) + cx,
                y: unitY * (r - splitLineLen - distance) + cy,
                verticalAlign: unitY < -0.8 ? 'top' : unitY > 0.8 ? 'bottom' : 'middle',
                align: unitX < -0.4 ? 'left' : unitX > 0.4 ? 'right' : 'center'
              }, {
                inheritColor: autoColor
              }),
              silent: true
            }));
          } // 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) {
            if (showPointer) {
              var pointer = createPointer(idx, startAngle);
              initProps(pointer, {
                rotation: -(linearMap(data.get(valueDim, idx), 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(data.get(valueDim, idx), valueExtent, angleExtent, isClip)
                }
              }, seriesModel);
              group.add(progress);
              progressList[idx] = progress;
            }
          }).update(function (newIdx, oldIdx) {
            if (showPointer) {
              var previousPointer = oldData.getItemGraphicEl(oldIdx);
              var previousRotate = previousPointer ? previousPointer.rotation : startAngle;
              var pointer = createPointer(newIdx, previousRotate);
              pointer.rotation = previousRotate;
              updateProps(pointer, {
                rotation: -(linearMap(data.get(valueDim, newIdx), 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(data.get(valueDim, newIdx), valueExtent, angleExtent, isClip)
                }
              }, seriesModel);
              group.add(progress);
              progressList[newIdx] = progress;
            }
          }).execute();
          data.each(function (idx) {
            var itemModel = data.getItemModel(idx);
            var emphasisModel = itemModel.getModel('emphasis');

            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);
              enableHoverEmphasis(pointer, emphasisModel.get('focus'), emphasisModel.get('blurScope'));
            }

            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);
              enableHoverEmphasis(progress, emphasisModel.get('focus'), emphasisModel.get('blurScope'));
            }
          });
          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();
        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({
              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({
              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';
        _this.useColorPaletteOnData = true;
        return _this;
      }

      GaugeSeriesModel.prototype.getInitialData = function (option, ecModel) {
        return createListSimply(this, ['value']);
      };

      GaugeSeriesModel.type = 'series.gauge';
      GaugeSeriesModel.defaultOption = {
        zlevel: 0,
        z: 2,
        // 默认全局居中
        center: ['50%', '50%'],
        legendHoverLink: true,
        radius: '75%',
        startAngle: 225,
        endAngle: -45,
        clockwise: true,
        // 最小值
        min: 0,
        // 最大值
        max: 100,
        // 分割段数，默认为10
        splitNumber: 10,
        // 坐标轴线
        axisLine: {
          // 默认显示，属性show控制显示与否
          show: true,
          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
        },
        pointer: {
          icon: null,
          offsetCenter: [0, 0],
          show: 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; // 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);

        enableHoverEmphasis(this, emphasisModel.get('focus'), emphasisModel.get('blurScope'));
      };

      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;
        _this.useColorPaletteOnData = true;
        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 createListSimply(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,
        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 (typeof sort === 'function') {
        indices.sort(sort);
      } else if (sort !== 'none') {
        indices.sort(function (a, b) {
          return isAscending ? valueArr[a] - valueArr[b] : valueArr[b] - valueArr[a];
        });
      }

      return indices;
    }

    function labelLayout(data) {
      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) {
        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);
          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);

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

      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');
      enableHoverEmphasis(el, emphasisModel.get('focus'), emphasisModel.get('blurScope'));
    } // 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 createListFromArray(this.getSource(), 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) {
        each(this._handlers, function (handler, eventName) {
          api.getZr().off(eventName, handler);
        });
        this._handlers = null;
      };
      /**
       * @internal
       * @param {Object} [opt] If null, cancle 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 // Cancle the last trigger, in case that mouse slide out of the area quickly.
        : {
          axisExpandWindow: result.axisExpandWindow,
          // Jumping uses animation, and sliding suppresses animation.
          animation: behavior === 'jump' ? null : {
            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$6 = each;
    var mathMin$8 = Math.min;
    var mathMax$8 = Math.max;
    var mathFloor$2 = Math.floor;
    var mathCeil$1 = Math.ceil;
    var round$2 = 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$6(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$6(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$2(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$2(round$2(axisExpandWindow[0] / axisExpandWidth, 1)) + 1, mathCeil$1(round$2(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$6(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
          };
        } // Conver the point from global to expand coordinates.


        var pointCoord = point[pixelDimIndex] - layoutInfo.layoutBase - layoutInfo.axisExpandWindow0Pos; // For dragging operation convenience, the window should not be
        // slided when mouse is the center area of the window.

        var delta;
        var behavior = 'slide';
        var axisCollapseWidth = layoutInfo.axisCollapseWidth;

        var triggerArea = this._model.get('axisExpandSlideTriggerArea'); // But consider touch device, jump is necessary.


        var useJump = triggerArea[0] != null;

        if (axisCollapseWidth) {
          if (useJump && axisCollapseWidth && pointCoord < winSize * triggerArea[0]) {
            behavior = 'jump';
            delta = pointCoord - winSize * triggerArea[2];
          } else if (useJump && axisCollapseWidth && pointCoord > winSize * (1 - triggerArea[0])) {
            behavior = 'jump';
            delta = pointCoord - winSize * (1 - triggerArea[2]);
          } else {
            (delta = pointCoord - winSize * triggerArea[1]) >= 0 && (delta = pointCoord - winSize * (1 - triggerArea[1])) <= 0 && (delta = 0);
          }

          delta *= layoutInfo.axisExpandWidth / axisCollapseWidth;
          delta ? sliderMove(delta, axisExpandWindow, extent, 'all') // Avoid nonsense triger on mousemove.
          : behavior = 'none';
        } // When screen is too narrow, make it visible and slidable, although it is hard to interact.
        else {
            var winSize2 = axisExpandWindow[1] - axisExpandWindow[0];
            var pos = extent[1] * pointCoord / winSize2;
            axisExpandWindow = [mathMax$8(0, pos - winSize2 / 2)];
            axisExpandWindow[1] = mathMin$8(extent[1], axisExpandWindow[0] + winSize2);
            axisExpandWindow[0] = axisExpandWindow[1] - winSize2;
          }

        return {
          axisExpandWindow: axisExpandWindow,
          behavior: behavior
        };
      };

      return Parallel;
    }();

    function restrict$1(len, extent) {
      return mathMin$8(mathMax$8(len, extent[0]), extent[1]);
    }

    function layoutAxisWithoutExpand(axisIndex, layoutInfo) {
      var step = layoutInfo.layoutLength / (layoutInfo.axisCount - 1);
      return {
        position: step * axisIndex,
        axisNameAvailableWidth: step,
        axisLabelShow: true
      };
    }

    function layoutAxisWithExpand(axisIndex, layoutInfo) {
      var layoutLength = layoutInfo.layoutLength;
      var axisExpandWidth = layoutInfo.axisExpandWidth;
      var axisCount = layoutInfo.axisCount;
      var axisCollapseWidth = layoutInfo.axisCollapseWidth;
      var winInnerIndices = layoutInfo.winInnerIndices;
      var position;
      var axisNameAvailableWidth = axisCollapseWidth;
      var axisLabelShow = false;
      var nameTruncateMaxWidth;

      if (axisIndex < winInnerIndices[0]) {
        position = axisIndex * axisCollapseWidth;
        nameTruncateMaxWidth = axisCollapseWidth;
      } else if (axisIndex <= winInnerIndices[1]) {
        position = layoutInfo.axisExpandWindow0Pos + axisIndex * axisExpandWidth - layoutInfo.axisExpandWindow[0];
        axisNameAvailableWidth = axisExpandWidth;
        axisLabelShow = true;
      } else {
        position = layoutLength - (axisCount - 1 - axisIndex) * axisCollapseWidth;
        nameTruncateMaxWidth = axisCollapseWidth;
      }

      return {
        position: position,
        axisNameAvailableWidth: axisNameAvailableWidth,
        axisLabelShow: axisLabelShow,
        nameTruncateMaxWidth: nameTruncateMaxWidth
      };
    }

    function createParallelCoordSys(ecModel, api) {
      var coordSysList = [];
      ecModel.eachComponent('parallel', function (parallelModel, idx) {
        var coordSys = new Parallel(parallelModel, ecModel, api);
        coordSys.name = 'parallel_' + idx;
        coordSys.resize(parallelModel, api);
        parallelModel.coordinateSystem = coordSys;
        coordSys.model = parallelModel;
        coordSysList.push(coordSys);
      }); // Inject the coordinateSystems into seriesModel

      ecModel.eachSeries(function (seriesModel) {
        if (seriesModel.get('coordinateSystem') === 'parallel') {
          var parallelModel = seriesModel.getReferringComponents('parallel', SINGLE_REFERRING).models[0];
          seriesModel.coordinateSystem = parallelModel.coordinateSystem;
        }
      });
      return coordSysList;
    }

    var parallelCoordSysCreator = {
      create: createParallelCoordSys
    };

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

      function ParallelAxisModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = ParallelAxisModel.type;
        /**
         * @readOnly
         */

        _this.activeIntervals = [];
        return _this;
      }

      ParallelAxisModel.prototype.getAreaSelectStyle = function () {
        return makeStyleMapper([['fill', 'color'], ['lineWidth', 'borderWidth'], ['stroke', 'borderColor'], ['width', 'width'], ['opacity', 'opacity'] // Option decal is in `DecalObject` but style.decal is in `PatternObject`.
        // So do not transfer decal directly.
        ])(this.getModel('areaSelectStyle'));
      };
      /**
       * The code of this feature is put on AxisModel but not ParallelAxis,
       * because axisModel can be alive after echarts updating but instance of
       * ParallelAxis having been disposed. this._activeInterval should be kept
       * when action dispatched (i.e. legend click).
       *
       * @param intervals `interval.length === 0` means set all active.
       */


      ParallelAxisModel.prototype.setActiveIntervals = function (intervals) {
        var activeIntervals = this.activeIntervals = clone(intervals); // Normalize

        if (activeIntervals) {
          for (var i = activeIntervals.length - 1; i >= 0; i--) {
            asc(activeIntervals[i]);
          }
        }
      };
      /**
       * @param value When only attempting detect whether 'no activeIntervals set',
       *        `value` is not needed to be input.
       */


      ParallelAxisModel.prototype.getActiveState = function (value) {
        var activeIntervals = this.activeIntervals;

        if (!activeIntervals.length) {
          return 'normal';
        }

        if (value == null || isNaN(+value)) {
          return 'inactive';
        } // Simple optimization


        if (activeIntervals.length === 1) {
          var interval = activeIntervals[0];

          if (interval[0] <= value && value <= interval[1]) {
            return 'active';
          }
        } else {
          for (var i = 0, len = activeIntervals.length; i < len; i++) {
            if (activeIntervals[i][0] <= value && value <= activeIntervals[i][1]) {
              return 'active';
            }
          }
        }

        return 'inactive';
      };

      return ParallelAxisModel;
    }(ComponentModel);

    mixin(ParallelAxisModel, AxisModelCommonMixin);

    var BRUSH_PANEL_GLOBAL = true;
    var mathMin$9 = Math.min;
    var mathMax$9 = Math.max;
    var mathPow$2 = Math.pow;
    var COVER_Z = 10000;
    var UNSELECT_THRESHOLD = 6;
    var MIN_RESIZE_LINE_WIDTH = 6;
    var MUTEX_RESOURCE_KEY = 'globalPan';
    var DIRECTION_MAP = {
      w: [0, 0],
      e: [0, 1],
      n: [1, 0],
      s: [1, 1]
    };
    var CURSOR_MAP = {
      w: 'ew',
      e: 'ew',
      n: 'ns',
      s: 'ns',
      ne: 'nesw',
      sw: 'nesw',
      nw: 'nwse',
      se: 'nwse'
    };
    var DEFAULT_BRUSH_OPT = {
      brushStyle: {
        lineWidth: 2,
        stroke: 'rgba(210,219,238,0.3)',
        fill: '#D2DBEE'
      },
      transformable: true,
      brushMode: 'single',
      removeOnClick: false
    };
    var baseUID = 0;
    /**
     * params:
     *     areas: Array.<Array>, coord relates to container group,
     *                             If no container specified, to global.
     *     opt {
     *         isEnd: boolean,
     *         removeOnClick: boolean
     *     }
     */

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

      function BrushController(zr) {
        var _this = _super.call(this) || this;
        /**
         * @internal
         */


        _this._track = [];
        /**
         * @internal
         */

        _this._covers = [];
        _this._handlers = {};

        if ("development" !== 'production') {
          assert(zr);
        }

        _this._zr = zr;
        _this.group = new Group();
        _this._uid = 'brushController_' + baseUID++;
        each(pointerHandlers, function (handler, eventName) {
          this._handlers[eventName] = bind(handler, this);
        }, _this);
        return _this;
      }
      /**
       * If set to `false`, select disabled.
       */


      BrushController.prototype.enableBrush = function (brushOption) {
        if ("development" !== 'production') {
          assert(this._mounted);
        }

        this._brushType && this._doDisableBrush();
        brushOption.brushType && this._doEnableBrush(brushOption);
        return this;
      };

      BrushController.prototype._doEnableBrush = function (brushOption) {
        var zr = this._zr; // Consider roam, which takes globalPan too.

        if (!this._enableGlobalPan) {
          take(zr, MUTEX_RESOURCE_KEY, this._uid);
        }

        each(this._handlers, function (handler, eventName) {
          zr.on(eventName, handler);
        });
        this._brushType = brushOption.brushType;
        this._brushOption = merge(clone(DEFAULT_BRUSH_OPT), brushOption, true);
      };

      BrushController.prototype._doDisableBrush = function () {
        var zr = this._zr;
        release(zr, MUTEX_RESOURCE_KEY, this._uid);
        each(this._handlers, function (handler, eventName) {
          zr.off(eventName, handler);
        });
        this._brushType = this._brushOption = null;
      };
      /**
       * @param panelOpts If not pass, it is global brush.
       */


      BrushController.prototype.setPanels = function (panelOpts) {
        if (panelOpts && panelOpts.length) {
          var panels_1 = this._panels = {};
          each(panelOpts, function (panelOpts) {
            panels_1[panelOpts.panelId] = clone(panelOpts);
          });
        } else {
          this._panels = null;
        }

        return this;
      };

      BrushController.prototype.mount = function (opt) {
        opt = opt || {};

        if ("development" !== 'production') {
          this._mounted = true; // should be at first.
        }

        this._enableGlobalPan = opt.enableGlobalPan;
        var thisGroup = this.group;

        this._zr.add(thisGroup);

        thisGroup.attr({
          x: opt.x || 0,
          y: opt.y || 0,
          rotation: opt.rotation || 0,
          scaleX: opt.scaleX || 1,
          scaleY: opt.scaleY || 1
        });
        this._transform = thisGroup.getLocalTransform();
        return this;
      }; // eachCover(cb, context): void {
      //     each(this._covers, cb, context);
      // }

      /**
       * Update covers.
       * @param coverConfigList
       *        If coverConfigList is null/undefined, all covers removed.
       */


      BrushController.prototype.updateCovers = function (coverConfigList) {
        if ("development" !== 'production') {
          assert(this._mounted);
        }

        coverConfigList = map(coverConfigList, function (coverConfig) {
          return merge(clone(DEFAULT_BRUSH_OPT), coverConfig, true);
        });
        var tmpIdPrefix = '\0-brush-index-';
        var oldCovers = this._covers;
        var newCovers = this._covers = [];
        var controller = this;
        var creatingCover = this._creatingCover;
        new DataDiffer(oldCovers, coverConfigList, oldGetKey, getKey).add(addOrUpdate).update(addOrUpdate).remove(remove).execute();
        return this;

        function getKey(brushOption, index) {
          return (brushOption.id != null ? brushOption.id : tmpIdPrefix + index) + '-' + brushOption.brushType;
        }

        function oldGetKey(cover, index) {
          return getKey(cover.__brushOption, index);
        }

        function addOrUpdate(newIndex, oldIndex) {
          var newBrushInternal = coverConfigList[newIndex]; // Consider setOption in event listener of brushSelect,
          // where updating cover when creating should be forbiden.

          if (oldIndex != null && oldCovers[oldIndex] === creatingCover) {
            newCovers[newIndex] = oldCovers[oldIndex];
          } else {
            var cover = newCovers[newIndex] = oldIndex != null ? (oldCovers[oldIndex].__brushOption = newBrushInternal, oldCovers[oldIndex]) : endCreating(controller, createCover(controller, newBrushInternal));
            updateCoverAfterCreation(controller, cover);
          }
        }

        function remove(oldIndex) {
          if (oldCovers[oldIndex] !== creatingCover) {
            controller.group.remove(oldCovers[oldIndex]);
          }
        }
      };

      BrushController.prototype.unmount = function () {
        if ("development" !== 'production') {
          if (!this._mounted) {
            return;
          }
        }

        this.enableBrush(false); // container may 'removeAll' outside.

        clearCovers(this);

        this._zr.remove(this.group);

        if ("development" !== 'production') {
          this._mounted = false; // should be at last.
        }

        return this;
      };

      BrushController.prototype.dispose = function () {
        this.unmount();
        this.off();
      };

      return BrushController;
    }(Eventful);

    function createCover(controller, brushOption) {
      var cover = coverRenderers[brushOption.brushType].createCover(controller, brushOption);
      cover.__brushOption = brushOption;
      updateZ(cover, brushOption);
      controller.group.add(cover);
      return cover;
    }

    function endCreating(controller, creatingCover) {
      var coverRenderer = getCoverRenderer(creatingCover);

      if (coverRenderer.endCreating) {
        coverRenderer.endCreating(controller, creatingCover);
        updateZ(creatingCover, creatingCover.__brushOption);
      }

      return creatingCover;
    }

    function updateCoverShape(controller, cover) {
      var brushOption = cover.__brushOption;
      getCoverRenderer(cover).updateCoverShape(controller, cover, brushOption.range, brushOption);
    }

    function updateZ(cover, brushOption) {
      var z = brushOption.z;
      z == null && (z = COVER_Z);
      cover.traverse(function (el) {
        el.z = z;
        el.z2 = z; // Consider in given container.
      });
    }

    function updateCoverAfterCreation(controller, cover) {
      getCoverRenderer(cover).updateCommon(controller, cover);
      updateCoverShape(controller, cover);
    }

    function getCoverRenderer(cover) {
      return coverRenderers[cover.__brushOption.brushType];
    } // return target panel or `true` (means global panel)


    function getPanelByPoint(controller, e, localCursorPoint) {
      var panels = controller._panels;

      if (!panels) {
        return BRUSH_PANEL_GLOBAL; // Global panel
      }

      var panel;
      var transform = controller._transform;
      each(panels, function (pn) {
        pn.isTargetByCursor(e, localCursorPoint, transform) && (panel = pn);
      });
      return panel;
    } // Return a panel or true


    function getPanelByCover(controller, cover) {
      var panels = controller._panels;

      if (!panels) {
        return BRUSH_PANEL_GLOBAL; // Global panel
      }

      var panelId = cover.__brushOption.panelId; // User may give cover without coord sys info,
      // which is then treated as global panel.

      return panelId != null ? panels[panelId] : BRUSH_PANEL_GLOBAL;
    }

    function clearCovers(controller) {
      var covers = controller._covers;
      var originalLength = covers.length;
      each(covers, function (cover) {
        controller.group.remove(cover);
      }, controller);
      covers.length = 0;
      return !!originalLength;
    }

    function trigger$1(controller, opt) {
      var areas = map(controller._covers, function (cover) {
        var brushOption = cover.__brushOption;
        var range = clone(brushOption.range);
        return {
          brushType: brushOption.brushType,
          panelId: brushOption.panelId,
          range: range
        };
      });
      controller.trigger('brush', {
        areas: areas,
        isEnd: !!opt.isEnd,
        removeOnClick: !!opt.removeOnClick
      });
    }

    function shouldShowCover(controller) {
      var track = controller._track;

      if (!track.length) {
        return false;
      }

      var p2 = track[track.length - 1];
      var p1 = track[0];
      var dx = p2[0] - p1[0];
      var dy = p2[1] - p1[1];
      var dist = mathPow$2(dx * dx + dy * dy, 0.5);
      return dist > UNSELECT_THRESHOLD;
    }

    function getTrackEnds(track) {
      var tail = track.length - 1;
      tail < 0 && (tail = 0);
      return [track[0], track[tail]];
    }

    function createBaseRectCover(rectRangeConverter, controller, brushOption, edgeNameSequences) {
      var cover = new Group();
      cover.add(new Rect({
        name: 'main',
        style: makeStyle(brushOption),
        silent: true,
        draggable: true,
        cursor: 'move',
        drift: curry(driftRect, rectRangeConverter, controller, cover, ['n', 's', 'w', 'e']),
        ondragend: curry(trigger$1, controller, {
          isEnd: true
        })
      }));
      each(edgeNameSequences, function (nameSequence) {
        cover.add(new Rect({
          name: nameSequence.join(''),
          style: {
            opacity: 0
          },
          draggable: true,
          silent: true,
          invisible: true,
          drift: curry(driftRect, rectRangeConverter, controller, cover, nameSequence),
          ondragend: curry(trigger$1, controller, {
            isEnd: true
          })
        }));
      });
      return cover;
    }

    function updateBaseRect(controller, cover, localRange, brushOption) {
      var lineWidth = brushOption.brushStyle.lineWidth || 0;
      var handleSize = mathMax$9(lineWidth, MIN_RESIZE_LINE_WIDTH);
      var x = localRange[0][0];
      var y = localRange[1][0];
      var xa = x - lineWidth / 2;
      var ya = y - lineWidth / 2;
      var x2 = localRange[0][1];
      var y2 = localRange[1][1];
      var x2a = x2 - handleSize + lineWidth / 2;
      var y2a = y2 - handleSize + lineWidth / 2;
      var width = x2 - x;
      var height = y2 - y;
      var widtha = width + lineWidth;
      var heighta = height + lineWidth;
      updateRectShape(controller, cover, 'main', x, y, width, height);

      if (brushOption.transformable) {
        updateRectShape(controller, cover, 'w', xa, ya, handleSize, heighta);
        updateRectShape(controller, cover, 'e', x2a, ya, handleSize, heighta);
        updateRectShape(controller, cover, 'n', xa, ya, widtha, handleSize);
        updateRectShape(controller, cover, 's', xa, y2a, widtha, handleSize);
        updateRectShape(controller, cover, 'nw', xa, ya, handleSize, handleSize);
        updateRectShape(controller, cover, 'ne', x2a, ya, handleSize, handleSize);
        updateRectShape(controller, cover, 'sw', xa, y2a, handleSize, handleSize);
        updateRectShape(controller, cover, 'se', x2a, y2a, handleSize, handleSize);
      }
    }

    function updateCommon(controller, cover) {
      var brushOption = cover.__brushOption;
      var transformable = brushOption.transformable;
      var mainEl = cover.childAt(0);
      mainEl.useStyle(makeStyle(brushOption));
      mainEl.attr({
        silent: !transformable,
        cursor: transformable ? 'move' : 'default'
      });
      each([['w'], ['e'], ['n'], ['s'], ['s', 'e'], ['s', 'w'], ['n', 'e'], ['n', 'w']], function (nameSequence) {
        var el = cover.childOfName(nameSequence.join(''));
        var globalDir = nameSequence.length === 1 ? getGlobalDirection1(controller, nameSequence[0]) : getGlobalDirection2(controller, nameSequence);
        el && el.attr({
          silent: !transformable,
          invisible: !transformable,
          cursor: transformable ? CURSOR_MAP[globalDir] + '-resize' : null
        });
      });
    }

    function updateRectShape(controller, cover, name, x, y, w, h) {
      var el = cover.childOfName(name);
      el && el.setShape(pointsToRect(clipByPanel(controller, cover, [[x, y], [x + w, y + h]])));
    }

    function makeStyle(brushOption) {
      return defaults({
        strokeNoScale: true
      }, brushOption.brushStyle);
    }

    function formatRectRange(x, y, x2, y2) {
      var min = [mathMin$9(x, x2), mathMin$9(y, y2)];
      var max = [mathMax$9(x, x2), mathMax$9(y, y2)];
      return [[min[0], max[0]], [min[1], max[1]] // y range
      ];
    }

    function getTransform$1(controller) {
      return getTransform(controller.group);
    }

    function getGlobalDirection1(controller, localDirName) {
      var map = {
        w: 'left',
        e: 'right',
        n: 'top',
        s: 'bottom'
      };
      var inverseMap = {
        left: 'w',
        right: 'e',
        top: 'n',
        bottom: 's'
      };
      var dir = transformDirection(map[localDirName], getTransform$1(controller));
      return inverseMap[dir];
    }

    function getGlobalDirection2(controller, localDirNameSeq) {
      var globalDir = [getGlobalDirection1(controller, localDirNameSeq[0]), getGlobalDirection1(controller, localDirNameSeq[1])];
      (globalDir[0] === 'e' || globalDir[0] === 'w') && globalDir.reverse();
      return globalDir.join('');
    }

    function driftRect(rectRangeConverter, controller, cover, dirNameSequence, dx, dy) {
      var brushOption = cover.__brushOption;
      var rectRange = rectRangeConverter.toRectRange(brushOption.range);
      var localDelta = toLocalDelta(controller, dx, dy);
      each(dirNameSequence, function (dirName) {
        var ind = DIRECTION_MAP[dirName];
        rectRange[ind[0]][ind[1]] += localDelta[ind[0]];
      });
      brushOption.range = rectRangeConverter.fromRectRange(formatRectRange(rectRange[0][0], rectRange[1][0], rectRange[0][1], rectRange[1][1]));
      updateCoverAfterCreation(controller, cover);
      trigger$1(controller, {
        isEnd: false
      });
    }

    function driftPolygon(controller, cover, dx, dy) {
      var range = cover.__brushOption.range;
      var localDelta = toLocalDelta(controller, dx, dy);
      each(range, function (point) {
        point[0] += localDelta[0];
        point[1] += localDelta[1];
      });
      updateCoverAfterCreation(controller, cover);
      trigger$1(controller, {
        isEnd: false
      });
    }

    function toLocalDelta(controller, dx, dy) {
      var thisGroup = controller.group;
      var localD = thisGroup.transformCoordToLocal(dx, dy);
      var localZero = thisGroup.transformCoordToLocal(0, 0);
      return [localD[0] - localZero[0], localD[1] - localZero[1]];
    }

    function clipByPanel(controller, cover, data) {
      var panel = getPanelByCover(controller, cover);
      return panel && panel !== BRUSH_PANEL_GLOBAL ? panel.clipPath(data, controller._transform) : clone(data);
    }

    function pointsToRect(points) {
      var xmin = mathMin$9(points[0][0], points[1][0]);
      var ymin = mathMin$9(points[0][1], points[1][1]);
      var xmax = mathMax$9(points[0][0], points[1][0]);
      var ymax = mathMax$9(points[0][1], points[1][1]);
      return {
        x: xmin,
        y: ymin,
        width: xmax - xmin,
        height: ymax - ymin
      };
    }

    function resetCursor(controller, e, localCursorPoint) {
      if ( // Check active
      !controller._brushType // resetCursor should be always called when mouse is in zr area,
      // but not called when mouse is out of zr area to avoid bad influence
      // if `mousemove`, `mouseup` are triggered from `document` event.
      || isOutsideZrArea(controller, e.offsetX, e.offsetY)) {
        return;
      }

      var zr = controller._zr;
      var covers = controller._covers;
      var currPanel = getPanelByPoint(controller, e, localCursorPoint); // Check whether in covers.

      if (!controller._dragging) {
        for (var i = 0; i < covers.length; i++) {
          var brushOption = covers[i].__brushOption;

          if (currPanel && (currPanel === BRUSH_PANEL_GLOBAL || brushOption.panelId === currPanel.panelId) && coverRenderers[brushOption.brushType].contain(covers[i], localCursorPoint[0], localCursorPoint[1])) {
            // Use cursor style set on cover.
            return;
          }
        }
      }

      currPanel && zr.setCursorStyle('crosshair');
    }

    function preventDefault(e) {
      var rawE = e.event;
      rawE.preventDefault && rawE.preventDefault();
    }

    function mainShapeContain(cover, x, y) {
      return cover.childOfName('main').contain(x, y);
    }

    function updateCoverByMouse(controller, e, localCursorPoint, isEnd) {
      var creatingCover = controller._creatingCover;
      var panel = controller._creatingPanel;
      var thisBrushOption = controller._brushOption;
      var eventParams;

      controller._track.push(localCursorPoint.slice());

      if (shouldShowCover(controller) || creatingCover) {
        if (panel && !creatingCover) {
          thisBrushOption.brushMode === 'single' && clearCovers(controller);
          var brushOption = clone(thisBrushOption);
          brushOption.brushType = determineBrushType(brushOption.brushType, panel);
          brushOption.panelId = panel === BRUSH_PANEL_GLOBAL ? null : panel.panelId;
          creatingCover = controller._creatingCover = createCover(controller, brushOption);

          controller._covers.push(creatingCover);
        }

        if (creatingCover) {
          var coverRenderer = coverRenderers[determineBrushType(controller._brushType, panel)];
          var coverBrushOption = creatingCover.__brushOption;
          coverBrushOption.range = coverRenderer.getCreatingRange(clipByPanel(controller, creatingCover, controller._track));

          if (isEnd) {
            endCreating(controller, creatingCover);
            coverRenderer.updateCommon(controller, creatingCover);
          }

          updateCoverShape(controller, creatingCover);
          eventParams = {
            isEnd: isEnd
          };
        }
      } else if (isEnd && thisBrushOption.brushMode === 'single' && thisBrushOption.removeOnClick) {
        // Help user to remove covers easily, only by a tiny drag, in 'single' mode.
        // But a single click do not clear covers, because user may have casual
        // clicks (for example, click on other component and do not expect covers
        // disappear).
        // Only some cover removed, trigger action, but not every click trigger action.
        if (getPanelByPoint(controller, e, localCursorPoint) && clearCovers(controller)) {
          eventParams = {
            isEnd: isEnd,
            removeOnClick: true
          };
        }
      }

      return eventParams;
    }

    function determineBrushType(brushType, panel) {
      if (brushType === 'auto') {
        if ("development" !== 'production') {
          assert(panel && panel.defaultBrushType, 'MUST have defaultBrushType when brushType is "atuo"');
        }

        return panel.defaultBrushType;
      }

      return brushType;
    }

    var pointerHandlers = {
      mousedown: function (e) {
        if (this._dragging) {
          // In case some browser do not support globalOut,
          // and release mouse out side the browser.
          handleDragEnd(this, e);
        } else if (!e.target || !e.target.draggable) {
          preventDefault(e);
          var localCursorPoint = this.group.transformCoordToLocal(e.offsetX, e.offsetY);
          this._creatingCover = null;
          var panel = this._creatingPanel = getPanelByPoint(this, e, localCursorPoint);

          if (panel) {
            this._dragging = true;
            this._track = [localCursorPoint.slice()];
          }
        }
      },
      mousemove: function (e) {
        var x = e.offsetX;
        var y = e.offsetY;
        var localCursorPoint = this.group.transformCoordToLocal(x, y);
        resetCursor(this, e, localCursorPoint);

        if (this._dragging) {
          preventDefault(e);
          var eventParams = updateCoverByMouse(this, e, localCursorPoint, false);
          eventParams && trigger$1(this, eventParams);
        }
      },
      mouseup: function (e) {
        handleDragEnd(this, e);
      }
    };

    function handleDragEnd(controller, e) {
      if (controller._dragging) {
        preventDefault(e);
        var x = e.offsetX;
        var y = e.offsetY;
        var localCursorPoint = controller.group.transformCoordToLocal(x, y);
        var eventParams = updateCoverByMouse(controller, e, localCursorPoint, true);
        controller._dragging = false;
        controller._track = [];
        controller._creatingCover = null; // trigger event shoule be at final, after procedure will be nested.

        eventParams && trigger$1(controller, eventParams);
      }
    }

    function isOutsideZrArea(controller, x, y) {
      var zr = controller._zr;
      return x < 0 || x > zr.getWidth() || y < 0 || y > zr.getHeight();
    }
    /**
     * key: brushType
     */


    var coverRenderers = {
      lineX: getLineRenderer(0),
      lineY: getLineRenderer(1),
      rect: {
        createCover: function (controller, brushOption) {
          function returnInput(range) {
            return range;
          }

          return createBaseRectCover({
            toRectRange: returnInput,
            fromRectRange: returnInput
          }, controller, brushOption, [['w'], ['e'], ['n'], ['s'], ['s', 'e'], ['s', 'w'], ['n', 'e'], ['n', 'w']]);
        },
        getCreatingRange: function (localTrack) {
          var ends = getTrackEnds(localTrack);
          return formatRectRange(ends[1][0], ends[1][1], ends[0][0], ends[0][1]);
        },
        updateCoverShape: function (controller, cover, localRange, brushOption) {
          updateBaseRect(controller, cover, localRange, brushOption);
        },
        updateCommon: updateCommon,
        contain: mainShapeContain
      },
      polygon: {
        createCover: function (controller, brushOption) {
          var cover = new Group(); // Do not use graphic.Polygon because graphic.Polyline do not close the
          // border of the shape when drawing, which is a better experience for user.

          cover.add(new Polyline({
            name: 'main',
            style: makeStyle(brushOption),
            silent: true
          }));
          return cover;
        },
        getCreatingRange: function (localTrack) {
          return localTrack;
        },
        endCreating: function (controller, cover) {
          cover.remove(cover.childAt(0)); // Use graphic.Polygon close the shape.

          cover.add(new Polygon({
            name: 'main',
            draggable: true,
            drift: curry(driftPolygon, controller, cover),
            ondragend: curry(trigger$1, controller, {
              isEnd: true
            })
          }));
        },
        updateCoverShape: function (controller, cover, localRange, brushOption) {
          cover.childAt(0).setShape({
            points: clipByPanel(controller, cover, localRange)
          });
        },
        updateCommon: updateCommon,
        contain: mainShapeContain
      }
    };

    function getLineRenderer(xyIndex) {
      return {
        createCover: function (controller, brushOption) {
          return createBaseRectCover({
            toRectRange: function (range) {
              var rectRange = [range, [0, 100]];
              xyIndex && rectRange.reverse();
              return rectRange;
            },
            fromRectRange: function (rectRange) {
              return rectRange[xyIndex];
            }
          }, controller, brushOption, [[['w'], ['e']], [['n'], ['s']]][xyIndex]);
        },
        getCreatingRange: function (localTrack) {
          var ends = getTrackEnds(localTrack);
          var min = mathMin$9(ends[0][xyIndex], ends[1][xyIndex]);
          var max = mathMax$9(ends[0][xyIndex], ends[1][xyIndex]);
          return [min, max];
        },
        updateCoverShape: function (controller, cover, localRange, brushOption) {
          var otherExtent; // If brushWidth not specified, fit the panel.

          var panel = getPanelByCover(controller, cover);

          if (panel !== BRUSH_PANEL_GLOBAL && panel.getLinearBrushOtherExtent) {
            otherExtent = panel.getLinearBrushOtherExtent(xyIndex);
          } else {
            var zr = controller._zr;
            otherExtent = [0, [zr.getWidth(), zr.getHeight()][1 - xyIndex]];
          }

          var rectRange = [localRange, otherExtent];
          xyIndex && rectRange.reverse();
          updateBaseRect(controller, cover, rectRange, brushOption);
        },
        updateCommon: updateCommon,
        contain: mainShapeContain
      };
    }

    function makeRectPanelClipPath(rect) {
      rect = normalizeRect(rect);
      return function (localPoints) {
        return clipPointsByRect(localPoints, rect);
      };
    }
    function makeLinearBrushOtherExtent(rect, specifiedXYIndex) {
      rect = normalizeRect(rect);
      return function (xyIndex) {
        var idx = specifiedXYIndex != null ? specifiedXYIndex : xyIndex;
        var brushWidth = idx ? rect.width : rect.height;
        var base = idx ? rect.x : rect.y;
        return [base, base + (brushWidth || 0)];
      };
    }
    function makeRectIsTargetByCursor(rect, api, targetModel) {
      var boundingRect = normalizeRect(rect);
      return function (e, localCursorPoint) {
        return boundingRect.contain(localCursorPoint[0], localCursorPoint[1]) && !onIrrelevantElement(e, api, targetModel);
      };
    } // Consider width/height is negative.

    function normalizeRect(rect) {
      return BoundingRect.create(rect);
    }

    var elementList = ['axisLine', 'axisTickLabel', 'axisName'];

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

      function ParallelAxisView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = ParallelAxisView.type;
        return _this;
      }

      ParallelAxisView.prototype.init = function (ecModel, api) {
        _super.prototype.init.apply(this, arguments);

        (this._brushController = new BrushController(api.getZr())).on('brush', bind(this._onBrush, this));
      };

      ParallelAxisView.prototype.render = function (axisModel, ecModel, api, payload) {
        if (fromAxisAreaSelect(axisModel, ecModel, payload)) {
          return;
        }

        this.axisModel = axisModel;
        this.api = api;
        this.group.removeAll();
        var oldAxisGroup = this._axisGroup;
        this._axisGroup = new Group();
        this.group.add(this._axisGroup);

        if (!axisModel.get('show')) {
          return;
        }

        var coordSysModel = getCoordSysModel(axisModel, ecModel);
        var coordSys = coordSysModel.coordinateSystem;
        var areaSelectStyle = axisModel.getAreaSelectStyle();
        var areaWidth = areaSelectStyle.width;
        var dim = axisModel.axis.dim;
        var axisLayout = coordSys.getAxisLayout(dim);
        var builderOpt = extend({
          strokeContainThreshold: areaWidth
        }, axisLayout);
        var axisBuilder = new AxisBuilder(axisModel, builderOpt);
        each(elementList, axisBuilder.add, axisBuilder);

        this._axisGroup.add(axisBuilder.getGroup());

        this._refreshBrushController(builderOpt, areaSelectStyle, axisModel, coordSysModel, areaWidth, api);

        groupTransition(oldAxisGroup, this._axisGroup, axisModel);
      }; // /**
      //  * @override
      //  */
      // updateVisual(axisModel, ecModel, api, payload) {
      //     this._brushController && this._brushController
      //         .updateCovers(getCoverInfoList(axisModel));
      // }


      ParallelAxisView.prototype._refreshBrushController = function (builderOpt, areaSelectStyle, axisModel, coordSysModel, areaWidth, api) {
        // After filtering, axis may change, select area needs to be update.
        var extent = axisModel.axis.getExtent();
        var extentLen = extent[1] - extent[0];
        var extra = Math.min(30, Math.abs(extentLen) * 0.1); // Arbitrary value.
        // width/height might be negative, which will be
        // normalized in BoundingRect.

        var rect = BoundingRect.create({
          x: extent[0],
          y: -areaWidth / 2,
          width: extentLen,
          height: areaWidth
        });
        rect.x -= extra;
        rect.width += 2 * extra;

        this._brushController.mount({
          enableGlobalPan: true,
          rotation: builderOpt.rotation,
          x: builderOpt.position[0],
          y: builderOpt.position[1]
        }).setPanels([{
          panelId: 'pl',
          clipPath: makeRectPanelClipPath(rect),
          isTargetByCursor: makeRectIsTargetByCursor(rect, api, coordSysModel),
          getLinearBrushOtherExtent: makeLinearBrushOtherExtent(rect, 0)
        }]).enableBrush({
          brushType: 'lineX',
          brushStyle: areaSelectStyle,
          removeOnClick: true
        }).updateCovers(getCoverInfoList(axisModel));
      };

      ParallelAxisView.prototype._onBrush = function (eventParam) {
        var coverInfoList = eventParam.areas; // Do not cache these object, because the mey be changed.

        var axisModel = this.axisModel;
        var axis = axisModel.axis;
        var intervals = map(coverInfoList, function (coverInfo) {
          return [axis.coordToData(coverInfo.range[0], true), axis.coordToData(coverInfo.range[1], true)];
        }); // If realtime is true, action is not dispatched on drag end, because
        // the drag end emits the same params with the last drag move event,
        // and may have some delay when using touch pad.

        if (!axisModel.option.realtime === eventParam.isEnd || eventParam.removeOnClick) {
          // jshint ignore:line
          this.api.dispatchAction({
            type: 'axisAreaSelect',
            parallelAxisId: axisModel.id,
            intervals: intervals
          });
        }
      };

      ParallelAxisView.prototype.dispose = function () {
        this._brushController.dispose();
      };

      ParallelAxisView.type = 'parallelAxis';
      return ParallelAxisView;
    }(ComponentView);

    function fromAxisAreaSelect(axisModel, ecModel, payload) {
      return payload && payload.type === 'axisAreaSelect' && ecModel.findComponents({
        mainType: 'parallelAxis',
        query: payload
      })[0] === axisModel;
    }

    function getCoverInfoList(axisModel) {
      var axis = axisModel.axis;
      return map(axisModel.activeIntervals, function (interval) {
        return {
          brushType: 'lineX',
          panelId: 'pl',
          range: [axis.dataToCoord(interval[0], true), axis.dataToCoord(interval[1], true)]
        };
      });
    }

    function getCoordSysModel(axisModel, ecModel) {
      return ecModel.getComponent('parallel', axisModel.get('parallelIndex'));
    }

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


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

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

    };
    function installParallelActions(registers) {
      registers.registerAction(actionInfo$1, function (payload, ecModel) {
        ecModel.eachComponent({
          mainType: 'parallelAxis',
          query: payload
        }, function (parallelAxisModel) {
          parallelAxisModel.axis.model.setActiveIntervals(payload.intervals);
        });
      });
      /**
       * @payload
       */

      registers.registerAction('parallelAxisExpand', function (payload, ecModel) {
        ecModel.eachComponent({
          mainType: 'parallel',
          query: payload
        }, function (parallelModel) {
          parallelModel.setAxisExpand(payload);
        });
      });
    }

    var defaultAxisOption = {
      type: 'value',
      areaSelectStyle: {
        width: 20,
        borderWidth: 1,
        borderColor: 'rgba(160,197,232)',
        color: 'rgba(160,197,232)',
        opacity: 0.3
      },
      realtime: true,
      z: 10
    };
    function install$g(registers) {
      registers.registerComponentView(ParallelView$1);
      registers.registerComponentModel(ParallelModel);
      registers.registerCoordinateSystem('parallel', parallelCoordSysCreator);
      registers.registerPreprocessor(parallelPreprocessor);
      registers.registerComponentModel(ParallelAxisModel);
      registers.registerComponentView(ParallelAxisView);
      axisModelCreator(registers, 'parallel', ParallelAxisModel, defaultAxisOption);
      installParallelActions(registers);
    }

    function install$h(registers) {
      use(install$g);
      registers.registerChartView(ParallelView);
      registers.registerSeriesModel(ParallelSeriesModel);
      registers.registerVisual(registers.PRIORITY.VISUAL.BRUSH, parallelVisual);
    }

    var SankeyPathShape =
    /** @class */
    function () {
      function SankeyPathShape() {
        this.x1 = 0;
        this.y1 = 0;
        this.x2 = 0;
        this.y2 = 0;
        this.cpx1 = 0;
        this.cpy1 = 0;
        this.cpx2 = 0;
        this.cpy2 = 0;
        this.extent = 0;
      }

      return SankeyPathShape;
    }();

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

      function SankeyPath(opts) {
        return _super.call(this, opts) || this;
      }

      SankeyPath.prototype.getDefaultShape = function () {
        return new SankeyPathShape();
      };

      SankeyPath.prototype.buildPath = function (ctx, shape) {
        var extent = shape.extent;
        ctx.moveTo(shape.x1, shape.y1);
        ctx.bezierCurveTo(shape.cpx1, shape.cpy1, shape.cpx2, shape.cpy2, shape.x2, shape.y2);

        if (shape.orient === 'vertical') {
          ctx.lineTo(shape.x2 + extent, shape.y2);
          ctx.bezierCurveTo(shape.cpx2 + extent, shape.cpy2, shape.cpx1 + extent, shape.cpy1, shape.x1 + extent, shape.y1);
        } else {
          ctx.lineTo(shape.x2, shape.y2 + extent);
          ctx.bezierCurveTo(shape.cpx2, shape.cpy2 + extent, shape.cpx1, shape.cpy1 + extent, shape.x1, shape.y1 + extent);
        }

        ctx.closePath();
      };

      SankeyPath.prototype.highlight = function () {
        enterEmphasis(this);
      };

      SankeyPath.prototype.downplay = function () {
        leaveEmphasis(this);
      };

      return SankeyPath;
    }(Path);

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

      function SankeyView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = SankeyView.type;
        _this._focusAdjacencyDisabled = false;
        return _this;
      }

      SankeyView.prototype.render = function (seriesModel, ecModel, api) {
        var sankeyView = this;
        var graph = seriesModel.getGraph();
        var group = this.group;
        var layoutInfo = seriesModel.layoutInfo; // view width

        var width = layoutInfo.width; // view height

        var height = layoutInfo.height;
        var nodeData = seriesModel.getData();
        var edgeData = seriesModel.getData('edge');
        var orient = seriesModel.get('orient');
        this._model = seriesModel;
        group.removeAll();
        group.x = layoutInfo.x;
        group.y = layoutInfo.y; // generate a bezire Curve for each edge

        graph.eachEdge(function (edge) {
          var curve = new SankeyPath();
          var ecData = getECData(curve);
          ecData.dataIndex = edge.dataIndex;
          ecData.seriesIndex = seriesModel.seriesIndex;
          ecData.dataType = 'edge';
          var edgeModel = edge.getModel();
          var lineStyleModel = edgeModel.getModel('lineStyle');
          var curvature = lineStyleModel.get('curveness');
          var n1Layout = edge.node1.getLayout();
          var node1Model = edge.node1.getModel();
          var dragX1 = node1Model.get('localX');
          var dragY1 = node1Model.get('localY');
          var n2Layout = edge.node2.getLayout();
          var node2Model = edge.node2.getModel();
          var dragX2 = node2Model.get('localX');
          var dragY2 = node2Model.get('localY');
          var edgeLayout = edge.getLayout();
          var x1;
          var y1;
          var x2;
          var y2;
          var cpx1;
          var cpy1;
          var cpx2;
          var cpy2;
          curve.shape.extent = Math.max(1, edgeLayout.dy);
          curve.shape.orient = orient;

          if (orient === 'vertical') {
            x1 = (dragX1 != null ? dragX1 * width : n1Layout.x) + edgeLayout.sy;
            y1 = (dragY1 != null ? dragY1 * height : n1Layout.y) + n1Layout.dy;
            x2 = (dragX2 != null ? dragX2 * width : n2Layout.x) + edgeLayout.ty;
            y2 = dragY2 != null ? dragY2 * height : n2Layout.y;
            cpx1 = x1;
            cpy1 = y1 * (1 - curvature) + y2 * curvature;
            cpx2 = x2;
            cpy2 = y1 * curvature + y2 * (1 - curvature);
          } else {
            x1 = (dragX1 != null ? dragX1 * width : n1Layout.x) + n1Layout.dx;
            y1 = (dragY1 != null ? dragY1 * height : n1Layout.y) + edgeLayout.sy;
            x2 = dragX2 != null ? dragX2 * width : n2Layout.x;
            y2 = (dragY2 != null ? dragY2 * height : n2Layout.y) + edgeLayout.ty;
            cpx1 = x1 * (1 - curvature) + x2 * curvature;
            cpy1 = y1;
            cpx2 = x1 * curvature + x2 * (1 - curvature);
            cpy2 = y2;
          }

          curve.setShape({
            x1: x1,
            y1: y1,
            x2: x2,
            y2: y2,
            cpx1: cpx1,
            cpy1: cpy1,
            cpx2: cpx2,
            cpy2: cpy2
          });
          curve.useStyle(lineStyleModel.getItemStyle()); // Special color, use source node color or target node color

          switch (curve.style.fill) {
            case 'source':
              curve.style.fill = edge.node1.getVisual('color');
              curve.style.decal = edge.node1.getVisual('style').decal;
              break;

            case 'target':
              curve.style.fill = edge.node2.getVisual('color');
              curve.style.decal = edge.node2.getVisual('style').decal;
              break;

            case 'gradient':
              var sourceColor = edge.node1.getVisual('color');
              var targetColor = edge.node2.getVisual('color');

              if (typeof sourceColor === 'string' && typeof targetColor === 'string') {
                curve.style.fill = new LinearGradient(0, 0, 1, 0, [{
                  color: sourceColor,
                  offset: 0
                }, {
                  color: targetColor,
                  offset: 1
                }]);
              }

          }

          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');
          enableHoverEmphasis(curve, focus === 'adjacency' ? edge.getAdjacentDataIndices() : focus, emphasisModel.get('blurScope'));
          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');
          enableHoverEmphasis(rect, focus === 'adjacency' ? node.getAdjacentDataIndices() : focus, emphasisModel.get('blurScope'));
        });
        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
       *
       * @param  {Object} option  the object used to config echarts view
       * @return {module:echarts/data/List} storage initial data
       */


      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 dataItem = this.option.data[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 () {
        var option = this.option;
      }; // 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
        },
        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;

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

    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; // ??? FIXME make a stage to perform data transfrom.
        // MUST create a new data, consider setOption({}) again.

        if (data && addOrdinal) {
          var newOptionData_1 = [];
          each(data, function (item, index) {
            var newItem;

            if (isArray(item)) {
              newItem = item.slice();
              item.unshift(index);
            } else if (isArray(item.value)) {
              newItem = item.value.slice();
              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 createListSimply(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 {
            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);
      setStatesStylesFromModel(el, itemModel);
      enableHoverEmphasis(el, itemModel.get(['emphasis', 'focus']), itemModel.get(['emphasis', 'blurScope']));
    }

    function transInit(points, dim, itemLayout) {
      return map(points, function (point) {
        point = point.slice();
        point[dim] = itemLayout.initBaseline;
        return point;
      });
    }

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

    var each$7 = each;
    function boxplotLayout(ecModel) {
      var groupResult = groupSeriesByAxis(ecModel);
      each$7(groupResult, function (groupItem) {
        var seriesModels = groupItem.seriesModels;

        if (!seriesModels.length) {
          return;
        }

        calculateBase(groupItem);
        each$7(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 extent;
      var baseAxis = groupItem.axis;
      var seriesModels = groupItem.seriesModels;
      var seriesCount = seriesModels.length;
      var boxWidthList = groupItem.boxWidthList = [];
      var boxOffsetList = groupItem.boxOffsetList = [];
      var boundList = [];
      var bandWidth;

      if (baseAxis.type === 'category') {
        bandWidth = baseAxis.getBandWidth();
      } else {
        var maxDataCount_1 = 0;
        each$7(seriesModels, function (seriesModel) {
          maxDataCount_1 = Math.max(maxDataCount_1, seriesModel.getData().count());
        });
        extent = baseAxis.getExtent(), Math.abs(extent[1] - extent[0]) / maxDataCount_1;
      }

      each$7(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$7(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.registerVisual(boxplotVisual);
      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();

        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._isLargeDraw ? this._incrementalRenderLarge(params, seriesModel) : this._incrementalRenderNormal(params, seriesModel);
      };

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

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

      CandlestickView.prototype._incrementalRenderLarge = function (params, seriesModel) {
        createLarge$1(seriesModel, this.group, 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, incremental) {
      var data = seriesModel.getData();
      var largePoints = data.getLayout('largePoints');
      var elP = new LargeBoxPath({
        shape: {
          points: largePoints
        },
        __sign: 1
      });
      group.add(elP);
      var elN = new LargeBoxPath({
        shape: {
          points: largePoints
        },
        __sign: -1
      });
      group.add(elN);
      setLargeStyle$1(1, elP, seriesModel);
      setLargeStyle$1(-1, elN, seriesModel);

      if (incremental) {
        elP.incremental = true;
        elN.incremental = true;
      }
    }

    function setLargeStyle$1(sign, el, seriesModel, data) {
      // TODO put in visual?
      var borderColor = seriesModel.get(['itemStyle', sign > 0 ? 'borderColor' : 'borderColor0']) || seriesModel.get(['itemStyle', sign > 0 ? 'color' : 'color0']); // 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',
          // 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 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 ? positiveBorderColorQuery : negativeBorderColorQuery);
        }

        var data = seriesModel.getData(); // 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 LargeArr$1 = typeof Float32Array !== 'undefined' ? Float32Array : Array;
    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 cDim = data.mapDimension(coordDims[cDimIdx]);
        var vDims = data.mapDimensionsAll(coordDims[vDimIdx]);
        var openDim = vDims[0];
        var closeDim = vDims[1];
        var lowestDim = vDims[2];
        var highestDim = vDims[3];
        data.setLayout({
          candleWidth: candleWidth,
          // The value is experimented visually.
          isSimpleBox: candleWidth <= 1.3
        });

        if (cDim == null || vDims.length < 4) {
          return;
        }

        return {
          progress: seriesModel.pipelineContext.large ? largeProgress : normalProgress
        };

        function normalProgress(params, data) {
          var dataIndex;

          while ((dataIndex = params.next()) != null) {
            var axisDimVal = data.get(cDim, dataIndex);
            var openVal = data.get(openDim, dataIndex);
            var closeVal = data.get(closeDim, dataIndex);
            var lowestVal = data.get(lowestDim, dataIndex);
            var highestVal = data.get(highestDim, 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));
            data.setItemLayout(dataIndex, {
              sign: getSign(data, dataIndex, openVal, closeVal, closeDim),
              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 = new LargeArr$1(params.count * 4);
          var offset = 0;
          var point;
          var tmpIn = [];
          var tmpOut = [];
          var dataIndex;

          while ((dataIndex = params.next()) != null) {
            var axisDimVal = data.get(cDim, dataIndex);
            var openVal = data.get(openDim, dataIndex);
            var closeVal = data.get(closeDim, dataIndex);
            var lowestVal = data.get(lowestDim, dataIndex);
            var highestVal = data.get(highestDim, dataIndex);

            if (isNaN(axisDimVal) || isNaN(lowestVal) || isNaN(highestVal)) {
              points[offset++] = NaN;
              offset += 3;
              continue;
            }

            points[offset++] = getSign(data, dataIndex, openVal, closeVal, closeDim);
            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);
        }
      }
    };

    function getSign(data, dataIndex, openVal, closeVal, closeDim) {
      var sign;

      if (openVal > closeVal) {
        sign = -1;
      } else if (openVal < closeVal) {
        sign = 1;
      } else {
        sign = dataIndex > 0 // If close === open, compare with close of last record
        ? data.get(closeDim, 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);
    }

    var EFFECT_RIPPLE_NUMBER = 3;

    function normalizeSymbolSize$1(symbolSize) {
      if (!isArray(symbolSize)) {
        symbolSize = [+symbolSize, +symbolSize];
      }

      return symbolSize;
    }

    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 rippleGroup = this.childAt(1);

        for (var i = 0; i < EFFECT_RIPPLE_NUMBER; 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 / EFFECT_RIPPLE_NUMBER * effectCfg.period + effectCfg.effectOffset; // TODO Configurable effectCfg.period

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

        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);
      };
      /**
       * 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$1(data.getItemVisual(idx, 'symbolSize'));
        var symbolStyle = data.getItemVisual(idx, 'style');
        var color = symbolStyle && symbolStyle.fill;
        rippleGroup.setScale(symbolSize);
        rippleGroup.traverse(function (ripplePath) {
          ripplePath.setStyle('fill', color);
        });
        var symbolOffset = data.getItemVisual(idx, 'symbolOffset');

        if (symbolOffset) {
          if (!isArray(symbolOffset)) {
            symbolOffset = [symbolOffset, symbolOffset];
          }

          rippleGroup.x = parsePercent$1(symbolOffset[0], symbolSize[0]);
          rippleGroup.y = parsePercent$1(retrieve2(symbolOffset[1], symbolOffset[0]) || 0, symbolSize[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']);
        this.off('mouseover').off('mouseout').off('emphasis').off('normal');

        if (effectCfg.showEffectOn === 'render') {
          this._effectCfg ? this.updateEffectAnimation(effectCfg) : this.startEffectAnimation(effectCfg);
          this._effectCfg = effectCfg;
        } else {
          // Not keep old effect config
          this._effectCfg = null;
          this.stopEffectAnimation();

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

      EffectSymbol.prototype.fadeOut = function (cb) {
        this.off('mouseover').off('mouseout');
        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 createListFromArray(this.getSource(), 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'
        },
        // 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 self = this;
        var points = lineData.getItemLayout(idx);
        var period = effectModel.get('period') * 1000;
        var loop = effectModel.get('loop');
        var constantSpeed = effectModel.get('constantSpeed');
        var delayExpr = 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) {
          symbol.stopAnimation();

          if (period > 0) {
            var delayNum = void 0;

            if (typeof delayExpr === 'function') {
              delayNum = delayExpr(idx);
            } else {
              delayNum = delayExpr;
            }

            if (symbol.__t > 0) {
              delayNum = -period * symbol.__t;
            }

            symbol.__t = 0;
            var animator = symbol.animate('', loop).when(period, {
              __t: 1
            }).delay(delayNum).during(function () {
              self._updateSymbolPosition(symbol);
            });

            if (!loop) {
              animator.done(function () {
                self.remove(symbol);
              });
            }

            animator.start();
          }
        }

        this._period = period;
        this._loop = loop;
      };

      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;
        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 = quadraticDerivativeAt$1(p1[0], cp1[0], p2[0], t);
        var ty = quadraticDerivativeAt$1(p1[1], cp1[1], p2[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 hoverLineStyle = seriesScope && seriesScope.emphasisLineStyle;

        if (!seriesScope || lineData.hasItemOption) {
          hoverLineStyle = itemModel.getModel(['emphasis', 'lineStyle']).getLineStyle();
        }

        line.useStyle(lineData.getItemVisual(idx, 'style'));
        line.style.fill = null;
        line.style.strokeNoScale = true;
        var lineEmphasisState = line.ensureState('emphasis');
        lineEmphasisState.style = hoverLineStyle;
        enableHoverEmphasis(this);
      };

      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;
        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 = p1[0] - p0[0];
        var ty = p1[1] - p0[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) {
        return _super.call(this, opts) || this;
      }

      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;

        if (shape.polyline) {
          for (var i = 0; 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 (var i = 0; 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);
            }
          }
        }
      };

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

      return LargeLinesPath;
    }(Path);

    var LargeLineDraw =
    /** @class */
    function () {
      function LargeLineDraw() {
        this.group = new Group();
      }

      LargeLineDraw.prototype.isPersistent = function () {
        return !this._incremental;
      };
      /**
       * Update symbols draw by new data
       */

      LargeLineDraw.prototype.updateData = function (data) {
        this.group.removeAll();
        var lineEl = new LargeLinesPath({
          rectHover: true,
          cursor: 'default'
        });
        lineEl.setShape({
          segs: data.getLayout('linesPoints')
        });

        this._setCommon(lineEl, data); // Add back


        this.group.add(lineEl);
        this._incremental = null;
      };
      /**
       * @override
       */

      LargeLineDraw.prototype.incrementalPrepareUpdate = function (data) {
        this.group.removeAll();

        this._clearIncremental();

        if (data.count() > 5e5) {
          if (!this._incremental) {
            this._incremental = new IncrementalDisplayable({
              silent: true
            });
          }

          this.group.add(this._incremental);
        } else {
          this._incremental = null;
        }
      };
      /**
       * @override
       */

      LargeLineDraw.prototype.incrementalUpdate = function (taskParams, data) {
        var lineEl = new LargeLinesPath();
        lineEl.setShape({
          segs: data.getLayout('linesPoints')
        });

        this._setCommon(lineEl, data, !!this._incremental);

        if (!this._incremental) {
          lineEl.rectHover = true;
          lineEl.cursor = 'default';
          lineEl.__startIndex = taskParams.start;
          this.group.add(lineEl);
        } else {
          this._incremental.addDisplayable(lineEl, true);
        }
      };
      /**
       * @override
       */

      LargeLineDraw.prototype.remove = function () {
        this._clearIncremental();

        this._incremental = null;
        this.group.removeAll();
      };

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

        if (!isIncremental) {
          var ecData_1 = getECData(lineEl); // Enable tooltip
          // PENDING May have performance issue when path is extremely large

          ecData_1.seriesIndex = hostModel.seriesIndex;
          lineEl.on('mousemove', function (e) {
            ecData_1.dataIndex = null;
            var dataIndex = lineEl.findDataIndex(e.offsetX, e.offsetY);

            if (dataIndex > 0) {
              // Provide dataIndex for tooltip
              ecData_1.dataIndex = dataIndex + lineEl.__startIndex;
            }
          });
        }
      };

      LargeLineDraw.prototype._clearIncremental = function () {
        var incremental = this._incremental;

        if (incremental) {
          incremental.clearDisplaybles();
        }
      };
      return LargeLineDraw;
    }();

    var linesLayout = {
      seriesType: 'lines',
      plan: createRenderPlanner(),
      reset: function (seriesModel) {
        var coordSys = seriesModel.coordinateSystem;
        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) {
          if ("development" !== 'production') {
            var notInIndividual_1 = false;
            ecModel.eachSeries(function (otherSeriesModel) {
              if (otherSeriesModel !== seriesModel && otherSeriesModel.get('zlevel') === zlevel) {
                notInIndividual_1 = true;
              }
            });
            notInIndividual_1 && console.warn('Lines with trail effect should have an individual zlevel');
          }

          if (!isSvg) {
            zr.configLayer(zlevel, {
              motionBlur: true,
              lastFrameAlpha: Math.max(Math.min(trailLength / 10 + 0.9, 1), 0)
            });
          }
        }

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

        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.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 (typeof data[0] === 'number') {
          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('Unkown coordinate system ' + option.coordinateSystem);
          }
        }

        var lineData = new List(['value'], this);
        lineData.hasItemOption = false;
        lineData.initData(option.data, [], function (dataItem, dimName, dataIndex, dimIndex) {
          // dataItem is simply coords
          if (dataItem instanceof Array) {
            return NaN;
          } else {
            lineData.hasItemOption = true;
            var value = dataItem.value;

            if (value != null) {
              return value instanceof Array ? value[dimIndex] : value;
            }
          }
        });
        return lineData;
      };

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

        this.group.removeAll();
        this._incrementalDisplayable = null;
        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._renderOnCartesianAndCalendar(seriesModel, api, params.start, params.end, true);
          }
        }
      };

      HeatmapView.prototype._renderOnCartesianAndCalendar = function (seriesModel, api, start, end, incremental) {
        var coordSys = seriesModel.coordinateSystem;
        var width;
        var height;
        var xAxisExtent;
        var yAxisExtent;

        if (isCoordinateSystemType(coordSys, 'cartesian2d')) {
          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');
            }
          }

          width = xAxis.getBandWidth();
          height = yAxis.getBandWidth();
          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 labelStatesModels = getLabelStatesModels(seriesModel);
        var focus = seriesModel.get(['emphasis', 'focus']);
        var blurScope = seriesModel.get(['emphasis', 'blurScope']);
        var dataDims = isCoordinateSystemType(coordSys, 'cartesian2d') ? [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 (isCoordinateSystemType(coordSys, 'cartesian2d')) {
            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)) || dataDimX < xAxisExtent[0] || dataDimX > xAxisExtent[1] || dataDimY < yAxisExtent[0] || dataDimY > yAxisExtent[1]) {
              continue;
            }

            var point = coordSys.dataToPoint([dataDimX, dataDimY]);
            rect = new Rect({
              shape: {
                x: Math.floor(Math.round(point[0]) - width / 2),
                y: Math.floor(Math.round(point[1]) - height / 2),
                width: Math.ceil(width),
                height: Math.ceil(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
            });
          }

          var itemModel = data.getItemModel(idx); // Optimization for large datset

          if (data.hasItemOption) {
            var emphasisModel = itemModel.getModel('emphasis');
            emphasisStyle = emphasisModel.getModel('itemStyle').getItemStyle();
            blurStyle = itemModel.getModel(['blur', 'itemStyle']).getItemStyle();
            selectStyle = itemModel.getModel(['select', 'itemStyle']).getItemStyle();
            focus = emphasisModel.get('focus');
            blurScope = emphasisModel.get('blurScope');
            labelStatesModels = getLabelStatesModels(itemModel);
          }

          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;
          enableHoverEmphasis(rect, focus, blurScope);
          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);
        }
      };

      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 createListFromArray(this.getSource(), 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 = itemModel.get('symbolOffset');

      if (isArray(symbolOffset)) {
        symbolOffset = [parsePercent$1(symbolOffset[0], symbolSize[0]), parsePercent$1(symbolOffset[1], symbolSize[1])];
      }

      prepareLayoutInfo(itemModel, symbolSize, layout, symbolRepeat, symbolClip, symbolOffset, symbolPosition, symbolMeta.valueLineWidth, symbolMeta.boundingLength, symbolMeta.repeatCutLength, opt, symbolMeta);
      return symbolMeta;
    } // bar length can be negative.


    function prepareBarLength(itemModel, symbolRepeat, layout, opt, 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];
      }

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

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

    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 : repeatTimes - 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
          }
        });
        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 pathes = [];
      eachPath(bar, function (path) {
        pathes.push(path);
      });
      bar.__pictorialMainPath && pathes.push(bar.__pictorialMainPath); // I do not find proper remove animation for clip yet.

      bar.__pictorialClipPath && (animationModel = null);
      each(pathes, 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
      });
      enableHoverEmphasis(bar, focus, blurScope);
    }

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

          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);
          enableHoverEmphasis(polygon, emphasisModel.get('focus'), emphasisModel.get('blurScope'));
        }

        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;
        _this.useColorPaletteOnData = true;
        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 gived
       * @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 dimensionsInfo = createDimensions(data, {
          coordDimensions: ['single'],
          dimensionsDefine: [{
            name: 'time',
            type: getDimensionTypeByAxis(axisType)
          }, {
            name: 'value',
            type: 'float'
          }, {
            name: 'name',
            type: 'ordinal'
          }],
          encodeDefine: {
            single: 0,
            value: 1,
            itemName: 2
          }
        });
        var list = new List(dimensionsInfo, 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,
        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);
        extend(sectorShape, cornerRadius);
        each(SPECIAL_STATES, function (stateName) {
          var state = sector.ensureState(stateName);
          var itemStyleModel = itemModel.getModel([stateName, 'itemStyle']);
          state.style = itemStyleModel.getItemStyle(); // border radius

          var cornerRadius = getSectorCornerRadius(itemStyleModel, sectorShape);

          if (cornerRadius) {
            state.shape = cornerRadius;
          }
        });

        if (firstCreate) {
          sector.setShape(sectorShape);
          sector.shape.r = layout.r0;
          updateProps(sector, {
            shape: {
              r: layout.r
            }
          }, seriesModel, node.dataIndex);
        } else {
          // Disable animation for gradient since no interpolation method
          // is supported for gradient
          updateProps(sector, {
            shape: sectorShape
          }, seriesModel);
        }

        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;
        enableHoverEmphasis(this, focusOrIndices, emphasisModel.get('blurScope'));
      };

      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') {
              r = (layout.r + layout.r0) / 2;
              textAlign = 'center';
            } else if (textAlign === 'left') {
              r = layout.r0 + labelPadding;

              if (midAngle > Math.PI / 2) {
                textAlign = 'right';
              }
            } else if (textAlign === 'right') {
              r = layout.r - labelPadding;

              if (midAngle > Math.PI / 2) {
                textAlign = 'left';
              }
            }
          }

          state.style.align = textAlign;
          state.style.verticalAlign = getLabelAttr(labelStateModel, 'verticalAlign') || 'middle';
          state.x = r * dx + layout.cx;
          state.y = r * dy + layout.cy;
          var rotateType = getLabelAttr(labelStateModel, 'rotate');
          var rotate = 0;

          if (rotateType === 'radial') {
            rotate = -midAngle;

            if (rotate < -Math.PI / 2) {
              rotate += Math.PI;
            }
          } else if (rotateType === 'tangential') {
            rotate = Math.PI / 2 - midAngle;

            if (rotate > Math.PI / 2) {
              rotate -= Math.PI;
            } else if (rotate < -Math.PI / 2) {
              rotate += Math.PI;
            }
          } else if (typeof rotateType === 'number') {
            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('highlight', 'sunburstHighlight');
        } // 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('downplay', 'sunburstUnhighlight');
        }

        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 = 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.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 outter
          // 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 canbe expansion, scale
        animationType: 'expansion',
        animationDuration: 1000,
        animationDurationUpdate: 500,
        data: [],
        levels: [],

        /**
         * 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 itemModel = node.getModel(); // @ts-ignore. TODO this is not provided to developer yet. Rename it.

            if (itemModel.get('r0') != null) {
              // @ts-ignore
              rStart = parsePercent$1(itemModel.get('r0'), size / 2);
            } // @ts-ignore


            if (itemModel.get('r') != null) {
              // @ts-ignore
              rEnd = parsePercent$1(itemModel.get('r'), 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 (typeof sortOrder === 'function') {
        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 && typeof color === 'string') {
          // 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);
    }

    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 wheter 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 retured.
     *         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);
        textContent = {
          type: 'text',
          style: textContentStyle,
          // ec4 do not support rectText trigger.
          // And when text postion is different in normal and emphasis
          // => hover text trigger emphasis;
          // => text position changed, leave mouse pointer immediately;
          // That might cause state incorrect.
          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 overwite 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 CMD$4 = PathProxy.CMD;
    var PI2$a = Math.PI * 2;
    var PROP_XY = ['x', 'y'];
    var PROP_WH = ['width', 'height'];
    var tmpArr$1 = [];
    function aroundEqual(a, b) {
        return Math.abs(a - b) < 1e-5;
    }
    function pathToBezierCurves(path) {
        var data = path.data;
        var len = path.len();
        var bezierArray = [];
        var currentSubpath;
        var xi = 0;
        var yi = 0;
        var x0 = 0;
        var y0 = 0;
        function createNewSubpath(x, y) {
            if (currentSubpath && currentSubpath.length > 2) {
                bezierArray.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) {
            bezierArray.push(currentSubpath);
        }
        return bezierArray;
    }
    function alignSubpath(subpath1, subpath2) {
        var len1 = subpath1.length;
        var len2 = subpath2.length;
        if (len1 === len2) {
            return [subpath1, subpath2];
        }
        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;
        var tmpSegX = [];
        var tmpSegY = [];
        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(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(fromSubpathBezier);
            var toCp = centroid(toSubpathBezier);
            if (fromNeedsReverse == null) {
                fromNeedsReverse = fromCp[2] < 0 !== toCp[2] < 0;
            }
            var newFromSubpathBezier = [];
            var newToSubpathBezier = [];
            var bestAngle = 0;
            var bestScore = Infinity;
            var tmpArr_1 = [];
            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_1[k] = newX1;
                        tmpArr_1[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_1.length; m++) {
                            newToSubpathBezier[m] = tmpArr_1[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 morphPath(fromPath, toPath, animationOpts) {
        var fromPathProxy;
        var toPathProxy;
        if (!fromPath || !toPath) {
            return toPath;
        }
        !fromPath.path && fromPath.createPathProxy();
        fromPathProxy = fromPath.path;
        fromPathProxy.beginPath();
        fromPath.buildPath(fromPathProxy, fromPath.shape);
        !toPath.path && toPath.createPathProxy();
        toPathProxy = toPath.path;
        toPathProxy === fromPathProxy && (toPathProxy = new PathProxy(false));
        toPathProxy.beginPath();
        if (isIndividualMorphingPath(toPath)) {
            toPath.__oldBuildPath(toPathProxy, toPath.shape);
        }
        else {
            toPath.buildPath(toPathProxy, toPath.shape);
        }
        var _a = alignBezierCurves(pathToBezierCurves(fromPathProxy), pathToBezierCurves(toPathProxy)), fromBezierCurves = _a[0], toBezierCurves = _a[1];
        var morphingData = findBestMorphingRotation(fromBezierCurves, toBezierCurves, 10, Math.PI);
        becomeIndividualMorphingPath(toPath, morphingData, 0);
        var oldDone = animationOpts && animationOpts.done;
        var oldAborted = animationOpts && animationOpts.aborted;
        var oldDuring = animationOpts && animationOpts.during;
        toPath.animateTo({
            __morphT: 1
        }, defaults({
            during: function (p) {
                toPath.dirtyShape();
                oldDuring && oldDuring(p);
            },
            done: function () {
                restoreIndividualMorphingPath(toPath);
                toPath.createPathProxy();
                toPath.dirtyShape();
                oldDone && oldDone();
            },
            aborted: function () {
                oldAborted && oldAborted();
            }
        }, animationOpts));
        return toPath;
    }
    function morphingPathBuildPath(path) {
        var morphingData = this.__morphingData;
        var t = this.__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 = from[m];
                var y0 = from[m + 1];
                var x1 = to[m];
                var y1 = to[m + 1];
                var x = x0 * onet + x1 * t;
                var y = y0 * onet + y1 * t;
                tmpArr$1[m] = (x * ca - y * sa) + newCp[0];
                tmpArr$1[m + 1] = (x * sa + y * ca) + newCp[1];
            }
            for (var m = 0; m < from.length;) {
                if (m === 0) {
                    path.moveTo(tmpArr$1[m++], tmpArr$1[m++]);
                }
                path.bezierCurveTo(tmpArr$1[m++], tmpArr$1[m++], tmpArr$1[m++], tmpArr$1[m++], tmpArr$1[m++], tmpArr$1[m++]);
            }
        }
    }
    function becomeIndividualMorphingPath(path, morphingData, morphT) {
        if (isIndividualMorphingPath(path)) {
            updateIndividualMorphingPath(path, morphingData, morphT);
            return;
        }
        var morphingPath = path;
        morphingPath.__oldBuildPath = morphingPath.buildPath;
        morphingPath.buildPath = morphingPathBuildPath;
        updateIndividualMorphingPath(morphingPath, morphingData, morphT);
    }
    function updateIndividualMorphingPath(morphingPath, morphingData, morphT) {
        morphingPath.__morphingData = morphingData;
        morphingPath.__morphT = morphT;
    }
    function restoreIndividualMorphingPath(path) {
        if (isIndividualMorphingPath(path)) {
            path.buildPath = path.__oldBuildPath;
            path.__oldBuildPath = path.__morphingData = null;
        }
    }
    function isIndividualMorphingPath(path) {
        return path.__oldBuildPath != null;
    }
    function isCombiningPath(path) {
        return !!path.__combiningSubList;
    }
    function isInAnyMorphing(path) {
        return isIndividualMorphingPath(path) || isCombiningPath(path);
    }
    function combine(fromPathList, toPath, animationOpts, copyPropsIfDivided) {
        var fromIndividuals = [];
        var separateCount = 0;
        for (var i = 0; i < fromPathList.length; i++) {
            var fromPath = fromPathList[i];
            if (isCombiningPath(fromPath)) {
                var fromCombiningSubList = fromPath.__combiningSubList;
                for (var j = 0; j < fromCombiningSubList.length; j++) {
                    fromIndividuals.push(fromCombiningSubList[j]);
                }
                separateCount += fromCombiningSubList.length;
            }
            else {
                fromIndividuals.push(fromPath);
                separateCount++;
            }
        }
        if (!separateCount) {
            return;
        }
        var dividingMethod = animationOpts ? animationOpts.dividingMethod : null;
        var toPathSplittedList = divideShape(toPath, separateCount, dividingMethod);
        assert(toPathSplittedList.length === separateCount);
        var oldDone = animationOpts && animationOpts.done;
        var oldAborted = animationOpts && animationOpts.aborted;
        var oldDuring = animationOpts && animationOpts.during;
        var doneCount = 0;
        var abortedCalled = false;
        var morphAnimationOpts = defaults({
            during: function (p) {
                oldDuring && oldDuring(p);
            },
            done: function () {
                doneCount++;
                if (doneCount === toPathSplittedList.length) {
                    restoreCombiningPath(toPath);
                    oldDone && oldDone();
                }
            },
            aborted: function () {
                if (!abortedCalled) {
                    abortedCalled = true;
                    oldAborted && oldAborted();
                }
            }
        }, animationOpts);
        for (var i = 0; i < separateCount; i++) {
            var from = fromIndividuals[i];
            var to = toPathSplittedList[i];
            copyPropsIfDivided && copyPropsIfDivided(toPath, to, true);
            morphPath(from, to, morphAnimationOpts);
        }
        becomeCombiningPath(toPath, toPathSplittedList);
        return {
            fromIndividuals: fromIndividuals,
            toIndividuals: toPathSplittedList,
            count: separateCount
        };
    }
    function becomeCombiningPath(path, combiningSubList) {
        if (isCombiningPath(path)) {
            updateCombiningPathSubList(path, combiningSubList);
            return;
        }
        var combiningPath = path;
        updateCombiningPathSubList(combiningPath, combiningSubList);
        combiningPath.__oldAddSelfToZr = path.addSelfToZr;
        combiningPath.__oldRemoveSelfFromZr = path.removeSelfFromZr;
        combiningPath.addSelfToZr = combiningAddSelfToZr;
        combiningPath.removeSelfFromZr = combiningRemoveSelfFromZr;
        combiningPath.__oldBuildPath = combiningPath.buildPath;
        combiningPath.buildPath = noop;
        combiningPath.childrenRef = combiningChildrenRef;
    }
    function restoreCombiningPath(path) {
        if (!isCombiningPath(path)) {
            return;
        }
        var combiningPath = path;
        updateCombiningPathSubList(combiningPath, null);
        combiningPath.addSelfToZr = combiningPath.__oldAddSelfToZr;
        combiningPath.removeSelfFromZr = combiningPath.__oldRemoveSelfFromZr;
        combiningPath.buildPath = combiningPath.__oldBuildPath;
        combiningPath.childrenRef =
            combiningPath.__combiningSubList =
                combiningPath.__oldAddSelfToZr =
                    combiningPath.__oldRemoveSelfFromZr =
                        combiningPath.__oldBuildPath = null;
    }
    function updateCombiningPathSubList(combiningPath, combiningSubList) {
        if (combiningPath.__combiningSubList !== combiningSubList) {
            combiningPathSubListAddRemoveWithZr(combiningPath, 'removeSelfFromZr');
            combiningPath.__combiningSubList = combiningSubList;
            if (combiningSubList) {
                for (var i = 0; i < combiningSubList.length; i++) {
                    combiningSubList[i].parent = combiningPath;
                }
            }
            combiningPathSubListAddRemoveWithZr(combiningPath, 'addSelfToZr');
        }
    }
    function combiningAddSelfToZr(zr) {
        this.__oldAddSelfToZr(zr);
        combiningPathSubListAddRemoveWithZr(this, 'addSelfToZr');
    }
    function combiningPathSubListAddRemoveWithZr(path, method) {
        var combiningSubList = path.__combiningSubList;
        var zr = path.__zr;
        if (combiningSubList && zr) {
            for (var i = 0; i < combiningSubList.length; i++) {
                var child = combiningSubList[i];
                child[method](zr);
            }
        }
    }
    function combiningRemoveSelfFromZr(zr) {
        this.__oldRemoveSelfFromZr(zr);
        var combiningSubList = this.__combiningSubList;
        for (var i = 0; i < combiningSubList.length; i++) {
            var child = combiningSubList[i];
            child.removeSelfFromZr(zr);
        }
    }
    function combiningChildrenRef() {
        return this.__combiningSubList;
    }
    function separate(fromPath, toPathList, animationOpts, copyPropsIfDivided) {
        var toPathListLen = toPathList.length;
        var fromPathList;
        var dividingMethod = animationOpts ? animationOpts.dividingMethod : null;
        var copyProps = false;
        if (isCombiningPath(fromPath)) {
            var fromCombiningSubList = fromPath.__combiningSubList;
            if (fromCombiningSubList.length === toPathListLen) {
                fromPathList = fromCombiningSubList;
            }
            else {
                fromPathList = divideShape(fromPath, toPathListLen, dividingMethod);
                copyProps = true;
            }
        }
        else {
            fromPathList = divideShape(fromPath, toPathListLen, dividingMethod);
            copyProps = true;
        }
        assert(fromPathList.length === toPathListLen);
        for (var i = 0; i < toPathListLen; i++) {
            if (copyProps && copyPropsIfDivided) {
                copyPropsIfDivided(fromPath, fromPathList[i], false);
            }
            morphPath(fromPathList[i], toPathList[i], animationOpts);
        }
        return {
            fromIndividuals: fromPathList,
            toIndividuals: toPathList,
            count: toPathListLen
        };
    }
    function divideShape(path, separateCount, dividingMethod) {
        return dividingMethod === 'duplicate'
            ? duplicateShape(path, separateCount)
            : splitShape(path, separateCount);
    }
    function splitShape(path, separateCount) {
        var resultPaths = [];
        if (separateCount <= 0) {
            return resultPaths;
        }
        if (separateCount === 1) {
            return duplicateShape(path, separateCount);
        }
        if (path instanceof Rect) {
            var toPathShape = path.shape;
            var splitPropIdx = toPathShape.height > toPathShape.width ? 1 : 0;
            var propWH = PROP_WH[splitPropIdx];
            var propXY = PROP_XY[splitPropIdx];
            var subWH = toPathShape[propWH] / separateCount;
            var xyCurr = toPathShape[propXY];
            for (var i = 0; i < separateCount; i++, xyCurr += subWH) {
                var subShape = {
                    x: toPathShape.x,
                    y: toPathShape.y,
                    width: toPathShape.width,
                    height: toPathShape.height
                };
                subShape[propXY] = xyCurr;
                subShape[propWH] = i < separateCount - 1
                    ? subWH
                    : toPathShape[propXY] + toPathShape[propWH] - xyCurr;
                var splitted = new Rect({ shape: subShape });
                resultPaths.push(splitted);
            }
        }
        else if (path instanceof Sector) {
            var toPathShape = path.shape;
            var clockwise = toPathShape.clockwise;
            var startAngle = toPathShape.startAngle;
            var endAngle = toPathShape.endAngle;
            var endAngleNormalized = normalizeRadian$1(startAngle, toPathShape.endAngle, clockwise);
            var step = (endAngleNormalized - startAngle) / separateCount;
            var angleCurr = startAngle;
            for (var i = 0; i < separateCount; i++, angleCurr += step) {
                var splitted = new Sector({
                    shape: {
                        cx: toPathShape.cx,
                        cy: toPathShape.cy,
                        r: toPathShape.r,
                        r0: toPathShape.r0,
                        clockwise: clockwise,
                        startAngle: angleCurr,
                        endAngle: i === separateCount - 1 ? endAngle : angleCurr + step
                    }
                });
                resultPaths.push(splitted);
            }
        }
        else {
            return duplicateShape(path, separateCount);
        }
        return resultPaths;
    }
    function duplicateShape(path, separateCount) {
        var resultPaths = [];
        if (separateCount <= 0) {
            return resultPaths;
        }
        var ctor = path.constructor;
        for (var i = 0; i < separateCount; i++) {
            var sub = new ctor({
                shape: clone(path.shape)
            });
            resultPaths.push(sub);
        }
        return resultPaths;
    }
    function normalizeRadian$1(start, end, clockwise) {
        return end + PI2$a * (Math[clockwise ? 'ceil' : 'floor']((start - end) / PI2$a));
    }

    var inner$9 = makeInner();
    var TRANSFORM_PROPS = {
      x: 1,
      y: 1,
      scaleX: 1,
      scaleY: 1,
      originX: 1,
      originY: 1,
      rotation: 1
    };
    var transformPropNamesStr = keys(TRANSFORM_PROPS).join(', ');
    // `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,
      legendSymbol: 1,
      visualMeta: 1,
      liftZ: 1,
      decal: 1
    };
    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']
    }; // 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: {}
    };
    var LEGACY_TRANSFORM_PROPS = {
      position: ['x', 'y'],
      scale: ['scaleX', 'scaleY'],
      origin: ['originX', 'originY']
    };
    var tmpTransformable = new Transformable();
    /**
     * 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,
      singleAxis: singlePrepareCustom,
      polar: polarPrepareCustom,
      calendar: calendarPrepareCustom
    };

    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 createListFromArray(this.getSource(), this);
      };

      CustomSeriesModel.prototype.getDataParams = function (dataIndex, dataType, el) {
        var params = _super.prototype.getDataParams.call(this, dataIndex, dataType);

        el && (params.info = inner$9(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);

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

      function CustomSeriesView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = CustomSeriesView.type;
        return _this;
      }

      CustomSeriesView.prototype.render = function (customSeries, ecModel, api, payload) {
        var oldData = this._data;
        var data = customSeries.getData();
        var group = this.group;
        var renderItem = makeRenderItem(customSeries, data, ecModel, api); // By default, merge mode is applied. In most cases, custom series is
        // used in the scenario that data amount is not large but graphic elements
        // is complicated, where merge mode is probably necessary for optimization.
        // For example, reuse graphic elements and only update the transform when
        // roam or data zoom according to `actionType`.

        var transOpt = customSeries.__transientTransitionOpt; // Enable user to disable transition animation by both set
        // `from` and `to` dimension as `null`/`undefined`.

        if (transOpt && (transOpt.from == null || transOpt.to == null)) {
          oldData && oldData.each(function (oldIdx) {
            doRemoveEl(oldData.getItemGraphicEl(oldIdx), customSeries, group);
          });
          data.each(function (newIdx) {
            createOrUpdateItem(api, null, newIdx, renderItem(newIdx, payload), customSeries, group, data, null);
          });
        } else {
          var morphPreparation_1 = new MorphPreparation(customSeries, transOpt);
          var diffMode = transOpt ? 'multiple' : 'oneToOne';
          new DataDiffer(oldData ? oldData.getIndices() : [], data.getIndices(), createGetKey(oldData, diffMode, transOpt && transOpt.from), createGetKey(data, diffMode, transOpt && transOpt.to), null, diffMode).add(function (newIdx) {
            createOrUpdateItem(api, null, newIdx, renderItem(newIdx, payload), customSeries, group, data, null);
          }).remove(function (oldIdx) {
            doRemoveEl(oldData.getItemGraphicEl(oldIdx), customSeries, group);
          }).update(function (newIdx, oldIdx) {
            morphPreparation_1.reset('oneToOne');
            var oldEl = oldData.getItemGraphicEl(oldIdx);
            morphPreparation_1.findAndAddFrom(oldEl); // PENDING:
            // if may morph, currently we alway recreate the whole el.
            // because if reuse some of the el in the group tree, the old el has to
            // be removed from the group, and consequently we can not calculate
            // the "global transition" of the old element.
            // But is there performance issue?

            if (morphPreparation_1.hasFrom()) {
              removeElementDirectly(oldEl, group);
              oldEl = null;
            }

            createOrUpdateItem(api, oldEl, newIdx, renderItem(newIdx, payload), customSeries, group, data, morphPreparation_1);
            morphPreparation_1.applyMorphing();
          }).updateManyToOne(function (newIdx, oldIndices) {
            morphPreparation_1.reset('manyToOne');

            for (var i = 0; i < oldIndices.length; i++) {
              var oldEl = oldData.getItemGraphicEl(oldIndices[i]);
              morphPreparation_1.findAndAddFrom(oldEl);
              removeElementDirectly(oldEl, group);
            }

            createOrUpdateItem(api, null, newIdx, renderItem(newIdx, payload), customSeries, group, data, morphPreparation_1);
            morphPreparation_1.applyMorphing();
          }).updateOneToMany(function (newIndices, oldIdx) {
            morphPreparation_1.reset('oneToMany');
            var newLen = newIndices.length;
            var oldEl = oldData.getItemGraphicEl(oldIdx);
            morphPreparation_1.findAndAddFrom(oldEl);
            removeElementDirectly(oldEl, group);

            for (var i = 0; i < newLen; i++) {
              createOrUpdateItem(api, null, newIndices[i], renderItem(newIndices[i], payload), customSeries, group, data, morphPreparation_1);
            }

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

      CustomSeriesView.prototype.incrementalPrepareRender = function (customSeries, ecModel, api) {
        this.group.removeAll();
        this._data = null;
      };

      CustomSeriesView.prototype.incrementalRender = function (params, customSeries, ecModel, api, payload) {
        var data = customSeries.getData();
        var renderItem = makeRenderItem(customSeries, data, ecModel, api);

        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, null);
          el.traverse(setIncrementalAndHoverLayer);
        }
      };

      CustomSeriesView.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 triggerd by its descendents.


        while ((targetEl = targetEl.__hostTarget || targetEl.parent) && targetEl !== this.group) {
          if (targetEl.name === elementName) {
            return true;
          }
        }

        return false;
      };

      CustomSeriesView.type = 'custom';
      return CustomSeriesView;
    }(ChartView);

    function createGetKey(data, diffMode, dimension) {
      if (!data) {
        return;
      }

      if (diffMode === 'oneToOne') {
        return function (rawIdx, dataIndex) {
          return data.getId(dataIndex);
        };
      }

      var diffByDimName = data.getDimension(dimension);
      var dimInfo = data.getDimensionInfo(diffByDimName);

      if (!dimInfo) {
        var errMsg = '';

        if ("development" !== 'production') {
          errMsg = dimension + " is not a valid dimension.";
        }

        throwError(errMsg);
      }

      var ordinalMeta = dimInfo.ordinalMeta;
      return function (rawIdx, dataIndex) {
        var key = data.get(diffByDimName, dataIndex);

        if (ordinalMeta) {
          key = ordinalMeta.categories[key];
        }

        return key == null || eqNaN(key) ? rawIdx + '' : '_ec_' + key;
      };
    }

    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');
        inner$9(el).customPathData = pathData;
      } else if (graphicType === 'image') {
        el = new ZRImage({});
        inner$9(el).customImagePath = elOption.style.image;
      } else if (graphicType === 'text') {
        el = new ZRText({}); // inner(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();
      }

      inner$9(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;
    }
    /**
     * ----------------------------------------------------------
     * [STRATEGY_MERGE] Merge properties or erase all properties:
     *
     * Based on the fact that the existing zr element probably be reused, we now consider whether
     * merge or erase all properties to the exsiting elements.
     * That is, if a certain props is not specified in the lastest return of `renderItem`:
     * + "Merge" means that do not modify the value on the existing element.
     * + "Erase all" means that use a default value to the existing element.
     *
     * "Merge" might bring some unexpected state retaining for users and "erase all" seams to be
     * more safe. "erase all" force users to specify all of the props each time, which is recommanded
     * in most cases.
     * But "erase all" theoretically disables the chance of performance optimization (e.g., just
     * generete shape and style at the first time rather than always do that).
     * So we still use "merge" rather than "erase all". If users need "erase all", they can
     * simple always set all of the props each time.
     * Some "object-like" config like `textConfig`, `textContent`, `style` which are not needed for
     * every elment, so we replace them only when user specify them. And the that is a total replace.
     *
     * TODO: there is no hint of 'isFirst' to users. So the performance enhancement can not be
     * performed yet. Consider the case:
     * (1) setOption to "mergeChildren" with a smaller children count
     * (2) Use dataZoom to make an item disappear.
     * (3) User dataZoom to make the item display again. At that time, renderItem need to return the
     * full option rather than partial option to recreate the element.
     *
     * ----------------------------------------------
     * [STRATEGY_NULL] `hasOwnProperty` or `== null`:
     *
     * Ditinguishing "own property" probably bring little trouble to user when make el options.
     * So we  trade a {xx: null} or {xx: undefined} as "not specified" if possible rather than
     * "set them to null/undefined". In most cases, props can not be cleared. Some typicall
     * clearable props like `style`/`textConfig`/`textContent` we enable `false` to means
     * "clear". In some othere special cases that the prop is able to set as null/undefined,
     * but not suitable to use `false`, `hasOwnProperty` is checked.
     *
     * ---------------------------------------------
     * [STRATEGY_TRANSITION] The rule of transition:
     * + For props on the root level of a element:
     *      If there is no `transition` specified, tansform props will be transitioned by default,
     *      which is the same as the previous setting in echarts4 and suitable for the scenario
     *      of dataZoom change.
     *      If `transition` specified, only the specified props will be transitioned.
     * + For props in `shape` and `style`:
     *      Only props specified in `transition` will be transitioned.
     * + Break:
     *      Since ec5, do not make transition to shape by default, because it might result in
     *      performance issue (especially `points` of polygon) and do not necessary in most cases.
     *
     * @return if `isMorphTo`, return `allPropsFinal`.
     */


    function updateElNormal( // Can be null/undefined
    api, el, // Whether be a morph target.
    isMorphTo, dataIndex, elOption, styleOpt, attachedTxInfo, seriesModel, isInit, isTextContent) {
      var transFromProps = {};
      var allPropsFinal = {};
      var elDisplayable = el.isGroup ? null : el; // If be "morph to", delay the `updateElNormal` when all of the els in
      // this data item processed. Because at that time we can get all of the
      // "morph from" and make correct separate/combine.

      !isMorphTo && prepareShapeOrExtraTransitionFrom('shape', el, null, elOption, transFromProps, isInit);
      prepareShapeOrExtraAllPropsFinal('shape', elOption, allPropsFinal);
      !isMorphTo && prepareShapeOrExtraTransitionFrom('extra', el, null, elOption, transFromProps, isInit);
      prepareShapeOrExtraAllPropsFinal('extra', elOption, allPropsFinal);
      !isMorphTo && prepareTransformTransitionFrom(el, null, elOption, transFromProps, isInit);
      prepareTransformAllPropsFinal(elOption, allPropsFinal);
      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);
      }

      if (el.type === 'text' && styleOpt) {
        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);
      }

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

      !isMorphTo && prepareStyleTransitionFrom(el, null, elOption, styleOpt, transFromProps, isInit);

      if (elDisplayable) {
        hasOwn(elOption, 'invisible') && (elDisplayable.invisible = elOption.invisible);
      } // If `isMorphTo`, we should not update these props to el directly, otherwise,
      // when applying morph finally, the original prop are missing for making "animation from".


      if (!isMorphTo) {
        applyPropsFinal(el, allPropsFinal, styleOpt);
        applyTransitionFrom(el, dataIndex, elOption, seriesModel, transFromProps, isInit);
      } // Merge by default.


      hasOwn(elOption, 'silent') && (el.silent = elOption.silent);
      hasOwn(elOption, 'ignore') && (el.ignore = elOption.ignore);

      if (!isTextContent) {
        // `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') && (inner$9(el).info = elOption.info);
      }

      styleOpt ? el.dirty() : el.markRedraw();
      return isMorphTo ? allPropsFinal : null;
    }

    function applyPropsFinal(el, // Can be null/undefined
    allPropsFinal, styleOpt) {
      var elDisplayable = el.isGroup ? null : el;

      if (elDisplayable && styleOpt) {
        var decalPattern = styleOpt.__decalPattern;
        var originalDecalObj = void 0;

        if (decalPattern) {
          originalDecalObj = styleOpt.decal;
          styleOpt.decal = decalPattern;
        } // PENDING: here the input style object is used directly.
        // Good for performance but bad for compatibility control.


        elDisplayable.useStyle(styleOpt);

        if (decalPattern) {
          styleOpt.decal = originalDecalObj;
        } // When style object changed, how to trade the existing animation?
        // It is probably conplicated 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 mousewhell. 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 = elDisplayable.animators;

        for (var i = 0; i < animators.length; i++) {
          var animator = animators[i]; // targetName is the "topKey".

          if (animator.targetName === 'style') {
            animator.changeTarget(elDisplayable.style);
          }
        }
      } // Set el to the final state firstly.


      allPropsFinal && el.attr(allPropsFinal);
    }

    function applyTransitionFrom(el, dataIndex, elOption, seriesModel, // Can be null/undefined
    transFromProps, isInit) {
      if (transFromProps) {
        // Do not use `el.updateDuringAnimation` here becuase `el.updateDuringAnimation` will
        // be called mutiple time in each animation frame. For example, if both "transform" props
        // and shape props and style props changed, it will generate three animator and called
        // one-by-one in each animation frame.
        // We use the during in `animateTo/From` params.
        var userDuring = elOption.during; // For simplicity, if during not specified, the previous during will not work any more.

        inner$9(el).userDuring = userDuring;
        var cfgDuringCall = userDuring ? bind(duringCall, {
          el: el,
          userDuring: userDuring
        }) : null;
        var cfg = {
          dataIndex: dataIndex,
          isFrom: true,
          during: cfgDuringCall
        };
        isInit ? initProps(el, transFromProps, seriesModel, cfg) : updateProps(el, transFromProps, seriesModel, cfg);
      }
    } // See [STRATEGY_TRANSITION]


    function prepareShapeOrExtraTransitionFrom(mainAttr, el, morphFromEl, elOption, transFromProps, isInit) {
      var attrOpt = elOption[mainAttr];

      if (!attrOpt) {
        return;
      }

      var elPropsInAttr = el[mainAttr];
      var transFromPropsInAttr;
      var enterFrom = attrOpt.enterFrom;

      if (isInit && enterFrom) {
        !transFromPropsInAttr && (transFromPropsInAttr = transFromProps[mainAttr] = {});
        var enterFromKeys = keys(enterFrom);

        for (var i = 0; i < enterFromKeys.length; i++) {
          // `enterFrom` props are not necessarily also declared in `shape`/`style`/...,
          // for example, `opacity` can only declared in `enterFrom` but not in `style`.
          var key = enterFromKeys[i]; // Do not clone, animator will perform that clone.

          transFromPropsInAttr[key] = enterFrom[key];
        }
      }

      if (!isInit && elPropsInAttr // Just ignore shape animation in morphing.
      && !(morphFromEl != null && mainAttr === 'shape')) {
        if (attrOpt.transition) {
          !transFromPropsInAttr && (transFromPropsInAttr = transFromProps[mainAttr] = {});
          var transitionKeys = normalizeToArray(attrOpt.transition);

          for (var i = 0; i < transitionKeys.length; i++) {
            var key = transitionKeys[i];
            var elVal = elPropsInAttr[key];

            if ("development" !== 'production') {
              checkNonStyleTansitionRefer(key, attrOpt[key], elVal);
            } // Do not clone, see `checkNonStyleTansitionRefer`.


            transFromPropsInAttr[key] = elVal;
          }
        } else if (indexOf(elOption.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;
            }
          }
        }
      }

      var leaveTo = attrOpt.leaveTo;

      if (leaveTo) {
        var leaveToProps = getOrCreateLeaveToPropsFromEl(el);
        var leaveToPropsInAttr = leaveToProps[mainAttr] || (leaveToProps[mainAttr] = {});
        var leaveToKeys = keys(leaveTo);

        for (var i = 0; i < leaveToKeys.length; i++) {
          var key = leaveToKeys[i];
          leaveToPropsInAttr[key] = leaveTo[key];
        }
      }
    }

    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]);
      }
    } // See [STRATEGY_TRANSITION].


    function prepareTransformTransitionFrom(el, morphFromEl, elOption, transFromProps, isInit) {
      var enterFrom = elOption.enterFrom;

      if (isInit && enterFrom) {
        var enterFromKeys = keys(enterFrom);

        for (var i = 0; i < enterFromKeys.length; i++) {
          var key = enterFromKeys[i];

          if ("development" !== 'production') {
            checkTransformPropRefer(key, 'el.enterFrom');
          } // Do not clone, animator will perform that clone.


          transFromProps[key] = enterFrom[key];
        }
      }

      if (!isInit) {
        // If morphing, force transition all transform props.
        // otherwise might have incorrect morphing animation.
        if (morphFromEl) {
          var fromTransformable = calcOldElLocalTransformBasedOnNewElParent(morphFromEl, el);
          setTransformPropToTransitionFrom(transFromProps, 'x', fromTransformable);
          setTransformPropToTransitionFrom(transFromProps, 'y', fromTransformable);
          setTransformPropToTransitionFrom(transFromProps, 'scaleX', fromTransformable);
          setTransformPropToTransitionFrom(transFromProps, 'scaleY', fromTransformable);
          setTransformPropToTransitionFrom(transFromProps, 'originX', fromTransformable);
          setTransformPropToTransitionFrom(transFromProps, 'originY', fromTransformable);
          setTransformPropToTransitionFrom(transFromProps, 'rotation', fromTransformable);
        } else if (elOption.transition) {
          var transitionKeys = normalizeToArray(elOption.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');
              checkNonStyleTansitionRefer(key, elOption[key], elVal);
            } // Do not clone, see `checkNonStyleTansitionRefer`.


            transFromProps[key] = elVal;
          }
        } // This default transition see [STRATEGY_TRANSITION]
        else {
            setTransformPropToTransitionFrom(transFromProps, 'x', el);
            setTransformPropToTransitionFrom(transFromProps, 'y', el);
          }
      }

      var leaveTo = elOption.leaveTo;

      if (leaveTo) {
        var leaveToProps = getOrCreateLeaveToPropsFromEl(el);
        var leaveToKeys = keys(leaveTo);

        for (var i = 0; i < leaveToKeys.length; i++) {
          var key = leaveToKeys[i];

          if ("development" !== 'production') {
            checkTransformPropRefer(key, 'el.leaveTo');
          }

          leaveToProps[key] = leaveTo[key];
        }
      }
    }

    function prepareTransformAllPropsFinal(elOption, allProps) {
      setLagecyTransformProp(elOption, allProps, 'position');
      setLagecyTransformProp(elOption, allProps, 'scale');
      setLagecyTransformProp(elOption, allProps, 'origin');
      setTransformProp(elOption, allProps, 'x');
      setTransformProp(elOption, allProps, 'y');
      setTransformProp(elOption, allProps, 'scaleX');
      setTransformProp(elOption, allProps, 'scaleY');
      setTransformProp(elOption, allProps, 'originX');
      setTransformProp(elOption, allProps, 'originY');
      setTransformProp(elOption, allProps, 'rotation');
    } // See [STRATEGY_TRANSITION].


    function prepareStyleTransitionFrom(el, morphFromEl, elOption, styleOpt, transFromProps, isInit) {
      if (!styleOpt) {
        return;
      } // At present in "many-to-one"/"one-to-many" case, to not support "many" have
      // different styles and make style transitions. That might be a rare case.


      var fromEl = morphFromEl || el;
      var fromElStyle = fromEl.style;
      var transFromStyleProps;
      var enterFrom = styleOpt.enterFrom;

      if (isInit && enterFrom) {
        var enterFromKeys = keys(enterFrom);
        !transFromStyleProps && (transFromStyleProps = transFromProps.style = {});

        for (var i = 0; i < enterFromKeys.length; i++) {
          var key = enterFromKeys[i]; // Do not clone, animator will perform that clone.

          transFromStyleProps[key] = enterFrom[key];
        }
      }

      if (!isInit && fromElStyle) {
        if (styleOpt.transition) {
          var transitionKeys = normalizeToArray(styleOpt.transition);
          !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 (el.getAnimationStyleProps && indexOf(elOption.transition, 'style') >= 0) {
          var animationProps = el.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;
              }
            }
          }
        }
      }

      var leaveTo = styleOpt.leaveTo;

      if (leaveTo) {
        var leaveToKeys = keys(leaveTo);
        var leaveToProps = getOrCreateLeaveToPropsFromEl(el);
        var leaveToStyleProps = leaveToProps.style || (leaveToProps.style = {});

        for (var i = 0; i < leaveToKeys.length; i++) {
          var key = leaveToKeys[i];
          leaveToStyleProps[key] = leaveTo[key];
        }
      }
    }
    /**
     * If make "transform"(x/y/scaleX/scaleY/orient/originX/originY) transition between
     * two path elements that have different hierarchy, before we retrieve the "from" props,
     * we have to calculate the local transition of the "oldPath" based on the parent of
     * the "newPath".
     * At present, the case only happend in "morphing". Without morphing, the transform
     * transition are all between elements in the same hierarchy, where this kind of process
     * is not needed.
     *
     * [CAVEAT]:
     * This method makes sense only if: (very tricky)
     * (1) "newEl" has been added to its final parent.
     * (2) Local transform props of "newPath.parent" are not at their final value but already
     * have been at the "from value".
     *     This is currently ensured by:
     *     (2.1) "graphicUtil.animationFrom", which will set the element to the "from value"
     *     immediately.
     *     (2.2) "morph" option is not allowed to be set on Group, so all of the groups have
     *     been finished their "updateElNormal" when calling this method in morphing process.
     */


    function calcOldElLocalTransformBasedOnNewElParent(oldEl, newEl) {
      if (!oldEl || oldEl === newEl || oldEl.parent === newEl.parent) {
        return oldEl;
      } // Not sure oldEl is rendered (may have "lazyUpdate"),
      // so always call `getComputedTransform`.


      var tmpM = tmpTransformable.transform || (tmpTransformable.transform = identity([]));
      var oldGlobalTransform = oldEl.getComputedTransform();
      oldGlobalTransform ? copy$1(tmpM, oldGlobalTransform) : identity(tmpM);
      var newParent = newEl.parent;

      if (newParent) {
        newParent.getComputedTransform();
      }

      tmpTransformable.originX = oldEl.originX;
      tmpTransformable.originY = oldEl.originY;
      tmpTransformable.parent = newParent;
      tmpTransformable.decomposeTransform();
      return tmpTransformable;
    }

    var checkNonStyleTansitionRefer;

    if ("development" !== 'production') {
      checkNonStyleTansitionRefer = function (propName, optVal, elVal) {
        if (!isArrayLike(optVal)) {
          assert(optVal != null && isFinite(optVal), 'Prop `' + propName + '` must refer to a finite number or ArrayLike for transition.');
        } else {
          // Try not to copy array for performance, but if user use the same object in different
          // call of `renderItem`, it will casue animation transition fail.
          assert(optVal !== elVal, 'Prop `' + propName + '` must use different Array object each time for transition.');
        }
      };
    }

    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) {
        assert(hasOwn(TRANSFORM_PROPS, key), 'Prop `' + key + '` is not a permitted in `' + usedIn + '`. ' + 'Only `' + keys(TRANSFORM_PROPS).join('`, `') + '` are permitted.');
      };
    }

    function getOrCreateLeaveToPropsFromEl(el) {
      var innerEl = inner$9(el);
      return innerEl.leaveToProps || (innerEl.leaveToProps = {});
    } // Use it to avoid it be exposed to user.


    var tmpDuringScope = {};
    var customDuringAPI = {
      // Usually other props do not need to be changed in animation during.
      setTransform: function (key, val) {
        if ("development" !== 'production') {
          assert(hasOwn(TRANSFORM_PROPS, key), 'Only ' + transformPropNamesStr + ' available in `setTransform`.');
        }

        tmpDuringScope.el[key] = val;
        return this;
      },
      getTransform: function (key) {
        if ("development" !== 'production') {
          assert(hasOwn(TRANSFORM_PROPS, key), 'Only ' + transformPropNamesStr + ' available in `getTransform`.');
        }

        return tmpDuringScope.el[key];
      },
      setShape: function (key, val) {
        if ("development" !== 'production') {
          assertNotReserved(key);
        }

        var shape = tmpDuringScope.el.shape || (tmpDuringScope.el.shape = {});
        shape[key] = val;
        tmpDuringScope.isShapeDirty = true;
        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 style = tmpDuringScope.el.style;

        if (style) {
          if ("development" !== 'production') {
            if (eqNaN(val)) {
              warn('style.' + key + ' must not be assigned with NaN.');
            }
          }

          style[key] = val;
          tmpDuringScope.isStyleDirty = true;
        }

        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,
      // becuase el will be added back to zr and the prop value should not be incorrect.


      var newstUserDuring = inner$9(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' calulation 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 (newstUserDuring !== scopeUserDuring) {
        // release
        scope.el = scope.userDuring = null;
        return;
      }

      tmpDuringScope.el = el;
      tmpDuringScope.isShapeDirty = false;
      tmpDuringScope.isStyleDirty = false; // Give no `this` to user in "during" calling.

      scopeUserDuring(customDuringAPI);

      if (tmpDuringScope.isShapeDirty && el.dirtyShape) {
        el.dirtyShape();
      }

      if (tmpDuringScope.isStyleDirty && el.dirtyStyle) {
        el.dirtyStyle();
      } // markRedraw() will be called by default in during.
      // FIXME `this.markRedraw();` directly ?
      // 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 updateElOnState(state, el, elStateOpt, styleOpt, attachedTxInfo, isRoot, isTextContent) {
      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 defaut 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, attachedTxInfo) {
      // 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 setLagecyTransformProp(elOption, targetProps, legacyName, fromTransformable // If provided, retrieve from the element.
    ) {
      var legacyArr = elOption[legacyName];
      var xyName = LEGACY_TRANSFORM_PROPS[legacyName];

      if (legacyArr) {
        if (fromTransformable) {
          targetProps[xyName[0]] = fromTransformable[xyName[0]];
          targetProps[xyName[1]] = fromTransformable[xyName[1]];
        } else {
          targetProps[xyName[0]] = legacyArr[0];
          targetProps[xyName[1]] = legacyArr[1];
        }
      }
    }

    function setTransformProp(elOption, allProps, name, fromTransformable // If provided, retrieve from the element.
    ) {
      if (elOption[name] != null) {
        allProps[name] = fromTransformable ? fromTransformable[name] : elOption[name];
      }
    }

    function setTransformPropToTransitionFrom(transitionFrom, name, fromTransformable // If provided, retrieve from the element.
    ) {
      if (fromTransformable) {
        transitionFrom[name] = fromTransformable[name];
      }
    }

    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.get(data.getDimension(dim || 0), dataIndexInside);
      }
      /**
       * @public
       * @param dim by default 0.
       * @param dataIndexInside by default `currDataIndexInside`.
       */


      function ordinalRawValue(dim, dataIndexInside) {
        dataIndexInside == null && (dataIndexInside = currDataIndexInside);
        var dimInfo = data.getDimensionInfo(dim || 0);

        if (!dimInfo) {
          return;
        }

        var val = data.get(dimInfo.name, dataIndexInside);
        var ordinalMeta = dimInfo && dimInfo.ordinalMeta;
        return ordinalMeta ? ordinalMeta.categories[val] : val;
      }
      /**
       * @deprecated The orgininal intention of `api.style` is enable to set itemStyle
       * like other series. But it not necessary and not easy to give a strict definition
       * of what it return. 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 feture 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, dataDimIndex) {
        var dimInfo = data.getDimensionInfo(dimName);

        if (!dimInfo.isExtraCoord) {
          var coordDim = dimInfo.coordDim;
          var dataDims = encodeDef[coordDim] = encodeDef[coordDim] || [];
          dataDims[dimInfo.coordDimIndex] = dataDimIndex;
        }
      });
      return encodeDef;
    }

    function createOrUpdateItem(api, el, dataIndex, elOption, seriesModel, group, data, morphPreparation) {
      // [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) {
        removeElementDirectly(el, group);
        return;
      }

      el = doCreateOrUpdateEl(api, el, dataIndex, elOption, seriesModel, group, true, morphPreparation);
      el && data.setItemGraphicEl(dataIndex, el);
      enableHoverEmphasis(el, elOption.focus, elOption.blurScope);
      return el;
    }

    function doCreateOrUpdateEl(api, el, dataIndex, elOption, seriesModel, group, isRoot, morphPreparation) {
      if ("development" !== 'production') {
        assert(elOption, 'should not have an null/undefined element setting');
      }

      var toBeReplacedIdx = -1;

      if (el && doesElNeedRecreate(el, elOption) // || (
      //     // 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.
      //     morphPreparation && morphPreparation.isOneToOneFrom(el)
      // )
      ) {
        // Should keep at the original index, otherwise "merge by index" will be incorrect.
        toBeReplacedIdx = group.childrenRef().indexOf(el);
        el = null;
      }

      var elIsNewCreated = !el;

      if (!el) {
        el = createEl(elOption);
      } 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();
      }

      var canMorph = inner$9(el).canMorph = elOption.morph && isPath$1(el);
      var thisElIsMorphTo = canMorph && morphPreparation && morphPreparation.hasFrom(); // Use update animation when morph is enabled.

      var isInit = elIsNewCreated && !thisElIsMorphTo;
      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);
      var pendingAllPropsFinal = updateElNormal(api, el, thisElIsMorphTo, dataIndex, elOption, elOption.style, attachedTxInfoTmp, seriesModel, isInit, false);

      if (thisElIsMorphTo) {
        morphPreparation.addTo(el, elOption, dataIndex, pendingAllPropsFinal);
      }

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

      if (toBeReplacedIdx >= 0) {
        group.replaceAt(el, toBeReplacedIdx);
      } else {
        group.add(el);
      }

      return el;
    } // `el` must not be null/undefined.


    function doesElNeedRecreate(el, elOption) {
      var elInner = inner$9(el);
      var elOptionType = elOption.type;
      var elOptionShape = elOption.shape;
      var elOptionStyle = elOption.style;
      return (// 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)) {
          clipPath = null;
        }

        if (!clipPath) {
          clipPath = createEl(clipPathOpt);

          if ("development" !== 'production') {
            assert(clipPath instanceof Path, 'Only any type of `path` can be used in `clipPath`, rather than ' + clipPath.type + '.');
          }

          el.setClipPath(clipPath);
        }

        updateElNormal(null, clipPath, null, dataIndex, clipPathOpt, null, null, seriesModel, isInit, false);
      } // If not define `clipPath` in option, do nothing unnecessary.

    }

    function doCreateOrUpdateAttachedTx(el, dataIndex, elOption, seriesModel, isInit, attachedTxInfo) {
      // group do not support textContent temporarily untill 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 sence.
      // 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();
          }

          var txConStlOptNormal = txConOptNormal && txConOptNormal.style;
          updateElNormal(null, textContent, null, dataIndex, txConOptNormal, txConStlOptNormal, null, seriesModel, isInit, true);

          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 incorret type for forward compat.
          txConOptNormal_1.type !== 'text' && 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.
    //
    // For implementation simpleness, do not provide a direct way to remove sinlge
    // child (otherwise the total indicies of the children array have to be modified).
    // User can remove a single child by set its `ignore` as `true`.


    function mergeChildren(api, el, dataIndex, elOption, seriesModel, morphPreparation) {
      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,
          morphPreparation: morphPreparation
        });
        return;
      }

      notMerge && el.removeAll(); // Mapping children of a group simply by index, which
      // might be better performance.

      var index = 0;

      for (; index < newLen; index++) {
        newChildren[index] && doCreateOrUpdateEl(api, el.childAt(index), dataIndex, newChildren[index], seriesModel, el, false, morphPreparation);
      }

      for (var i = el.childCount() - 1; i >= index; i--) {
        // Do not supprot leave elements that are not mentioned in the latest
        // `renderItem` return. Otherwise users may not have a clear and simple
        // concept that how to contorl all of the elements.
        doRemoveEl(el.childAt(i), seriesModel, el);
      }
    }

    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, false, context.morphPreparation);
    }

    function processRemove(oldIndex) {
      var context = this.context;
      var child = context.oldChildren[oldIndex];
      doRemoveEl(child, context.seriesModel, context.group);
    }

    function doRemoveEl(el, seriesModel, group) {
      if (el) {
        var leaveToProps = inner$9(el).leaveToProps;
        leaveToProps ? updateProps(el, leaveToProps, seriesModel, {
          cb: function () {
            group.remove(el);
          }
        }) : group.remove(el);
      }
    }
    /**
     * @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 isPath$1(el) {
      return el && el instanceof Path;
    }

    function removeElementDirectly(el, group) {
      el && group.remove(el);
    }
    /**
     * Any morph-potential el should added by `morphPreparation.addTo(el)`.
     * And they may apply morph or not when `morphPreparation.applyMorphing()`.
     * But at least, all of the "to" elements will apply all of the updates
     * as `doCreateOrUpdateItem` did.
     */


    var MorphPreparation =
    /** @class */
    function () {
      function MorphPreparation(seriesModel, transOpt) {
        this._fromList = [];
        this._toList = [];
        this._toElOptionList = [];
        this._allPropsFinalList = [];
        this._toDataIndices = []; // Key: `toDataIndex`, not `toIdx`

        this._morphConfigList = [];
        this._seriesModel = seriesModel;
        this._transOpt = transOpt;
      }

      MorphPreparation.prototype.hasFrom = function () {
        return !!this._fromList.length;
      }; // isOneToOneFrom(el: Element): boolean {
      //     if (el && inner(el).canMorph) {
      //         const fromList = this._fromList;
      //         for (let i = 0; i < fromList.length; i++) {
      //             if (fromList[i] === el) {
      //                 return true;
      //             }
      //         }
      //     }
      // }


      MorphPreparation.prototype.findAndAddFrom = function (el) {
        if (!el) {
          return;
        }

        if (inner$9(el).canMorph) {
          this._fromList.push(el);
        }

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

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

      MorphPreparation.prototype.addTo = function (path, elOption, dataIndex, allPropsFinal) {
        if (path) {
          this._toList.push(path);

          this._toElOptionList.push(elOption);

          this._toDataIndices.push(dataIndex);

          this._allPropsFinalList.push(allPropsFinal);
        }
      };

      MorphPreparation.prototype.applyMorphing = function () {
        // [MORPHING_LOGIC_HINT]
        // Pay attention to the order:
        // (A) Apply `allPropsFinal` and `styleOption` to "to".
        //     (Then "to" becomes to the final state.)
        // (B) Apply `morphPath`/`combine`/`separate`.
        //     (Based on the current state of "from" and the final state of "to".)
        //     (Then we may get "from.subList" or "to.subList".)
        // (C) Copy the related props from "from" to "from.subList", from "to" to "to.subList".
        // (D) Collect `transitionFromProps` for "to" and "to.subList"
        //     (Based on "from" or "from.subList".)
        // (E) Apply `transitionFromProps` to "to" and "to.subList"
        //     (It might change the prop values to the first frame value.)
        // Case_I:
        //     If (D) should be after (C), we use sequence: A - B - C - D - E
        // Case_II:
        //     If (A) should be after (D), we use sequence: D - A - B - C - E
        // [MORPHING_LOGIC_HINT]
        // zrender `morphPath`/`combine`/`separate` only manages the shape animation.
        // Other props (like transfrom, style transition) will handled in echarts).
        // [MORPHING_LOGIC_HINT]
        // Make sure `applyPropsFinal` always be called for "to".
        var type = this._type;
        var fromList = this._fromList;
        var toList = this._toList;
        var toListLen = toList.length;
        var fromListLen = fromList.length;

        if (!fromListLen || !toListLen) {
          return;
        }

        if (type === 'oneToOne') {
          // In one-to-one case, we by default apply a simple rule:
          // map "from" and "to" one by one.
          // For this case: old_data_item_el and new_data_item_el
          // has the same hierarchy of group tree but only some path type changed.
          for (var toIdx = 0; toIdx < toListLen; toIdx++) {
            this._oneToOneForSingleTo(toIdx, toIdx);
          }
        } else if (type === 'manyToOne') {
          // A rough strategy: if there are more than one "to", we simply divide "fromList" equally.
          var fromSingleSegLen = Math.max(1, Math.floor(fromListLen / toListLen));

          for (var toIdx = 0, fromIdxStart = 0; toIdx < toListLen; toIdx++, fromIdxStart += fromSingleSegLen) {
            var fromCount = toIdx + 1 >= toListLen ? fromListLen - fromIdxStart : fromSingleSegLen;

            this._manyToOneForSingleTo(toIdx, fromIdxStart >= fromListLen ? null : fromIdxStart, fromCount);
          }
        } else if (type === 'oneToMany') {
          // A rough strategy: if there are more than one "from", we simply divide "toList" equally.
          var toSingleSegLen = Math.max(1, Math.floor(toListLen / fromListLen));

          for (var toIdxStart = 0, fromIdx = 0; toIdxStart < toListLen; toIdxStart += toSingleSegLen, fromIdx++) {
            var toCount = toIdxStart + toSingleSegLen >= toListLen ? toListLen - toIdxStart : toSingleSegLen;

            this._oneToManyForSingleFrom(toIdxStart, toCount, fromIdx >= fromListLen ? null : fromIdx);
          }
        }
      };

      MorphPreparation.prototype._oneToOneForSingleTo = function ( // "to" must NOT be null/undefined.
      toIdx, // May `fromIdx >= this._fromList.length`
      fromIdx) {
        var to = this._toList[toIdx];
        var toElOption = this._toElOptionList[toIdx];
        var toDataIndex = this._toDataIndices[toIdx];
        var allPropsFinal = this._allPropsFinalList[toIdx];
        var from = this._fromList[fromIdx];

        var elAnimationConfig = this._getOrCreateMorphConfig(toDataIndex);

        var morphDuration = elAnimationConfig.duration;

        if (from && isCombiningPath(from)) {
          applyPropsFinal(to, allPropsFinal, toElOption.style);

          if (morphDuration) {
            var combineResult = combine([from], to, elAnimationConfig, copyPropsWhenDivided);

            this._processResultIndividuals(combineResult, toIdx, null);
          } // The target el will not be displayed and transition from multiple path.
          // transition on the target el does not make sense.

        } else {
          var morphFrom = morphDuration // from === to usually happen in scenarios where internal update like
          // "dataZoom", "legendToggle" happen. If from is not in any morphing,
          // we do not need to call `morphPath`.
          && from && (from !== to || isInAnyMorphing(from)) ? from : null; // See [Case_II] above.
          // In this case, there is probably `from === to`. And the `transitionFromProps` collecting
          // does not depends on morphing. So we collect `transitionFromProps` first.

          var transFromProps = {};
          prepareShapeOrExtraTransitionFrom('shape', to, morphFrom, toElOption, transFromProps, false);
          prepareShapeOrExtraTransitionFrom('extra', to, morphFrom, toElOption, transFromProps, false);
          prepareTransformTransitionFrom(to, morphFrom, toElOption, transFromProps, false);
          prepareStyleTransitionFrom(to, morphFrom, toElOption, toElOption.style, transFromProps, false);
          applyPropsFinal(to, allPropsFinal, toElOption.style);

          if (morphFrom) {
            morphPath(morphFrom, to, elAnimationConfig);
          }

          applyTransitionFrom(to, toDataIndex, toElOption, this._seriesModel, transFromProps, false);
        }
      };

      MorphPreparation.prototype._manyToOneForSingleTo = function ( // "to" must NOT be null/undefined.
      toIdx, // May be null.
      fromIdxStart, fromCount) {
        var to = this._toList[toIdx];
        var toElOption = this._toElOptionList[toIdx];
        var allPropsFinal = this._allPropsFinalList[toIdx];
        applyPropsFinal(to, allPropsFinal, toElOption.style);

        var elAnimationConfig = this._getOrCreateMorphConfig(this._toDataIndices[toIdx]);

        if (elAnimationConfig.duration && fromIdxStart != null) {
          var combineFromList = [];

          for (var fromIdx = fromIdxStart; fromIdx < fromCount; fromIdx++) {
            combineFromList.push(this._fromList[fromIdx]);
          }

          var combineResult = combine(combineFromList, to, elAnimationConfig, copyPropsWhenDivided);

          this._processResultIndividuals(combineResult, toIdx, null);
        }
      };

      MorphPreparation.prototype._oneToManyForSingleFrom = function ( // "to" must NOT be null/undefined.
      toIdxStart, toCount, // May be null
      fromIdx) {
        var from = fromIdx == null ? null : this._fromList[fromIdx];
        var toList = this._toList;
        var separateToList = [];

        for (var toIdx = toIdxStart; toIdx < toCount; toIdx++) {
          var to = toList[toIdx];
          applyPropsFinal(to, this._allPropsFinalList[toIdx], this._toElOptionList[toIdx].style);
          separateToList.push(to);
        }

        var elAnimationConfig = this._getOrCreateMorphConfig(this._toDataIndices[toIdxStart]);

        if (elAnimationConfig.duration && from) {
          var separateResult = separate(from, separateToList, elAnimationConfig, copyPropsWhenDivided);

          this._processResultIndividuals(separateResult, toIdxStart, toCount);
        }
      };

      MorphPreparation.prototype._processResultIndividuals = function (combineSeparateResult, toIdxStart, toCount) {
        var isSeparate = toCount != null;

        for (var i = 0; i < combineSeparateResult.count; i++) {
          var fromIndividual = combineSeparateResult.fromIndividuals[i];
          var toIndividual = combineSeparateResult.toIndividuals[i]; // Here it's a trick:
          // For "combine" case, all of the `toIndividuals` map to the same `toIdx`.
          // For "separate" case, the `toIndividuals` map to some certain segment of `_toList` accurately.

          var toIdx = toIdxStart + (isSeparate ? i : 0);
          var toElOption = this._toElOptionList[toIdx];
          var dataIndex = this._toDataIndices[toIdx];
          var transFromProps = {};
          prepareTransformTransitionFrom(toIndividual, fromIndividual, toElOption, transFromProps, false);
          prepareStyleTransitionFrom(toIndividual, fromIndividual, toElOption, toElOption.style, transFromProps, false);
          applyTransitionFrom(toIndividual, dataIndex, toElOption, this._seriesModel, transFromProps, false);
        }
      };

      MorphPreparation.prototype._getOrCreateMorphConfig = function (dataIndex) {
        var morphConfigList = this._morphConfigList;
        var config = morphConfigList[dataIndex];

        if (config) {
          return config;
        }

        var duration;
        var easing;
        var delay;
        var seriesModel = this._seriesModel;
        var transOpt = this._transOpt;

        if (seriesModel.isAnimationEnabled()) {
          // PENDING: refactor? this is the same logic as `src/util/graphic.ts#animateOrSetProps`.
          var animationPayload = void 0;

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

          if (animationPayload) {
            duration = animationPayload.duration || 0;
            easing = animationPayload.easing || 'cubicOut';
            delay = animationPayload.delay || 0;
          } else {
            easing = seriesModel.get('animationEasingUpdate');
            var delayOption = seriesModel.get('animationDelayUpdate');
            delay = isFunction(delayOption) ? delayOption(dataIndex) : delayOption;
            var durationOption = seriesModel.get('animationDurationUpdate');
            duration = isFunction(durationOption) ? durationOption(dataIndex) : durationOption;
          }
        }

        config = {
          duration: duration || 0,
          delay: delay,
          easing: easing,
          dividingMethod: transOpt ? transOpt.dividingMethod : null
        };
        morphConfigList[dataIndex] = config;
        return config;
      };

      MorphPreparation.prototype.reset = function (type) {
        // `this._morphConfigList` can be kept. It only related to `dataIndex`.
        this._type = type;
        this._fromList.length = this._toList.length = this._toElOptionList.length = this._allPropsFinalList.length = this._toDataIndices.length = 0;
      };

      return MorphPreparation;
    }();

    function copyPropsWhenDivided(srcPath, tarPath, willClone) {
      // Do not copy transform props.
      // Sub paths are transfrom based on their host path.
      // tarPath.x = srcPath.x;
      // tarPath.y = srcPath.y;
      // tarPath.scaleX = srcPath.scaleX;
      // tarPath.scaleY = srcPath.scaleY;
      // tarPath.originX = srcPath.originX;
      // tarPath.originY = srcPath.originY;
      // If just carry the style, will not be modifed, so do not copy.
      tarPath.style = willClone ? clone(srcPath.style) : srcPath.style;
      tarPath.zlevel = srcPath.zlevel;
      tarPath.z = srcPath.z;
      tarPath.z2 = srcPath.z2;
    }

    function install$r(registers) {
      registers.registerChartView(CustomSeriesView);
      registers.registerSeriesModel(CustomSeriesModel);
    }

    var inner$a = makeInner();
    var clone$3 = clone;
    var bind$1 = bind;
    /**
     * Base axis pointer class in 2D.
     */

    var BaseAxisPointer =
    /** @class */
    function () {
      function BaseAxisPointer() {
        this._dragging = false;
        /**
         * In px, arbitrary value. Do not set too small,
         * no animation is ok for most cases.
         */

        this.animationThreshold = 15;
      }
      /**
       * @implement
       */


      BaseAxisPointer.prototype.render = function (axisModel, axisPointerModel, api, forceRender) {
        var value = axisPointerModel.get('value');
        var status = axisPointerModel.get('status'); // Bind them to `this`, not in closure, otherwise they will not
        // be replaced when user calling setOption in not merge mode.

        this._axisModel = axisModel;
        this._axisPointerModel = axisPointerModel;
        this._api = api; // Optimize: `render` will be called repeatly during mouse move.
        // So it is power consuming if performing `render` each time,
        // especially on mobile device.

        if (!forceRender && this._lastValue === value && this._lastStatus === status) {
          return;
        }

        this._lastValue = value;
        this._lastStatus = status;
        var group = this._group;
        var handle = this._handle;

        if (!status || status === 'hide') {
          // Do not clear here, for animation better.
          group && group.hide();
          handle && handle.hide();
          return;
        }

        group && group.show();
        handle && handle.show(); // Otherwise status is 'show'

        var elOption = {};
        this.makeElOption(elOption, value, axisModel, axisPointerModel, api); // Enable change axis pointer type.

        var graphicKey = elOption.graphicKey;

        if (graphicKey !== this._lastGraphicKey) {
          this.clear(api);
        }

        this._lastGraphicKey = graphicKey;
        var moveAnimation = this._moveAnimation = this.determineAnimation(axisModel, axisPointerModel);

        if (!group) {
          group = this._group = new Group();
          this.createPointerEl(group, elOption, axisModel, axisPointerModel);
          this.createLabelEl(group, elOption, axisModel, axisPointerModel);
          api.getZr().add(group);
        } else {
          var doUpdateProps = curry(updateProps$1, axisPointerModel, moveAnimation);
          this.updatePointerEl(group, elOption, doUpdateProps);
          this.updateLabelEl(group, elOption, doUpdateProps, axisPointerModel);
        }

        updateMandatoryProps(group, axisPointerModel, true);

        this._renderHandle(value);
      };
      /**
       * @implement
       */


      BaseAxisPointer.prototype.remove = function (api) {
        this.clear(api);
      };
      /**
       * @implement
       */


      BaseAxisPointer.prototype.dispose = function (api) {
        this.clear(api);
      };
      /**
       * @protected
       */


      BaseAxisPointer.prototype.determineAnimation = function (axisModel, axisPointerModel) {
        var animation = axisPointerModel.get('animation');
        var axis = axisModel.axis;
        var isCategoryAxis = axis.type === 'category';
        var useSnap = axisPointerModel.get('snap'); // Value axis without snap always do not snap.

        if (!useSnap && !isCategoryAxis) {
          return false;
        }

        if (animation === 'auto' || animation == null) {
          var animationThreshold = this.animationThreshold;

          if (isCategoryAxis && axis.getBandWidth() > animationThreshold) {
            return true;
          } // It is important to auto animation when snap used. Consider if there is
          // a dataZoom, animation will be disabled when too many points exist, while
          // it will be enabled for better visual effect when little points exist.


          if (useSnap) {
            var seriesDataCount = getAxisInfo(axisModel).seriesDataCount;
            var axisExtent = axis.getExtent(); // Approximate band width

            return Math.abs(axisExtent[0] - axisExtent[1]) / seriesDataCount > animationThreshold;
          }

          return false;
        }

        return animation === true;
      };
      /**
       * add {pointer, label, graphicKey} to elOption
       * @protected
       */


      BaseAxisPointer.prototype.makeElOption = function (elOption, value, axisModel, axisPointerModel, api) {// Shoule be implemenented by sub-class.
      };
      /**
       * @protected
       */


      BaseAxisPointer.prototype.createPointerEl = function (group, elOption, axisModel, axisPointerModel) {
        var pointerOption = elOption.pointer;

        if (pointerOption) {
          var pointerEl = inner$a(group).pointerEl = new graphic[pointerOption.type](clone$3(elOption.pointer));
          group.add(pointerEl);
        }
      };
      /**
       * @protected
       */


      BaseAxisPointer.prototype.createLabelEl = function (group, elOption, axisModel, axisPointerModel) {
        if (elOption.label) {
          var labelEl = inner$a(group).labelEl = new ZRText(clone$3(elOption.label));
          group.add(labelEl);
          updateLabelShowHide(labelEl, axisPointerModel);
        }
      };
      /**
       * @protected
       */


      BaseAxisPointer.prototype.updatePointerEl = function (group, elOption, updateProps) {
        var pointerEl = inner$a(group).pointerEl;

        if (pointerEl && elOption.pointer) {
          pointerEl.setStyle(elOption.pointer.style);
          updateProps(pointerEl, {
            shape: elOption.pointer.shape
          });
        }
      };
      /**
       * @protected
       */


      BaseAxisPointer.prototype.updateLabelEl = function (group, elOption, updateProps, axisPointerModel) {
        var labelEl = inner$a(group).labelEl;

        if (labelEl) {
          labelEl.setStyle(elOption.label.style);
          updateProps(labelEl, {
            // Consider text length change in vertical axis, animation should
            // be used on shape, otherwise the effect will be weird.
            // TODOTODO
            // shape: elOption.label.shape,
            x: elOption.label.x,
            y: elOption.label.y
          });
          updateLabelShowHide(labelEl, axisPointerModel);
        }
      };
      /**
       * @private
       */


      BaseAxisPointer.prototype._renderHandle = function (value) {
        if (this._dragging || !this.updateHandleTransform) {
          return;
        }

        var axisPointerModel = this._axisPointerModel;

        var zr = this._api.getZr();

        var handle = this._handle;
        var handleModel = axisPointerModel.getModel('handle');
        var status = axisPointerModel.get('status');

        if (!handleModel.get('show') || !status || status === 'hide') {
          handle && zr.remove(handle);
          this._handle = null;
          return;
        }

        var isInit;

        if (!this._handle) {
          isInit = true;
          handle = this._handle = createIcon(handleModel.get('icon'), {
            cursor: 'move',
            draggable: true,
            onmousemove: function (e) {
              // Fot mobile devicem, prevent screen slider on the button.
              stop(e.event);
            },
            onmousedown: bind$1(this._onHandleDragMove, this, 0, 0),
            drift: bind$1(this._onHandleDragMove, this),
            ondragend: bind$1(this._onHandleDragEnd, this)
          });
          zr.add(handle);
        }

        updateMandatoryProps(handle, axisPointerModel, false); // update style

        handle.setStyle(handleModel.getItemStyle(null, ['color', 'borderColor', 'borderWidth', 'opacity', 'shadowColor', 'shadowBlur', 'shadowOffsetX', 'shadowOffsetY'])); // update position

        var handleSize = handleModel.get('size');

        if (!isArray(handleSize)) {
          handleSize = [handleSize, handleSize];
        }

        handle.scaleX = handleSize[0] / 2;
        handle.scaleY = handleSize[1] / 2;
        createOrUpdate(this, '_doDispatchAxisPointer', handleModel.get('throttle') || 0, 'fixRate');

        this._moveHandleToValue(value, isInit);
      };

      BaseAxisPointer.prototype._moveHandleToValue = function (value, isInit) {
        updateProps$1(this._axisPointerModel, !isInit && this._moveAnimation, this._handle, getHandleTransProps(this.getHandleTransform(value, this._axisModel, this._axisPointerModel)));
      };

      BaseAxisPointer.prototype._onHandleDragMove = function (dx, dy) {
        var handle = this._handle;

        if (!handle) {
          return;
        }

        this._dragging = true; // Persistent for throttle.

        var trans = this.updateHandleTransform(getHandleTransProps(handle), [dx, dy], this._axisModel, this._axisPointerModel);
        this._payloadInfo = trans;
        handle.stopAnimation();
        handle.attr(getHandleTransProps(trans));
        inner$a(handle).lastProp = null;

        this._doDispatchAxisPointer();
      };
      /**
       * Throttled method.
       */


      BaseAxisPointer.prototype._doDispatchAxisPointer = function () {
        var handle = this._handle;

        if (!handle) {
          return;
        }

        var payloadInfo = this._payloadInfo;
        var axisModel = this._axisModel;

        this._api.dispatchAction({
          type: 'updateAxisPointer',
          x: payloadInfo.cursorPoint[0],
          y: payloadInfo.cursorPoint[1],
          tooltipOption: payloadInfo.tooltipOption,
          axesInfo: [{
            axisDim: axisModel.axis.dim,
            axisIndex: axisModel.componentIndex
          }]
        });
      };

      BaseAxisPointer.prototype._onHandleDragEnd = function () {
        this._dragging = false;
        var handle = this._handle;

        if (!handle) {
          return;
        }

        var value = this._axisPointerModel.get('value'); // Consider snap or categroy axis, handle may be not consistent with
        // axisPointer. So move handle to align the exact value position when
        // drag ended.


        this._moveHandleToValue(value); // For the effect: tooltip will be shown when finger holding on handle
        // button, and will be hidden after finger left handle button.


        this._api.dispatchAction({
          type: 'hideTip'
        });
      };
      /**
       * @private
       */


      BaseAxisPointer.prototype.clear = function (api) {
        this._lastValue = null;
        this._lastStatus = null;
        var zr = api.getZr();
        var group = this._group;
        var handle = this._handle;

        if (zr && group) {
          this._lastGraphicKey = null;
          group && zr.remove(group);
          handle && zr.remove(handle);
          this._group = null;
          this._handle = null;
          this._payloadInfo = null;
        }
      };
      /**
       * @protected
       */


      BaseAxisPointer.prototype.doClear = function () {// Implemented by sub-class if necessary.
      };

      BaseAxisPointer.prototype.buildLabel = function (xy, wh, xDimIndex) {
        xDimIndex = xDimIndex || 0;
        return {
          x: xy[xDimIndex],
          y: xy[1 - xDimIndex],
          width: wh[xDimIndex],
          height: wh[1 - xDimIndex]
        };
      };

      return BaseAxisPointer;
    }();

    function updateProps$1(animationModel, moveAnimation, el, props) {
      // Animation optimize.
      if (!propsEqual(inner$a(el).lastProp, props)) {
        inner$a(el).lastProp = props;
        moveAnimation ? updateProps(el, props, animationModel) : (el.stopAnimation(), el.attr(props));
      }
    }

    function propsEqual(lastProps, newProps) {
      if (isObject(lastProps) && isObject(newProps)) {
        var equals_1 = true;
        each(newProps, function (item, key) {
          equals_1 = equals_1 && propsEqual(lastProps[key], item);
        });
        return !!equals_1;
      } else {
        return lastProps === newProps;
      }
    }

    function updateLabelShowHide(labelEl, axisPointerModel) {
      labelEl[axisPointerModel.get(['label', 'show']) ? 'show' : 'hide']();
    }

    function getHandleTransProps(trans) {
      return {
        x: trans.x || 0,
        y: trans.y || 0,
        rotation: trans.rotation || 0
      };
    }

    function updateMandatoryProps(group, axisPointerModel, silent) {
      var z = axisPointerModel.get('z');
      var zlevel = axisPointerModel.get('zlevel');
      group && group.traverse(function (el) {
        if (el.type !== 'group') {
          z != null && (el.z = z);
          zlevel != null && (el.zlevel = zlevel);
          el.silent = silent;
        }
      });
    }

    function buildElStyle(axisPointerModel) {
      var axisPointerType = axisPointerModel.get('type');
      var styleModel = axisPointerModel.getModel(axisPointerType + 'Style');
      var style;

      if (axisPointerType === 'line') {
        style = styleModel.getLineStyle();
        style.fill = null;
      } else if (axisPointerType === 'shadow') {
        style = styleModel.getAreaStyle();
        style.stroke = null;
      }

      return style;
    }
    /**
     * @param {Function} labelPos {align, verticalAlign, position}
     */

    function buildLabelElOption(elOption, axisModel, axisPointerModel, api, labelPos) {
      var value = axisPointerModel.get('value');
      var text = getValueLabel(value, axisModel.axis, axisModel.ecModel, axisPointerModel.get('seriesDataIndices'), {
        precision: axisPointerModel.get(['label', 'precision']),
        formatter: axisPointerModel.get(['label', 'formatter'])
      });
      var labelModel = axisPointerModel.getModel('label');
      var paddings = normalizeCssArray$1(labelModel.get('padding') || 0);
      var font = labelModel.getFont();
      var textRect = getBoundingRect(text, font);
      var position = labelPos.position;
      var width = textRect.width + paddings[1] + paddings[3];
      var height = textRect.height + paddings[0] + paddings[2]; // Adjust by align.

      var align = labelPos.align;
      align === 'right' && (position[0] -= width);
      align === 'center' && (position[0] -= width / 2);
      var verticalAlign = labelPos.verticalAlign;
      verticalAlign === 'bottom' && (position[1] -= height);
      verticalAlign === 'middle' && (position[1] -= height / 2); // Not overflow ec container

      confineInContainer(position, width, height, api);
      var bgColor = labelModel.get('backgroundColor');

      if (!bgColor || bgColor === 'auto') {
        bgColor = axisModel.get(['axisLine', 'lineStyle', 'color']);
      }

      elOption.label = {
        // shape: {x: 0, y: 0, width: width, height: height, r: labelModel.get('borderRadius')},
        x: position[0],
        y: position[1],
        style: createTextStyle(labelModel, {
          text: text,
          font: font,
          fill: labelModel.getTextColor(),
          padding: paddings,
          backgroundColor: bgColor
        }),
        // Lable should be over axisPointer.
        z2: 10
      };
    } // Do not overflow ec container

    function confineInContainer(position, width, height, api) {
      var viewWidth = api.getWidth();
      var viewHeight = api.getHeight();
      position[0] = Math.min(position[0] + width, viewWidth) - width;
      position[1] = Math.min(position[1] + height, viewHeight) - height;
      position[0] = Math.max(position[0], 0);
      position[1] = Math.max(position[1], 0);
    }

    function getValueLabel(value, axis, ecModel, seriesDataIndices, opt) {
      value = axis.scale.parse(value);
      var text = axis.scale.getLabel({
        value: value
      }, {
        // If `precision` is set, width can be fixed (like '12.00500'), which
        // helps to debounce when when moving label.
        precision: opt.precision
      });
      var formatter = opt.formatter;

      if (formatter) {
        var params_1 = {
          value: getAxisRawValue(axis, {
            value: value
          }),
          axisDimension: axis.dim,
          axisIndex: axis.index,
          seriesData: []
        };
        each(seriesDataIndices, function (idxItem) {
          var series = ecModel.getSeriesByIndex(idxItem.seriesIndex);
          var dataIndex = idxItem.dataIndexInside;
          var dataParams = series && series.getDataParams(dataIndex);
          dataParams && params_1.seriesData.push(dataParams);
        });

        if (isString(formatter)) {
          text = formatter.replace('{value}', text);
        } else if (isFunction(formatter)) {
          text = formatter(params_1);
        }
      }

      return text;
    }
    function getTransformedPosition(axis, value, layoutInfo) {
      var transform = create$1();
      rotate(transform, transform, layoutInfo.rotation);
      translate(transform, transform, layoutInfo.position);
      return applyTransform$1([axis.dataToCoord(value), (layoutInfo.labelOffset || 0) + (layoutInfo.labelDirection || 1) * (layoutInfo.labelMargin || 0)], transform);
    }
    function buildCartesianSingleLabelElOption(value, elOption, layoutInfo, axisModel, axisPointerModel, api) {
      // @ts-ignore
      var textLayout = AxisBuilder.innerTextLayout(layoutInfo.rotation, 0, layoutInfo.labelDirection);
      layoutInfo.labelMargin = axisPointerModel.get(['label', 'margin']);
      buildLabelElOption(elOption, axisModel, axisPointerModel, api, {
        position: getTransformedPosition(axisModel.axis, value, layoutInfo),
        align: textLayout.textAlign,
        verticalAlign: textLayout.textVerticalAlign
      });
    }
    function makeLineShape(p1, p2, xDimIndex) {
      xDimIndex = xDimIndex || 0;
      return {
        x1: p1[xDimIndex],
        y1: p1[1 - xDimIndex],
        x2: p2[xDimIndex],
        y2: p2[1 - xDimIndex]
      };
    }
    function makeRectShape(xy, wh, xDimIndex) {
      xDimIndex = xDimIndex || 0;
      return {
        x: xy[xDimIndex],
        y: xy[1 - xDimIndex],
        width: wh[xDimIndex],
        height: wh[1 - xDimIndex]
      };
    }
    function makeSectorShape(cx, cy, r0, r, startAngle, endAngle) {
      return {
        cx: cx,
        cy: cy,
        r0: r0,
        r: r,
        startAngle: startAngle,
        endAngle: endAngle,
        clockwise: true
      };
    }

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

      function CartesianAxisPointer() {
        return _super !== null && _super.apply(this, arguments) || this;
      }
      /**
       * @override
       */


      CartesianAxisPointer.prototype.makeElOption = function (elOption, value, axisModel, axisPointerModel, api) {
        var axis = axisModel.axis;
        var grid = axis.grid;
        var axisPointerType = axisPointerModel.get('type');
        var otherExtent = getCartesian(grid, axis).getOtherAxis(axis).getGlobalExtent();
        var pixelValue = axis.toGlobalCoord(axis.dataToCoord(value, true));

        if (axisPointerType && axisPointerType !== 'none') {
          var elStyle = buildElStyle(axisPointerModel);
          var pointerOption = pointerShapeBuilder[axisPointerType](axis, pixelValue, otherExtent);
          pointerOption.style = elStyle;
          elOption.graphicKey = pointerOption.type;
          elOption.pointer = pointerOption;
        }

        var layoutInfo = layout$1(grid.model, axisModel);
        buildCartesianSingleLabelElOption( // @ts-ignore
        value, elOption, layoutInfo, axisModel, axisPointerModel, api);
      };
      /**
       * @override
       */


      CartesianAxisPointer.prototype.getHandleTransform = function (value, axisModel, axisPointerModel) {
        var layoutInfo = layout$1(axisModel.axis.grid.model, axisModel, {
          labelInside: false
        }); // @ts-ignore

        layoutInfo.labelMargin = axisPointerModel.get(['handle', 'margin']);
        var pos = getTransformedPosition(axisModel.axis, value, layoutInfo);
        return {
          x: pos[0],
          y: pos[1],
          rotation: layoutInfo.rotation + (layoutInfo.labelDirection < 0 ? Math.PI : 0)
        };
      };
      /**
       * @override
       */


      CartesianAxisPointer.prototype.updateHandleTransform = function (transform, delta, axisModel, axisPointerModel) {
        var axis = axisModel.axis;
        var grid = axis.grid;
        var axisExtent = axis.getGlobalExtent(true);
        var otherExtent = getCartesian(grid, axis).getOtherAxis(axis).getGlobalExtent();
        var dimIndex = axis.dim === 'x' ? 0 : 1;
        var currPosition = [transform.x, transform.y];
        currPosition[dimIndex] += delta[dimIndex];
        currPosition[dimIndex] = Math.min(axisExtent[1], currPosition[dimIndex]);
        currPosition[dimIndex] = Math.max(axisExtent[0], currPosition[dimIndex]);
        var cursorOtherValue = (otherExtent[1] + otherExtent[0]) / 2;
        var cursorPoint = [cursorOtherValue, cursorOtherValue];
        cursorPoint[dimIndex] = currPosition[dimIndex]; // Make tooltip do not overlap axisPointer and in the middle of the grid.

        var tooltipOptions = [{
          verticalAlign: 'middle'
        }, {
          align: 'center'
        }];
        return {
          x: currPosition[0],
          y: currPosition[1],
          rotation: transform.rotation,
          cursorPoint: cursorPoint,
          tooltipOption: tooltipOptions[dimIndex]
        };
      };

      return CartesianAxisPointer;
    }(BaseAxisPointer);

    function getCartesian(grid, axis) {
      var opt = {};
      opt[axis.dim + 'AxisIndex'] = axis.index;
      return grid.getCartesian(opt);
    }

    var pointerShapeBuilder = {
      line: function (axis, pixelValue, otherExtent) {
        var targetShape = makeLineShape([pixelValue, otherExtent[0]], [pixelValue, otherExtent[1]], getAxisDimIndex(axis));
        return {
          type: 'Line',
          subPixelOptimize: true,
          shape: targetShape
        };
      },
      shadow: function (axis, pixelValue, otherExtent) {
        var bandWidth = Math.max(1, axis.getBandWidth());
        var span = otherExtent[1] - otherExtent[0];
        return {
          type: 'Rect',
          shape: makeRectShape([pixelValue - bandWidth / 2, otherExtent[0]], [bandWidth, span], getAxisDimIndex(axis))
        };
      }
    };

    function getAxisDimIndex(axis) {
      return axis.dim === 'x' ? 0 : 1;
    }

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

      function AxisPointerModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = AxisPointerModel.type;
        return _this;
      }

      AxisPointerModel.type = 'axisPointer';
      AxisPointerModel.defaultOption = {
        // 'auto' means that show when triggered by tooltip or handle.
        show: 'auto',
        zlevel: 0,
        z: 50,
        type: 'line',
        // axispointer triggered by tootip determine snap automatically,
        // see `modelHelper`.
        snap: false,
        triggerTooltip: true,
        value: null,
        status: null,
        link: [],
        // Do not set 'auto' here, otherwise global animation: false
        // will not effect at this axispointer.
        animation: null,
        animationDurationUpdate: 200,
        lineStyle: {
          color: '#B9BEC9',
          width: 1,
          type: 'dashed'
        },
        shadowStyle: {
          color: 'rgba(210,219,238,0.2)'
        },
        label: {
          show: true,
          formatter: null,
          precision: 'auto',
          margin: 3,
          color: '#fff',
          padding: [5, 7, 5, 7],
          backgroundColor: 'auto',
          borderColor: null,
          borderWidth: 0,
          borderRadius: 3
        },
        handle: {
          show: false,
          // eslint-disable-next-line
          icon: 'M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4h1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7v-1.2h6.6z M13.3,22H6.7v-1.2h6.6z M13.3,19.6H6.7v-1.2h6.6z',
          size: 45,
          // handle margin is from symbol center to axis, which is stable when circular move.
          margin: 50,
          // color: '#1b8bbd'
          // color: '#2f4554'
          color: '#333',
          shadowBlur: 3,
          shadowColor: '#aaa',
          shadowOffsetX: 0,
          shadowOffsetY: 2,
          // For mobile performance
          throttle: 40
        }
      };
      return AxisPointerModel;
    }(ComponentModel);

    var inner$b = makeInner();
    var each$8 = 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$8(inner$b(zr).records, function (record) {
            record && cb(record, e, dis.dispatchAction);
          });
          dispatchTooltipFinally(dis.pendings, api);
        });
      }
    }

    function dispatchTooltipFinally(pendings, api) {
      var showLen = pendings.showTip.length;
      var hideLen = pendings.hideTip.length;
      var actuallyPayload;

      if (showLen) {
        actuallyPayload = pendings.showTip[showLen - 1];
      } else if (hideLen) {
        actuallyPayload = pendings.hideTip[hideLen - 1];
      }

      if (actuallyPayload) {
        actuallyPayload.dispatchAction = null;
        api.dispatchAction(actuallyPayload);
      }
    }

    function onLeave(record, e, dispatchAction) {
      record.handler('leave', null, dispatchAction);
    }

    function doEnter(currTrigger, record, e, dispatchAction) {
      record.handler(currTrigger, e, dispatchAction);
    }

    function makeDispatchAction(api) {
      var pendings = {
        showTip: [],
        hideTip: []
      }; // FIXME
      // better approach?
      // 'showTip' and 'hideTip' can be triggered by axisPointer and tooltip,
      // which may be conflict, (axisPointer call showTip but tooltip call hideTip);
      // So we have to add "final stage" to merge those dispatched actions.

      var dispatchAction = function (payload) {
        var pendingList = pendings[payload.type];

        if (pendingList) {
          pendingList.push(payload);
        } else {
          payload.dispatchAction = dispatchAction;
          api.dispatchAction(payload);
        }
      };

      return {
        dispatchAction: dispatchAction,
        pendings: pendings
      };
    }

    function unregister(key, api) {
      if (env.node) {
        return;
      }

      var zr = api.getZr();
      var record = (inner$b(zr).records || {})[key];

      if (record) {
        inner$b(zr).records[key] = null;
      }
    }

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

      function AxisPointerView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = AxisPointerView.type;
        return _this;
      }

      AxisPointerView.prototype.render = function (globalAxisPointerModel, ecModel, api) {
        var globalTooltipModel = ecModel.getComponent('tooltip');
        var triggerOn = globalAxisPointerModel.get('triggerOn') || globalTooltipModel && globalTooltipModel.get('triggerOn') || 'mousemove|click'; // Register global listener in AxisPointerView to enable
        // AxisPointerView to be independent to Tooltip.

        register('axisPointer', api, function (currTrigger, e, dispatchAction) {
          // If 'none', it is not controlled by mouse totally.
          if (triggerOn !== 'none' && (currTrigger === 'leave' || triggerOn.indexOf(currTrigger) >= 0)) {
            dispatchAction({
              type: 'updateAxisPointer',
              currTrigger: currTrigger,
              x: e && e.offsetX,
              y: e && e.offsetY
            });
          }
        });
      };

      AxisPointerView.prototype.remove = function (ecModel, api) {
        unregister('axisPointer', api);
      };

      AxisPointerView.prototype.dispose = function (ecModel, api) {
        unregister('axisPointer', api);
      };

      AxisPointerView.type = 'axisPointer';
      return AxisPointerView;
    }(ComponentView);

    /**
     * @param finder contains {seriesIndex, dataIndex, dataIndexInside}
     * @param ecModel
     * @return  {point: [x, y], el: ...} point Will not be null.
     */

    function findPointFromSeries(finder, ecModel) {
      var point = [];
      var seriesIndex = finder.seriesIndex;
      var seriesModel;

      if (seriesIndex == null || !(seriesModel = ecModel.getSeriesByIndex(seriesIndex))) {
        return {
          point: []
        };
      }

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

      if (dataIndex == null || dataIndex < 0 || isArray(dataIndex)) {
        return {
          point: []
        };
      }

      var el = data.getItemGraphicEl(dataIndex);
      var coordSys = seriesModel.coordinateSystem;

      if (seriesModel.getTooltipPosition) {
        point = seriesModel.getTooltipPosition(dataIndex) || [];
      } else if (coordSys && coordSys.dataToPoint) {
        if (finder.isStacked) {
          var baseAxis = coordSys.getBaseAxis();
          var valueAxis = coordSys.getOtherAxis(baseAxis);
          var valueAxisDim = valueAxis.dim;
          var baseAxisDim = baseAxis.dim;
          var baseDataOffset = valueAxisDim === 'x' || valueAxisDim === 'radius' ? 1 : 0;
          var baseDim = data.mapDimension(baseAxisDim);
          var stackedData = [];
          stackedData[baseDataOffset] = data.get(baseDim, dataIndex);
          stackedData[1 - baseDataOffset] = data.get(data.getCalculationInfo('stackResultDimension'), dataIndex);
          point = coordSys.dataToPoint(stackedData) || [];
        } else {
          point = coordSys.dataToPoint(data.getValues(map(coordSys.dimensions, function (dim) {
            return data.mapDimension(dim);
          }), dataIndex)) || [];
        }
      } else if (el) {
        // Use graphic bounding rect
        var rect = el.getBoundingRect().clone();
        rect.applyTransform(el.transform);
        point = [rect.x + rect.width / 2, rect.y + rect.height / 2];
      }

      return {
        point: point,
        el: el
      };
    }

    var inner$c = makeInner();
    /**
     * Basic logic: check all axis, if they do not demand show/highlight,
     * then hide/downplay them.
     *
     * @return content of event obj for echarts.connect.
     */

    function axisTrigger(payload, ecModel, api) {
      var currTrigger = payload.currTrigger;
      var point = [payload.x, payload.y];
      var finder = payload;
      var dispatchAction = payload.dispatchAction || bind(api.dispatchAction, api);
      var coordSysAxesInfo = ecModel.getComponent('axisPointer').coordSysAxesInfo; // Pending
      // See #6121. But we are not able to reproduce it yet.

      if (!coordSysAxesInfo) {
        return;
      }

      if (illegalPoint(point)) {
        // Used in the default behavior of `connection`: use the sample seriesIndex
        // and dataIndex. And also used in the tooltipView trigger.
        point = findPointFromSeries({
          seriesIndex: finder.seriesIndex,
          // Do not use dataIndexInside from other ec instance.
          // FIXME: auto detect it?
          dataIndex: finder.dataIndex
        }, ecModel).point;
      }

      var isIllegalPoint = illegalPoint(point); // Axis and value can be specified when calling dispatchAction({type: 'updateAxisPointer'}).
      // Notice: In this case, it is difficult to get the `point` (which is necessary to show
      // tooltip, so if point is not given, we just use the point found by sample seriesIndex
      // and dataIndex.

      var inputAxesInfo = finder.axesInfo;
      var axesInfo = coordSysAxesInfo.axesInfo;
      var shouldHide = currTrigger === 'leave' || illegalPoint(point);
      var outputPayload = {};
      var showValueMap = {};
      var dataByCoordSys = {
        list: [],
        map: {}
      };
      var updaters = {
        showPointer: curry(showPointer, showValueMap),
        showTooltip: curry(showTooltip, dataByCoordSys)
      }; // Process for triggered axes.

      each(coordSysAxesInfo.coordSysMap, function (coordSys, coordSysKey) {
        // If a point given, it must be contained by the coordinate system.
        var coordSysContainsPoint = isIllegalPoint || coordSys.containPoint(point);
        each(coordSysAxesInfo.coordSysAxesInfo[coordSysKey], function (axisInfo, key) {
          var axis = axisInfo.axis;
          var inputAxisInfo = findInputAxisInfo(inputAxesInfo, axisInfo); // If no inputAxesInfo, no axis is restricted.

          if (!shouldHide && coordSysContainsPoint && (!inputAxesInfo || inputAxisInfo)) {
            var val = inputAxisInfo && inputAxisInfo.value;

            if (val == null && !isIllegalPoint) {
              val = axis.pointToData(point);
            }

            val != null && processOnAxis(axisInfo, val, updaters, false, outputPayload);
          }
        });
      }); // Process for linked axes.

      var linkTriggers = {};
      each(axesInfo, function (tarAxisInfo, tarKey) {
        var linkGroup = tarAxisInfo.linkGroup; // If axis has been triggered in the previous stage, it should not be triggered by link.

        if (linkGroup && !showValueMap[tarKey]) {
          each(linkGroup.axesInfo, function (srcAxisInfo, srcKey) {
            var srcValItem = showValueMap[srcKey]; // If srcValItem exist, source axis is triggered, so link to target axis.

            if (srcAxisInfo !== tarAxisInfo && srcValItem) {
              var val = srcValItem.value;
              linkGroup.mapper && (val = tarAxisInfo.axis.scale.parse(linkGroup.mapper(val, makeMapperParam(srcAxisInfo), makeMapperParam(tarAxisInfo))));
              linkTriggers[tarAxisInfo.key] = val;
            }
          });
        }
      });
      each(linkTriggers, function (val, tarKey) {
        processOnAxis(axesInfo[tarKey], val, updaters, true, outputPayload);
      });
      updateModelActually(showValueMap, axesInfo, outputPayload);
      dispatchTooltipActually(dataByCoordSys, point, payload, dispatchAction);
      dispatchHighDownActually(axesInfo, dispatchAction, api);
      return outputPayload;
    }

    function processOnAxis(axisInfo, newValue, updaters, noSnap, outputFinder) {
      var axis = axisInfo.axis;

      if (axis.scale.isBlank() || !axis.containData(newValue)) {
        return;
      }

      if (!axisInfo.involveSeries) {
        updaters.showPointer(axisInfo, newValue);
        return;
      } // Heavy calculation. So put it after axis.containData checking.


      var payloadInfo = buildPayloadsBySeries(newValue, axisInfo);
      var payloadBatch = payloadInfo.payloadBatch;
      var snapToValue = payloadInfo.snapToValue; // Fill content of event obj for echarts.connect.
      // By default use the first involved series data as a sample to connect.

      if (payloadBatch[0] && outputFinder.seriesIndex == null) {
        extend(outputFinder, payloadBatch[0]);
      } // If no linkSource input, this process is for collecting link
      // target, where snap should not be accepted.


      if (!noSnap && axisInfo.snap) {
        if (axis.containData(snapToValue) && snapToValue != null) {
          newValue = snapToValue;
        }
      }

      updaters.showPointer(axisInfo, newValue, payloadBatch); // Tooltip should always be snapToValue, otherwise there will be
      // incorrect "axis value ~ series value" mapping displayed in tooltip.

      updaters.showTooltip(axisInfo, payloadInfo, snapToValue);
    }

    function buildPayloadsBySeries(value, axisInfo) {
      var axis = axisInfo.axis;
      var dim = axis.dim;
      var snapToValue = value;
      var payloadBatch = [];
      var minDist = Number.MAX_VALUE;
      var minDiff = -1;
      each(axisInfo.seriesModels, function (series, idx) {
        var dataDim = series.getData().mapDimensionsAll(dim);
        var seriesNestestValue;
        var dataIndices;

        if (series.getAxisTooltipData) {
          var result = series.getAxisTooltipData(dataDim, value, axis);
          dataIndices = result.dataIndices;
          seriesNestestValue = result.nestestValue;
        } else {
          dataIndices = series.getData().indicesOfNearest(dataDim[0], value, // Add a threshold to avoid find the wrong dataIndex
          // when data length is not same.
          // false,
          axis.type === 'category' ? 0.5 : null);

          if (!dataIndices.length) {
            return;
          }

          seriesNestestValue = series.getData().get(dataDim[0], dataIndices[0]);
        }

        if (seriesNestestValue == null || !isFinite(seriesNestestValue)) {
          return;
        }

        var diff = value - seriesNestestValue;
        var dist = Math.abs(diff); // Consider category case

        if (dist <= minDist) {
          if (dist < minDist || diff >= 0 && minDiff < 0) {
            minDist = dist;
            minDiff = diff;
            snapToValue = seriesNestestValue;
            payloadBatch.length = 0;
          }

          each(dataIndices, function (dataIndex) {
            payloadBatch.push({
              seriesIndex: series.seriesIndex,
              dataIndexInside: dataIndex,
              dataIndex: series.getData().getRawIndex(dataIndex)
            });
          });
        }
      });
      return {
        payloadBatch: payloadBatch,
        snapToValue: snapToValue
      };
    }

    function showPointer(showValueMap, axisInfo, value, payloadBatch) {
      showValueMap[axisInfo.key] = {
        value: value,
        payloadBatch: payloadBatch
      };
    }

    function showTooltip(dataByCoordSys, axisInfo, payloadInfo, value) {
      var payloadBatch = payloadInfo.payloadBatch;
      var axis = axisInfo.axis;
      var axisModel = axis.model;
      var axisPointerModel = axisInfo.axisPointerModel; // If no data, do not create anything in dataByCoordSys,
      // whose length will be used to judge whether dispatch action.

      if (!axisInfo.triggerTooltip || !payloadBatch.length) {
        return;
      }

      var coordSysModel = axisInfo.coordSys.model;
      var coordSysKey = makeKey(coordSysModel);
      var coordSysItem = dataByCoordSys.map[coordSysKey];

      if (!coordSysItem) {
        coordSysItem = dataByCoordSys.map[coordSysKey] = {
          coordSysId: coordSysModel.id,
          coordSysIndex: coordSysModel.componentIndex,
          coordSysType: coordSysModel.type,
          coordSysMainType: coordSysModel.mainType,
          dataByAxis: []
        };
        dataByCoordSys.list.push(coordSysItem);
      }

      coordSysItem.dataByAxis.push({
        axisDim: axis.dim,
        axisIndex: axisModel.componentIndex,
        axisType: axisModel.type,
        axisId: axisModel.id,
        value: value,
        // Caustion: viewHelper.getValueLabel is actually on "view stage", which
        // depends that all models have been updated. So it should not be performed
        // here. Considering axisPointerModel used here is volatile, which is hard
        // to be retrieve in TooltipView, we prepare parameters here.
        valueLabelOpt: {
          precision: axisPointerModel.get(['label', 'precision']),
          formatter: axisPointerModel.get(['label', 'formatter'])
        },
        seriesDataIndices: payloadBatch.slice()
      });
    }

    function updateModelActually(showValueMap, axesInfo, outputPayload) {
      var outputAxesInfo = outputPayload.axesInfo = []; // Basic logic: If no 'show' required, 'hide' this axisPointer.

      each(axesInfo, function (axisInfo, key) {
        var option = axisInfo.axisPointerModel.option;
        var valItem = showValueMap[key];

        if (valItem) {
          !axisInfo.useHandle && (option.status = 'show');
          option.value = valItem.value; // For label formatter param and highlight.

          option.seriesDataIndices = (valItem.payloadBatch || []).slice();
        } // When always show (e.g., handle used), remain
        // original value and status.
        else {
            // If hide, value still need to be set, consider
            // click legend to toggle axis blank.
            !axisInfo.useHandle && (option.status = 'hide');
          } // If status is 'hide', should be no info in payload.


        option.status === 'show' && outputAxesInfo.push({
          axisDim: axisInfo.axis.dim,
          axisIndex: axisInfo.axis.model.componentIndex,
          value: option.value
        });
      });
    }

    function dispatchTooltipActually(dataByCoordSys, point, payload, dispatchAction) {
      // Basic logic: If no showTip required, hideTip will be dispatched.
      if (illegalPoint(point) || !dataByCoordSys.list.length) {
        dispatchAction({
          type: 'hideTip'
        });
        return;
      } // In most case only one axis (or event one series is used). It is
      // convinient to fetch payload.seriesIndex and payload.dataIndex
      // dirtectly. So put the first seriesIndex and dataIndex of the first
      // axis on the payload.


      var sampleItem = ((dataByCoordSys.list[0].dataByAxis[0] || {}).seriesDataIndices || [])[0] || {};
      dispatchAction({
        type: 'showTip',
        escapeConnect: true,
        x: point[0],
        y: point[1],
        tooltipOption: payload.tooltipOption,
        position: payload.position,
        dataIndexInside: sampleItem.dataIndexInside,
        dataIndex: sampleItem.dataIndex,
        seriesIndex: sampleItem.seriesIndex,
        dataByCoordSys: dataByCoordSys.list
      });
    }

    function dispatchHighDownActually(axesInfo, dispatchAction, api) {
      // FIXME
      // highlight status modification shoule be a stage of main process?
      // (Consider confilct (e.g., legend and axisPointer) and setOption)
      var zr = api.getZr();
      var highDownKey = 'axisPointerLastHighlights';
      var lastHighlights = inner$c(zr)[highDownKey] || {};
      var newHighlights = inner$c(zr)[highDownKey] = {}; // Update highlight/downplay status according to axisPointer model.
      // Build hash map and remove duplicate incidentally.

      each(axesInfo, function (axisInfo, key) {
        var option = axisInfo.axisPointerModel.option;
        option.status === 'show' && each(option.seriesDataIndices, function (batchItem) {
          var key = batchItem.seriesIndex + ' | ' + batchItem.dataIndex;
          newHighlights[key] = batchItem;
        });
      }); // Diff.

      var toHighlight = [];
      var toDownplay = [];
      each(lastHighlights, function (batchItem, key) {
        !newHighlights[key] && toDownplay.push(batchItem);
      });
      each(newHighlights, function (batchItem, key) {
        !lastHighlights[key] && toHighlight.push(batchItem);
      });
      toDownplay.length && api.dispatchAction({
        type: 'downplay',
        escapeConnect: true,
        // Not blur others when highlight in axisPointer.
        notBlur: true,
        batch: toDownplay
      });
      toHighlight.length && api.dispatchAction({
        type: 'highlight',
        escapeConnect: true,
        // Not blur others when highlight in axisPointer.
        notBlur: true,
        batch: toHighlight
      });
    }

    function findInputAxisInfo(inputAxesInfo, axisInfo) {
      for (var i = 0; i < (inputAxesInfo || []).length; i++) {
        var inputAxisInfo = inputAxesInfo[i];

        if (axisInfo.axis.dim === inputAxisInfo.axisDim && axisInfo.axis.model.componentIndex === inputAxisInfo.axisIndex) {
          return inputAxisInfo;
        }
      }
    }

    function makeMapperParam(axisInfo) {
      var axisModel = axisInfo.axis.model;
      var item = {};
      var dim = item.axisDim = axisInfo.axis.dim;
      item.axisIndex = item[dim + 'AxisIndex'] = axisModel.componentIndex;
      item.axisName = item[dim + 'AxisName'] = axisModel.name;
      item.axisId = item[dim + 'AxisId'] = axisModel.id;
      return item;
    }

    function illegalPoint(point) {
      return !point || point[0] == null || isNaN(point[0]) || point[1] == null || isNaN(point[1]);
    }

    function install$s(registers) {
      // CartesianAxisPointer is not supposed to be required here. But consider
      // echarts.simple.js and online build tooltip, which only require gridSimple,
      // CartesianAxisPointer should be able to required somewhere.
      AxisView.registerAxisPointerClass('CartesianAxisPointer', CartesianAxisPointer);
      registers.registerComponentModel(AxisPointerModel);
      registers.registerComponentView(AxisPointerView);
      registers.registerPreprocessor(function (option) {
        // Always has a global axisPointerModel for default setting.
        if (option) {
          (!option.axisPointer || option.axisPointer.length === 0) && (option.axisPointer = {});
          var link = option.axisPointer.link; // Normalize to array to avoid object mergin. But if link
          // is not set, remain null/undefined, otherwise it will
          // override existent link setting.

          if (link && !isArray(link)) {
            option.axisPointer.link = [link];
          }
        }
      }); // This process should proformed after coordinate systems created
      // and series data processed. So put it on statistic processing stage.

      registers.registerProcessor(registers.PRIORITY.PROCESSOR.STATISTIC, function (ecModel, api) {
        // Build axisPointerModel, mergin tooltip.axisPointer model for each axis.
        // allAxesInfo should be updated when setOption performed.
        ecModel.getComponent('axisPointer').coordSysAxesInfo = collect(ecModel, api);
      }); // Broadcast to all views.

      registers.registerAction({
        type: 'updateAxisPointer',
        event: 'updateAxisPointer',
        update: ':updateAxisPointer'
      }, axisTrigger);
    }

    function install$t(registers) {
      use(install$5);
      use(install$s);
    }

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

      function PolarAxisPointer() {
        return _super !== null && _super.apply(this, arguments) || this;
      }
      /**
       * @override
       */


      PolarAxisPointer.prototype.makeElOption = function (elOption, value, axisModel, axisPointerModel, api) {
        var axis = axisModel.axis;

        if (axis.dim === 'angle') {
          this.animationThreshold = Math.PI / 18;
        }

        var polar = axis.polar;
        var otherAxis = polar.getOtherAxis(axis);
        var otherExtent = otherAxis.getExtent();
        var coordValue = axis.dataToCoord(value);
        var axisPointerType = axisPointerModel.get('type');

        if (axisPointerType && axisPointerType !== 'none') {
          var elStyle = buildElStyle(axisPointerModel);
          var pointerOption = pointerShapeBuilder$1[axisPointerType](axis, polar, coordValue, otherExtent);
          pointerOption.style = elStyle;
          elOption.graphicKey = pointerOption.type;
          elOption.pointer = pointerOption;
        }

        var labelMargin = axisPointerModel.get(['label', 'margin']);
        var labelPos = getLabelPosition(value, axisModel, axisPointerModel, polar, labelMargin);
        buildLabelElOption(elOption, axisModel, axisPointerModel, api, labelPos);
      };

      return PolarAxisPointer;
    }(BaseAxisPointer);

    function getLabelPosition(value, axisModel, axisPointerModel, polar, labelMargin) {
      var axis = axisModel.axis;
      var coord = axis.dataToCoord(value);
      var axisAngle = polar.getAngleAxis().getExtent()[0];
      axisAngle = axisAngle / 180 * Math.PI;
      var radiusExtent = polar.getRadiusAxis().getExtent();
      var position;
      var align;
      var verticalAlign;

      if (axis.dim === 'radius') {
        var transform = create$1();
        rotate(transform, transform, axisAngle);
        translate(transform, transform, [polar.cx, polar.cy]);
        position = applyTransform$1([coord, -labelMargin], transform);
        var labelRotation = axisModel.getModel('axisLabel').get('rotate') || 0; // @ts-ignore

        var labelLayout = AxisBuilder.innerTextLayout(axisAngle, labelRotation * Math.PI / 180, -1);
        align = labelLayout.textAlign;
        verticalAlign = labelLayout.textVerticalAlign;
      } else {
        // angle axis
        var r = radiusExtent[1];
        position = polar.coordToPoint([r + labelMargin, coord]);
        var cx = polar.cx;
        var cy = polar.cy;
        align = Math.abs(position[0] - cx) / r < 0.3 ? 'center' : position[0] > cx ? 'left' : 'right';
        verticalAlign = Math.abs(position[1] - cy) / r < 0.3 ? 'middle' : position[1] > cy ? 'top' : 'bottom';
      }

      return {
        position: position,
        align: align,
        verticalAlign: verticalAlign
      };
    }

    var pointerShapeBuilder$1 = {
      line: function (axis, polar, coordValue, otherExtent) {
        return axis.dim === 'angle' ? {
          type: 'Line',
          shape: makeLineShape(polar.coordToPoint([otherExtent[0], coordValue]), polar.coordToPoint([otherExtent[1], coordValue]))
        } : {
          type: 'Circle',
          shape: {
            cx: polar.cx,
            cy: polar.cy,
            r: coordValue
          }
        };
      },
      shadow: function (axis, polar, coordValue, otherExtent) {
        var bandWidth = Math.max(1, axis.getBandWidth());
        var radian = Math.PI / 180;
        return axis.dim === 'angle' ? {
          type: 'Sector',
          shape: makeSectorShape(polar.cx, polar.cy, otherExtent[0], otherExtent[1], // In ECharts y is negative if angle is positive
          (-coordValue - bandWidth / 2) * radian, (-coordValue + bandWidth / 2) * radian)
        } : {
          type: 'Sector',
          shape: makeSectorShape(polar.cx, polar.cy, coordValue - bandWidth / 2, coordValue + bandWidth / 2, 0, Math.PI * 2)
        };
      }
    };

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

      function PolarModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = PolarModel.type;
        return _this;
      }

      PolarModel.prototype.findAxisModel = function (axisType) {
        var foundAxisModel;
        var ecModel = this.ecModel;
        ecModel.eachComponent(axisType, function (axisModel) {
          if (axisModel.getCoordSysModel() === this) {
            foundAxisModel = axisModel;
          }
        }, this);
        return foundAxisModel;
      };

      PolarModel.type = 'polar';
      PolarModel.dependencies = ['radiusAxis', 'angleAxis'];
      PolarModel.defaultOption = {
        zlevel: 0,
        z: 0,
        center: ['50%', '50%'],
        radius: '80%'
      };
      return PolarModel;
    }(ComponentModel);

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

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

      PolarAxisModel.prototype.getCoordSysModel = function () {
        return this.getReferringComponents('polar', SINGLE_REFERRING).models[0];
      };

      PolarAxisModel.type = 'polarAxis';
      return PolarAxisModel;
    }(ComponentModel);

    mixin(PolarAxisModel, AxisModelCommonMixin);

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

      function AngleAxisModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = AngleAxisModel.type;
        return _this;
      }

      AngleAxisModel.type = 'angleAxis';
      return AngleAxisModel;
    }(PolarAxisModel);

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

      function RadiusAxisModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = RadiusAxisModel.type;
        return _this;
      }

      RadiusAxisModel.type = 'radiusAxis';
      return RadiusAxisModel;
    }(PolarAxisModel);

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

      function RadiusAxis(scale, radiusExtent) {
        return _super.call(this, 'radius', scale, radiusExtent) || this;
      }

      RadiusAxis.prototype.pointToData = function (point, clamp) {
        return this.polar.pointToData(point, clamp)[this.dim === 'radius' ? 0 : 1];
      };

      return RadiusAxis;
    }(Axis);

    RadiusAxis.prototype.dataToRadius = Axis.prototype.dataToCoord;
    RadiusAxis.prototype.radiusToData = Axis.prototype.coordToData;

    var inner$d = makeInner();

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

      function AngleAxis(scale, angleExtent) {
        return _super.call(this, 'angle', scale, angleExtent || [0, 360]) || this;
      }

      AngleAxis.prototype.pointToData = function (point, clamp) {
        return this.polar.pointToData(point, clamp)[this.dim === 'radius' ? 0 : 1];
      };
      /**
       * Only be called in category axis.
       * Angle axis uses text height to decide interval
       *
       * @override
       * @return {number} Auto interval for cateogry axis tick and label
       */


      AngleAxis.prototype.calculateCategoryInterval = function () {
        var axis = this;
        var labelModel = axis.getLabelModel();
        var ordinalScale = axis.scale;
        var ordinalExtent = ordinalScale.getExtent(); // Providing this method is for optimization:
        // avoid generating a long array by `getTicks`
        // in large category data case.

        var tickCount = ordinalScale.count();

        if (ordinalExtent[1] - ordinalExtent[0] < 1) {
          return 0;
        }

        var tickValue = ordinalExtent[0];
        var unitSpan = axis.dataToCoord(tickValue + 1) - axis.dataToCoord(tickValue);
        var unitH = Math.abs(unitSpan); // Not precise, just use height as text width
        // and each distance from axis line yet.

        var rect = getBoundingRect(tickValue == null ? '' : tickValue + '', labelModel.getFont(), 'center', 'top');
        var maxH = Math.max(rect.height, 7);
        var dh = maxH / unitH; // 0/0 is NaN, 1/0 is Infinity.

        isNaN(dh) && (dh = Infinity);
        var interval = Math.max(0, Math.floor(dh));
        var cache = inner$d(axis.model);
        var lastAutoInterval = cache.lastAutoInterval;
        var lastTickCount = cache.lastTickCount; // Use cache to keep interval stable while moving zoom window,
        // otherwise the calculated interval might jitter when the zoom
        // window size is close to the interval-changing size.

        if (lastAutoInterval != null && lastTickCount != null && Math.abs(lastAutoInterval - interval) <= 1 && Math.abs(lastTickCount - tickCount) <= 1 // Always choose the bigger one, otherwise the critical
        // point is not the same when zooming in or zooming out.
        && lastAutoInterval > interval) {
          interval = lastAutoInterval;
        } // Only update cache if cache not used, otherwise the
        // changing of interval is too insensitive.
        else {
            cache.lastTickCount = tickCount;
            cache.lastAutoInterval = interval;
          }

        return interval;
      };

      return AngleAxis;
    }(Axis);

    AngleAxis.prototype.dataToAngle = Axis.prototype.dataToCoord;
    AngleAxis.prototype.angleToData = Axis.prototype.coordToData;

    var Polar =
    /** @class */
    function () {
      function Polar(name) {
        this.dimensions = ['radius', 'angle'];
        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;
            var d2 = dx * dx + dy * dy;
            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: Polar.prototype.dimensions,
      create: function (ecModel, api) {
        var polarList = [];
        ecModel.eachComponent('polar', function (polarModel, idx) {
          var polar = new Polar(idx + ''); // Inject resize and update method

          polar.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,
              r: ticksCoords[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],
              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
          });
        }
      });
    }
    /**
     * 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 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 colorIndex = lineCount++ % lineColors.length;
          splitLines[colorIndex] = splitLines[colorIndex] || [];
          splitLines[colorIndex].push(new Line({
            subPixelOptimize: true,
            shape: {
              x1: p1[0],
              y1: p1[1],
              x2: p2[0],
              y2: p2[1]
            },
            silent: true
          }));
        }

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

    /**
     * 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 = ['single'];
        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.reverse ? 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: Single.prototype.dimensions
    };

    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%',
          nameMap: 'en',
          color: '#000'
        },
        // month text style
        monthLabel: {
          show: true,
          // start end
          position: 'start',
          margin: 5,
          // center or left
          align: 'center',
          // cn en []
          nameMap: 'en',
          formatter: null,
          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 MONTH_TEXT = {
      EN: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
      CN: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月']
    };
    var WEEK_TEXT = {
      EN: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],
      CN: ['日', '一', '二', '三', '四', '五', '六']
    };

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

        this._renderDayRect(calendarModel, rangeData, group); // _renderLines must be called prior to following function


        this._renderLines(calendarModel, rangeData, orient, group);

        this._renderYearText(calendarModel, rangeData, orient, group);

        this._renderMonthText(calendarModel, orient, group);

        this._renderWeekText(calendarModel, rangeData, orient, group);
      }; // render day rect


      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 (typeof formatter === 'string' && formatter) {
          return formatTplSimple(formatter, params);
        }

        if (typeof formatter === 'function') {
          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, 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 (isString(nameMap)) {
          nameMap = MONTH_TEXT[nameMap.toUpperCase()] || [];
        }

        var idx = pos === 'start' ? 0 : 1;
        var axis = orient === 'horizontal' ? 0 : 1;
        margin = pos === 'start' ? -margin : margin;
        var isCenter = align === 'center';

        for (var i = 0; i < termPoints[idx].length - 1; i++) {
          var tmp = termPoints[idx][i].slice();
          var firstDay = this._firstDayOfMonth[i];

          if (isCenter) {
            var firstDayPoints = this._firstDayPoints[i];
            tmp[axis] = (firstDayPoints[axis] + termPoints[0][i + 1][axis]) / 2;
          }

          var formatter = monthLabel.get('formatter');
          var name_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, 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 (isString(nameMap)) {
          nameMap = WEEK_TEXT[nameMap.toUpperCase()] || [];
        }

        var start = coordSys.getNextNDay(rangeData.end.time, 7 - rangeData.lweek).time;
        var cellSize = [coordSys.getCellWidth(), coordSys.getCellHeight()];
        margin = 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);
    }

    var inner$e = makeInner();
    var _nonShapeGraphicElements = {
      // Reserved but not supported in graphic component.
      path: null,
      compoundPath: null,
      // Supported in graphic component.
      group: Group,
      image: ZRImage,
      text: ZRText
    }; // ------------------------
    // Preprocessor
    // ------------------------

    var preprocessor = function (option) {
      var graphicOption = option.graphic; // Convert
      // {graphic: [{left: 10, type: 'circle'}, ...]}
      // or
      // {graphic: {left: 10, type: 'circle'}}
      // to
      // {graphic: [{elements: [{left: 10, type: 'circle'}, ...]}]}

      if (isArray(graphicOption)) {
        if (!graphicOption[0] || !graphicOption[0].elements) {
          option.graphic = [{
            elements: graphicOption
          }];
        } else {
          // Only one graphic instance can be instantiated. (We dont
          // want that too many views are created in echarts._viewMap)
          option.graphic = [option.graphic[0]];
        }
      } else if (graphicOption && !graphicOption.elements) {
        option.graphic = [{
          elements: [graphicOption]
        }];
      }
    };

    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

        for (var i = existList.length - 1; i >= 0; i--) {
          if (existList[i] == null) {
            existList.splice(i, 1);
          } else {
            // $action should be volatile, otherwise option gotten from
            // `getOption` will contain unexpected $action.
            delete existList[i].$action;
          }
        }
      };
      /**
       * Convert
       * [{
       *  type: 'group',
       *  id: 'xx',
       *  children: [{type: 'circle'}, {type: 'polygon'}]
       * }]
       * to
       * [
       *  {type: 'group', id: 'xx'},
       *  {type: 'circle', parentId: 'xx'},
       *  {type: 'polygon', parentId: 'xx'}
       * ]
       */


      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;

          if (option.type === 'group' && children) {
            this._flatten(children, result, option);
          } // Deleting for JSON output, and for not affecting group creation.


          delete option.children;
        }, this);
      }; // FIXME
      // Pass to view using payload? setOption has a payload?


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

          if ($action === 'merge') {
            elExisting ? elExisting.attr(elOptionCleaned) : createEl$1(id, targetElParent, elOptionCleaned, elMap);
          } else if ($action === 'replace') {
            removeEl(elExisting, elMap);
            createEl$1(id, targetElParent, elOptionCleaned, elMap);
          } else if ($action === 'remove') {
            removeEl(elExisting, elMap);
          }

          var el = elMap.get(id);

          if (el && textContentOption) {
            if ($action === 'merge') {
              var textContentExisting = el.getTextContent();
              textContentExisting ? textContentExisting.attr(textContentOption) : el.setTextContent(new ZRText(textContentOption));
            } else if ($action === 'replace') {
              el.setTextContent(new ZRText(textContentOption));
            }
          }

          if (el) {
            var elInner = inner$e(el);
            elInner.__ecGraphicWidthOption = elOption.width;
            elInner.__ecGraphicHeightOption = elOption.height;
            setEventData(el, graphicModel, elOption);
            setTooltipConfig({
              el: el,
              componentModel: graphicModel,
              itemName: el.name,
              itemTooltipOption: elOption.tooltip
            });
          }
        });
      };
      /**
       * 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(); // 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.__ecGraphicWidth = parsePercent$1(elInner.__ecGraphicWidthOption, isParentRoot ? apiWidth : parentElInner.__ecGraphicWidth) || 0;
          elInner.__ecGraphicHeight = parsePercent$1(elInner.__ecGraphicHeightOption, isParentRoot ? apiHeight : parentElInner.__ecGraphicHeight) || 0;
        } // Bottom-up tranvese all elements (consider ec resize) to locate elements.


        for (var i = elOptions.length - 1; i >= 0; i--) {
          var elOption = elOptions[i];
          var 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.__ecGraphicWidth,
            height: parentElInner.__ecGraphicHeight
          }; // PENDING
          // Currently, when `bounding: 'all'`, the union bounding rect of the group
          // does not include the rect of [0, 0, group.width, group.height], which
          // is probably weird for users. Should we make a break change for it?

          positionElement(el, elOption, containerInfo, null, {
            hv: elOption.hv,
            boundingMode: elOption.bounding
          });
        }
      };
      /**
       * Clear all elements.
       */


      GraphicComponentView.prototype._clear = function () {
        var elMap = this._elMap;
        elMap.each(function (el) {
          removeEl(el, elMap);
        });
        this._elMap = createHashMap();
      };

      GraphicComponentView.prototype.dispose = function () {
        this._clear();
      };

      GraphicComponentView.type = 'graphic';
      return GraphicComponentView;
    }(ComponentView);

    function createEl$1(id, targetElParent, elOption, elMap) {
      var graphicType = elOption.type;

      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 can not be found');
      }

      var el = new Clz(elOption);
      targetElParent.add(el);
      elMap.set(id, el);
      inner$e(el).__ecGraphicId = id;
    }

    function removeEl(elExisting, elMap) {
      var existElParent = elExisting && elExisting.parent;

      if (existElParent) {
        elExisting.type === 'group' && elExisting.traverse(function (el) {
          removeEl(el, elMap);
        });
        elMap.removeKey(inner$e(elExisting).__ecGraphicId);
        existElParent.remove(elExisting);
      }
    } // Remove unnecessary props to avoid potential problems.


    function getCleanedElOption(elOption) {
      elOption = extend({}, elOption);
      each(['id', 'parentId', '$action', 'hv', 'bounding', 'textContent'].concat(LOCATION_PARAMS), function (name) {
        delete elOption[name];
      });
      return elOption;
    }

    function isSetLoc(obj, props) {
      var isSet;
      each(props, function (prop) {
        obj[prop] != null && obj[prop] !== 'auto' && (isSet = true);
      });
      return isSet;
    }

    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 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);
        } else {
          existList[index] = newElOptCopy;
        }
      } else if ($action === 'replace') {
        existList[index] = newElOptCopy;
      } else if ($action === 'remove') {
        // null will be cleaned later.
        existElOption && (existList[index] = null);
      }
    }

    function setLayoutInfoToExist(existItem, newElOption) {
      if (!existItem) {
        return;
      }

      existItem.hv = newElOption.hv = [// Rigid body, dont care `width`.
      isSetLoc(newElOption, ['left', 'right']), // Rigid body, dont care `height`.
      isSetLoc(newElOption, ['top', 'bottom'])]; // Give default group size. Otherwise layout error may occur.

      if (existItem.type === 'group') {
        var existingGroupOpt = existItem;
        var newGroupOpt = newElOption;
        existingGroupOpt.width == null && (existingGroupOpt.width = newGroupOpt.width = 0);
        existingGroupOpt.height == null && (existingGroupOpt.height = newGroupOpt.height = 0);
      }
    }

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

    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; // if (!env.canvasSupported) {
        //     thisOption.realtime = false;
        // }

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

          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 the those raw params from option, which will be cached separately.
     * becasue they will be overwritten by normalized/calculated values in the main
     * process.
     */


    function retrieveRawOption(option) {
      var ret = {};
      each(['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$9 = 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$9(['start', 'end'], function (prop, idx) {
          var boundPercent = opt[prop];
          var boundValue = opt[prop + 'Value']; // Notice: dataZoom is based either on `percentProp` ('start', 'end') or
          // on `valueProp` ('startValue', 'endValue'). (They are based on the data extent
          // but not min/max of axis, which will be calculated by data window then).
          // The former one is suitable for cases that a dataZoom component controls multiple
          // axes with different unit or extent, and the latter one is suitable for accurate
          // zoom by pixel (e.g., in dataZoomSelect).
          // we use `getRangePropMode()` to mark which prop is used. `rangePropMode` is updated
          // only when setOption or dispatchAction, otherwise it remains its original value.
          // (Why not only record `percentProp` and always map to `valueProp`? Because
          // the map `valueProp` -> `percentProp` -> `valueProp` probably not the original
          // `valueProp`. consider two axes constrolled by one dataZoom. They have different
          // data extent. All of values that are overflow the `dataExtent` will be calculated
          // to percent '100%').

          if (rangePropMode[idx] === 'percent') {
            boundPercent == null && (boundPercent = percentExtent[idx]); // Use scale.parse to math round for category or time axis.

            boundValue = scale.parse(linearMap(boundPercent, percentExtent, dataExtent));
          } else {
            hasPropModeValue = true;
            boundValue = boundValue == null ? dataExtent[idx] : scale.parse(boundValue); // Calculating `percent` from `value` may be not accurate, because
            // This calculation can not be inversed, because all of values that
            // are overflow the `dataExtent` will be calculated to percent '100%'

            boundPercent = linearMap(boundValue, dataExtent, percentExtent);
          } // valueWindow[idx] = round(boundValue);
          // percentWindow[idx] = round(boundPercent);


          valueWindow[idx] = boundValue;
          percentWindow[idx] = boundPercent;
        });
        asc$1(valueWindow);
        asc$1(percentWindow); // The windows from user calling of `dispatchAction` might be out of the extent,
        // or do not obey the `min/maxSpan`, `min/maxValueSpan`. But we dont restrict window
        // by `zoomLock` here, because we see `zoomLock` just as a interaction constraint,
        // where API is able to initialize/modify the window size even though `zoomLock`
        // specified.

        var spans = this._minMaxSpan;
        hasPropModeValue ? restrictSet(valueWindow, percentWindow, dataExtent, percentExtent, false) : restrictSet(percentWindow, valueWindow, percentExtent, dataExtent, true);

        function restrictSet(fromWindow, toWindow, fromExtent, toExtent, toValue) {
          var suffix = toValue ? 'Span' : 'ValueSpan';
          sliderMove(0, fromWindow, fromExtent, 'all', spans['min' + suffix], spans['max' + suffix]);

          for (var i = 0; i < 2; i++) {
            toWindow[i] = linearMap(fromWindow[i], fromExtent, toExtent, true);
            toValue && (toWindow[i] = scale.parse(toWindow[i]));
          }
        }

        return {
          valueWindow: valueWindow,
          percentWindow: percentWindow
        };
      };
      /**
       * Notice: reset should not be called before series.restoreData() called,
       * so it is recommanded to be called in "process stage" but not "model init
       * stage".
       */


      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); // this.hasSeriesStacked = false;
        // each(targetSeries, function (series) {
        // let data = series.getData();
        // let dataDim = data.mapDimension(this._dimName);
        // let stackedDimension = data.getCalculationInfo('stackedDimension');
        // if (stackedDimension && stackedDimension === dataDim) {
        // this.hasSeriesStacked = true;
        // }
        // }, this);
        // `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$9(seriesModels, function (seriesModel) {
          var seriesData = seriesModel.getData();
          var dataDims = seriesData.mapDimensionsAll(axisDim);

          if (!dataDims.length) {
            return;
          }

          if (filterMode === 'weakFilter') {
            seriesData.filterSelf(function (dataIndex) {
              var leftOut;
              var rightOut;
              var hasValue;

              for (var i = 0; i < dataDims.length; i++) {
                var value = seriesData.get(dataDims[i], dataIndex);
                var thisHasValue = !isNaN(value);
                var thisLeftOut = value < valueWindow[0];
                var thisRightOut = value > valueWindow[1];

                if (thisHasValue && !thisLeftOut && !thisRightOut) {
                  return true;
                }

                thisHasValue && (hasValue = true);
                thisLeftOut && (leftOut = true);
                thisRightOut && (rightOut = true);
              } // If both left out and right out, do not filter.


              return hasValue && leftOut && rightOut;
            });
          } else {
            each$9(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$9(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$9(['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$9(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 featureOpts = toolboxModel.get('feature') || {};
        var features = this._features || (this._features = {});
        var featureNames = [];
        each(featureOpts, function (opt, name) {
          featureNames.push(name);
        });
        new DataDiffer(this._featureNames || [], featureNames).add(processFeature).update(processFeature).remove(curry(processFeature, null)).execute(); // Keep for diff.

        this._featureNames = featureNames;

        function processFeature(newIndex, oldIndex) {
          var featureName = featureNames[newIndex];
          var oldName = featureNames[oldIndex];
          var featureOpt = featureOpts[featureName];
          var featureModel = new Model(featureOpt, toolboxModel, toolboxModel.ecModel);
          var feature; // FIX#11236, merge feature title from MagicType newOption. TODO: consider seriesIndex ?

          if (payload && payload.newTitle != null && payload.featureName === featureName) {
            featureOpt.title = payload.newTitle;
          }

          if (featureName && !oldName) {
            // Create
            if (isUserFeatureName(featureName)) {
              feature = {
                onclick: featureModel.option.onclick,
                featureName: featureName
              };
            } else {
              var Feature = getFeature(featureName);

              if (!Feature) {
                return;
              }

              feature = new Feature();
            }

            features[featureName] = feature;
          } else {
            feature = features[oldName]; // If feature does not exsit.

            if (!feature) {
              return;
            }
          }

          feature.uid = getUID('toolbox-feature');
          feature.model = featureModel;
          feature.ecModel = ecModel;
          feature.api = api;

          if (feature instanceof ToolboxFeature) {
            if (!featureName && oldName) {
              feature.dispose && feature.dispose(ecModel, api);
              return;
            }

            if (!featureModel.get('show') || feature.unusable) {
              feature.remove && feature.remove(ecModel, api);
              return;
            }
          }

          createIconPaths(featureModel, feature, featureName);

          featureModel.setIconStatus = function (iconName, status) {
            var option = this.option;
            var iconPaths = this.iconPaths;
            option.iconStatus = option.iconStatus || {};
            option.iconStatus[iconName] = status;

            if (iconPaths[iconName]) {
              (status === 'emphasis' ? enterEmphasis : leaveEmphasis)(iconPaths[iconName]);
            }
          };

          if (feature instanceof ToolboxFeature) {
            if (feature.render) {
              feature.render(featureModel, ecModel, api, payload);
            }
          }
        }

        function createIconPaths(featureModel, feature, featureName) {
          var iconStyleModel = featureModel.getModel('iconStyle');
          var iconStyleEmphasisModel = featureModel.getModel(['emphasis', 'iconStyle']); // If one feature has mutiple icon. they are orginaized as
          // {
          //     icon: {
          //         foo: '',
          //         bar: ''
          //     },
          //     title: {
          //         foo: '',
          //         bar: ''
          //     }
          // }

          var icons = feature instanceof ToolboxFeature && feature.getIcons ? feature.getIcons() : featureModel.get('icon');
          var titles = featureModel.get('title') || {};
          var iconsMap;
          var titlesMap;

          if (typeof icons === 'string') {
            iconsMap = {};
            iconsMap[featureName] = icons;
          } else {
            iconsMap = icons;
          }

          if (typeof titles === 'string') {
            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]
              }
            }); // graphic.enableHoverEmphasis(path);

            path.__title = titlesMap[iconName];
            path.on('mouseover', function () {
              // Should not reuse above hoverStyle, which might be modified.
              var hoverStyle = iconStyleEmphasisModel.getItemStyle();
              var defaultTextPosition = toolboxModel.get('orient') === 'vertical' ? toolboxModel.get('right') == null ? 'right' : 'left' : toolboxModel.get('bottom') == null ? 'bottom' : 'top';
              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.

              enterEmphasis(this);
            }).on('mouseout', function () {
              if (featureModel.get(['iconStatus', iconName]) !== 'emphasis') {
                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

        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.states.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 + 8;

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

    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')
        }); // Chrome, Firefox, New Edge

        if (typeof MouseEvent === 'function' && (env.browser.newEdge || !env.browser.ie && !env.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 {
            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 = atob(bstr));
              var filename = title + '.' + type;

              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]);
                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.getLocale(['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.getLocale(['toolbox', 'saveAsImage', 'lang'])
        };
        return defaultOption;
      };

      return SaveAsImage;
    }(ToolboxFeature);

    SaveAsImage.prototype.unusable = !env.canvasSupported;

    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.getLocale(['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; // 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);
        }

        api.dispatchAction({
          type: 'changeMagicType',
          currentType: type,
          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);
    });

    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) {
        var container = api.getDom();
        var model = this.model;

        if (this._dom) {
          container.removeChild(this._dom);
        }

        var root = document.createElement('div');
        root.style.cssText = 'position:absolute;left:5px;top:5px;bottom:5px;right:5px;';
        root.style.backgroundColor = model.get('backgroundColor') || '#fff'; // Create elements

        var header = document.createElement('h4');
        var lang = model.get('lang') || [];
        header.innerHTML = lang[0] || model.get('title');
        header.style.cssText = 'margin: 10px 20px;';
        header.style.color = model.get('textColor');
        var viewMain = document.createElement('div');
        var textarea = document.createElement('textarea');
        viewMain.style.cssText = 'display:block;width:100%;overflow:auto;';
        var optionToContent = model.get('optionToContent');
        var contentToOption = model.get('contentToOption');
        var result = getContentFromModel(ecModel);

        if (typeof optionToContent === 'function') {
          var htmlOrDom = optionToContent(api.getOption());

          if (typeof htmlOrDom === 'string') {
            viewMain.innerHTML = htmlOrDom;
          } else if (isDom(htmlOrDom)) {
            viewMain.appendChild(htmlOrDom);
          }
        } else {
          // Use default textarea
          viewMain.appendChild(textarea);
          textarea.readOnly = model.get('readOnly');
          textarea.style.cssText = 'width:100%;height:100%;font-family:monospace;font-size:14px;line-height:1.6rem;';
          textarea.style.color = model.get('textColor');
          textarea.style.borderColor = model.get('textareaBorderColor');
          textarea.style.backgroundColor = model.get('textareaColor');
          textarea.value = result.value;
        }

        var blockMetaList = result.meta;
        var buttonContainer = document.createElement('div');
        buttonContainer.style.cssText = 'position:absolute;bottom:0;left:0;right:0;';
        var buttonStyle = 'float:right;margin-right:20px;border:none;' + 'cursor:pointer;padding:2px 5px;font-size:12px;border-radius:3px';
        var closeButton = document.createElement('div');
        var refreshButton = document.createElement('div');
        buttonStyle += ';background-color:' + model.get('buttonColor');
        buttonStyle += ';color:' + model.get('buttonTextColor');
        var self = this;

        function close() {
          container.removeChild(root);
          self._dom = null;
        }

        addEventListener(closeButton, 'click', close);
        addEventListener(refreshButton, 'click', function () {
          if (contentToOption == null && optionToContent != null || contentToOption != null && optionToContent == null) {
            if ("development" !== 'production') {
              // eslint-disable-next-line
              console.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 (typeof contentToOption === 'function') {
              newOption = contentToOption(viewMain, api.getOption());
            } else {
              newOption = parseContents(textarea.value, blockMetaList);
            }
          } catch (e) {
            close();
            throw new Error('Data view format error ' + e);
          }

          if (newOption) {
            api.dispatchAction({
              type: 'changeDataView',
              newOption: newOption
            });
          }

          close();
        });
        closeButton.innerHTML = lang[1];
        refreshButton.innerHTML = lang[2];
        refreshButton.style.cssText = buttonStyle;
        closeButton.style.cssText = buttonStyle;
        !model.get('readOnly') && buttonContainer.appendChild(refreshButton);
        buttonContainer.appendChild(closeButton);
        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.getLocale(['toolbox', 'dataView', 'title']),
          lang: ecModel.getLocale(['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$a = 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$a(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$a(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.getLocale(['toolbox', 'restore', 'title'])
        };
        return defaultOption;
      };

      return RestoreOption;
    }(ToolboxFeature); // TODO: SELF REGISTERED.


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

    var COORD_CONVERTS = ['dataToPoint', 'pointToData']; // FIXME
    // how to genarialize to more coordinate systems.

    var INCLUDE_FINDER_MAIN_TYPES = ['grid', 'xAxis', 'yAxis', 'geo', 'graph', 'polar', 'radiusAxis', 'angleAxis', 'bmap'];

    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);
              cb(area, result.values, coordSys, ecModel);
            });
          }
        }, this);
      };
      /**
       * the `areas` is `BrushModel.areas`.
       * Called in layout stage.
       * convert `area.coordRange` to global range and set panelId to `area.range`.
       */


      BrushTargetManager.prototype.setInputRanges = function (areas, ecModel) {
        each(areas, function (area) {
          var targetInfo = this.findTargetInfo(area, ecModel);

          if ("development" !== 'production') {
            assert(!targetInfo || targetInfo === true || area.coordRange, 'coordRange must be specified when coord index specified.');
            assert(!targetInfo || targetInfo !== true || area.range, 'range must be specified in global brush.');
          }

          area.range = area.range || []; // convert coordRange to global range and set panelId.

          if (targetInfo && targetInfo !== true) {
            area.panelId = targetInfo.panelId; // (1) area.range shoule always be calculate from coordRange but does
            // not keep its original value, for the sake of the dataZoom scenario,
            // where area.coordRange remains unchanged but area.range may be changed.
            // (2) Only support converting one coordRange to pixel range in brush
            // component. So do not consider `coordRanges`.
            // (3) About __rangeOffset, see comment above.

            var result = coordConvert[area.brushType](0, targetInfo.coordSys, area.coordRange);
            var rangeOffset = area.__rangeOffset;
            area.range = rangeOffset ? diffProcessor[area.brushType](result.values, rangeOffset.offset, getScales(result.xyMinMax, rangeOffset.xyMinMax)) : result.values;
          }
        }, this);
      };

      BrushTargetManager.prototype.makePanelOpts = function (api, getDefaultBrushType) {
        return map(this._targetInfoList, function (targetInfo) {
          var rect = targetInfo.getPanelRect();
          return {
            panelId: targetInfo.panelId,
            defaultBrushType: getDefaultBrushType ? getDefaultBrushType(targetInfo) : null,
            clipPath: makeRectPanelClipPath(rect),
            isTargetByCursor: makeRectIsTargetByCursor(rect, api, targetInfo.coordSysModel),
            getLinearBrushOtherExtent: makeLinearBrushOtherExtent(rect)
          };
        });
      };

      BrushTargetManager.prototype.controlSeries = function (area, seriesModel, ecModel) {
        // Check whether area is bound in coord, and series do not belong to that coord.
        // If do not do this check, some brush (like lineX) will controll all axes.
        var targetInfo = this.findTargetInfo(area, ecModel);
        return targetInfo === true || targetInfo && indexOf(targetInfo.coordSyses, seriesModel.coordinateSystem) >= 0;
      };
      /**
       * If return Object, a coord found.
       * If reutrn true, global found.
       * Otherwise nothing found.
       */


      BrushTargetManager.prototype.findTargetInfo = function (area, ecModel) {
        var targetInfoList = this._targetInfoList;
        var foundCpts = parseFinder$1(ecModel, area);

        for (var i = 0; i < targetInfoList.length; i++) {
          var targetInfo = targetInfoList[i];
          var areaPanelId = area.panelId;

          if (areaPanelId) {
            if (targetInfo.panelId === areaPanelId) {
              return targetInfo;
            }
          } else {
            for (var j = 0; j < targetInfoMatchers.length; j++) {
              if (targetInfoMatchers[j](foundCpts, targetInfo)) {
                return targetInfo;
              }
            }
          }
        }

        return true;
      };

      return BrushTargetManager;
    }();

    function formatMinMax(minMax) {
      minMax[0] > minMax[1] && minMax.reverse();
      return minMax;
    }

    function parseFinder$1(ecModel, finder) {
      return parseFinder(ecModel, finder, {
        includeMainTypes: INCLUDE_FINDER_MAIN_TYPES
      });
    }

    var targetInfoBuilders = {
      grid: function (foundCpts, targetInfoList) {
        var xAxisModels = foundCpts.xAxisModels;
        var yAxisModels = foundCpts.yAxisModels;
        var gridModels = foundCpts.gridModels; // Remove duplicated.

        var gridModelMap = createHashMap();
        var xAxesHas = {};
        var yAxesHas = {};

        if (!xAxisModels && !yAxisModels && !gridModels) {
          return;
        }

        each(xAxisModels, function (axisModel) {
          var gridModel = axisModel.axis.grid.model;
          gridModelMap.set(gridModel.id, gridModel);
          xAxesHas[gridModel.id] = true;
        });
        each(yAxisModels, function (axisModel) {
          var gridModel = axisModel.axis.grid.model;
          gridModelMap.set(gridModel.id, gridModel);
          yAxesHas[gridModel.id] = true;
        });
        each(gridModels, function (gridModel) {
          gridModelMap.set(gridModel.id, gridModel);
          xAxesHas[gridModel.id] = true;
          yAxesHas[gridModel.id] = true;
        });
        gridModelMap.each(function (gridModel) {
          var grid = gridModel.coordinateSystem;
          var cartesians = [];
          each(grid.getCartesians(), function (cartesian, index) {
            if (indexOf(xAxisModels, cartesian.getAxis('x').model) >= 0 || indexOf(yAxisModels, cartesian.getAxis('y').model) >= 0) {
              cartesians.push(cartesian);
            }
          });
          targetInfoList.push({
            panelId: 'grid--' + gridModel.id,
            gridModel: gridModel,
            coordSysModel: gridModel,
            // Use the first one as the representitive coordSys.
            coordSys: cartesians[0],
            coordSyses: cartesians,
            getPanelRect: panelRectBuilders.grid,
            xAxisDeclared: xAxesHas[gridModel.id],
            yAxisDeclared: yAxesHas[gridModel.id]
          });
        });
      },
      geo: function (foundCpts, targetInfoList) {
        each(foundCpts.geoModels, function (geoModel) {
          var coordSys = geoModel.coordinateSystem;
          targetInfoList.push({
            panelId: 'geo--' + geoModel.id,
            geoModel: geoModel,
            coordSysModel: geoModel,
            coordSys: coordSys,
            coordSyses: [coordSys],
            getPanelRect: panelRectBuilders.geo
          });
        });
      }
    };
    var targetInfoMatchers = [// grid
    function (foundCpts, targetInfo) {
      var xAxisModel = foundCpts.xAxisModel;
      var yAxisModel = foundCpts.yAxisModel;
      var gridModel = foundCpts.gridModel;
      !gridModel && xAxisModel && (gridModel = xAxisModel.axis.grid.model);
      !gridModel && yAxisModel && (gridModel = yAxisModel.axis.grid.model);
      return gridModel && gridModel === targetInfo.gridModel;
    }, // geo
    function (foundCpts, targetInfo) {
      var geoModel = foundCpts.geoModel;
      return geoModel && geoModel === targetInfo.geoModel;
    }];
    var panelRectBuilders = {
      grid: function () {
        // grid is not Transformable.
        return this.coordSys.master.getRect().clone();
      },
      geo: function () {
        var coordSys = this.coordSys;
        var rect = coordSys.getBoundingRect().clone(); // geo roam and zoom transform

        rect.applyTransform(getTransform(coordSys));
        return rect;
      }
    };
    var coordConvert = {
      lineX: curry(axisConvert, 0),
      lineY: curry(axisConvert, 1),
      rect: function (to, coordSys, rangeOrCoordRange) {
        var xminymin = coordSys[COORD_CONVERTS[to]]([rangeOrCoordRange[0][0], rangeOrCoordRange[1][0]]);
        var xmaxymax = coordSys[COORD_CONVERTS[to]]([rangeOrCoordRange[0][1], rangeOrCoordRange[1][1]]);
        var values = [formatMinMax([xminymin[0], xmaxymax[0]]), formatMinMax([xminymin[1], xmaxymax[1]])];
        return {
          values: values,
          xyMinMax: values
        };
      },
      polygon: function (to, coordSys, rangeOrCoordRange) {
        var xyMinMax = [[Infinity, -Infinity], [Infinity, -Infinity]];
        var values = map(rangeOrCoordRange, function (item) {
          var p = coordSys[COORD_CONVERTS[to]](item);
          xyMinMax[0][0] = Math.min(xyMinMax[0][0], p[0]);
          xyMinMax[1][0] = Math.min(xyMinMax[1][0], p[1]);
          xyMinMax[0][1] = Math.max(xyMinMax[0][1], p[0]);
          xyMinMax[1][1] = Math.max(xyMinMax[1][1], p[1]);
          return p;
        });
        return {
          values: values,
          xyMinMax: xyMinMax
        };
      }
    };

    function axisConvert(axisNameIndex, to, coordSys, rangeOrCoordRange) {
      if ("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])) : 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(xyMinMaxCurr);
      var sizeOrigin = getSize(xyMinMaxOrigin);
      var scales = [sizeCurr[0] / sizeOrigin[0], sizeCurr[1] / sizeOrigin[1]];
      isNaN(scales[0]) && (scales[0] = 1);
      isNaN(scales[1]) && (scales[1] = 1);
      return scales;
    }

    function getSize(xyMinMax) {
      return xyMinMax ? [xyMinMax[0][1] - xyMinMax[0][0], xyMinMax[1][1] - xyMinMax[1][0]] : [NaN, NaN];
    }

    var each$b = 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$b(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.getLocale(['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);

      if (!toolboxModel) {
        return;
      }

      var dzFeatureModel = toolboxModel.getModel(['feature', 'dataZoom']);
      var dzOptions = [];
      var finder = makeAxisFinder(dzFeatureModel);
      var finderResult = parseFinder(ecModel, finder);
      each$b(finderResult.xAxisModels, function (axisModel) {
        return buildInternalOptions(axisModel, 'xAxis', 'xAxisIndex');
      });
      each$b(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(backgroundColor, borderColor, arrowPosition) {
      if (!isString(arrowPosition) || arrowPosition === 'inside') {
        return '';
      }

      borderColor = convertToColorString(borderColor);
      var arrowPos = mirrorPos(arrowPosition);
      var positionStyle = arrowPos + ":-6px;";
      var transformStyle = CSS_TRANSFORM_VENDOR + ':';

      if (indexOf(['left', 'right'], arrowPos) > -1) {
        positionStyle += 'top:50%';
        transformStyle += "translateY(-50%) rotate(" + (arrowPos === 'left' ? -225 : -45) + "deg)";
      } else {
        positionStyle += 'left:50%';
        transformStyle += "translateX(-50%) rotate(" + (arrowPos === 'top' ? 225 : 45) + "deg)";
      }

      var borderStyle = borderColor + " solid 1px;";
      var styleCss = ['position:absolute;width:10px;height:10px;', positionStyle + ";" + transformStyle + ";", "border-bottom:" + borderStyle, "border-right:" + borderStyle, "background-color:" + backgroundColor + ";", 'box-shadow:8px 8px 16px -3px #000;'];
      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 ? "," + 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) {
        if (env.canvasSupported) {
          cssText.push('background-color:' + backgroundColor);
        } else {
          // for ie
          cssText.push('background-color:#' + toHex(backgroundColor));
          cssText.push('filter:alpha(opacity=70)');
        }
      } // Border style


      each(['width', 'color', 'radius'], function (name) {
        var borderName = 'border-' + name;
        var camelCase = toCamelCase(borderName);
        var val = tooltipModel.get(camelCase);
        val != null && cssText.push(borderName + ':' + val + (name === 'color' ? '' : 'px'));
      }); // Text style

      cssText.push(assembleFont(textStyleModel)); // Padding

      if (padding != null) {
        cssText.push('padding:' + normalizeCssArray$1(padding).join('px ') + 'px');
      }

      return cssText.join(';') + ';';
    } // If not able to make, do not modify the input `out`.


    function makeStyleCoord(out, zr, appendToBody, zrX, zrY) {
      var zrPainter = zr && zr.painter;

      if (appendToBody) {
        var zrViewportRoot = zrPainter && zrPainter.getViewportRoot();

        if (zrViewportRoot) {
          // Some APPs might use scale on body, so we support CSS transform here.
          transformLocalCoord(out, zrViewportRoot, document.body, zrX, zrY);
        }
      } else {
        out[0] = zrX;
        out[1] = zrY; // xy should be based on canvas root. But tooltipContent is
        // the sibling of canvas root. So padding of ec container
        // should be considered here.

        var viewportRootOffset = zrPainter && zrPainter.getViewportRootOffset();

        if (viewportRootOffset) {
          out[0] += viewportRootOffset.offsetLeft;
          out[1] += viewportRootOffset.offsetTop;
        }
      }

      out[2] = out[0] / zr.getWidth();
      out[3] = out[1] / zr.getHeight();
    }

    var TooltipHTMLContent =
    /** @class */
    function () {
      function TooltipHTMLContent(container, api, opt) {
        this._show = false;
        this._styleCoord = [0, 0, 0, 0];
        this._enterable = true;
        this._firstShow = true;
        this._longHide = true;

        if (env.wxa) {
          return null;
        }

        var el = document.createElement('div'); // TODO: TYPE

        el.domBelongToZr = true;
        this.el = el;
        var zr = this._zr = api.getZr();
        var appendToBody = this._appendToBody = opt && opt.appendToBody;
        makeStyleCoord(this._styleCoord, zr, appendToBody, api.getWidth() / 2, api.getHeight() / 2);

        if (appendToBody) {
          document.body.appendChild(el);
        } else {
          container.appendChild(el);
        }

        this._container = container; // FIXME
        // Is it needed to trigger zr event manually if
        // the browser do not support `pointer-events: none`.

        var self = this;

        el.onmouseenter = function () {
          // clear the timeout in hideLater and keep showing tooltip
          if (self._enterable) {
            clearTimeout(self._hideTimeout);
            self._show = true;
          }

          self._inContent = true;
        };

        el.onmousemove = function (e) {
          e = e || window.event;

          if (!self._enterable) {
            // `pointer-events: none` is set to tooltip content div
            // if `enterable` is set as `false`, and `el.onmousemove`
            // can not be triggered. But in browser that do not
            // support `pointer-events`, we need to do this:
            // Try trigger zrender event to avoid mouse
            // in and out shape too frequently
            var handler = zr.handler;
            var zrViewportRoot = zr.painter.getViewportRoot();
            normalizeEvent(zrViewportRoot, e, true);
            handler.dispatch('mousemove', e);
          }
        };

        el.onmouseleave = function () {
          // set `_inContent` to `false` before `hideLater`
          self._inContent = false;

          if (self._enterable) {
            if (self._show) {
              self.hideLater(self._hideDelay);
            }
          }
        };
      }
      /**
       * Update when tooltip is rendered
       */


      TooltipHTMLContent.prototype.update = function (tooltipModel) {
        // FIXME
        // Move this logic to ec main?
        var container = this._container;
        var position = getComputedStyle(container, 'position');
        var domStyle = container.style;

        if (domStyle.position !== 'absolute' && position !== 'absolute') {
          domStyle.position = 'relative';
        } // move tooltip if chart resized


        var alwaysShowContent = tooltipModel.get('alwaysShowContent');
        alwaysShowContent && this._moveIfResized(); // update className

        this.el.className = tooltipModel.get('className') || ''; // Hide the tooltip
        // PENDING
        // this.hide();
      };

      TooltipHTMLContent.prototype.show = function (tooltipModel, nearPointColor) {
        clearTimeout(this._hideTimeout);
        clearTimeout(this._longHideTimeout);
        var el = this.el;
        var style = el.style;
        var styleCoord = this._styleCoord;

        if (!el.innerHTML) {
          style.display = 'none';
        } else {
          style.cssText = gCssText + assembleCssText(tooltipModel, !this._firstShow, this._longHide) // initial transform
          + assembleTransform(styleCoord[0], styleCoord[1], true) + ("border-color:" + convertToColorString(nearPointColor) + ";") + (tooltipModel.get('extraCssText') || '') // If mouse occasionally move over the tooltip, a mouseout event will be
          // triggered by canvas, and cause some unexpectable result like dragging
          // stop, "unfocusAdjacency". Here `pointer-events: none` is used to solve
          // it. Although it is not supported by IE8~IE10, fortunately it is a rare
          // scenario.
          + (";pointer-event:" + (this._enterable ? 'auto' : 'none'));
        }

        this._show = true;
        this._firstShow = false;
        this._longHide = false;
      };

      TooltipHTMLContent.prototype.setContent = function (content, markers, tooltipModel, borderColor, arrowPosition) {
        if (content == null) {
          return;
        }

        var el = this.el;

        if (isString(arrowPosition) && tooltipModel.get('trigger') === 'item' && !shouldTooltipConfine(tooltipModel)) {
          content += assembleArrow(tooltipModel.get('backgroundColor'), borderColor, arrowPosition);
        }

        if (isString(content)) {
          el.innerHTML = content;
        } 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]);
            }
          }
        }
      };

      TooltipHTMLContent.prototype.setEnterable = function (enterable) {
        this._enterable = enterable;
      };

      TooltipHTMLContent.prototype.getSize = function () {
        var el = this.el;
        return [el.clientWidth, el.clientHeight];
      };

      TooltipHTMLContent.prototype.moveTo = function (zrX, zrY) {
        var styleCoord = this._styleCoord;
        makeStyleCoord(styleCoord, this._zr, this._appendToBody, zrX, zrY);

        if (styleCoord[0] != null && styleCoord[1] != null) {
          var style_1 = this.el.style;
          var transforms = assembleTransform(styleCoord[0], styleCoord[1]);
          each(transforms, function (transform) {
            style_1[transform[0]] = transform[1];
          });
        }
      };
      /**
       * when `alwaysShowContent` is true,
       * move the tooltip after chart resized
       */


      TooltipHTMLContent.prototype._moveIfResized = function () {
        // The ratio of left to width
        var ratioX = this._styleCoord[2]; // The ratio of top to height

        var ratioY = this._styleCoord[3];
        this.moveTo(ratioX * this._zr.getWidth(), ratioY * this._zr.getHeight());
      };

      TooltipHTMLContent.prototype.hide = function () {
        var _this = this;

        var style = this.el.style;
        style.visibility = 'hidden';
        style.opacity = '0';
        env.transform3dSupported && (style.willChange = '');
        this._show = false;
        this._longHideTimeout = setTimeout(function () {
          return _this._longHide = true;
        }, 500);
      };

      TooltipHTMLContent.prototype.hideLater = function (time) {
        if (this._show && !(this._inContent && this._enterable)) {
          if (time) {
            this._hideDelay = time; // Set show false to avoid invoke hideLater multiple times

            this._show = false;
            this._hideTimeout = setTimeout(bind(this.hide, this), time);
          } else {
            this.hide();
          }
        }
      };

      TooltipHTMLContent.prototype.isShow = function () {
        return this._show;
      };

      TooltipHTMLContent.prototype.dispose = function () {
        this.el.parentNode.removeChild(this.el);
      };

      TooltipHTMLContent.prototype.getOuterSize = function () {
        var width = this.el.clientWidth;
        var height = this.el.clientHeight; // Consider browser compatibility.
        // IE8 does not support getComputedStyle.

        var stl = getComputedStyle(this.el);

        if (stl) {
          width += parseInt(stl.borderLeftWidth, 10) + parseInt(stl.borderRightWidth, 10);
          height += parseInt(stl.borderTopWidth, 10) + parseInt(stl.borderBottomWidth, 10);
        }

        return {
          width: width,
          height: height
        };
      };

      return TooltipHTMLContent;
    }();

    var TooltipRichContent =
    /** @class */
    function () {
      function TooltipRichContent(api) {
        this._show = false;
        this._styleCoord = [0, 0, 0, 0];
        this._enterable = true;
        this._zr = api.getZr();
        makeStyleCoord$1(this._styleCoord, this._zr, api.getWidth() / 2, api.getHeight() / 2);
      }
      /**
       * Update when tooltip is rendered
       */


      TooltipRichContent.prototype.update = function (tooltipModel) {
        var alwaysShowContent = tooltipModel.get('alwaysShowContent');
        alwaysShowContent && this._moveIfResized();
      };

      TooltipRichContent.prototype.show = function () {
        if (this._hideTimeout) {
          clearTimeout(this._hideTimeout);
        }

        this.el.show();
        this._show = true;
      };
      /**
       * Set tooltip content
       */


      TooltipRichContent.prototype.setContent = function (content, markupStyleCreator, tooltipModel, borderColor, arrowPosition) {
        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,
            backgroundColor: tooltipModel.get('backgroundColor'),
            borderRadius: tooltipModel.get('borderRadius'),
            borderWidth: 1,
            borderColor: borderColor,
            shadowColor: tooltipModel.get('shadowColor'),
            shadowBlur: tooltipModel.get('shadowBlur'),
            shadowOffsetX: tooltipModel.get('shadowOffsetX'),
            shadowOffsetY: tooltipModel.get('shadowOffsetY'),
            textShadowColor: textStyleModel.get('textShadowColor'),
            textShadowBlur: textStyleModel.get('textShadowBlur') || 0,
            textShadowOffsetX: textStyleModel.get('textShadowOffsetX') || 0,
            textShadowOffsetY: textStyleModel.get('textShadowOffsetY') || 0,
            fill: tooltipModel.get(['textStyle', 'color']),
            padding: getPaddingFromTooltipModel(tooltipModel, 'richText'),
            verticalAlign: 'top',
            align: 'left'
          },
          z: tooltipModel.get('z')
        });

        this._zr.add(this.el);

        var self = this;
        this.el.on('mouseover', function () {
          // clear the timeout in hideLater and keep showing tooltip
          if (self._enterable) {
            clearTimeout(self._hideTimeout);
            self._show = true;
          }

          self._inContent = true;
        });
        this.el.on('mouseout', function () {
          if (self._enterable) {
            if (self._show) {
              self.hideLater(self._hideDelay);
            }
          }

          self._inContent = false;
        });
      };

      TooltipRichContent.prototype.setEnterable = function (enterable) {
        this._enterable = enterable;
      };

      TooltipRichContent.prototype.getSize = function () {
        var el = this.el;
        var bounding = this.el.getBoundingRect(); // bounding rect does not include shadow. For renderMode richText,
        // if overflow, it will be cut. So calculate them accurately.

        var shadowOuterSize = calcShadowOuterSize(el.style);
        return [bounding.width + shadowOuterSize.left + shadowOuterSize.right, bounding.height + shadowOuterSize.top + shadowOuterSize.bottom];
      };

      TooltipRichContent.prototype.moveTo = function (x, y) {
        var el = this.el;

        if (el) {
          var styleCoord = this._styleCoord;
          makeStyleCoord$1(styleCoord, this._zr, x, y);
          x = styleCoord[0];
          y = styleCoord[1];
          var style = el.style;
          var borderWidth = mathMaxWith0(style.borderWidth || 0);
          var shadowOuterSize = calcShadowOuterSize(style); // rich text x, y do not include border.

          el.x = x + borderWidth + shadowOuterSize.left;
          el.y = y + borderWidth + shadowOuterSize.top;
          el.markRedraw();
        }
      };
      /**
       * when `alwaysShowContent` is true,
       * move the tooltip after chart resized
       */


      TooltipRichContent.prototype._moveIfResized = function () {
        // The ratio of left to width
        var ratioX = this._styleCoord[2]; // The ratio of top to height

        var ratioY = this._styleCoord[3];
        this.moveTo(ratioX * this._zr.getWidth(), ratioY * this._zr.getHeight());
      };

      TooltipRichContent.prototype.hide = function () {
        if (this.el) {
          this.el.hide();
        }

        this._show = false;
      };

      TooltipRichContent.prototype.hideLater = function (time) {
        if (this._show && !(this._inContent && this._enterable)) {
          if (time) {
            this._hideDelay = time; // Set show false to avoid invoke hideLater multiple times

            this._show = false;
            this._hideTimeout = setTimeout(bind(this.hide, this), time);
          } else {
            this.hide();
          }
        }
      };

      TooltipRichContent.prototype.isShow = function () {
        return this._show;
      };

      TooltipRichContent.prototype.getOuterSize = function () {
        var size = this.getSize();
        return {
          width: size[0],
          height: size[1]
        };
      };

      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 bind$2 = bind;
    var each$c = each;
    var parsePercent$2 = parsePercent$1;
    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) {
          return;
        }

        var tooltipModel = ecModel.getComponent('tooltip');
        var renderMode = tooltipModel.get('renderMode');
        this._renderMode = getTooltipRenderMode(renderMode);
        this._tooltipContent = this._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) {
          return;
        } // Reset


        this.group.removeAll();
        this._tooltipModel = tooltipModel;
        this._ecModel = ecModel;
        this._api = api;
        /**
         * @private
         * @type {boolean}
         */

        this._alwaysShowContent = tooltipModel.get('alwaysShowContent');
        var tooltipContent = this._tooltipContent;
        tooltipContent.update(tooltipModel);
        tooltipContent.setEnterable(tooltipModel.get('enterable'));

        this._initGlobalListener();

        this._keepShow();
      };

      TooltipView.prototype._initGlobalListener = function () {
        var tooltipModel = this._tooltipModel;
        var triggerOn = tooltipModel.get('triggerOn');
        register('itemTooltip', this._api, bind$2(function (currTrigger, e, dispatchAction) {
          // If 'none', it is not controlled by mouse totally.
          if (triggerOn !== 'none') {
            if (triggerOn.indexOf(currTrigger) >= 0) {
              this._tryShow(e, dispatchAction);
            } else if (currTrigger === 'leave') {
              this._hide(dispatchAction);
            }
          }
        }, this));
      };

      TooltipView.prototype._keepShow = function () {
        var tooltipModel = this._tooltipModel;
        var ecModel = this._ecModel;
        var api = this._api; // Try to keep the tooltip show when refreshing

        if (this._lastX != null && this._lastY != null // When user is willing to control tooltip totally using API,
        // self.manuallyShowTip({x, y}) might cause tooltip hide,
        // which is not expected.
        && tooltipModel.get('triggerOn') !== 'none') {
          var self_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) {
          return;
        }

        var dispatchAction = makeDispatchAction$1(payload, api); // Reset ticket

        this._ticket = ''; // When triggered from axisPointer.

        var dataByCoordSys = payload.dataByCoordSys;
        var cmptRef = findComponentReference(payload, ecModel, api);

        if (cmptRef) {
          var rect = cmptRef.el.getBoundingRect().clone();
          rect.applyTransform(cmptRef.el.transform);

          this._tryShow({
            offsetX: rect.x + rect.width / 2,
            offsetY: rect.y + rect.height / 2,
            target: cmptRef.el,
            position: payload.position,
            // When manully trigger, the mouse is not on the el, so we'd better to
            // position tooltip on the bottom of the el and display arrow is possible.
            positionDefault: 'bottom'
          }, dispatchAction);
        } else if (payload.tooltip && payload.x != null && payload.y != null) {
          var el = proxyRect;
          el.x = payload.x;
          el.y = payload.y;
          el.update();
          getECData(el).tooltipConfig = {
            name: null,
            option: payload.tooltip
          }; // Manually show tooltip while view is not using zrender elements.

          this._tryShow({
            offsetX: payload.x,
            offsetY: payload.y,
            target: el
          }, dispatchAction);
        } else if (dataByCoordSys) {
          this._tryShow({
            offsetX: payload.x,
            offsetY: payload.y,
            position: payload.position,
            dataByCoordSys: dataByCoordSys,
            tooltipOption: payload.tooltipOption
          }, dispatchAction);
        } else if (payload.seriesIndex != null) {
          if (this._manuallyAxisShowTip(tooltipModel, ecModel, api, payload)) {
            return;
          }

          var pointInfo = findPointFromSeries(payload, ecModel);
          var cx = pointInfo.point[0];
          var cy = pointInfo.point[1];

          if (cx != null && cy != null) {
            this._tryShow({
              offsetX: cx,
              offsetY: cy,
              target: pointInfo.el,
              position: payload.position,
              // When manully trigger, the mouse is not on the el, so we'd better to
              // position tooltip on the bottom of the el and display arrow is possible.
              positionDefault: 'bottom'
            }, dispatchAction);
          }
        } else if (payload.x != null && payload.y != null) {
          // FIXME
          // should wrap dispatchAction like `axisPointer/globalListener` ?
          api.dispatchAction({
            type: 'updateAxisPointer',
            x: payload.x,
            y: payload.y
          });

          this._tryShow({
            offsetX: payload.x,
            offsetY: payload.y,
            position: payload.position,
            target: api.getZr().findHover(payload.x, payload.y).target
          }, dispatchAction);
        }
      };

      TooltipView.prototype.manuallyHideTip = function (tooltipModel, ecModel, api, payload) {
        var tooltipContent = this._tooltipContent;

        if (!this._alwaysShowContent && this._tooltipModel) {
          tooltipContent.hideLater(this._tooltipModel.get('hideDelay'));
        }

        this._lastX = this._lastY = this._lastDataByCoordSys = null;

        if (payload.from !== this.uid) {
          this._hide(makeDispatchAction$1(payload, api));
        }
      }; // Be compatible with previous design, that is, when tooltip.type is 'axis' and
      // dispatchAction 'showTip' with seriesIndex and dataIndex will trigger axis pointer
      // and tooltip.


      TooltipView.prototype._manuallyAxisShowTip = function (tooltipModel, ecModel, api, payload) {
        var seriesIndex = payload.seriesIndex;
        var dataIndex = payload.dataIndex; // @ts-ignore

        var coordSysAxesInfo = ecModel.getComponent('axisPointer').coordSysAxesInfo;

        if (seriesIndex == null || dataIndex == null || coordSysAxesInfo == null) {
          return;
        }

        var seriesModel = ecModel.getSeriesByIndex(seriesIndex);

        if (!seriesModel) {
          return;
        }

        var data = seriesModel.getData();
        var tooltipCascadedModel = buildTooltipModel([data.getItemModel(dataIndex), seriesModel, (seriesModel.coordinateSystem || {}).model], this._tooltipModel);

        if (tooltipCascadedModel.get('trigger') !== 'axis') {
          return;
        }

        api.dispatchAction({
          type: 'updateAxisPointer',
          seriesIndex: seriesIndex,
          dataIndex: dataIndex,
          position: payload.position
        });
        return true;
      };

      TooltipView.prototype._tryShow = function (e, dispatchAction) {
        var el = e.target;
        var tooltipModel = this._tooltipModel;

        if (!tooltipModel) {
          return;
        } // Save mouse x, mouse y. So we can try to keep showing the tip if chart is refreshed


        this._lastX = e.offsetX;
        this._lastY = e.offsetY;
        var dataByCoordSys = e.dataByCoordSys;

        if (dataByCoordSys && dataByCoordSys.length) {
          this._showAxisTooltip(dataByCoordSys, e);
        } else if (el) {
          this._lastDataByCoordSys = null;
          var seriesDispatcher_1;
          var cmptDispatcher_1;
          findEventDispatcher(el, function (target) {
            // Always show item tooltip if mouse is on the element with dataIndex
            if (getECData(target).dataIndex != null) {
              seriesDispatcher_1 = target;
              return true;
            } // Tooltip provided directly. Like legend.


            if (getECData(target).tooltipConfig != null) {
              cmptDispatcher_1 = target;
              return true;
            }
          }, true);

          if (seriesDispatcher_1) {
            this._showSeriesItemTooltip(e, seriesDispatcher_1, dispatchAction);
          } else if (cmptDispatcher_1) {
            this._showComponentItemTooltip(e, cmptDispatcher_1, dispatchAction);
          } else {
            this._hide(dispatchAction);
          }
        } else {
          this._lastDataByCoordSys = null;

          this._hide(dispatchAction);
        }
      };

      TooltipView.prototype._showOrMove = function (tooltipModel, cb) {
        // showDelay is used in this case: tooltip.enterable is set
        // as true. User intent to move mouse into tooltip and click
        // something. `showDelay` makes it easier to enter the content
        // but tooltip do not move immediately.
        var delay = tooltipModel.get('showDelay');
        cb = bind(cb, this);
        clearTimeout(this._showTimout);
        delay > 0 ? this._showTimout = setTimeout(cb, delay) : cb();
      };

      TooltipView.prototype._showAxisTooltip = function (dataByCoordSys, e) {
        var ecModel = this._ecModel;
        var globalTooltipModel = this._tooltipModel;
        var point = [e.offsetX, e.offsetY];
        var singleTooltipModel = buildTooltipModel([e.tooltipOption], globalTooltipModel);
        var renderMode = this._renderMode;
        var cbParamsList = [];
        var articleMarkup = createTooltipMarkup('section', {
          blocks: [],
          noHeader: true
        }); // Only for legacy: `Serise['formatTooltip']` returns a string.

        var markupTextArrLegacy = [];
        var markupStyleCreator = new TooltipMarkupStyleCreator();
        each$c(dataByCoordSys, function (itemCoordSys) {
          each$c(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);
              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));

              if (seriesTooltipResult.markupFragment) {
                axisSectionMarkup.blocks.push(seriesTooltipResult.markupFragment);
              }

              if (seriesTooltipResult.markupText) {
                markupTextArrLegacy.push(seriesTooltipResult.markupText);
              }

              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)) {
            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 markupText = seriesTooltipResult.markupFragment ? buildTooltipMarkup(seriesTooltipResult.markupFragment, markupStyleCreator, renderMode, orderMode, ecModel.get('useUTC'), tooltipModel.get('textStyle')) : seriesTooltipResult.markupText;
        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);
        }

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

        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$2(positionExpr[0], viewWidth);
          y = parsePercent$2(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);
            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) {
        var lastCoordSys = this._lastDataByCoordSys;
        var contentNotChanged = !!lastCoordSys && lastCoordSys.length === dataByCoordSys.length;
        contentNotChanged && each$c(lastCoordSys, function (lastItemCoordSys, indexCoordSys) {
          var lastDataByAxis = lastItemCoordSys.dataByAxis || [];
          var thisItemCoordSys = dataByCoordSys[indexCoordSys] || {};
          var thisDataByAxis = thisItemCoordSys.dataByAxis || [];
          contentNotChanged = contentNotChanged && lastDataByAxis.length === thisDataByAxis.length;
          contentNotChanged && each$c(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$c(lastIndices, function (lastIdxItem, j) {
              var newIdxItem = newIndices[j];
              contentNotChanged = contentNotChanged && lastIdxItem.seriesIndex === newIdxItem.seriesIndex && lastIdxItem.dataIndex === newIdxItem.dataIndex;
            });
          });
        });
        this._lastDataByCoordSys = dataByCoordSys;
        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) {
          return;
        }

        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.getOuterSize();
      var width = size.width;
      var height = size.height;

      if (gapH != null) {
        // Add extra 2 pixels for this case:
        // At present the "values" in defaut tooltip are using CSS `float: right`.
        // When the right edge of the tooltip box is on the right side of the
        // viewport, the `float` layout might push the "values" to the second line.
        if (x + width + gapH + 2 > viewWidth) {
          x -= width + gapH;
        } else {
          x += gapH;
        }
      }

      if (gapV != null) {
        if (y + height + gapV > viewHeight) {
          y -= height + gapV;
        } else {
          y += gapV;
        }
      }

      return [x, y];
    }

    function confineTooltipPosition(x, y, content, viewWidth, viewHeight) {
      var size = content.getOuterSize();
      var width = size.width;
      var height = size.height;
      x = Math.min(x + width, viewWidth) - width;
      y = Math.min(y + height, viewHeight) - height;
      x = Math.max(x, 0);
      y = Math.max(y, 0);
      return [x, y];
    }

    function calcTooltipPosition(position, rect, contentSize) {
      var domWidth = contentSize[0];
      var domHeight = contentSize[1];
      var gap = 10;
      var offset = 5;
      var x = 0;
      var y = 0;
      var rectWidth = rect.width;
      var rectHeight = rect.height;

      switch (position) {
        case 'inside':
          x = rect.x + rectWidth / 2 - domWidth / 2;
          y = rect.y + rectHeight / 2 - domHeight / 2;
          break;

        case 'top':
          x = rect.x + rectWidth / 2 - domWidth / 2;
          y = rect.y - domHeight - gap;
          break;

        case 'bottom':
          x = rect.x + rectWidth / 2 - domWidth / 2;
          y = rect.y + rectHeight + gap;
          break;

        case 'left':
          x = rect.x - domWidth - gap - offset;
          y = rect.y + rectHeight / 2 - domHeight / 2;
          break;

        case 'right':
          x = rect.x + rectWidth + gap + 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
      function () {});
      registers.registerAction({
        type: 'hideTip',
        event: 'hideTip',
        update: 'tooltip:manuallyHideTip'
      }, // noop
      function () {});
    }

    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$d = 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$d(stateList, function (state) {
        var mappings = visualMappings[state] = createMappings();
        each$d(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 dimName;

          if (dim != null) {
            dimName = data.getDimension(dim);
          }

          function getVisual(key) {
            return getItemVisualFromData(data, dataIndex, key);
          }

          function setVisual(key, value) {
            setItemVisualFromData(data, dataIndex, key, value);
          }

          var dataIndex;

          while ((dataIndex = params.next()) != null) {
            var rawDataItem = data.getRawDataItem(dataIndex); // Consider performance
            // @ts-ignore

            if (rawDataItem && rawDataItem.visualMap === false) {
              continue;
            }

            var value = dim != null ? data.get(dimName, 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$1(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$1(points, x, y) || contain$1(points, x + width, y) || contain$1(points, x, y + height) || contain$1(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.getLocale(['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'
      }, function () {});
      registers.registerAction({
        type: 'brushEnd',
        event: 'brushEnd',
        update: 'none'
      }, function () {});
      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 List([{
          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',
          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',
          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.niceTicks();
        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 costomized 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 costomized 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();

        this._progressLine.shape.x2 = toCoord;

        this._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 = hostModel.get('symbolSize');
      symbolSize = symbolSize instanceof Array ? symbolSize.slice() : [+symbolSize, +symbolSize];
      opt.scaleX = symbolSize[0] / 2;
      opt.scaleY = symbolSize[1] / 2;
      var symbolOffset = hostModel.get('symbolOffset');

      if (symbolOffset) {
        opt.x = opt.x || 0;
        opt.y = opt.y || 0;
        opt.x += parsePercent$1(symbolOffset[0], symbolSize[0]);
        opt.y += parsePercent$1(symbolOffset[1], symbolSize[1]);
      }

      var symbolRotate = hostModel.get('symbolRotate');
      opt.rotation = (symbolRotate || 0) * Math.PI / 180 || 0;
      symbol.attr(opt); // FIXME
      // (1) When symbol.style.strokeNoScale is true and updateTransform is not performed,
      // getBoundingRect will return wrong result.
      // (This is supposed to be resolved in zrender, but it is a little difficult to
      // leverage performance and auto updateTransform)
      // (2) All of ancesters of symbol do not scale, so we can just updateTransform symbol.

      symbol.updateTransform();
      return symbol;
    }

    function pointerMoveTo(pointer, 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) {
        var timelineModel = ecModel.getComponent('timeline');

        if (timelineModel && payload.currentIndex != null) {
          timelineModel.setCurrentIndex(payload.currentIndex);

          if (!timelineModel.get('loop', true) && timelineModel.isIndexMax()) {
            timelineModel.setPlayState(false);
          }
        } // Set normalized currentIndex to payload.


        ecModel.resetOption('timeline', {
          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));
    } // Make it simple, do not visit all stacked value to count precision.
    // function getPrecision(data, valueAxisDim, dataIndex) {
    //     let precision = -1;
    //     let stackedDim = data.mapDimension(valueAxisDim);
    //     do {
    //         precision = Math.max(
    //             numberUtil.getPrecision(data.get(stackedDim, dataIndex)),
    //             precision
    //         );
    //         let stackedOnSeries = data.getCalculationInfo('stackedOnSeries');
    //         if (stackedOnSeries) {
    //             let byValue = data.get(data.getCalculationInfo('stackedByDimension'), dataIndex);
    //             data = stackedOnSeries.getData();
    //             dataIndex = data.indexOf(data.getCalculationInfo('stackedByDimension'), byValue);
    //             stackedDim = data.getCalculationInfo('stackedDimension');
    //         }
    //         else {
    //             data = null;
    //         }
    //     } while (data);
    //     return precision;
    // }


    function markerTypeCalculatorWithExtent(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
     * @param  {module:echarts/model/Series} seriesModel
     * @param  {module:echarts/coord/*} [coordSys]
     * @param  {Object} item
     * @return {Object}
     */

    function dataTransform(seriesModel, item) {
      var data = seriesModel.getData();
      var coordSys = seriesModel.coordinateSystem; // 1. If not specify the position with pixel directly
      // 2. If `coord` is not a data array. Which uses `xAxis`,
      // `yAxis` to specify the coord on each dimension
      // parseFloat first because item.x and item.y can be percent string like '20%'

      if (item && !hasXAndY(item) && !isArray(item.coord) && coordSys) {
        var dims = coordSys.dimensions;
        var axisInfo = getAxisInfo$1(item, data, coordSys, seriesModel); // Clone the option
        // Transform the properties xAxis, yAxis, radiusAxis, angleAxis, geoCoord to value

        item = clone(item);

        if (item.type && markerTypeCalculator[item.type] && axisInfo.baseAxis && axisInfo.valueAxis) {
          var otherCoordIndex = indexOf(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.
          var coord = [item.xAxis != null ? item.xAxis : item.radiusAxis, item.yAxis != null ? item.yAxis : item.angleAxis]; // Each coord support max, min, average

          for (var i = 0; i < 2; i++) {
            if (markerTypeCalculator[coord[i]]) {
              coord[i] = numCalculate(data, data.mapDimension(dims[i]), coord[i]);
            }
          }

          item.coord = coord;
        }
      }

      return item;
    }
    function getAxisInfo$1(item, data, coordSys, seriesModel) {
      var ret = {};

      if (item.valueIndex != null || item.valueDim != null) {
        ret.valueDataDim = item.valueIndex != null ? data.getDimension(item.valueIndex) : item.valueDim;
        ret.valueAxis = coordSys.getAxis(dataDimToCoordDim(seriesModel, ret.valueDataDim));
        ret.baseAxis = coordSys.getOtherAxis(ret.valueAxis);
        ret.baseDataDim = data.mapDimension(ret.baseAxis.dim);
      } else {
        ret.baseAxis = seriesModel.getBaseAxis();
        ret.valueAxis = coordSys.getOtherAxis(ret.baseAxis);
        ret.baseDataDim = data.mapDimension(ret.baseAxis.dim);
        ret.valueDataDim = data.mapDimension(ret.valueAxis.dim);
      }

      return ret;
    }

    function dataDimToCoordDim(seriesModel, dataDim) {
      var data = seriesModel.getData();
      var dimensions = data.dimensions;
      dataDim = data.getDimension(dataDim);

      for (var i = 0; i < dimensions.length; i++) {
        var dimItem = data.getDimensionInfo(dimensions[i]);

        if (dimItem.name === dataDim) {
          return dimItem.coordDim;
        }
      }
    }
    /**
     * Filter data which is out of coordinateSystem range
     * [dataFilter description]
     */


    function dataFilter$1( // Currently only polar and cartesian has containData.
    coordSys, item) {
      // Alwalys return true if there is no coordSys
      return coordSys && coordSys.containData && item.coord && !hasXOrY(item) ? coordSys.containData(item.coord) : true;
    }
    function dimValueGetter(item, dimName, dataIndex, dimIndex) {
      // x, y, radius, angle
      if (dimIndex < 2) {
        return item.coord && item.coord[dimIndex];
      }

      return item.value;
    }
    function numCalculate(data, valueDataDim, type) {
      if (type === 'average') {
        var sum_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.blurSeries = function (seriesModelList) {
        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) {
                enterBlur(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 getMarkerPoisition
            point = seriesModel.getMarkerPosition(mpData.getValues(mpData.dimensions, idx));
          } else if (coordSys) {
            var x = mpData.get(coordSys.dimensions[0], idx);
            var y = mpData.get(coordSys.dimensions[1], idx);
            point = coordSys.dataToPoint([x, y]);
          } // Use x, y if has any


        if (!isNaN(xPx)) {
          point[0] = xPx;
        }

        if (!isNaN(yPx)) {
          point[1] = yPx;
        }

        mpData.setItemLayout(idx, point);
      });
    }

    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 = createList$1(coordSys, seriesModel, mpModel); // FIXME

        mpModel.setData(mpData);
        updateMarkerLayout(mpModel.getData(), seriesModel, api);
        mpData.each(function (idx) {
          var itemModel = mpData.getItemModel(idx);
          var symbol = itemModel.getShallow('symbol');
          var symbolSize = itemModel.getShallow('symbolSize');
          var symbolRotate = itemModel.getShallow('symbolRotate');

          if (isFunction(symbol) || isFunction(symbolSize) || isFunction(symbolRotate)) {
            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);
            }
          }

          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,
            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 createList$1(coordSys, seriesModel, mpModel) {
      var coordDimsInfos;

      if (coordSys) {
        coordDimsInfos = map(coordSys && coordSys.dimensions, function (coordDim) {
          var info = seriesModel.getData().getDimensionInfo(seriesModel.getData().mapDimension(coordDim)) || {}; // In map series data don't have lng and lat dimension. Fallback to same with coordSys

          return defaults({
            name: coordDim
          }, info);
        });
      } else {
        coordDimsInfos = [{
          name: 'value',
          type: 'float'
        }];
      }

      var mpData = new List(coordDimsInfos, mpModel);
      var dataOpt = map(mpModel.get('data'), curry(dataTransform, seriesModel));

      if (coordSys) {
        dataOpt = filter(dataOpt, curry(dataFilter$1, coordSys));
      }

      mpData.initData(dataOpt, null, coordSys ? dimValueGetter : function (item) {
        return item.value;
      });
      return mpData;
    }

    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 && typeof value === 'number') {
            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 isInifinity(val) {
      return !isNaN(val) && !isFinite(val);
    } // If a markLine has one dim


    function ifMarkLineHasOnlyDim(dimIndex, fromCoord, toCoord, coordSys) {
      var otherDimIndex = 1 - dimIndex;
      var dimName = coordSys.dimensions[dimIndex];
      return isInifinity(fromCoord[otherDimIndex]) && isInifinity(toCoord[otherDimIndex]) && fromCoord[dimIndex] === toCoord[dimIndex] && coordSys.getAxis(dimName).containData(fromCoord[dimIndex]);
    }

    function markLineFilter(coordSys, item) {
      if (coordSys.type === 'cartesian2d') {
        var fromCoord = item[0].coord;
        var toCoord = item[1].coord; // In case
        // {
        //  markLine: {
        //    data: [{ yAxis: 2 }]
        //  }
        // }

        if (fromCoord && toCoord && (ifMarkLineHasOnlyDim(1, fromCoord, toCoord, coordSys) || ifMarkLineHasOnlyDim(0, fromCoord, toCoord, coordSys))) {
          return true;
        }
      }

      return dataFilter$1(coordSys, item[0]) && dataFilter$1(coordSys, item[1]);
    }

    function updateSingleMarkerEndLayout(data, idx, isFrom, seriesModel, api) {
      var coordSys = seriesModel.coordinateSystem;
      var itemModel = data.getItemModel(idx);
      var point;
      var xPx = parsePercent$1(itemModel.get('x'), api.getWidth());
      var yPx = parsePercent$1(itemModel.get('y'), api.getHeight());

      if (!isNaN(xPx) && !isNaN(yPx)) {
        point = [xPx, yPx];
      } else {
        // Chart like bar may have there own marker positioning logic
        if (seriesModel.getMarkerPosition) {
          // Use the getMarkerPoisition
          point = seriesModel.getMarkerPosition(data.getValues(data.dimensions, idx));
        } else {
          var dims = coordSys.dimensions;
          var x = data.get(dims[0], idx);
          var y = data.get(dims[1], idx);
          point = coordSys.dataToPoint([x, y]);
        } // Expand line to the edge of grid if value on one axis is Inifnity
        // In case
        //  markLine: {
        //    data: [{
        //      yAxis: 2
        //      // or
        //      type: 'average'
        //    }]
        //  }


        if (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 (isInifinity(data.get(dims[0], idx))) {
            point[0] = xAxis.toGlobalCoord(xAxis.getExtent()[isFrom ? 0 : 1]);
          } else if (isInifinity(data.get(dims[1], idx))) {
            point[1] = yAxis.toGlobalCoord(yAxis.getExtent()[isFrom ? 0 : 1]);
          }
        } // Use x, y if has any


        if (!isNaN(xPx)) {
          point[0] = xPx;
        }

        if (!isNaN(yPx)) {
          point[1] = yPx;
        }
      }

      data.setItemLayout(idx, point);
    }

    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$2(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);
        var symbolType = mlModel.get('symbol');
        var symbolSize = mlModel.get('symbolSize');
        var symbolRotate = mlModel.get('symbolRotate');
        var symbolOffset = mlModel.get('symbolOffset');

        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, idx) {
          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'), symbolOffset[isFrom ? 0 : 1]),
            symbolRotate: retrieve2(itemModel.get('symbolRotate', true), symbolRotate[isFrom ? 0 : 1]),
            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$2(coordSys, seriesModel, mlModel) {
      var coordDimsInfos;

      if (coordSys) {
        coordDimsInfos = map(coordSys && coordSys.dimensions, function (coordDim) {
          var info = seriesModel.getData().getDimensionInfo(seriesModel.getData().mapDimension(coordDim)) || {}; // In map series data don't have lng and lat dimension. Fallback to same with coordSys

          return defaults({
            name: coordDim
          }, info);
        });
      } else {
        coordDimsInfos = [{
          name: 'value',
          type: 'float'
        }];
      }

      var fromData = new List(coordDimsInfos, mlModel);
      var toData = new List(coordDimsInfos, mlModel); // No dimensions

      var lineData = new List([], mlModel);
      var optData = map(mlModel.get('data'), curry(markLineTransform, seriesModel, coordSys, mlModel));

      if (coordSys) {
        optData = filter(optData, curry(markLineFilter, coordSys));
      }

      var dimValueGetter$1 = coordSys ? dimValueGetter : function (item) {
        return item.value;
      };
      fromData.initData(map(optData, function (item) {
        return item[0];
      }), null, dimValueGetter$1);
      toData.initData(map(optData, function (item) {
        return item[1];
      }), null, dimValueGetter$1);
      lineData.initData(map(optData, function (item) {
        return item[2];
      }));
      lineData.hasItemOption = true;
      return {
        from: fromData,
        to: toData,
        line: lineData
      };
    }

    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) {
      var lt = dataTransform(seriesModel, item[0]);
      var rb = dataTransform(seriesModel, item[1]); // 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 isInifinity$1(val) {
      return !isNaN(val) && !isFinite(val);
    } // If a markArea has one dim


    function ifMarkAreaHasOnlyDim(dimIndex, fromCoord, toCoord, coordSys) {
      var otherDimIndex = 1 - dimIndex;
      return isInifinity$1(fromCoord[otherDimIndex]) && isInifinity$1(toCoord[otherDimIndex]);
    }

    function markAreaFilter(coordSys, item) {
      var fromCoord = item.coord[0];
      var toCoord = item.coord[1];

      if (isCoordinateSystemType(coordSys, 'cartesian2d')) {
        // In case
        // {
        //  markArea: {
        //    data: [{ yAxis: 2 }]
        //  }
        // }
        if (fromCoord && toCoord && (ifMarkAreaHasOnlyDim(1, fromCoord, toCoord) || ifMarkAreaHasOnlyDim(0, fromCoord, toCoord))) {
          return true;
        }
      }

      return dataFilter$1(coordSys, {
        coord: fromCoord,
        x: item.x0,
        y: item.y0
      }) || dataFilter$1(coordSys, {
        coord: toCoord,
        x: item.x1,
        y: item.y1
      });
    } // dims can be ['x0', 'y0'], ['x1', 'y1'], ['x0', 'y1'], ['x1', 'y0']


    function getSingleMarkerEndPoint(data, idx, dims, seriesModel, api) {
      var coordSys = seriesModel.coordinateSystem;
      var itemModel = data.getItemModel(idx);
      var point;
      var xPx = parsePercent$1(itemModel.get(dims[0]), api.getWidth());
      var yPx = parsePercent$1(itemModel.get(dims[1]), api.getHeight());

      if (!isNaN(xPx) && !isNaN(yPx)) {
        point = [xPx, yPx];
      } else {
        // Chart like bar may have there own marker positioning logic
        if (seriesModel.getMarkerPosition) {
          // Use the getMarkerPoisition
          point = seriesModel.getMarkerPosition(data.getValues(dims, idx));
        } else {
          var x = data.get(dims[0], idx);
          var y = data.get(dims[1], idx);
          var pt = [x, y];
          coordSys.clampData && coordSys.clampData(pt, pt);
          point = coordSys.dataToPoint(pt, true);
        }

        if (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 (isInifinity$1(x)) {
            point[0] = xAxis.toGlobalCoord(xAxis.getExtent()[dims[0] === 'x0' ? 0 : 1]);
          } else if (isInifinity$1(y)) {
            point[1] = yAxis.toGlobalCoord(yAxis.getExtent()[dims[1] === 'y0' ? 0 : 1]);
          }
        } // Use x, y if has any


        if (!isNaN(xPx)) {
          point[0] = xPx;
        }

        if (!isNaN(yPx)) {
          point[1] = yPx;
        }
      }

      return point;
    }

    var dimPermutations = [['x0', 'y0'], ['x1', 'y0'], ['x1', 'y1'], ['x0', 'y1']];

    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$3(coordSys, seriesModel, maModel); // Line data for tooltip and formatter

        maModel.setData(areaData); // Update visual and layout of line

        areaData.each(function (idx) {
          // Layout
          var points = map(dimPermutations, function (dim) {
            return getSingleMarkerEndPoint(areaData, idx, dim, seriesModel, api);
          });
          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 (typeof style.fill === 'string') {
              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: typeof style.fill === 'string' ? modifyAlpha(style.fill, 1) : '#000'
          });
          setStatesStylesFromModel(polygon, itemModel);
          enableHoverEmphasis(polygon);
          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$3(coordSys, seriesModel, maModel) {
      var coordDimsInfos;
      var areaData;
      var dims = ['x0', 'y0', 'x1', 'y1'];

      if (coordSys) {
        coordDimsInfos = map(coordSys && coordSys.dimensions, function (coordDim) {
          var data = seriesModel.getData();
          var info = data.getDimensionInfo(data.mapDimension(coordDim)) || {}; // In map series data don't have lng and lat dimension. Fallback to same with coordSys

          return defaults({
            name: coordDim
          }, info);
        });
        areaData = new List(map(dims, function (dim, idx) {
          return {
            name: dim,
            type: coordDimsInfos[idx % 2].type
          };
        }), maModel);
      } else {
        coordDimsInfos = [{
          name: 'value',
          type: 'float'
        }];
        areaData = new List(coordDimsInfos, maModel);
      }

      var optData = map(maModel.get('data'), curry(markAreaTransform, seriesModel, coordSys, maModel));

      if (coordSys) {
        optData = filter(optData, curry(markAreaFilter, coordSys));
      }

      var dimValueGetter = coordSys ? function (item, dimName, dataIndex, dimIndex) {
        // TODO should convert to ParsedValue?
        return item.coord[Math.floor(dimIndex / 2)][dimIndex % 2];
      } : function (item) {
        return item.value;
      };
      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.getLocale(['legend', 'selector', 'all'])
        };
      } else if (type === 'inverse') {
        return {
          type: 'inverse',
          title: ecModel.getLocale(['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 realy width/height is calculated by its content.
          // (Setting {left: 10, right: 10} does not make sense).
          // So consider the case:
          // `setOption({legend: {left: 10});`
          // then `setOption({legend: {right: 10});`
          // The previous `left` should be cleared by setting `ignoreSize`.
          ignoreSize: true
        };
        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 not specified in option, use availableNames as data,
        // which is convinient for user preparing option.

        var rawData = this.get('data') || potentialData;
        var legendData = map(rawData, function (dataItem) {
          // Can be string or number
          if (typeof dataItem === 'string' || typeof dataItem === 'number') {
            dataItem = {
              name: dataItem
            };
          }

          return new Model(dataItem, this, this.ecModel);
        }, this);
        /**
         * @type {Array.<module:echarts/model/Model>}
         * @private
         */

        this._data = legendData;
      };

      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,
        symbolSize: 'auto',
        inactiveColor: '#ccc',
        inactiveBorderColor: '#ccc',
        inactiveBorderWidth: 'auto',
        itemStyle: {
          color: 'inherit',
          opacity: 'inherit',
          decal: 'inherit',
          shadowBlur: 0,
          shadowColor: null,
          shadowOffsetX: 0,
          shadowOffsetY: 0,
          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',
          shadowBlur: 0,
          shadowColor: null,
          shadowOffsetX: 0,
          shadowOffsetY: 0
        },
        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$e = 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$e(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 drawed
            return;
          } // Legend to control series.


          if (seriesModel) {
            var data = seriesModel.getData();
            var lineVisualStyle = data.getVisual('legendLineStyle') || {};
            var symbolType = data.getVisual('legendSymbol');
            /**
             * `data.getVisual('style')` may be the color from the register
             * in series. For example, for line series,
             */

            var style = data.getVisual('style');
            data.getVisual('symbolSize');

            var itemGroup = this._createItem(seriesModel, name, dataIndex, legendItemModel, legendModel, itemAlign, lineVisualStyle, style, symbolType, selectMode);

            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 symbolType = provider.getItemVisual(idx, 'legendSymbol');
                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.fill = stringify(colorArr, 'rgba');
                }

                var itemGroup = this._createItem(seriesModel, name, dataIndex, legendItemModel, legendModel, itemAlign, {}, style, symbolType, selectMode); // 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$e(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, itemModel, legendModel, itemAlign, lineVisualStyle, itemVisualStyle, symbolType, selectMode) {
        var drawType = seriesModel.visualDrawType;
        var itemWidth = legendModel.get('itemWidth');
        var itemHeight = legendModel.get('itemHeight');
        var isSelected = legendModel.isSelected(name);
        var symbolKeepAspect = itemModel.get('symbolKeepAspect');
        var legendIconType = itemModel.get('icon');
        symbolType = legendIconType || symbolType || 'roundRect';
        var legendLineStyle = legendModel.getModel('lineStyle');
        var style = getLegendStyle(symbolType, itemModel, legendLineStyle, lineVisualStyle, itemVisualStyle, drawType, isSelected);
        var itemGroup = new Group$2();
        var textStyleModel = itemModel.getModel('textStyle');

        if (typeof seriesModel.getLegendIcon === 'function' && !legendIconType) {
          // Series has specific way to define legend icon
          itemGroup.add(seriesModel.getLegendIcon({
            itemWidth: itemWidth,
            itemHeight: itemHeight,
            symbolType: symbolType,
            symbolKeepAspect: symbolKeepAspect,
            itemStyle: style.itemStyle,
            lineStyle: style.lineStyle
          }));
        } else {
          // Use default legend icon policy for most series
          itemGroup.add(getDefaultLegendIcon({
            itemWidth: itemWidth,
            itemHeight: itemHeight,
            symbolType: symbolType,
            symbolKeepAspect: symbolKeepAspect,
            itemStyle: style.itemStyle,
            lineStyle: style.lineStyle
          }));
        }

        var textX = itemAlign === 'left' ? itemWidth + 5 : -5;
        var textAlign = itemAlign;
        var formatter = legendModel.get('formatter');
        var content = name;

        if (typeof formatter === 'string' && formatter) {
          content = formatter.replace('{name}', name != null ? name : '');
        } else if (typeof formatter === 'function') {
          content = formatter(name);
        }

        var inactiveColor = itemModel.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 = itemModel.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(symbolType, legendModel, legendLineStyle, lineVisualStyle, itemVisualStyle, drawType, isSelected) {
      /**
       * Use series style if is inherit;
       * elsewise, use legend style
       */
      // itemStyle
      var legendItemModel = legendModel.getModel('itemStyle');
      var itemProperties = ITEM_STYLE_KEY_MAP.concat([['decal']]);
      var itemStyle = {};

      for (var i = 0; i < itemProperties.length; ++i) {
        var propName = itemProperties[i][itemProperties[i].length - 1];
        var visualName = itemProperties[i][0];
        var value = legendItemModel.getShallow(propName);

        if (value === 'inherit') {
          switch (visualName) {
            case 'fill':
              /**
               * Series with visualDrawType as 'stroke' should have
               * series stroke as legend fill
               */
              itemStyle.fill = itemVisualStyle[drawType];
              break;

            case 'stroke':
              /**
               * symbol type with "emptyXXX" should use fill color
               * in visual style
               */
              itemStyle.stroke = itemVisualStyle[symbolType.startsWith('empty') ? 'fill' : 'stroke'];
              break;

            case 'opacity':
              /**
               * Use lineStyle.opacity if drawType is stroke
               */
              itemStyle.opacity = (drawType === 'fill' ? itemVisualStyle : lineVisualStyle).opacity;
              break;

            default:
              itemStyle[visualName] = itemVisualStyle[visualName];
          }
        } else if (value === 'auto' && visualName === 'lineWidth') {
          // If lineStyle.width is 'auto', it is set to be 2 if series has border
          itemStyle.lineWidth = itemVisualStyle.lineWidth > 0 ? 2 : 0;
        } else {
          itemStyle[visualName] = value;
        }
      } // lineStyle


      var legendLineModel = legendModel.getModel('lineStyle');
      var lineProperties = LINE_STYLE_KEY_MAP.concat([['inactiveColor'], ['inactiveWidth']]);
      var lineStyle = {};

      for (var i = 0; i < lineProperties.length; ++i) {
        var propName = lineProperties[i][1];
        var visualName = lineProperties[i][0];
        var value = legendLineModel.getShallow(propName);

        if (value === 'inherit') {
          lineStyle[visualName] = lineVisualStyle[visualName];
        } else if (value === 'auto' && visualName === 'lineWidth') {
          // If lineStyle.width is 'auto', it is set to be 2 if series has border
          lineStyle.lineWidth = lineVisualStyle.lineWidth > 0 ? 2 : 0;
        } else {
          lineStyle[visualName] = value;
        }
      } // 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 = legendModel.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[symbolType.indexOf('empty') > -1 ? 'fill' : 'stroke'];
        itemStyle.lineWidth = borderWidth === 'auto' ? itemVisualStyle.lineWidth > 0 && visualHasBorder ? 2 : 0 : itemStyle.lineWidth;
        itemStyle.fill = legendModel.get('inactiveColor');
        itemStyle.stroke = legendModel.get('inactiveBorderColor');
        lineStyle.stroke = legendLineStyle.get('inactiveColor');
        lineStyle.lineWidth = legendLineStyle.get('inactiveWidth');
      }

      return {
        itemStyle: itemStyle,
        lineStyle: lineStyle
      };
    }

    function getDefaultLegendIcon(opt) {
      var symboType = opt.symbolType || 'roundRect';
      var symbol = createSymbol(symboType, 0, 0, opt.itemWidth, opt.itemHeight, opt.itemStyle.fill, opt.symbolKeepAspect);
      symbol.setStyle(opt.itemStyle);

      if (symboType.indexOf('empty') > -1) {
        symbol.style.stroke = symbol.style.fill;
        symbol.style.fill = '#fff';
        symbol.style.lineWidth = 2;
      }

      return symbol;
    }

    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 higlight 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) {
      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 (becuase it hold 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
    };

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

      function SliderZoomView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = SliderZoomView.type;
        _this._displayables = {};
        return _this;
      }

      SliderZoomView.prototype.init = function (ecModel, api) {
        this.api = api; // A unique handler for each dataZoom component

        this._onBrush = bind(this._onBrush, this);
        this._onBrushEnd = bind(this._onBrushEnd, this);
      };

      SliderZoomView.prototype.render = function (dataZoomModel, ecModel, api, payload) {
        _super.prototype.render.apply(this, arguments);

        createOrUpdate(this, '_dispatchZoomAction', dataZoomModel.get('throttle'), 'fixRate');
        this._orient = dataZoomModel.getOrient();

        if (dataZoomModel.get('show') === false) {
          this.group.removeAll();
          return;
        }

        if (dataZoomModel.noTarget()) {
          this._clear();

          this.group.removeAll();
          return;
        } // Notice: this._resetInterval() should not be executed when payload.type
        // is 'dataZoom', origin this._range should be maintained, otherwise 'pan'
        // or 'zoom' info will be missed because of 'throttle' of this.dispatchAction,


        if (!payload || payload.type !== 'dataZoom' || payload.from !== this.uid) {
          this._buildView();
        }

        this._updateView();
      };

      SliderZoomView.prototype.dispose = function () {
        this._clear();

        _super.prototype.dispose.apply(this, arguments);
      };

      SliderZoomView.prototype._clear = function () {
        clear(this, '_dispatchZoomAction');
        var zr = this.api.getZr();
        zr.off('mousemove', this._onBrush);
        zr.off('mouseup', this._onBrushEnd);
      };

      SliderZoomView.prototype._buildView = function () {
        var thisGroup = this.group;
        thisGroup.removeAll();
        this._brushing = false;
        this._displayables.brushRect = null;

        this._resetLocation();

        this._resetInterval();

        var barGroup = this._displayables.sliderGroup = new Group();

        this._renderBackground();

        this._renderHandle();

        this._renderDataShadow();

        thisGroup.add(barGroup);

        this._positionGroup();
      };

      SliderZoomView.prototype._resetLocation = function () {
        var dataZoomModel = this.dataZoomModel;
        var api = this.api;
        var showMoveHandle = dataZoomModel.get('brushSelect');
        var moveHandleSize = showMoveHandle ? DEFAULT_MOVE_HANDLE_SIZE : 0; // If some of x/y/width/height are not specified,
        // auto-adapt according to target grid.

        var coordRect = this._findCoordRect();

        var ecSize = {
          width: api.getWidth(),
          height: api.getHeight()
        }; // Default align by coordinate system rect.

        var positionInfo = this._orient === HORIZONTAL ? {
          // Why using 'right', because right should be used in vertical,
          // and it is better to be consistent for dealing with position param merge.
          right: ecSize.width - coordRect.x - coordRect.width,
          top: ecSize.height - DEFAULT_FILLER_SIZE - DEFAULT_LOCATION_EDGE_GAP - moveHandleSize,
          width: coordRect.width,
          height: DEFAULT_FILLER_SIZE
        } : {
          right: DEFAULT_LOCATION_EDGE_GAP,
          top: coordRect.y,
          width: DEFAULT_FILLER_SIZE,
          height: coordRect.height
        }; // Do not write back to option and replace value 'ph', because
        // the 'ph' value should be recalculated when resize.

        var layoutParams = getLayoutParams(dataZoomModel.option); // Replace the placeholder value.

        each(['right', 'top', 'width', 'height'], function (name) {
          if (layoutParams[name] === 'ph') {
            layoutParams[name] = positionInfo[name];
          }
        });
        var layoutRect = getLayoutRect(layoutParams, ecSize);
        this._location = {
          x: layoutRect.x,
          y: layoutRect.y
        };
        this._size = [layoutRect.width, layoutRect.height];
        this._orient === VERTICAL && this._size.reverse();
      };

      SliderZoomView.prototype._positionGroup = function () {
        var thisGroup = this.group;
        var location = this._location;
        var orient = this._orient; // Just use the first axis to determine mapping.

        var targetAxisModel = this.dataZoomModel.getFirstTargetAxisModel();
        var inverse = targetAxisModel && targetAxisModel.get('inverse');
        var sliderGroup = this._displayables.sliderGroup;
        var otherAxisInverse = (this._dataShadowInfo || {}).otherAxisInverse; // Transform barGroup.

        sliderGroup.attr(orient === HORIZONTAL && !inverse ? {
          scaleY: otherAxisInverse ? 1 : -1,
          scaleX: 1
        } : orient === HORIZONTAL && inverse ? {
          scaleY: otherAxisInverse ? 1 : -1,
          scaleX: -1
        } : orient === VERTICAL && !inverse ? {
          scaleY: otherAxisInverse ? -1 : 1,
          scaleX: 1,
          rotation: Math.PI / 2
        } // Dont use Math.PI, considering shadow direction.
        : {
          scaleY: otherAxisInverse ? -1 : 1,
          scaleX: -1,
          rotation: Math.PI / 2
        }); // Position barGroup

        var rect = thisGroup.getBoundingRect([sliderGroup]);
        thisGroup.x = location.x - rect.x;
        thisGroup.y = location.y - rect.y;
        thisGroup.markRedraw();
      };

      SliderZoomView.prototype._getViewExtent = function () {
        return [0, this._size[0]];
      };

      SliderZoomView.prototype._renderBackground = function () {
        var dataZoomModel = this.dataZoomModel;
        var size = this._size;
        var barGroup = this._displayables.sliderGroup;
        var brushSelect = dataZoomModel.get('brushSelect');
        barGroup.add(new Rect$2({
          silent: true,
          shape: {
            x: 0,
            y: 0,
            width: size[0],
            height: size[1]
          },
          style: {
            fill: dataZoomModel.get('backgroundColor')
          },
          z2: -40
        })); // Click panel, over shadow, below handles.

        var clickPanel = new Rect$2({
          shape: {
            x: 0,
            y: 0,
            width: size[0],
            height: size[1]
          },
          style: {
            fill: 'transparent'
          },
          z2: 0,
          onclick: bind(this._onClickPanel, this)
        });
        var zr = this.api.getZr();

        if (brushSelect) {
          clickPanel.on('mousedown', this._onBrushStart, this);
          clickPanel.cursor = 'crosshair';
          zr.on('mousemove', this._onBrush);
          zr.on('mouseup', this._onBrushEnd);
        } else {
          zr.off('mousemove', this._onBrush);
          zr.off('mouseup', this._onBrushEnd);
        }

        barGroup.add(clickPanel);
      };

      SliderZoomView.prototype._renderDataShadow = function () {
        var info = this._dataShadowInfo = this._prepareDataShadowInfo();

        this._displayables.dataShadowSegs = [];

        if (!info) {
          return;
        }

        var size = this._size;
        var seriesModel = info.series;
        var data = seriesModel.getRawData();
        var otherDim = seriesModel.getShadowDim ? seriesModel.getShadowDim() // @see candlestick
        : info.otherDim;

        if (otherDim == null) {
          return;
        }

        var otherDataExtent = data.getDataExtent(otherDim); // Nice extent.

        var otherOffset = (otherDataExtent[1] - otherDataExtent[0]) * 0.3;
        otherDataExtent = [otherDataExtent[0] - otherOffset, otherDataExtent[1] + otherOffset];
        var otherShadowExtent = [0, size[1]];
        var thisShadowExtent = [0, size[0]];
        var areaPoints = [[size[0], 0], [0, 0]];
        var linePoints = [];
        var step = thisShadowExtent[1] / (data.count() - 1);
        var thisCoord = 0; // Optimize for large data shadow

        var stride = Math.round(data.count() / size[0]);
        var lastIsEmpty;
        data.each([otherDim], function (value, index) {
          if (stride > 0 && index % stride) {
            thisCoord += step;
            return;
          } // FIXME
          // Should consider axis.min/axis.max when drawing dataShadow.
          // FIXME
          // 应该使用统一的空判断？还是在list里进行空判断？


          var isEmpty = value == null || isNaN(value) || value === ''; // See #4235.

          var otherCoord = isEmpty ? 0 : linearMap(value, otherDataExtent, otherShadowExtent, true); // Attempt to draw data shadow precisely when there are empty value.

          if (isEmpty && !lastIsEmpty && index) {
            areaPoints.push([areaPoints[areaPoints.length - 1][0], 0]);
            linePoints.push([linePoints[linePoints.length - 1][0], 0]);
          } else if (!isEmpty && lastIsEmpty) {
            areaPoints.push([thisCoord, 0]);
            linePoints.push([thisCoord, 0]);
          }

          areaPoints.push([thisCoord, otherCoord]);
          linePoints.push([thisCoord, otherCoord]);
          thisCoord += step;
          lastIsEmpty = isEmpty;
        });
        var dataZoomModel = this.dataZoomModel;

        function createDataShadowGroup(isSelectedArea) {
          var model = dataZoomModel.getModel(isSelectedArea ? 'selectedDataBackground' : 'dataBackground');
          var group = new Group();
          var polygon = new Polygon({
            shape: {
              points: areaPoints
            },
            segmentIgnoreThreshold: 1,
            style: model.getModel('areaStyle').getAreaStyle(),
            silent: true,
            z2: -20
          });
          var polyline = new Polyline({
            shape: {
              points: linePoints
            },
            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: {
            stroke: dataZoomModel.get('dataBackgroundColor') // deprecated option
            || dataZoomModel.get('borderColor'),
            lineWidth: DEFAULT_FRAME_BORDER_WIDTH,
            fill: 'rgba(0,0,0,0)'
          }
        })); // Left and right handle to resize

        each([0, 1], function (handleIndex) {
          var iconStr = dataZoomModel.get('handleIcon');

          if (!symbolBuildProxies[iconStr] && iconStr.indexOf('path://') < 0 && iconStr.indexOf('image://') < 0) {
            // Compatitable with the old icon parsers. Which can use a path string without path://
            iconStr = 'path://' + iconStr;

            if ("development" !== 'production') {
              deprecateLog('handleIcon now needs \'path://\' prefix when using a path string');
            }
          }

          var path = createSymbol(iconStr, -1, 0, 2, 2, null, true);
          path.attr({
            cursor: getCursor(this._orient),
            draggable: true,
            drift: bind(this._onDragMove, this, handleIndex),
            ondragend: bind(this._onDragEnd, this),
            onmouseover: bind(this._showDataInfo, this, true),
            onmouseout: bind(this._showDataInfo, this, false),
            z2: 5
          });
          var bRect = path.getBoundingRect();
          var handleSize = dataZoomModel.get('handleSize');
          this._handleHeight = parsePercent$1(handleSize, this._size[1]);
          this._handleWidth = bRect.width / bRect.height * this._handleHeight;
          path.setStyle(dataZoomModel.getModel('handleStyle').getItemStyle());
          path.style.strokeNoScale = true;
          path.rectHover = true;
          path.ensureState('emphasis').style = dataZoomModel.getModel(['emphasis', 'handleStyle']).getItemStyle();
          enableHoverEmphasis(path);
          var handleColor = dataZoomModel.get('handleColor'); // deprecated option
          // Compatitable with previous version

          if (handleColor != null) {
            path.style.fill = handleColor;
          }

          sliderGroup.add(handles[handleIndex] = path);
          var textStyleModel = dataZoomModel.getModel('textStyle');
          thisGroup.add(handleLabels[handleIndex] = new ZRText({
            silent: true,
            invisible: true,
            style: createTextStyle(textStyleModel, {
              x: 0,
              y: 0,
              text: '',
              verticalAlign: 'middle',
              align: 'center',
              fill: textStyleModel.getTextColor(),
              font: textStyleModel.getFont()
            }),
            z2: 10
          }));
        }, this); // Handle to move. Only visible when brushSelect is set true.

        var actualMoveZone = filler;

        if (brushSelect) {
          var moveHandleHeight = parsePercent$1(dataZoomModel.get('moveHandleSize'), size[1]);
          var moveHandle_1 = displayables.moveHandle = new Rect({
            style: dataZoomModel.getModel('moveHandleStyle').getItemStyle(),
            silent: true,
            shape: {
              r: [0, 0, 2, 2],
              y: size[1] - 0.5,
              height: moveHandleHeight
            }
          });
          var iconSize = moveHandleHeight * 0.8;
          var moveHandleIcon = displayables.moveHandleIcon = createSymbol(dataZoomModel.get('moveHandleIcon'), -iconSize / 2, -iconSize / 2, iconSize, iconSize, '#fff', true);
          moveHandleIcon.silent = true;
          moveHandleIcon.y = size[1] + moveHandleHeight / 2 - 0.5;
          moveHandle_1.ensureState('emphasis').style = dataZoomModel.getModel(['emphasis', 'moveHandleStyle']).getItemStyle();
          var moveZoneExpandSize = Math.min(size[1] / 2, Math.max(moveHandleHeight, 10));
          actualMoveZone = displayables.moveZone = new Rect({
            invisible: true,
            shape: {
              y: size[1] - moveZoneExpandSize,
              height: moveHandleHeight + moveZoneExpandSize
            }
          });
          actualMoveZone.on('mouseover', function () {
            api.enterEmphasis(moveHandle_1);
          }).on('mouseout', function () {
            api.leaveEmphasis(moveHandle_1);
          });
          sliderGroup.add(moveHandle_1);
          sliderGroup.add(moveHandleIcon);
          sliderGroup.add(actualMoveZone);
        }

        actualMoveZone.attr({
          draggable: true,
          cursor: getCursor(this._orient),
          drift: bind(this._onDragMove, this, 'all'),
          ondragstart: bind(this._showDataInfo, this, true),
          ondragend: bind(this._onDragEnd, this),
          onmouseover: bind(this._showDataInfo, this, true),
          onmouseout: bind(this._showDataInfo, this, false)
        });
      };

      SliderZoomView.prototype._resetInterval = function () {
        var range = this._range = this.dataZoomModel.getPercentRange();

        var viewExtent = this._getViewExtent();

        this._handleEnds = [linearMap(range[0], [0, 100], viewExtent, true), linearMap(range[1], [0, 100], viewExtent, true)];
      };

      SliderZoomView.prototype._updateInterval = function (handleIndex, delta) {
        var dataZoomModel = this.dataZoomModel;
        var handleEnds = this._handleEnds;

        var viewExtend = this._getViewExtent();

        var minMaxSpan = dataZoomModel.findRepresentativeAxisProxy().getMinMaxSpan();
        var percentExtent = [0, 100];
        sliderMove(delta, handleEnds, viewExtend, dataZoomModel.get('zoomLock') ? 'all' : handleIndex, minMaxSpan.minSpan != null ? linearMap(minMaxSpan.minSpan, percentExtent, viewExtend, true) : null, minMaxSpan.maxSpan != null ? linearMap(minMaxSpan.maxSpan, percentExtent, viewExtend, true) : null);
        var lastRange = this._range;
        var range = this._range = asc([linearMap(handleEnds[0], viewExtend, percentExtent, true), linearMap(handleEnds[1], viewExtend, percentExtent, true)]);
        return !lastRange || lastRange[0] !== range[0] || lastRange[1] !== range[1];
      };

      SliderZoomView.prototype._updateView = function (nonRealtime) {
        var displaybles = this._displayables;
        var handleEnds = this._handleEnds;
        var handleInterval = asc(handleEnds.slice());
        var size = this._size;
        each([0, 1], function (handleIndex) {
          // Handles
          var handle = displaybles.handles[handleIndex];
          var handleHeight = this._handleHeight;
          handle.attr({
            scaleX: handleHeight / 2,
            scaleY: handleHeight / 2,
            // This is a trick, by adding an extra tiny offset to let the default handle's end point align to the drag window.
            // NOTE: It may affect some custom shapes a bit. But we prefer to have better result by default.
            x: handleEnds[handleIndex] + (handleIndex ? -1 : 1),
            y: size[1] / 2 - handleHeight / 2
          });
        }, this); // Filler

        displaybles.filler.setShape({
          x: handleInterval[0],
          y: 0,
          width: handleInterval[1] - handleInterval[0],
          height: size[1]
        });
        var viewExtent = {
          x: handleInterval[0],
          width: handleInterval[1] - handleInterval[0]
        }; // Move handle

        if (displaybles.moveHandle) {
          displaybles.moveHandle.setShape(viewExtent);
          displaybles.moveZone.setShape(viewExtent); // Force update path on the invisible object

          displaybles.moveZone.getBoundingRect();
          displaybles.moveHandleIcon && displaybles.moveHandleIcon.attr('x', viewExtent.x + viewExtent.width / 2);
        } // update clip path of shadow.


        var dataShadowSegs = displaybles.dataShadowSegs;
        var segIntervals = [0, handleInterval[0], handleInterval[1], size[0]];

        for (var i = 0; i < dataShadowSegs.length; i++) {
          var segGroup = dataShadowSegs[i];
          var clipPath = segGroup.getClipPath();

          if (!clipPath) {
            clipPath = new Rect();
            segGroup.setClipPath(clipPath);
          }

          clipPath.setShape({
            x: segIntervals[i],
            y: 0,
            width: segIntervals[i + 1] - segIntervals[i],
            height: size[1]
          });
        }

        this._updateDataInfo(nonRealtime);
      };

      SliderZoomView.prototype._updateDataInfo = function (nonRealtime) {
        var dataZoomModel = this.dataZoomModel;
        var displaybles = this._displayables;
        var handleLabels = displaybles.handleLabels;
        var orient = this._orient;
        var labelTexts = ['', '']; // FIXME
        // date型，支持formatter，autoformatter（ec2 date.getAutoFormatter）

        if (dataZoomModel.get('showDetail')) {
          var axisProxy = dataZoomModel.findRepresentativeAxisProxy();

          if (axisProxy) {
            var axis = axisProxy.getAxisModel().axis;
            var range = this._range;
            var dataInterval = nonRealtime // See #4434, data and axis are not processed and reset yet in non-realtime mode.
            ? axisProxy.calculateDataWindow({
              start: range[0],
              end: range[1]
            }).valueWindow : axisProxy.getDataValueWindow();
            labelTexts = [this._formatLabel(dataInterval[0], axis), this._formatLabel(dataInterval[1], axis)];
          }
        }

        var orderedHandleEnds = asc(this._handleEnds.slice());
        setLabel.call(this, 0);
        setLabel.call(this, 1);

        function setLabel(handleIndex) {
          // Label
          // Text should not transform by barGroup.
          // Ignore handlers transform
          var barTransform = getTransform(displaybles.handles[handleIndex].parent, this.group);
          var direction = transformDirection(handleIndex === 0 ? 'right' : 'left', barTransform);
          var offset = this._handleWidth / 2 + LABEL_GAP;
          var textPoint = applyTransform$1([orderedHandleEnds[handleIndex] + (handleIndex === 0 ? -offset : offset), this._size[1] / 2], barTransform);
          handleLabels[handleIndex].setStyle({
            x: textPoint[0],
            y: textPoint[1],
            verticalAlign: orient === HORIZONTAL ? 'middle' : direction,
            align: orient === HORIZONTAL ? direction : 'center',
            text: labelTexts[handleIndex]
          });
        }
      };

      SliderZoomView.prototype._formatLabel = function (value, axis) {
        var dataZoomModel = this.dataZoomModel;
        var labelFormatter = dataZoomModel.get('labelFormatter');
        var labelPrecision = dataZoomModel.get('labelPrecision');

        if (labelPrecision == null || labelPrecision === 'auto') {
          labelPrecision = axis.getPixelPrecision();
        }

        var valueStr = value == null || isNaN(value) ? '' // FIXME Glue code
        : axis.type === 'category' || axis.type === 'time' ? axis.scale.getLabel({
          value: Math.round(value)
        }) // param of toFixed should less then 20.
        : value.toFixed(Math.min(labelPrecision, 20));
        return isFunction(labelFormatter) ? labelFormatter(value, valueStr) : isString(labelFormatter) ? labelFormatter.replace('{value}', valueStr) : valueStr;
      };
      /**
       * @param showOrHide true: show, false: hide
       */


      SliderZoomView.prototype._showDataInfo = function (showOrHide) {
        // Always show when drgging.
        showOrHide = this._dragging || showOrHide;
        var displayables = this._displayables;
        var handleLabels = displayables.handleLabels;
        handleLabels[0].attr('invisible', !showOrHide);
        handleLabels[1].attr('invisible', !showOrHide); // Highlight move handle

        displayables.moveHandle && this.api[showOrHide ? 'enterEmphasis' : 'leaveEmphasis'](displayables.moveHandle, 1);
      };

      SliderZoomView.prototype._onDragMove = function (handleIndex, dx, dy, event) {
        this._dragging = true; // For mobile device, prevent screen slider on the button.

        stop(event.event); // Transform dx, dy to bar coordination.

        var barTransform = this._displayables.sliderGroup.getLocalTransform();

        var vertex = applyTransform$1([dx, dy], barTransform, true);

        var changed = this._updateInterval(handleIndex, vertex[0]);

        var realtime = this.dataZoomModel.get('realtime');

        this._updateView(!realtime); // Avoid dispatch dataZoom repeatly but range not changed,
        // which cause bad visual effect when progressive enabled.


        changed && realtime && this._dispatchZoomAction(true);
      };

      SliderZoomView.prototype._onDragEnd = function () {
        this._dragging = false;

        this._showDataInfo(false); // While in realtime mode and stream mode, dispatch action when
        // drag end will cause the whole view rerender, which is unnecessary.


        var realtime = this.dataZoomModel.get('realtime');
        !realtime && this._dispatchZoomAction(false);
      };

      SliderZoomView.prototype._onClickPanel = function (e) {
        var size = this._size;

        var localPoint = this._displayables.sliderGroup.transformCoordToLocal(e.offsetX, e.offsetY);

        if (localPoint[0] < 0 || localPoint[0] > size[0] || localPoint[1] < 0 || localPoint[1] > size[1]) {
          return;
        }

        var handleEnds = this._handleEnds;
        var center = (handleEnds[0] + handleEnds[1]) / 2;

        var changed = this._updateInterval('all', localPoint[0] - center);

        this._updateView();

        changed && this._dispatchZoomAction(false);
      };

      SliderZoomView.prototype._onBrushStart = function (e) {
        var x = e.offsetX;
        var y = e.offsetY;
        this._brushStart = new Point(x, y);
        this._brushing = true;
        this._brushStartTime = +new Date(); // this._updateBrushRect(x, y);
      };

      SliderZoomView.prototype._onBrushEnd = function (e) {
        if (!this._brushing) {
          return;
        }

        var brushRect = this._displayables.brushRect;
        this._brushing = false;

        if (!brushRect) {
          return;
        }

        brushRect.attr('ignore', true);
        var brushShape = brushRect.shape;
        var brushEndTime = +new Date(); // console.log(brushEndTime - this._brushStartTime);

        if (brushEndTime - this._brushStartTime < 200 && Math.abs(brushShape.width) < 5) {
          // Will treat it as a click
          return;
        }

        var viewExtend = this._getViewExtent();

        var percentExtent = [0, 100];
        this._range = asc([linearMap(brushShape.x, viewExtend, percentExtent, true), linearMap(brushShape.x + brushShape.width, viewExtend, percentExtent, true)]);
        this._handleEnds = [brushShape.x, brushShape.x + brushShape.width];

        this._updateView();

        this._dispatchZoomAction(false);
      };

      SliderZoomView.prototype._onBrush = function (e) {
        if (this._brushing) {
          // For mobile device, prevent screen slider on the button.
          stop(e.event);

          this._updateBrushRect(e.offsetX, e.offsetY);
        }
      };

      SliderZoomView.prototype._updateBrushRect = function (mouseX, mouseY) {
        var displayables = this._displayables;
        var dataZoomModel = this.dataZoomModel;
        var brushRect = displayables.brushRect;

        if (!brushRect) {
          brushRect = displayables.brushRect = new Rect$2({
            silent: true,
            style: dataZoomModel.getModel('brushStyle').getItemStyle()
          });
          displayables.sliderGroup.add(brushRect);
        }

        brushRect.attr('ignore', false);
        var brushStart = this._brushStart;
        var sliderGroup = this._displayables.sliderGroup;
        var endPoint = sliderGroup.transformCoordToLocal(mouseX, mouseY);
        var startPoint = sliderGroup.transformCoordToLocal(brushStart.x, brushStart.y);
        var size = this._size;
        endPoint[0] = Math.max(Math.min(size[0], endPoint[0]), 0);
        brushRect.setShape({
          x: startPoint[0],
          y: 0,
          width: endPoint[0] - startPoint[0],
          height: size[1]
        });
      };
      /**
       * This action will be throttled.
       */


      SliderZoomView.prototype._dispatchZoomAction = function (realtime) {
        var range = this._range;
        this.api.dispatchAction({
          type: 'dataZoom',
          from: this.uid,
          dataZoomId: this.dataZoomModel.id,
          animation: realtime ? REALTIME_ANIMATION_CONFIG : null,
          start: range[0],
          end: range[1]
        });
      };

      SliderZoomView.prototype._findCoordRect = function () {
        // Find the grid coresponding to the first axis referred by dataZoom.
        var rect;
        var coordSysInfoList = collectReferCoordSysModelInfo(this.dataZoomModel).infoList;

        if (!rect && coordSysInfoList.length) {
          var coordSys = coordSysInfoList[0].model.coordinateSystem;
          rect = coordSys.getRect && coordSys.getRect();
        }

        if (!rect) {
          var width = this.api.getWidth();
          var height = this.api.getHeight();
          rect = {
            x: width * 0.2,
            y: height * 0.2,
            width: width * 0.6,
            height: height * 0.6
          };
        }

        return rect;
      };

      SliderZoomView.type = 'dataZoom.slider';
      return SliderZoomView;
    }(DataZoomView);

    function getOtherDim(thisDim) {
      // FIXME
      // 这个逻辑和getOtherAxis里一致，但是写在这里是否不好
      var map = {
        x: 'y',
        y: 'x',
        radius: 'angle',
        angle: 'radius'
      };
      return map[thisDim];
    }

    function getCursor(orient) {
      return orient === 'vertical' ? 'ns-resize' : 'ew-resize';
    }

    function install$L(registers) {
      registers.registerComponentModel(SliderZoomModel);
      registers.registerComponentView(SliderZoomView);
      installCommon(registers);
    }

    function install$M(registers) {
      use(install$K);
      use(install$L); // Do not install './dataZoomSelect',
      // since it only work for toolbox dataZoom.
    }

    var visualDefault = {
      /**
       * @public
       */
      get: function (visualType, key, isCategory) {
        var value = clone((defaultOption$1[visualType] || {})[key]);
        return isCategory ? isArray(value) ? value[value.length - 1] : value : value;
      }
    };
    var defaultOption$1 = {
      color: {
        active: ['#006edd', '#e0ffff'],
        inactive: ['rgba(0,0,0,0)']
      },
      colorHue: {
        active: [0, 360],
        inactive: [0, 0]
      },
      colorSaturation: {
        active: [0.3, 1],
        inactive: [0, 0]
      },
      colorLightness: {
        active: [0.9, 0.5],
        inactive: [0, 0]
      },
      colorAlpha: {
        active: [0.3, 1],
        inactive: [0, 0]
      },
      opacity: {
        active: [0.3, 1],
        inactive: [0, 0]
      },
      symbol: {
        active: ['circle', 'roundRect', 'diamond'],
        inactive: ['none']
      },
      symbolSize: {
        active: [10, 50],
        inactive: [0, 0]
      }
    };

    var mapVisual$1 = VisualMapping.mapVisual;
    var eachVisual = VisualMapping.eachVisual;
    var isArray$1 = isArray;
    var each$f = 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; // FIXME
        // necessary?
        // Disable realtime view update if canvas is not supported.

        if (!env.canvasSupported) {
          thisOption.realtime = false;
        }

        !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;
      };
      /**
       * Return  Concrete dimention. If return null/undefined, no dimension used.
       */


      VisualMapModel.prototype.getDataDimension = function (list) {
        var optDim = this.option.dimension;
        var listDimensions = list.dimensions;

        if (optDim == null && !listDimensions.length) {
          return;
        }

        if (optDim != null) {
          return list.getDimension(optDim);
        }

        var dimNames = list.dimensions;

        for (var i = dimNames.length - 1; i >= 0; i--) {
          var dimName = dimNames[i];
          var dimInfo = list.getDimensionInfo(dimName);

          if (!dimInfo.isCalculationCoord) {
            return dimName;
          }
        }
      };

      VisualMapModel.prototype.getExtent = function () {
        return this._dataExtent.slice();
      };

      VisualMapModel.prototype.completeVisualOption = function () {
        var ecModel = this.ecModel;
        var thisOption = this.option;
        var base = {
          inRange: thisOption.inRange,
          outOfRange: thisOption.outOfRange
        };
        var target = thisOption.target || (thisOption.target = {});
        var controller = thisOption.controller || (thisOption.controller = {});
        merge(target, base); // Do not override

        merge(controller, base); // Do not override

        var isCategory = this.isCategory();
        completeSingle.call(this, target);
        completeSingle.call(this, controller);
        completeInactive.call(this, target, 'inRange', 'outOfRange'); // completeInactive.call(this, target, 'outOfRange', 'inRange');

        completeController.call(this, controller);

        function completeSingle(base) {
          // Compatible with ec2 dataRange.color.
          // The mapping order of dataRange.color is: [high value, ..., low value]
          // whereas inRange.color and outOfRange.color is [low value, ..., high value]
          // Notice: ec2 has no inverse.
          if (isArray$1(thisOption.color) // If there has been inRange: {symbol: ...}, adding color is a mistake.
          // So adding color only when no inRange defined.
          && !base.inRange) {
            base.inRange = {
              color: thisOption.color.slice().reverse()
            };
          } // Compatible with previous logic, always give a defautl color, otherwise
          // simple config with no inRange and outOfRange will not work.
          // Originally we use visualMap.color as the default color, but setOption at
          // the second time the default color will be erased. So we change to use
          // constant DEFAULT_COLOR.
          // If user do not want the default color, set inRange: {color: null}.


          base.inRange = base.inRange || {
            color: ecModel.get('gradientColor')
          };
        }

        function completeInactive(base, stateExist, stateAbsent) {
          var optExist = base[stateExist];
          var optAbsent = base[stateAbsent];

          if (optExist && !optAbsent) {
            optAbsent = base[stateAbsent] = {};
            each$f(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$f(this.stateList, function (state) {
            var itemSize = this.itemSize;
            var visuals = controller[state]; // Set inactive color for controller if no other color
            // attr (like colorAlpha) specified.

            if (!visuals) {
              visuals = controller[state] = {
                color: isCategory ? inactiveColor : [inactiveColor]
              };
            } // Consistent symbol and symbolSize if not specified.


            if (visuals.symbol == null) {
              visuals.symbol = symbolExists && clone(symbolExists) || (isCategory ? defaultSymbol : [defaultSymbol]);
            }

            if (visuals.symbolSize == null) {
              visuals.symbolSize = symbolSizeExists && clone(symbolSizeExists) || (isCategory ? itemSize[0] : [itemSize[0], itemSize[0]]);
            } // Filter none


            visuals.symbol = mapVisual$1(visuals.symbol, function (symbol) {
              return symbol === 'none' ? defaultSymbol : symbol;
            }); // Normalize symbolSize

            var symbolSize = visuals.symbolSize;

            if (symbolSize != null) {
              var max_1 = -Infinity; // symbolSize can be object when categories defined.

              eachVisual(symbolSize, function (value) {
                value > max_1 && (max_1 = value);
              });
              visuals.symbolSize = mapVisual$1(symbolSize, function (value) {
                return linearMap$1(value, [0, max_1], [0, itemSize[0]], true);
              });
            }
          }, this);
        }
      };

      VisualMapModel.prototype.resetItemSize = function () {
        this.itemSize = [parseFloat(this.get('itemWidth')), parseFloat(this.get('itemHeight'))];
      };

      VisualMapModel.prototype.isCategory = function () {
        return !!this.option.categories;
      };
      /**
       * @public
       * @abstract
       */


      VisualMapModel.prototype.setSelected = function (selected) {};

      VisualMapModel.prototype.getSelected = function () {
        return null;
      };
      /**
       * @public
       * @abstract
       */


      VisualMapModel.prototype.getValueState = function (value) {
        return null;
      };
      /**
       * FIXME
       * Do not publish to thirt-part-dev temporarily
       * util the interface is stable. (Should it return
       * a function but not visual meta?)
       *
       * @pubilc
       * @abstract
       * @param getColorVisual
       *        params: value, valueState
       *        return: color
       * @return {Object} visualMeta
       *        should includes {stops, outerColors}
       *        outerColor means [colorBeyondMinValue, colorBeyondMaxValue]
       */


      VisualMapModel.prototype.getVisualMeta = function (getColorVisual) {
        return null;
      };

      VisualMapModel.type = 'visualMap';
      VisualMapModel.dependencies = ['series'];
      VisualMapModel.defaultOption = {
        show: true,
        zlevel: 0,
        z: 4,
        seriesIndex: 'all',
        min: 0,
        max: 200,
        left: 0,
        right: null,
        top: null,
        bottom: 0,
        itemWidth: null,
        itemHeight: null,
        inverse: false,
        orient: 'vertical',
        backgroundColor: 'rgba(0,0,0,0)',
        borderColor: '#ccc',
        contentColor: '#5793f3',
        inactiveColor: '#aaa',
        borderWidth: 0,
        padding: 5,
        // 接受数组分别设定上右下左边距，同css
        textGap: 10,
        precision: 0,
        textStyle: {
          color: '#333' // 值域文字颜色

        }
      };
      return VisualMapModel;
    }(ComponentModel);

    var DEFAULT_BAR_BOUND = [20, 140];

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

      function ContinuousModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = ContinuousModel.type;
        return _this;
      }
      /**
       * @override
       */


      ContinuousModel.prototype.optionUpdated = function (newOption, isInit) {
        _super.prototype.optionUpdated.apply(this, arguments);

        this.resetExtent();
        this.resetVisual(function (mappingOption) {
          mappingOption.mappingMethod = 'linear';
          mappingOption.dataExtent = this.getExtent();
        });

        this._resetRange();
      };
      /**
       * @protected
       * @override
       */


      ContinuousModel.prototype.resetItemSize = function () {
        _super.prototype.resetItemSize.apply(this, arguments);

        var itemSize = this.itemSize;
        (itemSize[0] == null || isNaN(itemSize[0])) && (itemSize[0] = DEFAULT_BAR_BOUND[0]);
        (itemSize[1] == null || isNaN(itemSize[1])) && (itemSize[1] = DEFAULT_BAR_BOUND[1]);
      };
      /**
       * @private
       */


      ContinuousModel.prototype._resetRange = function () {
        var dataExtent = this.getExtent();
        var range = this.option.range;

        if (!range || range.auto) {
          // `range` should always be array (so we dont use other
          // value like 'auto') for user-friend. (consider getOption).
          dataExtent.auto = 1;
          this.option.range = dataExtent;
        } else if (isArray(range)) {
          if (range[0] > range[1]) {
            range.reverse();
          }

          range[0] = Math.max(range[0], dataExtent[0]);
          range[1] = Math.min(range[1], dataExtent[1]);
        }
      };
      /**
       * @protected
       * @override
       */


      ContinuousModel.prototype.completeVisualOption = function () {
        _super.prototype.completeVisualOption.apply(this, arguments);

        each(this.stateList, function (state) {
          var symbolSize = this.option.controller[state].symbolSize;

          if (symbolSize && symbolSize[0] !== symbolSize[1]) {
            symbolSize[0] = symbolSize[1] / 3; // For good looking.
          }
        }, this);
      };
      /**
       * @override
       */


      ContinuousModel.prototype.setSelected = function (selected) {
        this.option.range = selected.slice();

        this._resetRange();
      };
      /**
       * @public
       */


      ContinuousModel.prototype.getSelected = function () {
        var dataExtent = this.getExtent();
        var dataInterval = asc((this.get('range') || []).slice()); // Clamp

        dataInterval[0] > dataExtent[1] && (dataInterval[0] = dataExtent[1]);
        dataInterval[1] > dataExtent[1] && (dataInterval[1] = dataExtent[1]);
        dataInterval[0] < dataExtent[0] && (dataInterval[0] = dataExtent[0]);
        dataInterval[1] < dataExtent[0] && (dataInterval[1] = dataExtent[0]);
        return dataInterval;
      };
      /**
       * @override
       */


      ContinuousModel.prototype.getValueState = function (value) {
        var range = this.option.range;
        var dataExtent = this.getExtent(); // When range[0] === dataExtent[0], any value larger than dataExtent[0] maps to 'inRange'.
        // range[1] is processed likewise.

        return (range[0] <= dataExtent[0] || range[0] <= value) && (range[1] >= dataExtent[1] || value <= range[1]) ? 'inRange' : 'outOfRange';
      };

      ContinuousModel.prototype.findTargetDataIndices = function (range) {
        var result = [];
        this.eachTargetSeries(function (seriesModel) {
          var dataIndices = [];
          var data = seriesModel.getData();
          data.each(this.getDataDimension(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$g = 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: {
            x: position[0],
            y: position[1],
            verticalAlign: orient === 'horizontal' ? 'middle' : align,
            align: orient === 'horizontal' ? align : 'center',
            text: text,
            font: textStyleModel.getFont(),
            fill: textStyleModel.getTextColor()
          }
        }));
      };

      ContinuousView.prototype._renderBar = function (targetGroup) {
        var visualMapModel = this.visualMapModel;
        var shapes = this._shapes;
        var itemSize = visualMapModel.itemSize;
        var orient = this._orient;
        var useHandle = this._useHandle;
        var itemAlign = getItemAlign(visualMapModel, this.api, itemSize);

        var mainGroup = shapes.mainGroup = this._createBarGroup(itemAlign);

        var gradientBarGroup = new Group();
        mainGroup.add(gradientBarGroup); // Bar

        gradientBarGroup.add(shapes.outOfRange = createPolygon());
        gradientBarGroup.add(shapes.inRange = createPolygon(null, useHandle ? getCursor$1(this._orient) : null, bind(this._dragHandle, this, 'all', false), bind(this._dragHandle, this, 'all', true))); // A border radius clip.

        gradientBarGroup.setClipPath(new Rect({
          shape: {
            x: 0,
            y: 0,
            width: itemSize[0],
            height: itemSize[1],
            r: 3
          }
        }));
        var textRect = visualMapModel.textStyleModel.getTextRect('国');
        var textSize = mathMax$a(textRect.width, textRect.height); // Handle

        if (useHandle) {
          shapes.handleThumbs = [];
          shapes.handleLabels = [];
          shapes.handleLabelPoints = [];

          this._createHandle(visualMapModel, mainGroup, 0, itemSize, textSize, orient);

          this._createHandle(visualMapModel, mainGroup, 1, itemSize, textSize, orient);
        }

        this._createIndicator(visualMapModel, mainGroup, itemSize, textSize, orient);

        targetGroup.add(mainGroup);
      };

      ContinuousView.prototype._createHandle = function (visualMapModel, mainGroup, handleIndex, itemSize, textSize, orient) {
        var onDrift = bind(this._dragHandle, this, handleIndex, false);
        var onDragEnd = bind(this._dragHandle, this, handleIndex, true);
        var handleSize = parsePercent(visualMapModel.get('handleSize'), itemSize[0]);
        var handleThumb = createSymbol(visualMapModel.get('handleIcon'), -handleSize / 2, -handleSize / 2, handleSize, handleSize, null, true);
        var cursor = getCursor$1(this._orient);
        handleThumb.attr({
          cursor: cursor,
          draggable: true,
          drift: onDrift,
          ondragend: onDragEnd,
          onmousemove: function (e) {
            stop(e.event);
          }
        });
        handleThumb.x = itemSize[0] / 2;
        handleThumb.useStyle(visualMapModel.getModel('handleStyle').getItemStyle());
        handleThumb.setStyle({
          strokeNoScale: true,
          strokeFirst: true
        });
        handleThumb.style.lineWidth *= 2;
        handleThumb.ensureState('emphasis').style = visualMapModel.getModel(['emphasis', 'handleStyle']).getItemStyle();
        setAsHighDownDispatcher(handleThumb, true);
        mainGroup.add(handleThumb); // Text is always horizontal layout but should not be effected by
        // transform (orient/inverse). So label is built separately but not
        // use zrender/graphic/helper/RectText, and is located based on view
        // group (according to handleLabelPoint) but not barGroup.

        var textStyleModel = this.visualMapModel.textStyleModel;
        var handleLabel = new ZRText({
          cursor: cursor,
          draggable: true,
          drift: onDrift,
          onmousemove: function (e) {
            // Fot mobile devicem, prevent screen slider on the button.
            stop(e.event);
          },
          ondragend: onDragEnd,
          style: {
            x: 0,
            y: 0,
            text: '',
            font: textStyleModel.getFont(),
            fill: textStyleModel.getTextColor()
          }
        });
        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: {
            x: 0,
            y: 0,
            text: '',
            font: textStyleModel.getFont(),
            fill: textStyleModel.getTextColor()
          }
        });
        this.group.add(indicatorLabel);
        var indicatorLabelPoint = [(orient === 'horizontal' ? textSize / 2 : HOVER_LINK_OUT) + itemSize[0] / 2, 0];
        var shapes = this._shapes;
        shapes.indicator = indicator;
        shapes.indicatorLabel = indicatorLabel;
        shapes.indicatorLabelPoint = indicatorLabelPoint;
        this._firstShowIndicator = true;
      };

      ContinuousView.prototype._dragHandle = function (handleIndex, isEnd, // dx is event from ondragend if isEnd is true. It's not used
      dx, dy) {
        if (!this._useHandle) {
          return;
        }

        this._dragging = !isEnd;

        if (!isEnd) {
          // Transform dx, dy to bar coordination.
          var vertex = this._applyTransform([dx, dy], this._shapes.mainGroup, true);

          this._updateInterval(handleIndex, vertex[1]);

          this._hideIndicator(); // Considering realtime, update view should be executed
          // before dispatch action.


          this._updateView();
        } // dragEnd do not dispatch action when realtime.


        if (isEnd === !this.visualMapModel.get('realtime')) {
          // jshint ignore:line
          this.api.dispatchAction({
            type: 'selectDataRange',
            from: this.uid,
            visualMapId: this.visualMapModel.id,
            selected: this._dataInterval.slice()
          });
        }

        if (isEnd) {
          !this._hovering && this._clearHoverLinkToSeries();
        } else if (useHoverLinkOnHandle(this.visualMapModel)) {
          this._doHoverLinkToSeries(this._handleEnds[handleIndex], false);
        }
      };

      ContinuousView.prototype._resetInterval = function () {
        var visualMapModel = this.visualMapModel;
        var dataInterval = this._dataInterval = visualMapModel.getSelected();
        var dataExtent = visualMapModel.getExtent();
        var sizeExtent = [0, visualMapModel.itemSize[1]];
        this._handleEnds = [linearMap$2(dataInterval[0], dataExtent, sizeExtent, true), linearMap$2(dataInterval[1], dataExtent, sizeExtent, true)];
      };
      /**
       * @private
       * @param {(number|string)} handleIndex 0 or 1 or 'all'
       * @param {number} dx
       * @param {number} dy
       */


      ContinuousView.prototype._updateInterval = function (handleIndex, delta) {
        delta = delta || 0;
        var visualMapModel = this.visualMapModel;
        var handleEnds = this._handleEnds;
        var sizeExtent = [0, visualMapModel.itemSize[1]];
        sliderMove(delta, handleEnds, sizeExtent, handleIndex, // cross is forbiden
        0);
        var dataExtent = visualMapModel.getExtent(); // Update data interval.

        this._dataInterval = [linearMap$2(handleEnds[0], sizeExtent, dataExtent, true), linearMap$2(handleEnds[1], sizeExtent, dataExtent, true)];
      };

      ContinuousView.prototype._updateView = function (forSketch) {
        var visualMapModel = this.visualMapModel;
        var dataExtent = visualMapModel.getExtent();
        var shapes = this._shapes;
        var outOfRangeHandleEnds = [0, visualMapModel.itemSize[1]];
        var inRangeHandleEnds = forSketch ? outOfRangeHandleEnds : this._handleEnds;

        var visualInRange = this._createBarVisual(this._dataInterval, dataExtent, inRangeHandleEnds, 'inRange');

        var visualOutOfRange = this._createBarVisual(dataExtent, dataExtent, outOfRangeHandleEnds, 'outOfRange');

        shapes.inRange.setStyle({
          fill: visualInRange.barColor // opacity: visualInRange.opacity

        }).setShape('points', visualInRange.barPoints);
        shapes.outOfRange.setStyle({
          fill: visualOutOfRange.barColor // opacity: visualOutOfRange.opacity

        }).setShape('points', visualOutOfRange.barPoints);

        this._updateHandle(inRangeHandleEnds, visualInRange);
      };

      ContinuousView.prototype._createBarVisual = function (dataInterval, dataExtent, handleEnds, forceState) {
        var opts = {
          forceState: forceState,
          convertOpacityToAlpha: true
        };

        var colorStops = this._makeColorGradient(dataInterval, opts);

        var symbolSizes = [this.getControllerVisual(dataInterval[0], 'symbolSize', opts), this.getControllerVisual(dataInterval[1], 'symbolSize', opts)];

        var barPoints = this._createBarPoints(handleEnds, symbolSizes);

        return {
          barColor: new LinearGradient(0, 0, 0, 1, colorStops),
          barPoints: barPoints,
          handlesColor: [colorStops[0].color, colorStops[colorStops.length - 1].color]
        };
      };

      ContinuousView.prototype._makeColorGradient = function (dataInterval, opts) {
        // Considering colorHue, which is not linear, so we have to sample
        // to calculate gradient color stops, but not only caculate head
        // and tail.
        var sampleNumber = 100; // Arbitrary value.

        var colorStops = [];
        var step = (dataInterval[1] - dataInterval[0]) / sampleNumber;
        colorStops.push({
          color: this.getControllerVisual(dataInterval[0], 'color', opts),
          offset: 0
        });

        for (var i = 1; i < sampleNumber; i++) {
          var currValue = dataInterval[0] + step * i;

          if (currValue > dataInterval[1]) {
            break;
          }

          colorStops.push({
            color: this.getControllerVisual(currValue, 'color', opts),
            offset: i / sampleNumber
          });
        }

        colorStops.push({
          color: this.getControllerVisual(dataInterval[1], 'color', opts),
          offset: 1
        });
        return colorStops;
      };

      ContinuousView.prototype._createBarPoints = function (handleEnds, symbolSizes) {
        var itemSize = this.visualMapModel.itemSize;
        return [[itemSize[0] - symbolSizes[0], handleEnds[0]], [itemSize[0], handleEnds[0]], [itemSize[0], handleEnds[1]], [itemSize[0] - symbolSizes[1], handleEnds[1]]];
      };

      ContinuousView.prototype._createBarGroup = function (itemAlign) {
        var orient = this._orient;
        var inverse = this.visualMapModel.get('inverse');
        return new Group(orient === 'horizontal' && !inverse ? {
          scaleX: itemAlign === 'bottom' ? 1 : -1,
          rotation: Math.PI / 2
        } : orient === 'horizontal' && inverse ? {
          scaleX: itemAlign === 'bottom' ? -1 : 1,
          rotation: -Math.PI / 2
        } : orient === 'vertical' && !inverse ? {
          scaleX: itemAlign === 'left' ? 1 : -1,
          scaleY: -1
        } : {
          scaleX: itemAlign === 'left' ? 1 : -1
        });
      };

      ContinuousView.prototype._updateHandle = function (handleEnds, visualInRange) {
        if (!this._useHandle) {
          return;
        }

        var shapes = this._shapes;
        var visualMapModel = this.visualMapModel;
        var handleThumbs = shapes.handleThumbs;
        var handleLabels = shapes.handleLabels;
        var itemSize = visualMapModel.itemSize;
        var dataExtent = visualMapModel.getExtent();
        each$g([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 el = e.target;
        var visualMapModel = this.visualMapModel;

        if (!el || getECData(el).dataIndex == null) {
          return;
        }

        var ecData = getECData(el);
        var dataModel = this.ecModel.getSeriesByIndex(ecData.seriesIndex);

        if (!visualMapModel.isTargetSeries(dataModel)) {
          return;
        }

        var data = dataModel.getData(ecData.dataType);
        var value = data.get(visualMapModel.getDataDimension(data), ecData.dataIndex);

        if (!isNaN(value)) {
          this._showIndicator(value, value);
        }
      };

      ContinuousView.prototype._hideIndicator = function () {
        var shapes = this._shapes;
        shapes.indicator && shapes.indicator.attr('invisible', true);
        shapes.indicatorLabel && shapes.indicatorLabel.attr('invisible', true);
        var handleLabels = this._shapes.handleLabels;

        if (handleLabels) {
          for (var i = 0; i < handleLabels.length; i++) {
            // Fade out handle labels.
            // NOTE: Must use api enter/leave on emphasis/blur/select state. Or the global states manager will change it.
            this._api.leaveBlur(handleLabels[i]);
          }
        }
      };

      ContinuousView.prototype._clearHoverLinkToSeries = function () {
        this._hideIndicator();

        var indices = this._hoverLinkDataIndices;

        this._dispatchHighDown('downplay', makeHighDownBatch(indices, this.visualMapModel));

        indices.length = 0;
      };

      ContinuousView.prototype._clearHoverLinkFromSeries = function () {
        this._hideIndicator();

        var zr = this.api.getZr();
        zr.off('mouseover', this._hoverLinkFromSeriesMouseOver);
        zr.off('mouseout', this._hideIndicator);
      };

      ContinuousView.prototype._applyTransform = function (vertex, element, inverse, global) {
        var transform = getTransform(element, global ? null : this.group);
        return isArray(vertex) ? applyTransform$1(vertex, transform, inverse) : transformDirection(vertex, transform, inverse);
      }; // TODO: TYPE more specified payload types.


      ContinuousView.prototype._dispatchHighDown = function (type, batch) {
        batch && batch.length && this.api.dispatchAction({
          type: type,
          batch: batch
        });
      };
      /**
       * @override
       */


      ContinuousView.prototype.dispose = function () {
        this._clearHoverLinkFromSeries();

        this._clearHoverLinkToSeries();
      };
      /**
       * @override
       */


      ContinuousView.prototype.remove = function () {
        this._clearHoverLinkFromSeries();

        this._clearHoverLinkToSeries();
      };

      ContinuousView.type = 'visualMap.continuous';
      return ContinuousView;
    }(VisualMapView);

    function createPolygon(points, cursor, onDrift, onDragEnd) {
      return new Polygon({
        shape: {
          points: points
        },
        draggable: !!onDrift,
        cursor: cursor,
        drift: onDrift,
        onmousemove: function (e) {
          // Fot mobile devicem, prevent screen slider on the button.
          stop(e.event);
        },
        ondragend: onDragEnd
      });
    }

    function getHalfHoverLinkSize(visualMapModel, dataExtent, sizeExtent) {
      var halfHoverLinkSize = HOVER_LINK_SIZE / 2;
      var hoverLinkDataSize = visualMapModel.get('hoverLinkDataSize');

      if (hoverLinkDataSize) {
        halfHoverLinkSize = linearMap$2(hoverLinkDataSize, dataExtent, sizeExtent, true) / 2;
      }

      return halfHoverLinkSize;
    }

    function useHoverLinkOnHandle(visualMapModel) {
      var hoverLinkOnHandle = visualMapModel.get('hoverLinkOnHandle');
      return !!(hoverLinkOnHandle == null ? visualMapModel.get('realtime') : hoverLinkOnHandle);
    }

    function getCursor$1(orient) {
      return orient === 'vertical' ? 'ns-resize' : 'ew-resize';
    }

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


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

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */
    var visualMapActionInfo = {
      type: 'selectDataRange',
      event: 'dataRangeSelected',
      // FIXME use updateView appears wrong
      update: 'update'
    };
    var visualMapActionHander = function (payload, ecModel) {
      ecModel.eachComponent({
        mainType: 'visualMap',
        query: payload
      }, function (model) {
        model.setSelected(payload.selected);
      });
    };

    var visualMapEncodingHandlers = [{
      createOnAllSeries: true,
      reset: function (seriesModel, ecModel) {
        var resetDefines = [];
        ecModel.eachComponent('visualMap', function (visualMapModel) {
          var pipelineContext = seriesModel.pipelineContext;

          if (!visualMapModel.isTargetSeries(seriesModel) || pipelineContext && pipelineContext.large) {
            return;
          }

          resetDefines.push(incrementalApplyVisual(visualMapModel.stateList, visualMapModel.targetVisuals, bind(visualMapModel.getValueState, visualMapModel), visualMapModel.getDataDimension(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 concreteDim = visualMapModel.getDataDimension(data);
            var dimInfo = data.getDimensionInfo(concreteDim);

            if (dimInfo != null) {
              // visualMeta.dimension should be dimension index, but not concrete dimension.
              visualMeta.dimension = dimInfo.index;
              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$h = each;
    function visualMapPreprocessor(option) {
      var visualMap = option && option.visualMap;

      if (!isArray(visualMap)) {
        visualMap = visualMap ? [visualMap] : [];
      }

      each$h(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$h(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.getDataDimension(data), function (value, dataIndex) {
            // Should always base on model pieceList, because it is order sensitive.
            var pIdx = VisualMapping.findPieceIndex(value, pieceList);
            pIdx === pieceIndex && dataIndices.push(dataIndex);
          }, this);
          result.push({
            seriesId: seriesModel.id,
            dataIndex: dataIndices
          });
        }, this);
        return result;
      };
      /**
       * @private
       * @param piece piece.value or piece.interval is required.
       * @return  Can be Infinity or -Infinity
       */


      PiecewiseModel.prototype.getRepresentValue = function (piece) {
        var representValue;

        if (this.isCategory()) {
          representValue = piece.value;
        } else {
          if (piece.value != null) {
            representValue = piece.value;
          } else {
            var pieceInterval = piece.interval || [];
            representValue = pieceInterval[0] === -Infinity && pieceInterval[1] === Infinity ? 0 : (pieceInterval[0] + pieceInterval[1]) / 2;
          }
        }

        return representValue;
      };

      PiecewiseModel.prototype.getVisualMeta = function (getColorVisual) {
        // Do not support category. (category axis is ordinal, numerical)
        if (this.isCategory()) {
          return;
        }

        var stops = [];
        var outerColors = ['', ''];
        var visualMapModel = this;

        function setStop(interval, valueState) {
          var representValue = visualMapModel.getRepresentValue({
            interval: interval
          }); // Not category

          if (!valueState) {
            valueState = visualMapModel.getValueState(representValue);
          }

          var color = getColorVisual(representValue, valueState);

          if (interval[0] === -Infinity) {
            outerColors[0] = color;
          } else if (interval[1] === Infinity) {
            outerColors[1] = color;
          } else {
            stops.push({
              value: interval[0],
              color: color
            }, {
              value: interval[1],
              color: color
            });
          }
        } // Suplement


        var pieceList = this._pieceList.slice();

        if (!pieceList.length) {
          pieceList.push({
            interval: [-Infinity, Infinity]
          });
        } else {
          var edge = pieceList[0].interval[0];
          edge !== -Infinity && pieceList.unshift({
            interval: [-Infinity, edge]
          });
          edge = pieceList[pieceList.length - 1].interval[1];
          edge !== Infinity && pieceList.push({
            interval: [edge, Infinity]
          });
        }

        var curr = -Infinity;
        each(pieceList, function (piece) {
          var interval = piece.interval;

          if (interval) {
            // Fulfill gap.
            interval[0] > curr && setStop([curr, interval[0]], 'outOfRange');
            setStop(interval.slice());
            curr = interval[1];
          }
        }, this);
        return {
          stops: stops,
          outerColors: outerColors
        };
      };

      PiecewiseModel.type = 'visualMap.piecewise';
      PiecewiseModel.defaultOption = inheritDefaultOption(VisualMapModel.defaultOption, {
        selected: null,
        minOpen: false,
        maxOpen: false,
        align: 'auto',
        itemWidth: 20,
        itemHeight: 14,
        itemSymbol: 'roundRect',
        pieces: null,
        categories: null,
        splitNumber: 5,
        selectedMode: 'multiple',
        itemGap: 10,
        hoverLink: true // Enable hover highlight.

      });
      return PiecewiseModel;
    }(VisualMapModel);
    /**
     * Key is this._mode
     * @type {Object}
     * @this {module:echarts/component/viusalMap/PiecewiseMode}
     */

    var resetMethods = {
      splitNumber: function (outPieceList) {
        var thisOption = this.option;
        var precision = Math.min(thisOption.precision, 20);
        var dataExtent = this.getExtent();
        var splitNumber = thisOption.splitNumber;
        splitNumber = Math.max(parseInt(splitNumber, 10), 1);
        thisOption.splitNumber = splitNumber;
        var splitStep = (dataExtent[1] - dataExtent[0]) / splitNumber; // Precision auto-adaption

        while (+splitStep.toFixed(precision) !== splitStep && precision < 5) {
          precision++;
        }

        thisOption.precision = precision;
        splitStep = +splitStep.toFixed(precision);

        if (thisOption.minOpen) {
          outPieceList.push({
            interval: [-Infinity, dataExtent[0]],
            close: [0, 0]
          });
        }

        for (var index = 0, curr = dataExtent[0]; index < splitNumber; curr += splitStep, index++) {
          var max = index === splitNumber - 1 ? dataExtent[1] : curr + splitStep;
          outPieceList.push({
            interval: [curr, max],
            close: [1, 1]
          });
        }

        if (thisOption.maxOpen) {
          outPieceList.push({
            interval: [dataExtent[1], Infinity],
            close: [0, 0]
          });
        }

        reformIntervals(outPieceList);
        each(outPieceList, function (piece, index) {
          piece.index = index;
          piece.text = this.formatValueText(piece.interval);
        }, this);
      },
      categories: function (outPieceList) {
        var thisOption = this.option;
        each(thisOption.categories, function (cate) {
          // FIXME category模式也使用pieceList，但在visualMapping中不是使用pieceList。
          // 是否改一致。
          outPieceList.push({
            text: this.formatValueText(cate, true),
            value: cate
          });
        }, this); // See "Order Rule".

        normalizeReverse(thisOption, outPieceList);
      },
      pieces: function (outPieceList) {
        var thisOption = this.option;
        each(thisOption.pieces, function (pieceListItem, index) {
          if (!isObject(pieceListItem)) {
            pieceListItem = {
              value: pieceListItem
            };
          }

          var item = {
            text: '',
            index: index
          };

          if (pieceListItem.label != null) {
            item.text = pieceListItem.label;
          }

          if (pieceListItem.hasOwnProperty('value')) {
            var value = item.value = pieceListItem.value;
            item.interval = [value, value];
            item.close = [1, 1];
          } else {
            // `min` `max` is legacy option.
            // `lt` `gt` `lte` `gte` is recommanded.
            var interval = item.interval = [];
            var close_1 = item.close = [0, 0];
            var closeList = [1, 0, 1];
            var infinityList = [-Infinity, Infinity];
            var useMinMax = [];

            for (var lg = 0; lg < 2; lg++) {
              var names = [['gte', 'gt', 'min'], ['lte', 'lt', 'max']][lg];

              for (var i = 0; i < 3 && interval[lg] == null; i++) {
                interval[lg] = pieceListItem[names[i]];
                close_1[lg] = closeList[i];
                useMinMax[lg] = i === 2;
              }

              interval[lg] == null && (interval[lg] = infinityList[lg]);
            }

            useMinMax[0] && interval[1] === Infinity && (close_1[0] = 0);
            useMinMax[1] && interval[0] === -Infinity && (close_1[1] = 0);

            if ("development" !== 'production') {
              if (interval[0] > interval[1]) {
                console.warn('Piece ' + index + 'is illegal: ' + interval + ' lower bound should not greater then uppper bound.');
              }
            }

            if (interval[0] === interval[1] && close_1[0] && close_1[1]) {
              // Consider: [{min: 5, max: 5, visual: {...}}, {min: 0, max: 5}],
              // we use value to lift the priority when min === max
              item.value = interval[0];
            }
          }

          item.visual = VisualMapping.retrieveVisuals(pieceListItem);
          outPieceList.push(item);
        }, this); // See "Order Rule".

        normalizeReverse(thisOption, outPieceList); // Only pieces

        reformIntervals(outPieceList);
        each(outPieceList, function (piece) {
          var close = piece.close;
          var edgeSymbols = [['<', '≤'][close[1]], ['>', '≥'][close[0]]];
          piece.text = piece.text || this.formatValueText(piece.value != null ? piece.value : piece.interval, false, edgeSymbols);
        }, this);
      }
    };

    function normalizeReverse(thisOption, pieceList) {
      var inverse = thisOption.inverse;

      if (thisOption.orient === 'vertical' ? !inverse : inverse) {
        pieceList.reverse();
      }
    }

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

      function PiecewiseVisualMapView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = PiecewiseVisualMapView.type;
        return _this;
      }

      PiecewiseVisualMapView.prototype.doRender = function () {
        var thisGroup = this.group;
        thisGroup.removeAll();
        var visualMapModel = this.visualMapModel;
        var textGap = visualMapModel.get('textGap');
        var textStyleModel = visualMapModel.textStyleModel;
        var textFont = textStyleModel.getFont();
        var textFill = textStyleModel.getTextColor();

        var itemAlign = this._getItemAlign();

        var itemSize = visualMapModel.itemSize;

        var viewData = this._getViewData();

        var endsText = viewData.endsText;
        var showLabel = retrieve(visualMapModel.get('showLabel', true), !endsText);
        endsText && this._renderEndsText(thisGroup, endsText[0], itemSize, showLabel, itemAlign);
        each(viewData.viewPieceList, function (item) {
          var piece = item.piece;
          var itemGroup = new Group();
          itemGroup.onclick = bind(this._onItemClick, this, piece);

          this._enableHoverLink(itemGroup, item.indexInModelPieceList); // TODO Category


          var representValue = visualMapModel.getRepresentValue(piece);

          this._createItemSymbol(itemGroup, representValue, [0, 0, itemSize[0], itemSize[1]]);

          if (showLabel) {
            var visualState = this.visualMapModel.getValueState(representValue);
            itemGroup.add(new ZRText({
              style: {
                x: itemAlign === 'right' ? -textGap : itemSize[0] + textGap,
                y: itemSize[1] / 2,
                text: piece.text,
                verticalAlign: 'middle',
                align: itemAlign,
                font: textFont,
                fill: textFill,
                opacity: visualState === 'outOfRange' ? 0.5 : 1
              }
            }));
          }

          thisGroup.add(itemGroup);
        }, this);
        endsText && this._renderEndsText(thisGroup, endsText[1], itemSize, showLabel, itemAlign);
        box(visualMapModel.get('orient'), thisGroup, visualMapModel.get('itemGap'));
        this.renderBackground(thisGroup);
        this.positionGroup(thisGroup);
      };

      PiecewiseVisualMapView.prototype._enableHoverLink = function (itemGroup, pieceIndex) {
        var _this = this;

        itemGroup.on('mouseover', function () {
          return onHoverLink('highlight');
        }).on('mouseout', function () {
          return onHoverLink('downplay');
        });

        var onHoverLink = function (method) {
          var visualMapModel = _this.visualMapModel; // TODO: TYPE More detailed action types

          visualMapModel.option.hoverLink && _this.api.dispatchAction({
            type: method,
            batch: makeHighDownBatch(visualMapModel.findTargetDataIndices(pieceIndex), visualMapModel)
          });
        };
      };

      PiecewiseVisualMapView.prototype._getItemAlign = function () {
        var visualMapModel = this.visualMapModel;
        var modelOption = visualMapModel.option;

        if (modelOption.orient === 'vertical') {
          return getItemAlign(visualMapModel, this.api, visualMapModel.itemSize);
        } else {
          // horizontal, most case left unless specifying right.
          var align = modelOption.align;

          if (!align || align === 'auto') {
            align = 'left';
          }

          return align;
        }
      };

      PiecewiseVisualMapView.prototype._renderEndsText = function (group, text, itemSize, showLabel, itemAlign) {
        if (!text) {
          return;
        }

        var itemGroup = new Group();
        var textStyleModel = this.visualMapModel.textStyleModel;
        itemGroup.add(new ZRText({
          style: {
            x: showLabel ? itemAlign === 'right' ? itemSize[0] : 0 : itemSize[0] / 2,
            y: itemSize[1] / 2,
            verticalAlign: 'middle',
            align: showLabel ? itemAlign : 'center',
            text: text,
            font: textStyleModel.getFont(),
            fill: textStyleModel.getTextColor()
          }
        }));
        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 selected = clone(option.selected);
        var newKey = visualMapModel.getSelectedMapKey(piece);

        if (option.selectedMode === 'single') {
          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 diferrent scopes
          var paletteScopeGroupByType_1 = createHashMap();
          ecModel.eachSeries(function (seriesModel) {
            if (!seriesModel.useColorPaletteOnData) {
              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 (typeof seriesModel.enableAriaDecal === 'function') {
              // Let series define how to use decal palette on data
              seriesModel.enableAriaDecal();
              return;
            }

            var data = seriesModel.getData();

            if (seriesModel.useColorPaletteOnData) {
              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 dataLabels = [];

              for (var i = 0; i < data.count(); i++) {
                if (i < maxDataCnt) {
                  var name_1 = data.getName(i);
                  var value = retrieveRawValue(data, i);
                  var dataLabel = labelModel.get(['data', name_1 ? 'withName' : 'withoutName']);
                  dataLabels.push(replace(dataLabel, {
                    name: name_1,
                    value: value
                  }));
                }
              }

              var middleSeparator_1 = labelModel.get(['data', 'separator', 'middle']);
              var endSeparator_1 = labelModel.get(['data', 'separator', 'end']);
              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 (typeof str !== 'string') {
          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 mileading for sake of the different between '==' and '===',
      // So dont support them.
      // '==': 'eq',
      // '===': 'seq',
      // '!==': 'sne'
      // PENDING: Whether support some common alias "ge", "le", "neq"?
      // ge: 'gte',
      // le: 'lte',
      // neq: 'ne',

    };

    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 type === 'string' ? this._condVal.test(lVal) : type === 'number' ? this._condVal.test(lVal + '') : false;
      };

      return RegExpEvaluator;
    }();

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

      ConstConditionInternal.prototype.evaluate = function () {
        return this.value;
      };

      return ConstConditionInternal;
    }();

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

      AndConditionInternal.prototype.evaluate = function () {
        var children = this.children;

        for (var i = 0; i < children.length; i++) {
          if (!children[i].evaluate()) {
            return false;
          }
        }

        return true;
      };

      return AndConditionInternal;
    }();

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

      OrConditionInternal.prototype.evaluate = function () {
        var children = this.children;

        for (var i = 0; i < children.length; i++) {
          if (children[i].evaluate()) {
            return true;
          }
        }

        return false;
      };

      return OrConditionInternal;
    }();

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

      NotConditionInternal.prototype.evaluate = function () {
        return !this.child.evaluate();
      };

      return NotConditionInternal;
    }();

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

      RelationalConditionInternal.prototype.evaluate = function () {
        var needParse = !!this.valueParser; // Call getValue with no `this`.

        var getValue = this.getValue;
        var tarValRaw = getValue(this.valueGetterParam);
        var tarValParsed = needParse ? this.valueParser(tarValRaw) : null; // Relational cond follow "and" logic internally.

        for (var i = 0; i < this.subCondList.length; i++) {
          if (!this.subCondList[i].evaluate(needParse ? tarValParsed : tarValRaw)) {
            return false;
          }
        }

        return true;
      };

      return RelationalConditionInternal;
    }();

    function parseOption(exprOption, getters) {
      if (exprOption === true || exprOption === false) {
        var cond = new ConstConditionInternal();
        cond.value = exprOption;
        return cond;
      }

      var errMsg = '';

      if (!isObjectNotArray(exprOption)) {
        if ("development" !== 'production') {
          errMsg = makePrintable('Illegal config. Expect a plain object but actually', exprOption);
        }

        throwError(errMsg);
      }

      if (exprOption.and) {
        return parseAndOrOption('and', exprOption, getters);
      } else if (exprOption.or) {
        return parseAndOrOption('or', exprOption, getters);
      } else if (exprOption.not) {
        return parseNotOption(exprOption, getters);
      }

      return parseRelationalOption(exprOption, getters);
    }

    function parseAndOrOption(op, exprOption, getters) {
      var subOptionArr = exprOption[op];
      var errMsg = '';

      if ("development" !== 'production') {
        errMsg = makePrintable('"and"/"or" condition should only be `' + op + ': [...]` and must not be empty array.', 'Illegal condition:', exprOption);
      }

      if (!isArray(subOptionArr)) {
        throwError(errMsg);
      }

      if (!subOptionArr.length) {
        throwError(errMsg);
      }

      var cond = op === 'and' ? new AndConditionInternal() : new OrConditionInternal();
      cond.children = map(subOptionArr, function (subOption) {
        return parseOption(subOption, getters);
      });

      if (!cond.children.length) {
        throwError(errMsg);
      }

      return cond;
    }

    function parseNotOption(exprOption, getters) {
      var subOption = exprOption.not;
      var errMsg = '';

      if ("development" !== 'production') {
        errMsg = makePrintable('"not" condition should only be `not: {}`.', 'Illegal condition:', exprOption);
      }

      if (!isObjectNotArray(subOption)) {
        throwError(errMsg);
      }

      var cond = new NotConditionInternal();
      cond.child = parseOption(subOption, getters);

      if (!cond.child) {
        throwError(errMsg);
      }

      return cond;
    }

    function parseRelationalOption(exprOption, getters) {
      var errMsg = '';
      var valueGetterParam = getters.prepareGetValue(exprOption);
      var subCondList = [];
      var exprKeys = keys(exprOption);
      var parserName = exprOption.parser;
      var valueParser = parserName ? getRawValueParser(parserName) : null;

      for (var i = 0; i < exprKeys.length; i++) {
        var keyRaw = exprKeys[i];

        if (keyRaw === 'parser' || getters.valueGetterAttrMap.get(keyRaw)) {
          continue;
        }

        var op = hasOwn(RELATIONAL_EXPRESSION_OP_ALIAS_MAP, keyRaw) ? RELATIONAL_EXPRESSION_OP_ALIAS_MAP[keyRaw] : keyRaw;
        var condValueRaw = exprOption[keyRaw];
        var condValueParsed = valueParser ? valueParser(condValueRaw) : condValueRaw;
        var evaluator = createFilterComparator(op, condValueParsed) || op === 'reg' && new RegExpEvaluator(condValueParsed);

        if (!evaluator) {
          if ("development" !== 'production') {
            errMsg = makePrintable('Illegal relational operation: "' + keyRaw + '" in condition:', exprOption);
          }

          throwError(errMsg);
        }

        subCondList.push(evaluator);
      }

      if (!subCondList.length) {
        if ("development" !== 'production') {
          errMsg = makePrintable('Relational condition must have at least one operator.', 'Illegal condition:', exprOption);
        } // No relational operator always disabled in case of dangers result.


        throwError(errMsg);
      }

      var cond = new RelationalConditionInternal();
      cond.valueGetterParam = valueGetterParam;
      cond.valueParser = valueParser;
      cond.getValue = getters.getValue;
      cond.subCondList = subCondList;
      return cond;
    }

    function isObjectNotArray(val) {
      return isObject(val) && !isArrayLike(val);
    }

    var ConditionalExpressionParsed =
    /** @class */
    function () {
      function ConditionalExpressionParsed(exprOption, getters) {
        this._cond = parseOption(exprOption, getters);
      }

      ConditionalExpressionParsed.prototype.evaluate = function () {
        return this._cond.evaluate();
      };

      return ConditionalExpressionParsed;
    }();
    function parseConditionalExpression(exprOption, getters) {
      return new ConditionalExpressionParsed(exprOption, getters);
    }

    var filterTransform = {
      type: 'echarts:filter',
      // PEDING: enhance to filter by index rather than create new data
      transform: function (params) {
        // [Caveat] Fail-Fast:
        // Do not return the whole dataset unless user config indicate it explicitly.
        // For example, if no condition specified by mistake, return an empty result
        // is better than return the entire raw soruce for user to find the mistake.
        var upstream = params.upstream;
        var rawItem;
        var condition = parseConditionalExpression(params.config, {
          valueGetterAttrMap: createHashMap({
            dimension: true
          }),
          prepareGetValue: function (exprOption) {
            var errMsg = '';
            var dimLoose = exprOption.dimension;

            if (!hasOwn(exprOption, 'dimension')) {
              if ("development" !== 'production') {
                errMsg = makePrintable('Relation condition must has prop "dimension" specified.', 'Illegal condition:', exprOption);
              }

              throwError(errMsg);
            }

            var dimInfo = upstream.getDimensionInfo(dimLoose);

            if (!dimInfo) {
              if ("development" !== 'production') {
                errMsg = makePrintable('Can not find dimension info via: ' + dimLoose + '.\n', 'Existing dimensions: ', upstream.cloneAllDimensionInfo(), '.\n', 'Illegal condition:', exprOption, '.\n');
              }

              throwError(errMsg);
            }

            return {
              dimIdx: dimInfo.index
            };
          },
          getValue: function (param) {
            return upstream.retrieveValueFromItem(rawItem, param.dimIdx);
          }
        });
        var resultData = [];

        for (var i = 0, len = upstream.count(); i < len; i++) {
          rawItem = upstream.getRawDataItem(i);

          if (condition.evaluate()) {
            resultData.push(rawItem);
          }
        }

        return {
          data: resultData
        };
      }
    };

    var sampleLog = '';

    if ("development" !== 'production') {
      sampleLog = ['Valid config is like:', '{ dimension: "age", order: "asc" }', 'or [{ dimension: "age", order: "asc"], { dimension: "date", order: "desc" }]'].join(' ');
    }

    var sortTransform = {
      type: 'echarts:sort',
      transform: function (params) {
        var upstream = params.upstream;
        var config = params.config;
        var errMsg = ''; // Normalize
        // const orderExprList: OrderExpression[] = isArray(config[0])
        //     ? config as OrderExpression[]
        //     : [config as OrderExpression];

        var orderExprList = normalizeToArray(config);

        if (!orderExprList.length) {
          if ("development" !== 'production') {
            errMsg = 'Empty `config` in sort transform.';
          }

          throwError(errMsg);
        }

        var orderDefList = [];
        each(orderExprList, function (orderExpr) {
          var dimLoose = orderExpr.dimension;
          var order = orderExpr.order;
          var parserName = orderExpr.parser;
          var incomparable = orderExpr.incomparable;

          if (dimLoose == null) {
            if ("development" !== 'production') {
              errMsg = 'Sort transform config must has "dimension" specified.' + sampleLog;
            }

            throwError(errMsg);
          }

          if (order !== 'asc' && order !== 'desc') {
            if ("development" !== 'production') {
              errMsg = 'Sort transform config must has "order" specified.' + sampleLog;
            }

            throwError(errMsg);
          }

          if (incomparable && incomparable !== 'min' && incomparable !== 'max') {
            var errMsg_1 = '';

            if ("development" !== 'production') {
              errMsg_1 = 'incomparable must be "min" or "max" rather than "' + incomparable + '".';
            }

            throwError(errMsg_1);
          }

          if (order !== 'asc' && order !== 'desc') {
            var errMsg_2 = '';

            if ("development" !== 'production') {
              errMsg_2 = 'order must be "asc" or "desc" rather than "' + order + '".';
            }

            throwError(errMsg_2);
          }

          var dimInfo = upstream.getDimensionInfo(dimLoose);

          if (!dimInfo) {
            if ("development" !== 'production') {
              errMsg = makePrintable('Can not find dimension info via: ' + dimLoose + '.\n', 'Existing dimensions: ', upstream.cloneAllDimensionInfo(), '.\n', 'Illegal config:', orderExpr, '.\n');
            }

            throwError(errMsg);
          }

          var parser = parserName ? getRawValueParser(parserName) : null;

          if (parserName && !parser) {
            if ("development" !== 'production') {
              errMsg = makePrintable('Invalid parser name ' + parserName + '.\n', 'Illegal config:', orderExpr, '.\n');
            }

            throwError(errMsg);
          }

          orderDefList.push({
            dimIdx: dimInfo.index,
            parser: parser,
            comparator: new SortOrderComparator(order, incomparable)
          });
        }); // TODO: support it?

        var sourceFormat = upstream.sourceFormat;

        if (sourceFormat !== SOURCE_FORMAT_ARRAY_ROWS && sourceFormat !== SOURCE_FORMAT_OBJECT_ROWS) {
          if ("development" !== 'production') {
            errMsg = 'sourceFormat "' + sourceFormat + '" is not supported yet';
          }

          throwError(errMsg);
        } // Other upstream format are all array.


        var resultData = [];

        for (var i = 0, len = upstream.count(); i < len; i++) {
          resultData.push(upstream.getRawDataItem(i));
        }

        resultData.sort(function (item0, item1) {
          for (var i = 0; i < orderDefList.length; i++) {
            var orderDef = orderDefList[i];
            var val0 = upstream.retrieveValueFromItem(item0, orderDef.dimIdx);
            var val1 = upstream.retrieveValueFromItem(item1, orderDef.dimIdx);

            if (orderDef.parser) {
              val0 = orderDef.parser(val0);
              val1 = orderDef.parser(val1);
            }

            var result = orderDef.comparator.evaluate(val0, val1);

            if (result !== 0) {
              return result;
            }
          }

          return 0;
        });
        return {
          data: resultData
        };
      }
    };

    function install$R(registers) {
      registers.registerTransform(filterTransform);
      registers.registerTransform(sortTransform);
    }

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

      function DatasetModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = 'dataset';
        return _this;
      }

      DatasetModel.prototype.init = function (option, parentModel, ecModel) {
        _super.prototype.init.call(this, option, parentModel, ecModel);

        this._sourceManager = new SourceManager(this);
        disableTransformOptionMerge(this);
      };

      DatasetModel.prototype.mergeOption = function (newOption, ecModel) {
        _super.prototype.mergeOption.call(this, newOption, ecModel);

        disableTransformOptionMerge(this);
      };

      DatasetModel.prototype.optionUpdated = function () {
        this._sourceManager.dirty();
      };

      DatasetModel.prototype.getSourceManager = function () {
        return this._sourceManager;
      };

      DatasetModel.type = 'dataset';
      DatasetModel.defaultOption = {
        seriesLayoutBy: SERIES_LAYOUT_BY_COLUMN
      };
      return DatasetModel;
    }(ComponentModel);

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

      function DatasetView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = 'dataset';
        return _this;
      }

      DatasetView.type = 'dataset';
      return DatasetView;
    }(ComponentView);

    function install$S(registers) {
      registers.registerComponentModel(DatasetModel);
      registers.registerComponentView(DatasetView);
    }

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

    exports.Axis = Axis;
    exports.ChartView = ChartView;
    exports.ComponentModel = ComponentModel;
    exports.ComponentView = ComponentView;
    exports.List = List;
    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.registerVisual = registerVisual;
    exports.setCanvasCreator = setCanvasCreator;
    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
