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

import { ChartData } from "../chart-meta/data";

import { GlobalScale } from "../../scale/global-scale";

import { ComponentTypeEnum } from "../../component/interface";

import { Factory } from "../../core/factory";

import { Event } from "../../event/event";

import { isArray, isValid, createID, calcPadding, normalizeLayoutPaddingSpec, array } from "../../util";

import { BaseModel } from "../../model/base-model";

import { BaseMark } from "../../mark/base/base-mark";

import { DEFAULT_CHART_WIDTH, DEFAULT_CHART_HEIGHT } from "../../constant/base";

import { isFunction, isEmpty, isNil, isString, isEqual, pickWithout } from "@visactor/vutils";

import { getDataScheme } from "../../theme/color-scheme/util";

import { CompilableBase } from "../../compile/compilable-base";

import { STATE_VALUE_ENUM } from "../../compile/mark/interface";

import { ChartEvent, VGRAMMAR_HOOK_EVENT } from "../../constant/event";

import { DimensionEventEnum } from "../../event/events/dimension";

import { calculateChartSize, mergeUpdateResult } from "../util";

import { isDiscrete } from "@visactor/vscale";

import { updateDataViewInData } from "../../data/initialize";

import { LayoutZIndex } from "../../constant/layout";

export class BaseChart extends CompilableBase {
    getSpec() {
        return this._spec;
    }
    setSpec(s) {
        this._spec = s;
    }
    getOption() {
        return this._option;
    }
    getLayoutRect() {
        return this._layoutRect;
    }
    getViewRect() {
        return this._viewRect;
    }
    getLayoutTag() {
        return this._layoutTag;
    }
    setLayoutTag(tag, morphConfig, renderNextTick = !0) {
        this._layoutTag = tag;
        const compiler = this.getCompiler();
        return (null == compiler ? void 0 : compiler.getVGrammarView()) && (compiler.getVGrammarView().updateLayoutTag(), 
        tag && renderNextTick && compiler.renderNextTick(morphConfig)), this._layoutTag;
    }
    getGlobalScale() {
        return this._globalScale;
    }
    getEvent() {
        return this._event;
    }
    get chartData() {
        return this._chartData;
    }
    constructor(spec, option) {
        var _a, _b, _c;
        super(option), this.type = "chart", this.id = createID(), this._regions = [], this._series = [], 
        this._components = [], this._layoutRect = {
            x: 0,
            y: 0,
            width: DEFAULT_CHART_WIDTH,
            height: DEFAULT_CHART_HEIGHT
        }, this._viewRect = {
            width: DEFAULT_CHART_WIDTH,
            height: DEFAULT_CHART_HEIGHT
        }, this._viewBox = {
            x1: 0,
            y1: 0,
            x2: DEFAULT_CHART_WIDTH,
            y2: DEFAULT_CHART_HEIGHT
        }, this._layoutTag = !0, this._idMap = new Map, this.state = {
            layoutUpdateRank: 1
        }, this.padding = {
            top: 0,
            left: 0,
            right: 0,
            bottom: 0
        }, this.getAllSeries = () => {
            var _a;
            return null !== (_a = this._series) && void 0 !== _a ? _a : [];
        }, this.getRegionsInIndex = index => index && 0 !== index.length ? this._regions.filter(((_r, i) => index.includes(i))) : [ this._regions[0] ], 
        this.getAllRegions = () => this._regions, this.getRegionsInIds = ids => ids ? this._regions.filter((r => ids.includes(r.id))) : [], 
        this.getRegionsInQuerier = region => region ? this._regions.filter(((r, index) => array(region).some((regionFilter => isValid(regionFilter.regionId) && regionFilter.regionId === r.userId || regionFilter.regionIndex === index)))) : this._regions, 
        this.getRegionsInUserId = userId => {
            if (userId) return this._regions.find((r => r.userId === userId));
        }, this.getRegionsInUserIdOrIndex = (user_ids, index) => this.getAllRegions().filter((r => (null == user_ids ? void 0 : user_ids.length) ? r.userId && user_ids.includes(r.userId) : !(null == index ? void 0 : index.length) || index.includes(r.getSpecIndex()))), 
        this.getComponents = () => this._components, this.getSeriesInIndex = index => index && 0 !== index.length ? this._series.filter(((_r, i) => index.includes(i))) : [ this._series[0] ], 
        this.getSeriesInIds = ids => ids ? this._series.filter((r => ids.includes(r.id))) : [], 
        this.getSeriesInUserId = userId => {
            if (userId) return this._series.find((r => r.userId === userId));
        }, this.getSeriesInUserIdOrIndex = (user_ids, index) => this.getAllSeries().filter((s => (null == user_ids ? void 0 : user_ids.length) ? s.userId && user_ids.includes(s.userId) : !(null == index ? void 0 : index.length) || index.includes(s.getSpecIndex()))), 
        this.getComponentByIndex = (key, index) => {
            const components = this._components.filter((c => (c.specKey || c.type) === key));
            if (components && 0 !== components.length) return components[index];
        }, this.getComponentsByKey = key => this._components.filter((c => (c.specKey || c.type) === key)), 
        this.getComponentByUserId = userId => {
            const component = this._components.find((s => s.userId === userId));
            if (component) return component;
        }, this.getComponentsByType = type => this._components.filter((c => c.type === type)), 
        this._paddingSpec = normalizeLayoutPaddingSpec(null !== (_a = spec.padding) && void 0 !== _a ? _a : option.getTheme().padding), 
        this._event = new Event(option.eventDispatcher, option.mode), this._dataSet = option.dataSet, 
        this._chartData = new ChartData(this._dataSet), this._modelOption = Object.assign(Object.assign({}, option), {
            mode: this._option.mode,
            map: this._idMap,
            getChartLayoutRect: () => this._layoutRect,
            getChartViewRect: () => this._viewRect,
            getChart: () => this,
            globalScale: this._globalScale,
            onError: null === (_b = this._option) || void 0 === _b ? void 0 : _b.onError,
            disableTriggerEvent: !0 === (null === (_c = this._option) || void 0 === _c ? void 0 : _c.disableTriggerEvent),
            getSeriesData: this._chartData.getSeriesData.bind(this._chartData)
        }), this._spec = spec;
    }
    created(transformer) {
        this._chartData.parseData(this._spec.data), this._createGlobalScale(), this._createBackground(), 
        this._createLayout(), transformer.forEachRegionInSpec(this._spec, this._createRegion.bind(this)), 
        transformer.forEachSeriesInSpec(this._spec, this._createSeries.bind(this)), transformer.forEachComponentInSpec(this._spec, this._createComponent.bind(this), this._option.getSpecInfo());
    }
    init() {
        var _b, _d;
        null === (_b = this._beforeInit) || void 0 === _b || _b.call(this), this._regions.forEach((r => r.init({}))), 
        this._series.forEach((s => s.init({}))), this._components.forEach((c => c.init({
            dataSet: this._dataSet
        }))), this._initEvent(), null === (_d = this._initStack) || void 0 === _d || _d.call(this), 
        this.reDataFlow();
    }
    reDataFlow() {
        this._series.forEach((s => {
            var _a;
            return null === (_a = s.getRawData()) || void 0 === _a ? void 0 : _a.markRunning();
        })), this._series.forEach((s => s.fillData())), this.updateGlobalScaleDomain();
    }
    onResize(width, height, reRender = !0) {
        const canvasRect = {
            width: width,
            height: height
        };
        this._canvasRect = canvasRect, this._updateLayoutRect(this._option.viewBox), this.setLayoutTag(!0, null, reRender);
    }
    updateViewBox(viewBox, reLayout) {
        this._option.viewBox = viewBox, this._updateLayoutRect(viewBox), this.setLayoutTag(!0, null, reLayout);
    }
    _createBackground() {
        const bg = this._spec.background;
        if (!bg || "object" != typeof bg || isValid(bg.gradient)) return;
        const backgroundStyle = pickWithout(bg, [ "x", "y", "width", "height", "x1", "y1", "image" ]);
        backgroundStyle.background = bg.image, this._backgroundMark = Factory.createMark("group", "chart-background", {
            model: this,
            map: this._option.map,
            getCompiler: this.getCompiler,
            globalScale: this._globalScale
        }), this._backgroundMark.created(), this._backgroundMark.setStyle(Object.assign(Object.assign({}, backgroundStyle), {
            x: () => this._viewBox.x1,
            y: () => this._viewBox.y1,
            width: () => this._viewBox.x2 - this._viewBox.x1,
            height: () => this._viewBox.y2 - this._viewBox.y1
        })), this._backgroundMark.setMarkConfig({
            zIndex: LayoutZIndex.SeriesGroup - 2
        });
    }
    _createRegion(constructor, specInfo) {
        if (!constructor) return;
        const {spec: spec} = specInfo, others = __rest(specInfo, [ "spec" ]), region = new constructor(spec, Object.assign(Object.assign({}, this._modelOption), others));
        region && (region.created(), this._regions.push(region));
    }
    _createSeries(constructor, specInfo) {
        if (!constructor) return;
        const {spec: spec} = specInfo, others = __rest(specInfo, [ "spec" ]);
        let region;
        if (isValid(spec.regionId) ? region = this.getRegionsInUserId(spec.regionId) : isValid(spec.regionIndex) && (region = this.getRegionsInIndex([ spec.regionIndex ])[0]), 
        !region && !(region = this._regions[0])) return;
        const series = new constructor(spec, Object.assign(Object.assign(Object.assign({}, this._modelOption), others), {
            type: spec.type,
            region: region,
            globalScale: this._globalScale,
            sourceDataList: this._chartData.dataList
        }));
        series && (series.created(), this._series.push(series), region.addSeries(series));
    }
    getSeriesById(id) {
        return this._series.find((x => x.id === id));
    }
    _createComponent(constructor, specInfo) {
        const component = constructor.createComponent(specInfo, Object.assign(Object.assign({}, this._modelOption), {
            type: constructor.type,
            getAllRegions: this.getAllRegions,
            getRegionsInIndex: this.getRegionsInIndex,
            getRegionsInIds: this.getRegionsInIds,
            getRegionsInUserIdOrIndex: this.getRegionsInUserIdOrIndex,
            getAllSeries: this.getAllSeries,
            getSeriesInIndex: this.getSeriesInIndex,
            getSeriesInIds: this.getSeriesInIds,
            getSeriesInUserIdOrIndex: this.getSeriesInUserIdOrIndex,
            getAllComponents: this.getComponents,
            getComponentByIndex: this.getComponentByIndex,
            getComponentByUserId: this.getComponentByUserId,
            getComponentsByKey: this.getComponentsByKey,
            getComponentsByType: this.getComponentsByType
        }));
        component && (component.created(), this._components.push(component));
    }
    getAllComponents() {
        return this._components;
    }
    getAllModels() {
        return [].concat(this.getAllSeries(), this.getAllComponents(), this.getAllRegions());
    }
    getModelInFilter(filter) {
        if (isString(filter)) return this.getAllModels().find((m => m.userId === filter));
        if (isFunction(filter)) return this.getAllModels().find((m => filter(m)));
        let index = 0;
        return this.getAllModels().find((m => {
            var _a;
            if ((null !== (_a = m.specKey) && void 0 !== _a ? _a : m.type) === filter.type) {
                if (index === filter.index) return !0;
                index++;
            }
            return !1;
        }));
    }
    _createLayout() {
        this._updateLayoutRect(this._option.viewBox), this._initLayoutFunc();
    }
    setLayout(layout) {
        this._option.layout = layout, this._initLayoutFunc();
    }
    _initLayoutFunc() {
        var _a, _b, _c;
        if (this._layoutFunc = this._option.layout, !this._layoutFunc) {
            let use3dLayout = !1;
            (this._spec.zField || this._spec.series && this._spec.series.some((s => s.zField))) && (use3dLayout = !0);
            const constructor = Factory.getLayoutInKey(null !== (_b = null === (_a = this._spec.layout) || void 0 === _a ? void 0 : _a.type) && void 0 !== _b ? _b : use3dLayout ? "layout3d" : "base");
            if (constructor) {
                const layout = new constructor(this._spec.layout, {
                    onError: null === (_c = this._option) || void 0 === _c ? void 0 : _c.onError
                });
                this._layoutFunc = layout.layoutItems.bind(layout);
            }
        }
    }
    layout(params) {
        var _a, _b, _c, _d;
        if (null === (_b = null === (_a = this._option.performanceHook) || void 0 === _a ? void 0 : _a.beforeLayoutWithSceneGraph) || void 0 === _b || _b.call(_a), 
        this.getLayoutTag()) {
            this._event.emit(ChartEvent.layoutStart, {
                chart: this,
                vchart: this._option.globalInstance
            }), this.onLayoutStart(params);
            const elements = this.getLayoutElements();
            this._layoutFunc(this, elements, this._layoutRect, this._viewBox), this._event.emit(ChartEvent.afterLayout, {
                elements: elements,
                chart: this
            }), this.setLayoutTag(!1), this.onLayoutEnd(params), this._event.emit(ChartEvent.layoutEnd, {
                chart: this,
                vchart: this._option.globalInstance
            });
        }
        null === (_d = null === (_c = this._option.performanceHook) || void 0 === _c ? void 0 : _c.afterLayoutWithSceneGraph) || void 0 === _d || _d.call(_c);
    }
    onLayoutStart(option) {
        this.getAllModels().forEach((element => element.onLayoutStart(this._layoutRect, this._viewRect, option)));
    }
    onLayoutEnd(option) {
        this.getAllModels().forEach((element => {
            "series" !== element.modelType && element.onLayoutEnd(option);
        }));
    }
    onEvaluateEnd(option) {
        [ ...this._components, ...this._regions, ...this._series ].forEach((element => element.onEvaluateEnd(option)));
    }
    onBeforeRender(view) {
        [ ...this._components, ...this._regions, ...this._series ].forEach((element => element.onBeforeRender()));
    }
    getLayoutElements() {
        return this.getAllModels().map((i => i.layout)).filter((i => !!i));
    }
    getModelById(id) {
        const model = this._idMap.get(id);
        if (model && model instanceof BaseModel) return model;
    }
    getModelByUserId(userId) {
        const series = this.getSeriesInUserId(userId);
        if (series) return series;
        const region = this.getRegionsInUserId(userId);
        if (region) return region;
        const component = this.getComponentByUserId(userId);
        return component || void 0;
    }
    getAllMarks() {
        return Array.from(this._idMap.values()).filter((item => item && item instanceof BaseMark));
    }
    getMarkById(id) {
        const mark = this._idMap.get(id);
        if (mark && mark instanceof BaseMark) return mark;
    }
    getMarkByUserName(name) {
        return this.getAllMarks().filter((m => m.name && m.name === name));
    }
    updateData(id, data, updateGlobalScale = !0, options) {
        const dv = this._dataSet.getDataView(id);
        dv && (dv.markRunning(), dv.parseNewData(data, options)), updateGlobalScale && this.updateGlobalScaleDomain(), 
        this.getAllModels().forEach((model => model.onDataUpdate()));
    }
    updateFullData(data, updateGlobalScale = !0) {
        array(data).forEach((d => {
            const dv = this._dataSet.getDataView(d.id);
            dv && dv.markRunning();
        })), array(data).forEach((d => {
            const dv = this._dataSet.getDataView(d.id);
            dv && updateDataViewInData(dv, d, !0);
        })), updateGlobalScale && this.updateGlobalScaleDomain(), this.getAllModels().forEach((model => model.onDataUpdate()));
    }
    onRender(option) {}
    setCanvasRect(width, height) {
        this._canvasRect = {
            width: width,
            height: height
        };
    }
    getCanvasRect() {
        return this._canvasRect || (this._canvasRect = calculateChartSize(this._spec, this._option, {
            width: DEFAULT_CHART_WIDTH,
            height: DEFAULT_CHART_HEIGHT
        })), this._canvasRect;
    }
    getSeriesData(id, index) {
        return this._chartData.getSeriesData(id, index);
    }
    _transformSpecScale() {
        var _a;
        const scales = this._spec.scales ? [ ...this._spec.scales ] : [];
        let colorScaleSpec = scales.find((s => "color" === s.id));
        const colorScheme = this.getColorScheme();
        if (!colorScaleSpec && (colorScaleSpec = {
            type: "ordinal",
            id: "color",
            domain: null,
            range: null
        }, scales.push(colorScaleSpec), this._spec.color)) {
            const colorSpec = this._spec.color;
            if (isArray(colorSpec)) colorScaleSpec.range = colorSpec; else {
                const tempSpec = colorSpec;
                Object.prototype.hasOwnProperty.call(tempSpec, "type") && (colorScaleSpec.type = tempSpec.type), 
                Object.prototype.hasOwnProperty.call(tempSpec, "domain") && (colorScaleSpec.domain = tempSpec.domain), 
                Object.prototype.hasOwnProperty.call(tempSpec, "range") && (colorScaleSpec.range = tempSpec.range), 
                Object.prototype.hasOwnProperty.call(tempSpec, "specified") && (colorScaleSpec.specified = tempSpec.specified), 
                Object.prototype.hasOwnProperty.call(tempSpec, "clamp") && (colorScaleSpec.clamp = tempSpec.clamp);
            }
        }
        return (null === (_a = colorScaleSpec.range) || void 0 === _a ? void 0 : _a.length) || (colorScaleSpec.range = getDataScheme(colorScheme), 
        colorScaleSpec.rangeTheme = !0), scales;
    }
    _createGlobalScale() {
        this._globalScale = new GlobalScale(this._transformSpecScale(), this), this._modelOption.globalScale = this._globalScale;
    }
    updateGlobalScaleDomain() {
        const domainSet = new Set;
        this._series.forEach((s => {
            const keys = s.getSeriesKeys();
            keys && keys.forEach((k => domainSet.add(k)));
        }));
        const domain = Array.from(domainSet);
        this._globalScale.updateScaleDomain(domain);
    }
    updateGlobalScale(result) {
        mergeUpdateResult(result, this._globalScale.updateSpec(this._transformSpecScale()));
    }
    updateGlobalScaleTheme() {
        const colorSpec = this._globalScale.getScaleSpec("color"), colorScheme = this.getColorScheme();
        colorSpec.rangeTheme && (colorSpec.range = getDataScheme(colorScheme), this._globalScale.getScale("color").range(colorSpec.range));
    }
    _getSpecKeys(spec) {
        const ignoreKeys = {
            width: !0,
            height: !0
        };
        return Object.keys(spec).filter((key => !ignoreKeys[key])).sort();
    }
    updateSpec(spec) {
        const result = {
            change: !1,
            reMake: !1,
            reRender: !1,
            reSize: !1,
            reCompile: !1
        };
        if (this.setLayoutTag(!0, null, !1), spec.type !== this.type) return result.reMake = !0, 
        result;
        const currentKeys = this._getSpecKeys(this._spec), nextKeys = this._getSpecKeys(spec);
        if (!isEqual(currentKeys, nextKeys)) return result.reMake = !0, result;
        for (let i = 0; i < currentKeys.length; i++) {
            const key = currentKeys[i];
            if (isArray(this._spec[key]) && this._spec[key].length !== array(spec[key]).length) return result.reMake = !0, 
            result;
        }
        const oldSpec = this._spec;
        return this._spec = spec, this.updateChartConfig(result, oldSpec), result.reMake ? result : (this.updateGlobalScale(result), 
        result.reMake ? result : (this.updateRegionSpec(result), result.reMake ? result : (this.updateComponentSpec(result), 
        result.reMake ? result : (this.updateSeriesSpec(result), result.reMake || (this.reInit(), 
        this.updateDataSpec(), this.updateGlobalScaleDomain()), result))));
    }
    updateChartConfig(result, oldSpec) {
        var _a, _b;
        this._paddingSpec = normalizeLayoutPaddingSpec(null !== (_a = this._spec.padding) && void 0 !== _a ? _a : null === (_b = this._option) || void 0 === _b ? void 0 : _b.getTheme().padding), 
        this._updateLayoutRect(this._viewBox);
    }
    updateDataSpec() {
        this._spec.data && this._chartData.updateData(this._spec.data, !1, !0);
    }
    updateRegionSpec(result) {
        var _a;
        (null === (_a = this._spec) || void 0 === _a ? void 0 : _a.region) && (this._spec.region.length === this._regions.length ? this._regions.forEach((r => {
            mergeUpdateResult(result, r.updateSpec(this._spec.region[r.getSpecIndex()]));
        })) : result.reMake = !0);
    }
    updateComponentSpec(result) {
        const componentCache = {}, checkVisibleComponents = {
            [ComponentTypeEnum.title]: !0,
            [ComponentTypeEnum.brush]: !0,
            [ComponentTypeEnum.mapLabel]: !0,
            [ComponentTypeEnum.indicator]: !0
        };
        this._components.forEach((c => {
            var _a, _b;
            if (c.type === ComponentTypeEnum.label || c.type === ComponentTypeEnum.totalLabel) return;
            checkVisibleComponents[c.type] && (checkVisibleComponents[c.type] = !1);
            const compSpecKey = c.specKey || c.type, cmpSpec = null !== (_a = this._spec[compSpecKey]) && void 0 !== _a ? _a : {};
            isArray(cmpSpec) ? (componentCache[compSpecKey] = componentCache[compSpecKey] || {
                specCount: cmpSpec.length,
                componentCount: 0
            }, componentCache[compSpecKey].componentCount++, mergeUpdateResult(result, c.updateSpec(null !== (_b = cmpSpec[c.getSpecIndex()]) && void 0 !== _b ? _b : {}, cmpSpec))) : mergeUpdateResult(result, c.updateSpec(cmpSpec));
        }));
        for (const key in componentCache) if (Object.prototype.hasOwnProperty.call(componentCache, key)) {
            const element = componentCache[key];
            element.componentCount !== element.specCount && (result.reMake = !0);
        }
        const isVisible = compSpec => compSpec && !1 !== compSpec.visible;
        Object.keys(checkVisibleComponents).forEach((type => {
            if (checkVisibleComponents[type]) {
                const compSpec = this._spec[type];
                (isArray(compSpec) ? compSpec.some(isVisible) : isVisible(compSpec)) && (result.reMake = !0);
            }
        }));
    }
    updateSeriesSpec(result) {
        this._spec.series.length === this._series.length ? this._series.forEach((s => {
            const spec = this._spec.series[s.getSpecIndex()];
            mergeUpdateResult(result, s.updateSpec(spec));
        })) : result.reMake = !0;
    }
    getCanvas() {
        var _a, _b;
        return null !== (_b = null === (_a = this.getCompiler()) || void 0 === _a ? void 0 : _a.getCanvas()) && void 0 !== _b ? _b : null;
    }
    _updateLayoutRect(viewBox) {
        var _a, _b;
        let viewRect = this.getCanvasRect();
        if (viewBox) {
            this._viewBox = viewBox;
            const {x1: x1 = 0, y1: y1 = 0, x2: x2, y2: y2} = viewBox;
            viewRect = {
                width: x2 - x1,
                height: y2 - y1
            };
        } else this._viewBox = {
            x1: 0,
            y1: 0,
            x2: viewRect.width,
            y2: viewRect.height
        };
        this._viewRect = viewRect, this.padding = calcPadding(this._paddingSpec, viewRect, viewRect), 
        this._layoutRect.width = viewRect.width - this.padding.left - this.padding.right, 
        this._layoutRect.height = viewRect.height - this.padding.top - this.padding.bottom, 
        this._layoutRect.x = this.padding.left, this._layoutRect.y = this.padding.top, this._event.emit(ChartEvent.layoutRectUpdate, {
            chart: this
        }), null === (_b = null === (_a = this._option) || void 0 === _a ? void 0 : _a.chartPluginApply) || void 0 === _b || _b.call(_a, "onLayoutRectUpdate", {
            chart: this
        });
    }
    setCurrentTheme() {
        this.updateChartConfig({
            change: !0,
            reMake: !1
        }, this._spec), this.setLayoutTag(!0, null, !1), this.updateGlobalScaleTheme(), 
        this.reInit();
    }
    reInit() {
        [ ...this._regions, ...this._series, ...this._components ].forEach((model => {
            const specInfo = model.getSpecInfo();
            specInfo && specInfo.spec && model.reInit(specInfo.spec);
        }));
    }
    clear() {
        this.getAllModels().forEach((i => {
            var _a;
            return null === (_a = i.clear) || void 0 === _a ? void 0 : _a.call(i);
        }));
    }
    compile() {
        this.compileBackground(), this.compileLayout(), this.compileRegions(), this.compileSeries(), 
        this.compileComponents();
    }
    afterCompile() {
        this.getAllRegions().forEach((r => {
            var _a;
            null === (_a = r.afterCompile) || void 0 === _a || _a.call(r);
        })), this.getAllSeries().forEach((s => {
            var _a;
            null === (_a = s.afterCompile) || void 0 === _a || _a.call(s);
        })), this.getAllComponents().forEach((c => {
            var _a;
            null === (_a = c.afterCompile) || void 0 === _a || _a.call(c);
        }));
    }
    compileLayout() {
        const {width: width, height: height} = this.getCanvasRect();
        this.getCompiler().setSize(width, height);
    }
    compileBackground() {
        var _a;
        this._backgroundMark && (this._backgroundMark.compile({
            context: {
                model: this
            }
        }), null === (_a = this._backgroundMark.getProduct()) || void 0 === _a || _a.layout((() => {})));
    }
    compileRegions() {
        var _a, _b, _c, _d;
        null === (_b = null === (_a = this._option.performanceHook) || void 0 === _a ? void 0 : _a.beforeRegionCompile) || void 0 === _b || _b.call(_a), 
        this.getAllRegions().forEach((r => {
            r.compile();
        })), null === (_d = null === (_c = this._option.performanceHook) || void 0 === _c ? void 0 : _c.afterRegionCompile) || void 0 === _d || _d.call(_c);
    }
    compileSeries() {
        var _a, _b, _c, _d;
        null === (_b = null === (_a = this._option.performanceHook) || void 0 === _a ? void 0 : _a.beforeSeriesCompile) || void 0 === _b || _b.call(_a), 
        this.getAllSeries().forEach((s => {
            s.compile();
        })), null === (_d = null === (_c = this._option.performanceHook) || void 0 === _c ? void 0 : _c.afterSeriesCompile) || void 0 === _d || _d.call(_c);
    }
    compileComponents() {
        var _a, _b, _c, _d;
        null === (_b = null === (_a = this._option.performanceHook) || void 0 === _a ? void 0 : _a.beforeComponentCompile) || void 0 === _b || _b.call(_a), 
        this.getAllComponents().forEach((c => {
            c.compile();
        })), null === (_d = null === (_c = this._option.performanceHook) || void 0 === _c ? void 0 : _c.afterComponentCompile) || void 0 === _d || _d.call(_c);
    }
    release() {
        [ ...this._components, ...this._regions, ...this._series ].forEach((m => {
            m.beforeRelease();
        })), super.release(), this.clear(), [ ...this._components, ...this._regions, ...this._series ].forEach((m => {
            m.release();
        })), this._components = this._regions = this._series = [], this._spec = {}, this._dataSet = this._globalScale = this._layoutFunc = null, 
        this._layoutTag = !1, this._idMap.clear();
    }
    onLayout(srView) {
        const root = srView.rootMark;
        this.layout({
            group: root,
            srView: srView
        });
    }
    updateState(state, filter) {
        const seriesArr = this.getAllSeries();
        for (const key in state) {
            if (isEmpty(state[key])) continue;
            const stateSpec = state[key];
            let stateInfo = {
                stateValue: key
            };
            stateInfo = isFunction(stateSpec.filter) ? Object.assign({
                filter: stateSpec.filter
            }, stateInfo) : Object.assign(Object.assign({}, stateSpec.filter), stateInfo), stateSpec.level && (stateInfo.level = stateSpec.level), 
            seriesArr.forEach((series => {
                series.getMarks().forEach((m => {
                    m.stateStyle[key] && (filter && !filter(series, m, key) || (m.state.changeStateInfo(stateInfo), 
                    m.updateMarkState(key)));
                }));
            }));
        }
    }
    setSelected(datum, filter, region) {
        this._setStateInDatum(STATE_VALUE_ENUM.STATE_SELECTED, !0, datum, filter, region);
    }
    setHovered(datum, filter, region) {
        this._setStateInDatum(STATE_VALUE_ENUM.STATE_HOVER, !0, datum, filter, region);
    }
    clearState(state) {
        this.getAllRegions().forEach((r => {
            r.interaction.clearEventElement(state, !0), r.interaction.resetInteraction(state, null);
        }));
    }
    clearAllStates() {
        this.getAllRegions().forEach((r => {
            r.interaction.clearAllEventElement(), r.interaction.resetAllInteraction();
        }));
    }
    clearSelected() {
        this.clearState(STATE_VALUE_ENUM.STATE_SELECTED);
    }
    clearHovered() {
        this.clearState(STATE_VALUE_ENUM.STATE_HOVER);
    }
    _initEvent() {
        [ ChartEvent.dataZoomChange, ChartEvent.scrollBarChange ].forEach((event => {
            this._event.on(event, (({value: value}) => {
                this._disableMarkAnimation([ "exit", "update" ]);
                const enableMarkAnimate = () => {
                    this._enableMarkAnimation([ "exit", "update" ]), this._event.off(VGRAMMAR_HOOK_EVENT.AFTER_MARK_RENDER_END, enableMarkAnimate);
                };
                this._event.on(VGRAMMAR_HOOK_EVENT.AFTER_MARK_RENDER_END, enableMarkAnimate);
            }));
        }));
    }
    _enableMarkAnimation(states) {
        this.getAllMarks().forEach((mark => {
            const product = mark.getProduct();
            product && product.animate && product.animate.enableAnimationState(states);
        }));
    }
    _disableMarkAnimation(states) {
        this.getAllMarks().forEach((mark => {
            const product = mark.getProduct();
            product && product.animate && product.animate.disableAnimationState(states);
        }));
    }
    filterGraphicsByDatum(datum, opt = {}) {
        var _a;
        const keys = (datum = datum ? array(datum) : null) ? Object.keys(datum[0]) : null, allElements = [], getDatumOfElement = null !== (_a = opt.getDatum) && void 0 !== _a ? _a : el => el.getDatum();
        return this.getRegionsInQuerier(opt.region).forEach((r => {
            const pickElements = [];
            datum && r.getSeries().forEach((s => {
                s.getMarks().forEach((m => {
                    if (m.getProduct() && (!opt.filter || isFunction(opt.filter) && opt.filter(s, m))) {
                        const isCollect = m.getProduct().isCollectionMark(), elements = m.getProduct().elements;
                        if (isCollect) elements.filter((e => {
                            const elDatum = getDatumOfElement(e, m, s, r);
                            elDatum && datum.every(((d, index) => keys.every((k => d[k] == elDatum[index][k])))) && (pickElements.push(e), 
                            allElements.push(e), opt.callback && opt.callback(e, m, s, r));
                        })); else if (datum.length > 1) {
                            const datumTemp = datum.slice();
                            elements.forEach((e => {
                                const elDatum = getDatumOfElement(e, m, s, r), index = elDatum && datumTemp.findIndex((d => keys.every((k => d[k] == elDatum[k]))));
                                index >= 0 && (datumTemp.splice(index, 1), pickElements.push(e), allElements.push(e), 
                                opt.callback && opt.callback(e, m, s, r));
                            }));
                        } else {
                            const el = elements.find((e => {
                                const elDatum = getDatumOfElement(e, m, s, r);
                                return elDatum && keys.every((k => datum[0][k] == elDatum[k]));
                            }));
                            el && (pickElements.push(el), allElements.push(el), opt.callback && opt.callback(el, m, s, r));
                        }
                    }
                }));
            })), opt.regionCallback && opt.regionCallback(pickElements, r);
        })), allElements;
    }
    _setStateInDatum(stateKey, checkReverse, datum, filter, region) {
        this.filterGraphicsByDatum(datum, {
            filter: filter,
            region: region,
            regionCallback: (elements, r) => {
                datum ? elements.length && (elements.forEach((e => {
                    r.interaction.startInteraction(stateKey, e);
                })), checkReverse && r.interaction.reverseEventElement(stateKey)) : r.interaction.clearEventElement(stateKey, !0);
            }
        });
    }
    setDimensionIndex(value, opt) {
        var _a, _b;
        let dimensionInfo = null;
        Array.from(this._event.getComposedEventMap().values()).forEach((e => {
            const {eventType: eventType, event: event} = e;
            if (eventType === DimensionEventEnum.dimensionHover || eventType === DimensionEventEnum.dimensionClick) {
                const info = event.dispatch(value, opt);
                (null == info ? void 0 : info.length) && (dimensionInfo = info);
            }
        }));
        const isUnableValue = isNil(value) || !dimensionInfo || dimensionInfo.every((d => isDiscrete(d.axis.getScale().type) && isNil(d.index)));
        if (!1 !== opt.tooltip) {
            const tooltip = this.getComponentsByType(ComponentTypeEnum.tooltip)[0];
            if (null == tooltip ? void 0 : tooltip.getVisible()) if (isUnableValue) null === (_b = (_a = tooltip).hideTooltip) || void 0 === _b || _b.call(_a); else {
                const dataFilter = {};
                dimensionInfo.forEach((d => {
                    const {axis: axis, value: value, data: data} = d, isY = "left" === axis.getOrient() || "right" === axis.getOrient();
                    data.forEach((d => {
                        var _a, _b, _c;
                        const field = isY ? d.series.fieldY[0] : d.series.fieldX[0];
                        dataFilter[field] = null !== (_c = null === (_b = null === (_a = d.datum) || void 0 === _a ? void 0 : _a[0]) || void 0 === _b ? void 0 : _b[field]) && void 0 !== _c ? _c : value;
                    }));
                })), tooltip.showTooltip(dataFilter, opt.showTooltipOption);
            }
        }
        if (!1 !== opt.crosshair) {
            const crosshair = this.getComponentsByType(ComponentTypeEnum.cartesianCrosshair)[0];
            crosshair && crosshair.clearAxisValue && crosshair.setAxisValue && (isUnableValue ? crosshair.hideCrosshair() : crosshair.showCrosshair(dimensionInfo));
        }
    }
    getColorScheme() {
        var _a, _b;
        return null === (_b = (_a = this._option).getTheme) || void 0 === _b ? void 0 : _b.call(_a).colorScheme;
    }
}
//# sourceMappingURL=base-chart.js.map
