"use strict";

var __rest = this && this.__rest || function(s, e) {
    var t = {};
    for (var p in s) Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0 && (t[p] = s[p]);
    if (null != s && "function" == typeof Object.getOwnPropertySymbols) {
        var i = 0;
        for (p = Object.getOwnPropertySymbols(s); i < p.length; i++) e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]) && (t[p[i]] = s[p[i]]);
    }
    return t;
};

Object.defineProperty(exports, "__esModule", {
    value: !0
}), exports.BaseMark = void 0;

const enum_1 = require("../interface/enum"), interface_1 = require("../../compile/mark/interface"), vutils_extension_1 = require("@visactor/vutils-extension"), color_1 = require("../../util/color"), scale_1 = require("../../util/scale"), gradient_1 = require("../../constant/gradient"), attribute_1 = require("../../constant/attribute"), vscale_1 = require("@visactor/vscale"), util_1 = require("../../theme/color-scheme/util"), mark_1 = require("../../compile/mark"), vutils_1 = require("@visactor/vutils"), common_1 = require("../utils/common"), interface_2 = require("../../compile/interface"), vrender_core_1 = require("@visactor/vrender-core"), util_2 = require("../../compile/mark/util"), factory_1 = require("../../core/factory"), data_1 = require("../../constant/data"), grammar_item_1 = require("../../compile/grammar-item"), layout_1 = require("../../constant/layout"), interface_3 = require("../../animation/interface"), compilable_data_1 = require("../../compile/data/compilable-data"), mark_2 = require("../../util/mark"), debug_1 = require("../../util/debug"), morph_1 = require("../../compile/morph");

class BaseMark extends grammar_item_1.GrammarItem {
    commit(render, recursion) {
        recursion && this.getMarks().length > 0 && this.getMarks().forEach((m => m.commit(!1, recursion))), 
        this._isCommited = !0, render && this.getCompiler().renderNextTick();
    }
    uncommit() {
        this._isCommited = !1;
    }
    isCommited() {
        return this._isCommited;
    }
    getMarkConfig() {
        return this._markConfig;
    }
    setMarkConfig(config) {
        Object.keys(config).forEach((key => {
            this._markConfig[key] = config[key];
        }));
    }
    getVisible() {
        return this._visible;
    }
    setVisible(visible) {
        this._visible = visible;
    }
    getUserId() {
        return this._userId;
    }
    setUserId(userId) {
        (0, vutils_1.isValid)(userId) && (this._userId = userId);
    }
    getDataView() {
        var _a;
        return null === (_a = this._data) || void 0 === _a ? void 0 : _a.getDataView();
    }
    setDataView(d) {
        (0, vutils_1.isNil)(this._data) && this.initMarkData(this._option), this._data.setDataView(d);
    }
    getData() {
        return this._data;
    }
    setData(d) {
        this._data = d, d && d.addRelatedMark(this);
    }
    hasState(state) {
        return state in this.state.getStateMap();
    }
    getState(state) {
        return this.state.getStateMap()[state];
    }
    getAnimationConfig() {
        return this._animationConfig;
    }
    setAnimationConfig(config) {
        const defaultPrams = "group" === this.type ? {
            selfOnly: !0
        } : {}, formatAnimationCfg = cfg => {
            var _a;
            const options = null !== (_a = cfg.options) && void 0 !== _a ? _a : {};
            return Object.assign(Object.assign(Object.assign({}, defaultPrams), cfg), {
                options: (datum, graphic, customParams) => {
                    var _a, _b;
                    const _options = "function" == typeof options ? options(datum, graphic, customParams) : options;
                    if (graphic && graphic.context && graphic.context.compiler && (0, vutils_1.isValid)(graphic.context.modelId)) {
                        const model = null === (_a = graphic.context.compiler.getChart()) || void 0 === _a ? void 0 : _a.getModelById(graphic.context.modelId);
                        return Object.assign(Object.assign({}, _options), {
                            layoutRect: null === (_b = null == model ? void 0 : model.getLayoutRect) || void 0 === _b ? void 0 : _b.call(model)
                        });
                    }
                    return Object.assign({}, _options);
                }
            });
        }, animationConfig = {};
        Object.keys(config).forEach((key => {
            const value = config[key];
            (0, vutils_1.isArray)(value) ? animationConfig[key] = value.map(formatAnimationCfg) : (0, 
            vutils_1.isValid)(value) && (animationConfig[key] = formatAnimationCfg(value));
        })), this._animationConfig = animationConfig;
    }
    disableAnimationByState(state) {
        const states = (0, vutils_1.array)(state);
        this._disabledAnimationStates = [ ...new Set([ ...this._disabledAnimationStates, ...states ]) ];
    }
    enableAnimationByState(state) {
        const states = (0, vutils_1.array)(state);
        this._disabledAnimationStates = this._disabledAnimationStates.filter((s => !states.includes(s)));
    }
    setSkipBeforeLayouted(skip) {
        this._skipBeforeLayouted = skip;
    }
    setGroupKey(groupKey) {
        this._groupKey = groupKey;
    }
    getProduct() {
        return this._product;
    }
    initMarkData(option) {
        this._data = new compilable_data_1.CompilableData(option), this._data.addRelatedMark(this);
    }
    _compileProduct(option) {
        this.commit(), this._context = null == option ? void 0 : option.context;
        const product = this.getProduct();
        if (this._visible) {
            if ((0, vutils_1.isValid)(product)) option.group && product.parent !== option.group && option.group.appendChild(product); else {
                if (!this.getCompiler().isInited) return;
                this._initProduct(null == option ? void 0 : option.group);
            }
            (0, vutils_1.isNil)(this._product) || (this.compileData(), this.compileState(), 
            this.compileEncode());
        } else (0, vutils_1.isValid)(product) && this.removeProduct();
    }
    _initProduct(group) {
        var _a;
        if (!this.getStage()) return;
        const id = this.getProductId();
        this._product = (0, vrender_core_1.createGroup)("group" !== this.type ? {
            pickable: !1,
            zIndex: this._markConfig.zIndex,
            overflow: this._markConfig.overflow
        } : {}), this._product.name = id, this._product.mark = this, (null != group ? group : null === (_a = this.getCompiler()) || void 0 === _a ? void 0 : _a.getRootGroup()).appendChild(this._product), 
        this._compiledProductId = id;
    }
    generateProductId() {
        return this._userId ? `${this._userId}` : `${this.name}_${this.id}`;
    }
    layout(layout) {}
    compileData() {
        (0, vutils_1.isNil)(this._data) || this._data.compile();
    }
    compileEncode() {}
    compileState() {}
    compileAnimation() {}
    compileContext(extraContext) {
        this._context = Object.assign({
            markId: this.id,
            modelId: this.model.id,
            markUserId: this._userId,
            modelUserId: this.model.userId
        }, extraContext);
    }
    getContext() {
        return this._context;
    }
    compileTransform() {}
    updateState(newState, noRender) {
        return this.commit(), this.state.updateState(newState, noRender);
    }
    getMarks() {
        return [];
    }
    runAnimationByState(state) {}
    stopAnimationByState(state) {}
    pauseAnimationByState(state) {}
    resumeAnimationByState(state) {}
    removeProduct() {
        this._product && this._product.parent && this._product.parent.removeChild(this._product), 
        this._product = null, this._compiledProductId = null;
    }
    release() {
        this.state.release(), super.release(), this._lastMark = null;
    }
    setSimpleStyle(s) {
        this._simpleStyle = s;
    }
    getSimpleStyle() {
        return this._simpleStyle;
    }
    constructor(name, option) {
        var _a;
        super(option), this.type = void 0, this.name = "mark", this._markConfig = {
            zIndex: layout_1.LayoutZIndex.Mark,
            morph: !1
        }, this._visible = !0, this.stateStyle = {}, this._unCompileChannel = {}, this._disabledAnimationStates = [], 
        this._skipBeforeLayouted = !1, this._extensionChannel = {}, this._computeExChannel = {}, 
        this._graphicMap = new Map, this._graphics = [], this._getEncoderOfStyle = (stateName, style) => {
            if (style && stateName) {
                const validEncoder = {};
                return Object.keys(style).forEach((key => {
                    this._unCompileChannel[key] || (validEncoder[key] = this._computeAttribute(key, stateName));
                })), validEncoder;
            }
            return null;
        }, this._setGraphicFromMarkConfig = g => {
            const {setCustomizedShape: setCustomizedShape, graphicName: graphicName} = this._markConfig;
            setCustomizedShape && (g.pathProxy = attrs => setCustomizedShape(g.context.data, attrs, new vrender_core_1.CustomPath2D)), 
            graphicName && ((0, vutils_1.isFunction)(graphicName) ? g.name = graphicName(g) : g.name = graphicName);
        }, this._setStateOfGraphic = (g, hasAnimation) => {
            g.clearStates(), g.stateProxy = null, g.context.diffState !== enum_1.DiffState.enter && g.context.diffState !== enum_1.DiffState.update || (g.stateProxy = (stateName, nexStates) => {
                var _a;
                return this._runEncoderOfGraphic(null === (_a = this._encoderOfState) || void 0 === _a ? void 0 : _a[stateName], g);
            }, g.context.states && g.useStates(g.context.states, hasAnimation));
        }, this.name = name, this.model = option.model, this.key = option.key, this.state = new mark_1.MarkStateManager(option, this), 
        this._attributeContext = option.attributeContext, null === (_a = option.map) || void 0 === _a || _a.set(this.id, this);
    }
    created() {
        this._initStyle();
    }
    initStyleWithSpec(spec) {
        spec && ((0, vutils_1.isValid)(spec.id) && (this._userId = spec.id), (0, vutils_1.isBoolean)(spec.interactive) && (this._markConfig.interactive = spec.interactive), 
        (0, vutils_1.isValid)(spec.zIndex) && (this._markConfig.zIndex = spec.zIndex), (0, 
        vutils_1.isBoolean)(spec.visible) && this.setVisible(spec.visible), this._markConfig.setCustomizedShape = spec.customShape, 
        this._stateSort = spec.stateSort, this._initSpecStyle(spec));
    }
    _transformStyleValue(styleConverter, transform) {
        if (styleConverter.scale) {
            const scale = styleConverter.scale, range = scale.range();
            return scale.range(range.map(transform)), styleConverter;
        }
        return "function" == typeof styleConverter ? (...args) => transform(styleConverter(...args)) : transform(styleConverter);
    }
    convertAngleToRadian(styleConverter) {
        return this._transformStyleValue(styleConverter, vutils_1.degreeToRadian);
    }
    isUserLevel(level) {
        return [ attribute_1.AttributeLevel.User_Mark, attribute_1.AttributeLevel.User_Series, attribute_1.AttributeLevel.User_Chart, attribute_1.AttributeLevel.User_SeriesStyle ].includes(level);
    }
    setStyle(style, state = "normal", level = 0) {
        if ((0, vutils_1.isNil)(style)) return;
        void 0 === this.stateStyle[state] && (this.stateStyle[state] = {});
        const isUserLevel = this.isUserLevel(level);
        Object.keys(style).forEach((attr => {
            let attrStyle = style[attr];
            (0, vutils_1.isNil)(attrStyle) || (attrStyle = this._filterAttribute(attr, attrStyle, state, level, isUserLevel), 
            this.setAttribute(attr, attrStyle, state, level));
        }));
    }
    getStyle(key, state = "normal") {
        var _a;
        return null === (_a = this.stateStyle[state][key]) || void 0 === _a ? void 0 : _a.style;
    }
    _filterAttribute(attr, style, state, level, isUserLevel) {
        let newStyle = this._styleConvert(style);
        if (isUserLevel) switch (attr) {
          case "angle":
            newStyle = this.convertAngleToRadian(newStyle);
            break;

          case "innerPadding":
          case "outerPadding":
            newStyle = this._transformStyleValue(newStyle, (value => -value));
            break;

          case "curveType":
            newStyle = this._transformStyleValue(newStyle, (value => (0, common_1.curveTypeTransform)(value, this._option.model.direction)));
        }
        return newStyle;
    }
    setReferer(mark, styleKey, state) {
        var _a;
        if (mark) if (styleKey && state) {
            const style = null !== (_a = this.stateStyle[state]) && void 0 !== _a ? _a : {
                [styleKey]: {}
            };
            this.stateStyle[state][styleKey] = Object.assign(Object.assign({}, style[styleKey]), {
                referer: mark
            });
        } else Object.entries(this.stateStyle).forEach((([state, style]) => {
            Object.entries(style).forEach((([styleKey, style]) => {
                this.stateStyle[state][styleKey].referer = mark;
            }));
        }));
    }
    setPostProcess(key, postProcessFunc, state = "normal") {
        var _a;
        (null === (_a = this.stateStyle[state]) || void 0 === _a ? void 0 : _a[key]) && (this.stateStyle[state][key].postProcess = postProcessFunc);
    }
    getAttribute(key, datum, state = "normal") {
        return this._computeAttribute(key, state)(datum);
    }
    getAttributesOfState(datum, state = "normal") {
        const style = this.stateStyle[state];
        if (style) {
            const res = {};
            return Object.keys(style).forEach((k => {
                this._unCompileChannel[k] || (res[k] = this._computeAttribute(k, state)(datum));
            })), res;
        }
    }
    setAttribute(attr, style, state = "normal", level = 0) {
        var _a;
        void 0 === this.stateStyle[state] && (this.stateStyle[state] = {}), void 0 === this.stateStyle[state][attr] && (this.stateStyle[state][attr] = {
            level: level,
            style: style,
            referer: void 0
        });
        const attrLevel = null === (_a = this.stateStyle[state][attr]) || void 0 === _a ? void 0 : _a.level;
        (0, vutils_1.isValid)(attrLevel) && attrLevel <= level && (0, vutils_extension_1.mergeSpec)(this.stateStyle[state][attr], {
            style: style,
            level: level
        }), "normal" !== state && attr in this._extensionChannel && this._extensionChannel[attr].forEach((key => {
            void 0 === this.stateStyle[state][key] && (this.stateStyle[state][key] = this.stateStyle.normal[key]);
        }));
    }
    _getDefaultStyle() {
        return {
            visible: !0,
            x: 0,
            y: 0
        };
    }
    _styleConvert(style) {
        if (!style) return style;
        if ((0, vscale_1.isValidScaleType)(style.type) || style.scale) {
            const scale = (0, scale_1.createScaleWithSpec)(style, {
                globalScale: this._option.globalScale,
                seriesId: this._option.seriesId
            });
            if (scale) return {
                scale: scale,
                field: style.field,
                changeDomain: style.changeDomain
            };
        }
        return style;
    }
    _computeAttribute(key, state) {
        var _a;
        let stateStyle = null === (_a = this.stateStyle[state]) || void 0 === _a ? void 0 : _a[key];
        stateStyle || (stateStyle = this.stateStyle.normal[key]);
        const baseValueFunctor = this._computeStateAttribute(stateStyle, key, state), hasPostProcess = (0, 
        vutils_1.isFunction)(null == stateStyle ? void 0 : stateStyle.postProcess), hasExCompute = key in this._computeExChannel;
        if (hasPostProcess && hasExCompute) {
            const exCompute = this._computeExChannel[key];
            return datum => {
                let baseValue = baseValueFunctor(datum);
                return baseValue = stateStyle.postProcess(baseValue, datum, this._attributeContext, this.getDataView()), 
                exCompute(key, datum, state, baseValue);
            };
        }
        if (hasPostProcess) return datum => stateStyle.postProcess(baseValueFunctor(datum), datum, this._attributeContext, this.getDataView());
        if (hasExCompute) {
            const exCompute = this._computeExChannel[key];
            return datum => exCompute(key, datum, state, baseValueFunctor(datum));
        }
        return baseValueFunctor;
    }
    _computeStateAttribute(stateStyle, key, state) {
        var _a;
        return stateStyle ? stateStyle.referer ? stateStyle.referer._computeAttribute(key, state) : stateStyle.style ? "function" == typeof stateStyle.style ? datum => stateStyle.style(datum, this._attributeContext, {
            mark: this
        }, this.getDataView()) : gradient_1.GradientType.includes(stateStyle.style.gradient) ? this._computeGradientAttr(stateStyle.style) : [ "outerBorder", "innerBorder" ].includes(key) ? this._computeBorderAttr(stateStyle.style) : (0, 
        vscale_1.isValidScaleType)(null === (_a = stateStyle.style.scale) || void 0 === _a ? void 0 : _a.type) ? datum => {
            let data = datum;
            return "series" === this.model.modelType && this.model.getMarkData && (data = this.model.getMarkData(datum)), 
            stateStyle.style.scale.scale(data[stateStyle.style.field]);
        } : datum => stateStyle.style : datum => stateStyle.style : datum => {};
    }
    _initStyle() {
        const defaultStyle = this._getDefaultStyle();
        this.setStyle(defaultStyle, "normal", 0);
    }
    _initSpecStyle(spec) {
        spec.style && this.setStyle(spec.style, "normal", attribute_1.AttributeLevel.User_Mark);
        const state = spec.state;
        state && Object.keys(state).forEach((key => {
            const stateTemp = state[key];
            if ("style" in stateTemp) {
                const style = stateTemp.style;
                let stateInfo = {
                    stateValue: key
                };
                "level" in stateTemp && (stateInfo.level = stateTemp.level), "filter" in stateTemp && (stateInfo = (0, 
                vutils_1.isFunction)(stateTemp.filter) ? Object.assign({
                    filter: stateTemp.filter
                }, stateInfo) : Object.assign(Object.assign({}, stateTemp.filter), stateInfo)), 
                this.state.addStateInfo(stateInfo), this.setStyle(style, key, attribute_1.AttributeLevel.User_Mark);
            } else this.setStyle(stateTemp, key, attribute_1.AttributeLevel.User_Mark);
        }));
    }
    _computeGradientAttr(gradientStyle) {
        var _a, _b;
        const {gradient: gradient, scale: scale, field: field} = gradientStyle, rest = __rest(gradientStyle, [ "gradient", "scale", "field" ]);
        let colorScale = scale, colorField = field;
        if (!(scale && field || "series" !== this.model.modelType)) {
            const {scale: globalColorScale, field: globalField} = this.model.getColorAttribute();
            scale || (colorScale = globalColorScale), colorField || (colorField = globalField);
        }
        const themeColor = (0, util_1.computeActualDataScheme)((0, util_1.getDataScheme)(this.model.getColorScheme(), "series" === this.model.modelType ? null === (_b = (_a = this.model).getSpec) || void 0 === _b ? void 0 : _b.call(_a) : void 0), this.model.getDefaultColorDomain()), mergedStyle = Object.assign(Object.assign({}, gradient_1.DEFAULT_GRADIENT_CONFIG[gradient]), rest);
        return data => {
            const computeStyle = {}, markData = this.getDataView();
            return Object.keys(mergedStyle).forEach((key => {
                const value = mergedStyle[key];
                "stops" === key ? computeStyle.stops = value.map((stop => {
                    const {opacity: opacity, color: color, offset: offset} = stop;
                    let computeColor = null != color ? color : null == colorScale ? void 0 : colorScale.scale(data[colorField]);
                    return (0, vutils_1.isFunction)(color) && (computeColor = color(data, this._attributeContext, markData)), 
                    (0, vutils_1.isValid)(opacity) && (computeColor = color_1.Color.SetOpacity(computeColor, opacity)), 
                    {
                        offset: (0, vutils_1.isFunction)(offset) ? offset(data, this._attributeContext, markData) : offset,
                        color: computeColor || themeColor[0]
                    };
                })) : (0, vutils_1.isFunction)(value) ? computeStyle[key] = value(data, this._attributeContext, markData) : computeStyle[key] = value;
            })), computeStyle.gradient = gradient, computeStyle;
        };
    }
    _computeBorderAttr(borderStyle) {
        const {scale: scale, field: field} = borderStyle, mergedStyle = __rest(borderStyle, [ "scale", "field" ]);
        return data => {
            var _a, _b, _c;
            const computeStyle = {};
            if (Object.keys(mergedStyle).forEach((key => {
                const value = mergedStyle[key];
                (0, vutils_1.isFunction)(value) ? computeStyle[key] = value(data, this._attributeContext, this.getDataView()) : computeStyle[key] = value;
            })), "stroke" in computeStyle) gradient_1.GradientType.includes(null === (_c = mergedStyle.stroke) || void 0 === _c ? void 0 : _c.gradient) && (computeStyle.stroke = this._computeGradientAttr(mergedStyle.stroke)(data)); else {
                const themeColor = (0, util_1.computeActualDataScheme)((0, util_1.getDataScheme)(this.model.getColorScheme(), "series" === this.model.modelType ? null === (_b = (_a = this.model).getSpec) || void 0 === _b ? void 0 : _b.call(_a) : void 0), this.model.getDefaultColorDomain());
                let colorScale = scale, colorField = field;
                if (!(scale && field || "series" !== this.model.modelType)) {
                    const {scale: globalColorScale, field: globalField} = this.model.getColorAttribute();
                    scale || (colorScale = globalColorScale), colorField || (colorField = globalField), 
                    computeStyle.stroke = (null == colorScale ? void 0 : colorScale.scale(data[colorField])) || themeColor[0];
                }
            }
            return computeStyle;
        };
    }
    _getDataByKey(data) {
        return (0, common_1.groupData)(data, ((datum, index) => {
            var _a;
            return `${this._groupKeyGetter(datum)}_${null !== (_a = this._keyGetter(datum)) && void 0 !== _a ? _a : index}`;
        }));
    }
    _getCommonContext() {
        return {
            compiler: this.getCompiler(),
            markType: this.type,
            markId: this.id,
            modelId: this.model.id,
            markUserId: this._userId,
            modelUserId: this.model.userId
        };
    }
    prepareMorph(mark) {
        this._lastMark = mark;
    }
    reuse(mark) {
        this.type === mark.type && (this._product = mark.getProduct(), this._graphics = mark.getGraphics(), 
        this._graphicMap = mark._graphicMap, this._graphicMap.forEach((g => {
            g.context = Object.assign(Object.assign({}, g.context), this._getCommonContext());
        })), this._dataByKey = mark._dataByKey, this._prevDataByKey = mark._prevDataByKey, 
        this.needClear = mark.needClear);
    }
    _parseProgressiveContext(data) {
        const enableProgressive = this._markConfig.progressiveStep > 0 && this._markConfig.progressiveThreshold > 0 && this._markConfig.progressiveStep < this._markConfig.progressiveThreshold, large = this._markConfig.large && this._markConfig.largeThreshold > 0 && data.length >= this._markConfig.largeThreshold;
        if (enableProgressive) {
            const groupedData = this._dataByGroup;
            return groupedData && groupedData.keys && groupedData.keys.some((key => groupedData.data.get(key).length > this._markConfig.progressiveThreshold)) ? {
                large: large,
                progressive: {
                    data: data,
                    step: this._markConfig.progressiveStep,
                    currentIndex: 0,
                    totalStep: groupedData.keys.reduce(((total, key) => Math.max(Math.ceil(groupedData.data.get(key).length / this._markConfig.progressiveStep), total)), 1),
                    groupedData: groupedData.data
                }
            } : {
                large: large
            };
        }
        return {
            large: large
        };
    }
    getGraphics() {
        return this._graphics;
    }
    _createGraphic(attrs = {}) {
        return factory_1.Factory.createGraphicComponent(this.type, attrs);
    }
    _runGroupData(data) {
        this._keyGetter = (0, vutils_1.isFunction)(this.key) ? this.key : (0, vutils_1.isValid)(this.key) ? datum => null == datum ? void 0 : datum[this.key] : datum => null == datum ? void 0 : datum[data_1.DEFAULT_DATA_KEY], 
        this._groupKeyGetter = (0, vutils_1.isValid)(this._groupKey) ? datum => `${null == datum ? void 0 : datum[this._groupKey]}` : () => "key", 
        this._dataByGroup = (0, common_1.groupData)(data, this._groupKeyGetter);
    }
    getAnimationState() {
        const graphicsAnimationStates = this._graphics.map((g => g.context.animationState)), animationState = graphicsAnimationStates.every((state => state === interface_3.AnimationStateEnum.appear)) ? interface_3.AnimationStateEnum.appear : graphicsAnimationStates.every((state => state === interface_3.AnimationStateEnum.disappear)) ? interface_3.AnimationStateEnum.disappear : graphicsAnimationStates[0];
        return null != animationState ? animationState : interface_3.AnimationStateEnum.none;
    }
    createAnimationStateList(type, animationConfig) {
        var _a;
        let config = animationConfig[type];
        return config && Array.isArray(config) && (config = 1 === config.length ? config[0] : config), 
        Array.isArray(config) ? config.map(((item, index) => {
            var _a;
            return Object.assign(Object.assign({}, item), {
                priority: null !== (_a = item.priority) && void 0 !== _a ? _a : 1 / 0
            });
        })) : config ? Object.assign(Object.assign({}, config), {
            priority: "normal" === type ? null !== (_a = config.priority) && void 0 !== _a ? _a : 1 / 0 : config.priority
        }) : config;
    }
    tryRunMorphing(graphics) {
        if (this._lastMark) {
            graphics.forEach((g => {
                "appear" !== g.context.animationState && "enter" !== g.context.animationState || g.setAttributes(g.getAttributes(!0));
            }));
            const res = (0, morph_1.morph)([ this._lastMark ], [ this ], {});
            return this._lastMark = null, res;
        }
        return !1;
    }
    _runStateAnimation(graphics) {
        var _a, _b;
        if (!this._animationConfig || 0 === graphics.length) return;
        if (this.tryRunMorphing(graphics)) return;
        const animationConfig = this.getAnimationConfig();
        if (null !== (_a = this._markConfig.useSequentialAnimation) && void 0 !== _a && _a && this._runSequentialAnimations) return void this._runSequentialAnimations(graphics);
        const isAppear = graphics.every((g => "appear" === g.context.animationState)), appearConfig = this.createAnimationStateList("appear", animationConfig);
        if (isAppear && this._product) {
            const stateArray = appearConfig ? [ "appear" ] : [], configArray = appearConfig ? [ {
                name: "appear",
                animation: appearConfig
            } ] : [];
            if (animationConfig.normal) {
                stateArray.push("normal");
                const normalConfig = {
                    name: "normal",
                    animation: this.createAnimationStateList("normal", animationConfig)
                };
                configArray.push(normalConfig);
            }
            this._product.applyAnimationState(stateArray, configArray);
        }
        let shouldRunNormal = !1;
        if (graphics.forEach((g => {
            const state = g.context.animationState;
            if ("appear" === state) return;
            const config = animationConfig[state];
            if (config && config.length > 0) {
                const configList = config.map(((item, index) => ({
                    name: `${state}_${index}`,
                    animation: item
                })));
                configList.forEach((item => {
                    item.animation.customParameters = g.context;
                }));
                const stateArray = [ state ];
                g.applyAnimationState(stateArray, [ 1 === configList.length ? configList[0] : configList ]);
            }
            "enter" === state && animationConfig.normal && (shouldRunNormal = !0);
        })), shouldRunNormal && this._product && (null === (_b = animationConfig.normal) || void 0 === _b ? void 0 : _b.length)) {
            this._product.stopAnimationState("normal", "start");
            const normalConfig = {
                name: "normal",
                animation: this.createAnimationStateList("normal", animationConfig)
            };
            this._product.applyAnimationState([ "normal" ], [ normalConfig ]);
        }
    }
    _setAnimationState(g) {
        var _a, _b, _c;
        const callback = ("component" === this.type ? this.model.getAnimationStateCallback() : null === (_c = null === (_b = (_a = this.model).getRegion) || void 0 === _b ? void 0 : _b.call(_a)) || void 0 === _c ? void 0 : _c.getAnimationStateCallback()) || (g => {
            var _a;
            const diffState = null === (_a = g.context) || void 0 === _a ? void 0 : _a.diffState;
            return diffState === interface_3.AnimationStateEnum.exit ? interface_3.AnimationStateEnum.exit : diffState === interface_3.AnimationStateEnum.update ? interface_3.AnimationStateEnum.update : interface_3.AnimationStateEnum.appear;
        }), customizedState = callback(g);
        g.context.animationState = null != customizedState ? customizedState : g.context.diffState, 
        g.context.animationState === enum_1.DiffState.exit && (g.context.reusing = !0, g.animates && g.animates.forEach((a => a.stop())));
    }
    _runJoin(data) {
        const newGroupedData = this._getDataByKey(data), prevGroupedData = this._prevDataByKey, allGraphics = [], enterGraphics = new Set(this._graphics.filter((g => g.context.diffState === enum_1.DiffState.enter))), callback = (key, newData, prevData) => {
            var _a, _b, _c, _d, _e, _f, _g, _h, _j;
            let g, diffState;
            return (0, vutils_1.isNil)(newData) ? (g = this._graphicMap.get(key), g && (diffState = enum_1.DiffState.exit)) : (0, 
            vutils_1.isNil)(prevData) ? (g = this._graphicMap.has(key) ? this._graphicMap.get(key) : {}, 
            diffState = enum_1.DiffState.enter, g.isExiting = !1, this._graphicMap.set(key, g), 
            allGraphics.push(g)) : (g = this._graphicMap.get(key), g && (diffState = enum_1.DiffState.update, 
            allGraphics.push(g))), g && (enterGraphics.delete(g), g.context = Object.assign(Object.assign({}, this._getCommonContext()), {
                diffState: diffState,
                reusing: null === (_a = g.context) || void 0 === _a ? void 0 : _a.reusing,
                originalFieldX: null === (_b = g.context) || void 0 === _b ? void 0 : _b.originalFieldX,
                originalFieldY: null === (_c = g.context) || void 0 === _c ? void 0 : _c.originalFieldY,
                fieldX: null === (_d = g.context) || void 0 === _d ? void 0 : _d.fieldX,
                fieldY: null === (_e = g.context) || void 0 === _e ? void 0 : _e.fieldY,
                data: null != newData ? newData : null === (_f = g.context) || void 0 === _f ? void 0 : _f.data,
                uniqueKey: key,
                key: newData ? this._keyGetter(newData[0]) : null === (_g = g.context) || void 0 === _g ? void 0 : _g.key,
                groupKey: newData ? this._groupKeyGetter(newData[0]) : null === (_h = g.context) || void 0 === _h ? void 0 : _h.groupKey,
                indexKey: "__VCHART_DEFAULT_DATA_INDEX",
                stateAnimateConfig: null === (_j = this.getAnimationConfig()) || void 0 === _j ? void 0 : _j.state
            }), this._setAnimationState(g)), g;
        };
        if (prevGroupedData && newGroupedData) {
            const prevMap = new Map(prevGroupedData.data);
            newGroupedData.keys.forEach((key => {
                callback(key, newGroupedData.data.get(key), prevMap.get(key)), prevMap.delete(key);
            })), prevGroupedData.keys.forEach((key => {
                prevMap.has(key) && callback(key, null, prevMap.get(key));
            }));
        } else newGroupedData ? newGroupedData.keys.forEach((key => {
            const g = callback(key, newGroupedData.data.get(key), null);
            g && (g.context.animationState = interface_3.AnimationStateEnum.appear);
        })) : prevGroupedData && prevGroupedData.keys.forEach((key => {
            callback(key, null, prevGroupedData.data.get(key)).context.animationState = interface_3.AnimationStateEnum.disappear;
        }));
        enterGraphics.forEach((g => {
            this._graphicMap.delete(g.context.uniqueKey), g.parent && g.parent.removeChild(g), 
            g.release();
        }));
        const graphicCount = allGraphics.length;
        allGraphics.forEach(((g, index) => {
            g.context.graphicCount = graphicCount, g.context.graphicIndex = index, g.stateSort = this._stateSort;
        })), this._dataByKey = newGroupedData, this._graphics = allGraphics, this.needClear = !0;
    }
    _runEncoderOfGraphic(styles, g, attrs = {}) {
        return (0, common_1.runEncoder)(styles, g.context.data[0], attrs);
    }
    _runGroupEncoder(groupStyles) {
        if (!this._dataByGroup) return null;
        const attrsByGroup = {};
        return this._dataByGroup.keys.forEach((key => {
            attrsByGroup[key] = (0, common_1.runEncoder)(groupStyles, this._dataByGroup.data.get(key)[0]);
        })), this._attrsByGroup = attrsByGroup, attrsByGroup;
    }
    _transformGraphicAttributes(g, attrs, groupAttrs) {
        return Object.assign(Object.assign({}, groupAttrs), attrs);
    }
    _separateNormalStyle(normalStyle) {
        const updateStyles = {}, groupStyles = {};
        return Object.keys(normalStyle).forEach((key => {
            this._unCompileChannel[key] || (this._option.noSeparateStyle || (0, util_2.isStateAttrChangeable)(key, normalStyle, this._groupKey) ? updateStyles[key] = normalStyle[key] : groupStyles[key] = normalStyle[key]);
        })), {
            updateStyles: updateStyles,
            groupStyles: groupStyles
        };
    }
    _addProgressiveGraphic(parent, g) {
        parent.incrementalAppendChild(g);
    }
    _runEncoder(graphics, noGroupEncode) {
        var _a;
        const attrsByGroup = noGroupEncode ? null : this._runGroupEncoder(null === (_a = this._encoderOfState) || void 0 === _a ? void 0 : _a.group);
        graphics.forEach(((g, index) => {
            var _a, _b;
            let attrs = this._runEncoderOfGraphic(null === (_a = this._encoderOfState) || void 0 === _a ? void 0 : _a.update, g);
            null === (_b = g.currentStates) || void 0 === _b || _b.forEach((_state => {
                var _a;
                const stateAttr = this._runEncoderOfGraphic(null === (_a = this._encoderOfState) || void 0 === _a ? void 0 : _a[_state], g);
                attrs = Object.assign(Object.assign({}, attrs), stateAttr);
            })), (0, vutils_1.isNil)(this._markConfig.interactive) || (attrs.pickable = this._markConfig.interactive);
            const finalAttrs = this._transformGraphicAttributes(g, attrs, null == attrsByGroup ? void 0 : attrsByGroup[g.context.groupKey]);
            g.context.finalAttrs = finalAttrs;
        }));
    }
    _runApplyGraphic(graphics) {
        const hasAnimation = this.hasAnimation();
        graphics.forEach(((g, index) => {
            var _a, _b;
            const finalAttrs = g.context.finalAttrs, hasStateAnimation = this.hasAnimationByState(g.context.animationState);
            if (g.setAttributes) {
                const diffAttrs = (0, mark_2.getDiffAttributesOfGraphic)(g, finalAttrs);
                g.context.diffAttrs = diffAttrs, g.context.reusing ? (g.context.lastAttrs = g.attribute, 
                g.initAttributes({}), g.context.reusing = !1) : hasStateAnimation || (hasAnimation ? g.setAttributesAndPreventAnimate(diffAttrs) : g.setAttributes(diffAttrs)), 
                hasAnimation && g.setFinalAttributes(finalAttrs);
            } else {
                const mockGraphic = g;
                g = this._createGraphic(finalAttrs), hasAnimation && (null === (_a = g.setFinalAttributes) || void 0 === _a || _a.call(g, finalAttrs)), 
                g.context = mockGraphic.context, g.context.diffAttrs = finalAttrs, g.stateSort = this._stateSort;
                const gIndex = this._graphics === graphics ? index : index + this._graphics.length - graphics.length;
                if (gIndex >= 0 && (this._graphics[gIndex] = g), null === (_b = this.renderContext) || void 0 === _b ? void 0 : _b.progressive) {
                    const groupIndex = this._dataByGroup ? this._dataByGroup.keys.indexOf(g.context.groupKey) : 0, group = groupIndex >= 0 ? this._product.getChildAt(groupIndex) : null;
                    group && this._addProgressiveGraphic(group, g);
                } else this._product.appendChild(g), this._graphicMap.set(g.context.uniqueKey, g);
            }
            this._setStateOfGraphic(g, hasStateAnimation), this._setGraphicFromMarkConfig(g);
        }));
    }
    _updateEncoderByState() {
        const encoderOfState = {};
        Object.keys(this.stateStyle).forEach((stateName => {
            if (stateName === interface_1.STATE_VALUE_ENUM.STATE_NORMAL) {
                const {groupStyles: groupStyles, updateStyles: updateStyles} = this._separateNormalStyle(this.stateStyle[stateName]);
                encoderOfState.group = this._getEncoderOfStyle(stateName, groupStyles), encoderOfState.update = this._getEncoderOfStyle(stateName, updateStyles);
            } else encoderOfState[stateName] = this._getEncoderOfStyle(stateName, this.stateStyle[stateName]);
        })), this._encoderOfState = encoderOfState;
    }
    _runState(graphics) {
        graphics.forEach((g => {
            var _a;
            const newStateValues = [ ...(null !== (_a = g.currentStates) && void 0 !== _a ? _a : []).filter((sv => !this.state.getStateInfo(sv))), ...this.state.checkState(g, g.context.data) ];
            this._stateSort && newStateValues.length && newStateValues.sort(this._stateSort), 
            g.context.states = newStateValues;
        }));
    }
    _getAttrsFromConfig(attrs = {}) {
        const {zIndex: zIndex, clip: clip, clipPath: clipPath, overflow: overflow} = this._markConfig;
        if ((0, vutils_1.isNil)(zIndex) || (attrs.zIndex = zIndex), (0, vutils_1.isNil)(clip) || (attrs.clip = clip), 
        !(0, vutils_1.isNil)(clipPath)) {
            const paths = (0, vutils_1.isArray)(clipPath) ? clipPath : clipPath(this._graphics);
            paths && paths.length || (attrs.clip = !1), attrs.path = paths;
        }
        return (0, vutils_1.isNil)(overflow) || (attrs.overflow = overflow), attrs;
    }
    _updateAttrsOfGroup() {
        var _a;
        const attrs = this._getAttrsFromConfig();
        null === (_a = this._product) || void 0 === _a || _a.setAttributes(attrs), this._markConfig.support3d && this._product && this._product.setMode("3d");
    }
    _runBeforeTransform(data) {
        var _a;
        const transforms = null === (_a = this._transform) || void 0 === _a ? void 0 : _a.filter((transformSpec => {
            if (transformSpec.type) {
                const transform = factory_1.Factory.getGrammarTransform(transformSpec.type);
                return transform && (!transform.runType || "beforeJoin" === transform.runType);
            }
            return !1;
        }));
        return this.runTransforms(transforms, data);
    }
    _runEncoderTransform(data, isProgressive) {
        var _a;
        const transforms = null === (_a = this._transform) || void 0 === _a ? void 0 : _a.filter((transformSpec => {
            if (transformSpec.type) {
                const transform = factory_1.Factory.getGrammarTransform(transformSpec.type);
                return transform && "afterEncode" === transform.runType && !!transform.canProgressive === isProgressive;
            }
            return !1;
        }));
        return this.runTransforms(transforms, data);
    }
    renderInner() {
        var _a, _b, _c;
        this._updateEncoderByState();
        const data = null !== (_b = null === (_a = this._data) || void 0 === _a ? void 0 : _a.getProduct()) && void 0 !== _b ? _b : [ {} ], transformData = this._runBeforeTransform(data);
        let markData;
        if (null == transformData ? void 0 : transformData.progressive) {
            this.renderContext = {
                beforeTransformProgressive: transformData.progressive
            };
            const p = transformData.progressive;
            if (p.canAnimate && p.canAnimate() && p.unfinished()) return void this._updateAttrsOfGroup();
            markData = p.output();
        } else markData = (0, vutils_1.array)(transformData), this._runGroupData(markData), 
        this.renderContext = this._parseProgressiveContext(markData);
        (null === (_c = this.renderContext) || void 0 === _c ? void 0 : _c.progressive) ? (this._graphicMap.clear(), 
        this._runProgressiveStep()) : (this._runJoin(markData), this._runState(this._graphics), 
        this._runEncoder(this._graphics), this._runEncoderTransform(this._graphics, !1), 
        this._runApplyGraphic(this._graphics)), this._updateAttrsOfGroup();
    }
    render() {
        this.isCommited() && (!this.getVisible() || this._skipBeforeLayouted && this.getCompiler().getLayoutState() === interface_2.LayoutState.before || ((0, 
        debug_1.log)(`render mark: ${this.getProductId()}, type is ${this.type}`), this.renderInner()), 
        this.uncommit());
    }
    updateMarkState(key) {
        if (!this._product) return;
        const stateInfo = this.state.getStateInfo(key);
        this._graphics.forEach((g => {
            "in" === this.state.checkOneState(g, g.context.data, stateInfo) ? g.addState(key, !0, this.hasAnimationByState("state")) : g.removeState(key, this.hasAnimationByState("state"));
        }));
    }
    clearExitGraphics() {
        this._prevDataByKey = this._dataByKey;
        const doRemove = (g, key) => {
            this._graphicMap.delete(key), g.parent && g.parent.removeChild(g), g.release && g.release();
        };
        this._graphicMap.forEach(((g, key) => {
            if (g.context.diffState === enum_1.DiffState.exit && !g.isExiting) if (g.context.animationState === enum_1.DiffState.exit && this.hasAnimationByState("exit")) {
                g.isExiting = !0;
                const animationConfig = this.getAnimationConfig();
                if (animationConfig.exit && animationConfig.exit.length) {
                    const exitConfigList = animationConfig.exit.map(((item, index) => ({
                        name: `exit_${index}`,
                        animation: Object.assign(Object.assign({}, item), {
                            customParameters: g.context
                        })
                    })));
                    g.applyAnimationState([ "exit" ], [ 1 === exitConfigList.length ? exitConfigList[0] : exitConfigList ], (() => {
                        doRemove(g, key);
                    }));
                }
            } else doRemove(g, key);
        }));
    }
    isProgressive() {
        return this.renderContext && (!!this.renderContext.progressive || !!this.renderContext.beforeTransformProgressive);
    }
    canAnimateAfterProgressive() {
        var _a, _b;
        return this.renderContext && this.renderContext.beforeTransformProgressive && (null === (_b = (_a = this.renderContext.beforeTransformProgressive).canAnimate) || void 0 === _b ? void 0 : _b.call(_a));
    }
    isDoingProgressive() {
        return this.renderContext && (this.renderContext.progressive && this.renderContext.progressive.currentIndex < this.renderContext.progressive.totalStep || this.renderContext.beforeTransformProgressive && this.renderContext.beforeTransformProgressive.unfinished());
    }
    clearProgressive() {
        this.renderContext && this.renderContext.progressive && (this._graphics = [], this._product.children.forEach((group => {
            group.incrementalClearChild();
        })), this._product.removeAllChild()), this.renderContext && this.renderContext.beforeTransformProgressive && this.renderContext.beforeTransformProgressive.release(), 
        this.renderContext = null;
    }
    restartProgressive() {
        this.renderContext && this.renderContext.progressive && (this.renderContext.progressive.currentIndex = 0);
    }
    _runBeforeProgressive() {
        var _a;
        const transform = this.renderContext.beforeTransformProgressive;
        transform.progressiveRun();
        const output = transform.output();
        if (null === (_a = transform.canAnimate) || void 0 === _a ? void 0 : _a.call(transform)) {
            if (transform.unfinished()) return;
            this._runGroupData(output), this._runJoin(output), this._runState(this._graphics), 
            this._runEncoder(this._graphics), this._runApplyGraphic(this._graphics);
        }
    }
    _runProgressiveJoin() {
        const currentIndex = this.renderContext.progressive.currentIndex, graphics = [], graphicsByGroup = {};
        return this._dataByGroup.keys.forEach((groupKey => {
            const data = this.renderContext.progressive.groupedData.get(groupKey), groupStep = this.renderContext.progressive.step, dataSlice = data.slice(currentIndex * groupStep, (currentIndex + 1) * groupStep), group = [];
            dataSlice.forEach(((entry, i) => {
                const key = this._keyGetter(entry), g = {
                    context: Object.assign(Object.assign({}, this._getCommonContext()), {
                        diffState: enum_1.DiffState.enter,
                        data: [ entry ],
                        uniqueKey: `${groupKey}_${null != key ? key : currentIndex * groupStep + i}`,
                        key: key,
                        groupKey: groupKey
                    })
                };
                group.push(g), graphics.push(g);
            })), graphicsByGroup[groupKey] = group;
        })), {
            graphicsByGroup: graphicsByGroup,
            graphics: graphics,
            needUpdate: !0
        };
    }
    _createIncrementalGraphics() {
        this._product.removeAllChild(), this._dataByGroup.keys.forEach((key => {
            const graphicItem = (0, vrender_core_1.createGroup)({
                pickable: !1,
                zIndex: this._markConfig.zIndex
            });
            graphicItem.incremental = this.renderContext.progressive.step, this._product.appendChild(graphicItem);
        }));
    }
    _setCommonAttributesToTheme(g) {
        var _a, _b, _c;
        if (this._attrsByGroup && g) {
            const parent = g.parent;
            parent && (null === (_a = this._attrsByGroup) || void 0 === _a ? void 0 : _a[null === (_b = g.context) || void 0 === _b ? void 0 : _b.groupKey]) && parent.setTheme({
                common: this._attrsByGroup[null === (_c = g.context) || void 0 === _c ? void 0 : _c.groupKey]
            });
        }
    }
    _runProgressiveEncoder(graphics) {
        0 === this.renderContext.progressive.currentIndex ? this._runEncoder(graphics) : this._runEncoder(graphics, !0);
    }
    _runProgressiveApplyGraphic(graphics) {
        0 === this.renderContext.progressive.currentIndex ? (this._runApplyGraphic(graphics), 
        this._setCommonAttributesToTheme(graphics[0])) : this._runApplyGraphic(graphics);
    }
    _runProgressiveStep() {
        const {graphics: graphics, graphicsByGroup: graphicsByGroup, needUpdate: needUpdate} = this._runProgressiveJoin();
        0 === this.renderContext.progressive.currentIndex ? (this._createIncrementalGraphics(), 
        this._graphics = graphics) : needUpdate && graphics.forEach((g => {
            this._graphics.push(g);
        })), this._runState(graphics), Object.keys(graphicsByGroup).forEach((groupKey => {
            this._runProgressiveEncoder(graphicsByGroup[groupKey]);
        })), this._runEncoderTransform(this._graphics, !0), Object.keys(graphicsByGroup).forEach((groupKey => {
            this._runProgressiveApplyGraphic(graphicsByGroup[groupKey]);
        })), this.renderContext.progressive.currentIndex += 1;
    }
    renderProgressive() {
        var _a;
        (null === (_a = this.renderContext) || void 0 === _a ? void 0 : _a.beforeTransformProgressive) ? this._runBeforeProgressive() : this.renderContext.progressive && this._runProgressiveStep();
    }
    hasAnimationByState(state) {
        if (!state || !this._animationConfig || !this._animationConfig[state] || this._disabledAnimationStates.includes(state)) return !1;
        const stateAnimationConfig = this._animationConfig[state];
        return stateAnimationConfig.length > 0 || (0, vutils_1.isObject)(stateAnimationConfig);
    }
    hasAnimation() {
        return !!this._animationConfig && Object.keys(this._animationConfig).length > 0;
    }
    runAnimation() {
        this._runStateAnimation(this.getGraphics());
    }
}

exports.BaseMark = BaseMark;
//# sourceMappingURL=base-mark.js.map
