import * as i0 from '@angular/core';
import { Injectable, Optional, inject, NgZone, ChangeDetectorRef, DestroyRef, signal, EventEmitter, Component, ChangeDetectionStrategy, HostBinding, Input, Output, ViewChild, NgModule } from '@angular/core';
import * as i5 from '@angular/material/menu';
import { MatMenuModule } from '@angular/material/menu';
import * as i1 from '@metad/ocap-angular/core';
import { DisplayDensity, csvDownload, OcapCoreModule } from '@metad/ocap-angular/core';
import { ChartBusinessService, isEqual, isAdvancedFilter, getEntityProperty, slicerAsString, getPropertyName, putFilter, getEntityHierarchy, getEntityLevel, nonNullable, isSlicer, omit, pick, getPropertyHierarchy, Drill, parseDimension } from '@metad/ocap-core';
import { SmartEChartEngine } from '@metad/ocap-echarts';
import { ComponentStore } from '@metad/store';
import { isEmpty, isNil, cloneDeep, findIndex, assign } from 'lodash-es';
import { BehaviorSubject, combineLatest } from 'rxjs';
import { skip, distinctUntilChanged, filter, map, startWith, withLatestFrom, shareReplay, pairwise, tap } from 'rxjs/operators';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import * as i14 from '@ngx-translate/core';
import { TranslateService, TranslateModule } from '@ngx-translate/core';
import * as i1$1 from '@angular/common';
import { CommonModule } from '@angular/common';
import * as i2 from '@angular/forms';
import { FormsModule } from '@angular/forms';
import * as i3 from '@angular/material/button';
import { MatButtonModule } from '@angular/material/button';
import * as i4 from '@angular/material/icon';
import { MatIconModule } from '@angular/material/icon';
import * as i6 from '@angular/material/progress-spinner';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import * as i7 from '@angular/material/divider';
import { MatDividerModule } from '@angular/material/divider';
import * as i8 from '@angular/material/tooltip';
import { MatTooltipModule } from '@angular/material/tooltip';
import * as i9 from '@angular/material/button-toggle';
import { MatButtonToggleModule } from '@angular/material/button-toggle';
import * as i10 from 'ngx-echarts';
import { NgxEchartsModule } from 'ngx-echarts';
import * as i11 from '@metad/ocap-angular/common';
import { NgmCommonModule } from '@metad/ocap-angular/common';
import * as i13 from '@metad/ocap-angular/entity';
import { NgmEntityPropertyComponent } from '@metad/ocap-angular/entity';
import { MatCardModule } from '@angular/material/card';

class AnalyticalCardService extends ChartBusinessService {
    constructor(dsCoreService, filterBarService) {
        super(dsCoreService, filterBarService);
    }
    ngOnDestroy() {
        super.onDestroy();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.10", ngImport: i0, type: AnalyticalCardService, deps: [{ token: i1.NgmDSCoreService }, { token: i1.NgmSmartFilterBarService, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.10", ngImport: i0, type: AnalyticalCardService }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.10", ngImport: i0, type: AnalyticalCardService, decorators: [{
            type: Injectable
        }], ctorParameters: () => [{ type: i1.NgmDSCoreService }, { type: i1.NgmSmartFilterBarService, decorators: [{
                    type: Optional
                }] }] });

class AnalyticalCardComponent extends ComponentStore {
    #destroyRef;
    /**
     * Data Settings
     */
    get dataSettings() {
        return this.get((state) => state.dataSettings);
    }
    set dataSettings(value) {
        this._dataSettings.set(value);
        this.patchState({
            dataSettings: value
        });
    }
    get slicers() {
        return this.get((state) => state.slicers);
    }
    set slicers(value) {
        this.patchState({ slicers: value });
    }
    get displayDensity() {
        return this.appearance?.displayDensity;
    }
    get chartType() {
        return this.dataSettings?.chartAnnotation?.chartType;
    }
    set chartType(chartType) {
        this.patchState({
            dataSettings: {
                ...this.dataSettings,
                chartAnnotation: {
                    ...(this.dataSettings.chartAnnotation ?? {}),
                    chartType
                }
            }
        });
    }
    set empty(value) {
        this._empty$.next(value);
    }
    constructor() {
        super({});
        this.DisplayDensity = DisplayDensity;
        this.businessService = inject(AnalyticalCardService);
        this.translate = inject(TranslateService);
        this._ngZone = inject(NgZone);
        this._cdr = inject(ChangeDetectorRef);
        this.#destroyRef = inject(DestroyRef);
        this.echartsEngine = new SmartEChartEngine();
        this._slicersChanging$ = new BehaviorSubject(null);
        this._isAnalyticalCard = true;
        this._dataSettings$ = this.select((state) => state.dataSettings);
        this._dataSettings = signal(null);
        /**
         * @deprecated use slicersChanging
         */
        this.slicersChange = new EventEmitter();
        /**
         * To avoid being confused with slicers & slicersChange
         */
        this.slicersChanging = this._slicersChanging$.pipe(skip(1), distinctUntilChanged(isEqual));
        this.chartClick = this.echartsEngine.chartClick$;
        this.chartHighlight = this.echartsEngine.chartHighlight$;
        this.chartContextMenu = this.echartsEngine.chartContextMenu$;
        this.explain = new EventEmitter();
        this.contextMenuPosition = { x: '0px', y: '0px' };
        // Inner states
        // The final option for ECharts instance
        this.options$ = this.echartsEngine.selectChartOptions().pipe(filter(({ error }) => {
            if (error) {
                this.error$.next(error);
            }
            else {
                this.error$.next(null);
            }
            return !error;
        }), map(({ options }) => options), 
        // 为初始化 ECharts 实例，然后传递给 SmartEChartEngine 以便进行事件绑定
        startWith({}));
        this.isLoading$ = this.businessService.loading$;
        this.error$ = new BehaviorSubject(null);
        this._empty$ = new BehaviorSubject(false);
        this.empty$ = combineLatest([this._empty$, this.error$]).pipe(map(([empty, error]) => empty && !error));
        // For drill down
        this.selectedDrilledDimensions$ = this.select((state) => state.selectedDrilledDimensions);
        this.selectedSlicers$ = this.select((state) => state.selectedSlicers);
        this.drilledDimensions$ = this.select((state) => state.drilledDimensions);
        this.breadcrumbs$ = this.drilledDimensions$.pipe(map((drills) => {
            return drills?.map((item) => ({
                value: item,
                label: item.slicer.members[0].label || item.slicer.members[0].value,
                active: true
            }));
        }));
        this.dillSlicers$ = this.selectedSlicers$.pipe(map((slicers) => {
            if (isAdvancedFilter(slicers?.[0])) {
                return slicers[0].children;
            }
            return slicers;
        }), withLatestFrom(this.businessService.selectEntityType()), map(([slicers, entityType]) => {
            return slicers?.map((slicer) => {
                const property = getEntityProperty(entityType, slicer.dimension);
                return {
                    value: slicer,
                    label: (property.caption || property.name) + ':' + slicerAsString(slicer)
                };
            });
        }));
        /**
         * 维度下钻
         * 1. 来自于 PresentationVariant 中的 groupBy
         * 2. disable 已被选中的下钻维度
         */
        this.drillDimensions$ = this.select(this.businessService.presentationVariant$, this.businessService.selectEntityType(), this.selectedDrilledDimensions$, (presentationVariant, entityType, selectedDrilledDimensions) => {
            return presentationVariant?.groupBy?.map((item) => ({
                dimension: item,
                property: getEntityProperty(entityType, item),
                disabled: !!selectedDrilledDimensions?.find((selected) => getPropertyName(selected.dimension) === getPropertyName(item))
            })).filter(({ property }) => !!property);
        });
        this.canDrillDimensions$ = this.drillDimensions$.pipe(map((drillDimensions) => !isEmpty(drillDimensions)));
        /**
         * 最终的数据设置
         */
        this.dataSettings$ = combineLatest([
            this._dataSettings$,
            this.select((state) => state.slicers),
            this.selectedDrilledDimensions$
        ]).pipe(filter(([dataSettings]) => !isNil(dataSettings)), map(([dataSettings, slicers, selectedHierachyLevels]) => {
            const chartAnnotation = dataSettings.chartAnnotation;
            const _selectOptions = (dataSettings.selectionVariant?.selectOptions ?? []);
            const selectionVariant = {
                ...(dataSettings.selectionVariant ?? {}),
                selectOptions: slicers?.reduce((slicers, item) => putFilter(slicers, item), _selectOptions) ?? _selectOptions
            };
            if (isEmpty(selectedHierachyLevels)) {
                return {
                    ...dataSettings,
                    selectionVariant
                };
            }
            // 每次都 clone chartAnnotation 防止重复修改
            const _chartAnnotation = cloneDeep(chartAnnotation);
            const dimensions = _chartAnnotation.dimensions;
            selectedHierachyLevels.forEach((item) => {
                const index = findIndex(dimensions, (o) => getPropertyName(o) === getPropertyName(item.parent));
                dimensions.splice(index, 1, {
                    ...dimensions[index],
                    ...item.dimension
                });
            });
            const selectOptions = selectedHierachyLevels.reduce((slicers, item) => putFilter(slicers, item.slicer), selectionVariant.selectOptions);
            return assign(cloneDeep(dataSettings), {
                chartAnnotation: {
                    ..._chartAnnotation,
                    dimensions
                },
                selectionVariant: {
                    ...selectionVariant,
                    selectOptions
                }
            });
        }), takeUntilDestroyed(), shareReplay(1));
        /**
         * 1. TODO 暂时取 chartAnnotation 中所有的 dimensions 维度
         * 2. disable 级别数小于已选中层级的维度
         */
        this.drillLevels$ = combineLatest([
            this.dataSettings$,
            this.businessService.selectEntityType(),
            this.select((state) => state.selectedSlicers)
        ]).pipe(map(([dataSettings, entityType, selectedSlicers]) => {
            const chartAnnotation = dataSettings.chartAnnotation;
            return chartAnnotation.dimensions
                .map((dimension) => {
                return {
                    dimension,
                    hierarchy: getEntityHierarchy(entityType, dimension)
                };
            })
                .filter(({ hierarchy }) => hierarchy?.levels)
                .map(({ dimension, hierarchy }) => {
                const selectedSlicer = selectedSlicers[0];
                const slicer = isAdvancedFilter(selectedSlicer)
                    ? selectedSlicer.children?.find((slicer) => slicer.dimension.dimension === dimension.dimension)
                    : selectedSlicer;
                if (slicer?.dimension?.dimension !== dimension.dimension) {
                    return {
                        property: hierarchy,
                        slicer: null,
                    };
                }
                const slicerLevel = getEntityLevel(entityType, slicer?.dimension);
                return {
                    slicer,
                    property: hierarchy,
                    levels: hierarchy.levels.map((level) => ({
                        property: level,
                        disabled: level.levelNumber <= (slicerLevel?.levelNumber || 0)
                    })),
                    slicerCaption: slicerAsString(slicer)
                };
            })
                .filter(({ slicer }) => nonNullable(slicer));
        }), takeUntilDestroyed(), shareReplay(1));
        this.canDrillLevels$ = this.drillLevels$.pipe(map((levels) => !isEmpty(levels)));
        /**
         * 默认下钻行为: 如果图形为多维度, 则默认取第一个维度
         */
        this.dilldown$ = this.selectedSlicers$.pipe(map((selectedSlicers) => {
            const first = selectedSlicers[0];
            return isAdvancedFilter(first) ? first.children[0] : isSlicer(first) ? first : null;
        }));
        /**
        |--------------------------------------------------------------------------
        | Subscriptions (effect)
        |--------------------------------------------------------------------------
        */
        // Listener for dataSettings changed
        this._dataSettingsSub = this.dataSettings$
            .pipe(filter(Boolean), startWith(null), pairwise(), takeUntilDestroyed())
            .subscribe(([a, b]) => {
            if (isEqual({
                ...(a ?? {}),
                chartAnnotation: omit(a?.chartAnnotation, 'chartType')
            }, {
                ...b,
                chartAnnotation: omit(b.chartAnnotation, 'chartType')
            })) {
                this.echartsEngine.chartAnnotation = b?.chartAnnotation;
            }
            this.businessService.dataSettings = b;
        });
        // Listeners for explain logic
        this._explainSub = combineLatest([
            this.dataSettings$,
            this.businessService.selectResult(),
            this.echartsEngine.selectChartOptions().pipe(startWith(null))
        ]).pipe(takeUntilDestroyed()).subscribe(([dataSettings, queryReturn, chartOptions]) => {
            this.explain.emit([
                dataSettings, queryReturn, chartOptions
            ]);
        });
        // Clear slicers changed output when ECharts refresh
        this._echartsOptionSub = this.echartsEngine.selectChartOptions().pipe(takeUntilDestroyed()).subscribe(() => {
            this.openContextMenu(null);
        });
        // Listeners for ECharts events
        // ECharts ContextMenu event
        this._contextMenuSub = this.echartsEngine.chartContextMenu$.pipe(takeUntilDestroyed()).subscribe((event) => {
            event.event.stopPropagation();
            event.event.preventDefault();
            // Unselect selected data item in series component
            this.echartsEngine.dispatchAction({
                ...pick(event, 'seriesIndex', 'seriesId', 'seriesName', 'dataIndex', 'name'),
                type: 'unselect',
            });
        });
        // ECharts selecchanged event
        this._selectChangedSub = this.echartsEngine.selectChanged$.pipe(takeUntilDestroyed()).subscribe((event) => {
            this._ngZone.run(() => {
                this.openContextMenu(event.slicers, event.event);
            });
        });
        this.drill = this.updater((state, drillLevel) => {
            state.selectedDrilledDimensions = state.selectedDrilledDimensions || [];
            state.drilledDimensions = state.drilledDimensions || [];
            state.drilledDimensions = [...state.selectedDrilledDimensions, drillLevel];
            state.selectedDrilledDimensions = [...state.drilledDimensions];
        });
        this.reselectDrill = this.updater((state, drillLevels) => {
            state.selectedDrilledDimensions = drillLevels.map(({ value }) => value);
        });
        this.drillLevel = this.effect((origin$) => {
            return origin$.pipe(withLatestFrom(this.businessService.selectEntityType()), tap(([{ slicer, property }, entityType]) => {
                if (isAdvancedFilter(slicer)) {
                    const parentFilter = slicer.children.find((item) => getPropertyHierarchy(item.dimension) === property.hierarchyLevelFor);
                    parentFilter.drill = Drill.Children;
                    this.drill({
                        parent: parentFilter.dimension,
                        slicer: parentFilter,
                        dimension: parseDimension(property.name, entityType)
                    });
                }
                else {
                    this.drill({
                        parent: slicer.dimension,
                        slicer: {
                            ...slicer,
                            drill: Drill.Children
                        },
                        dimension: parseDimension(property.name, entityType)
                    });
                }
                this.contextMenu.closeMenu();
            }));
        });
        this.drillDown = this.updater((state, slicer) => {
            if (isAdvancedFilter(slicer)) {
                slicer.children.forEach((slicer) => {
                    this.drill({
                        parent: slicer.dimension,
                        slicer: {
                            ...slicer,
                            drill: Drill.Children
                        },
                        dimension: slicer.dimension
                    });
                });
            }
            else {
                this.drill({
                    parent: slicer.dimension,
                    slicer: {
                        ...slicer,
                        drill: Drill.Children
                    },
                    dimension: slicer.dimension
                });
            }
        });
        this.clearDrill = this.updater((state) => {
            state.drilledDimensions = null;
            state.selectedDrilledDimensions = null;
        });
    }
    ngOnInit() {
        this.businessService
            .selectResult()
            .pipe(filter(({ error }) => {
            if (error) {
                this.error$.next(error);
            }
            else {
                this.error$.next(null);
            }
            return !error;
        }), withLatestFrom(this.businessService.chartAnnotation$), takeUntilDestroyed(this.#destroyRef))
            .subscribe(([result, chartAnnotation]) => {
            this.empty = !result.data?.length;
            this.echartsEngine.data = result;
            this.echartsEngine.chartAnnotation = chartAnnotation;
        });
        this.businessService
            .onAfterServiceInit()
            .pipe(takeUntilDestroyed(this.#destroyRef))
            .subscribe(async () => {
            this.echartsEngine.entityType = await this.businessService.getEntityType();
            this.refresh();
        });
    }
    ngOnChanges({ dataSettings, chartSettings, chartOptions }) {
        if (dataSettings || chartSettings || chartOptions) {
            this.error$.next(null);
        }
        if (chartSettings) {
            this.echartsEngine.settings = chartSettings.currentValue;
        }
        if (chartOptions) {
            this.echartsEngine.options = chartOptions.currentValue;
        }
    }
    /**
     * 刷新数据
     *
     * @param force 强制刷新
     */
    refresh(force) {
        this.businessService.refresh(force);
    }
    onChartInit(event) {
        this.echartsEngine.echarts = event;
    }
    onOptionsError(event) {
        this.error$.next(event.message);
        this.echartsEngine.echarts.dispose();
        this._cdr.detectChanges();
    }
    openContextMenu(slicers, event) {
        event?.stopPropagation();
        event?.preventDefault();
        // 设置当前选中过滤器
        this.patchState({ selectedSlicers: slicers });
        // 弹出菜单坐标
        if (event?.type === 'touchend') {
            this.contextMenuPosition.x = event.zrX + 50 + 'px';
            this.contextMenuPosition.y = event.zrY + 'px';
        }
        else if (event) {
            this.contextMenuPosition.x = event.offsetX + 50 + 'px';
            this.contextMenuPosition.y = event.offsetY + 'px';
        }
        this.contextMenu.menuData = { slicers };
        if (isEmpty(slicers)) {
            this.contextMenu.closeMenu();
            this.onLinkAnalysis([]);
        }
        else {
            if (!this.options?.disableContextMenu) {
                this.contextMenu.openMenu();
            }
            if (this.options?.realtimeLinked) {
                this.onLinkAnalysis(slicers);
            }
        }
    }
    /**
     * Linked analysis, output selected slicers on chart
     *
     * @param slicers
     */
    onLinkAnalysis(slicers) {
        this.slicersChange.emit(slicers);
        this._slicersChanging$.next(slicers);
    }
    screenshot() {
        const baseImage = this.echartsEngine.echarts.getDataURL({ type: 'png' });
        const downloadLink = document.createElement('a');
        document.body.appendChild(downloadLink);
        downloadLink.href = baseImage;
        downloadLink.target = '_self';
        downloadLink.download = (this.title || 'image') + '.png';
        downloadLink.click();
    }
    downloadData() {
        csvDownload(this.echartsEngine.data.data, (this.title || 'data') + '.csv', ',');
    }
    get _drilled() {
        return this.get((state) => state.selectedDrilledDimensions);
    }
    ngOnDestroy() {
        this.echartsEngine.onDestroy();
        super.onDestroy();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.10", ngImport: i0, type: AnalyticalCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.10", type: AnalyticalCardComponent, selector: "ngm-analytical-card", inputs: { title: "title", appearance: "appearance", dataSettings: "dataSettings", chartSettings: "chartSettings", chartOptions: "chartOptions", options: "options", slicers: "slicers" }, outputs: { slicersChange: "slicersChange", slicersChanging: "slicersChanging", chartClick: "chartClick", chartHighlight: "chartHighlight", chartContextMenu: "chartContextMenu", explain: "explain" }, host: { properties: { "class.ngm-density__compact": "!displayDensity||displayDensity==='compact'", "class.ngm-density__cosy": "displayDensity==='cosy'", "class.ngm-analytical-card": "this._isAnalyticalCard", "class.ngm-analytical-card__drilled": "this._drilled" } }, providers: [AnalyticalCardService], viewQueries: [{ propertyName: "contextMenu", first: true, predicate: ["contextMenuTrigger"], descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "@if (!options?.hideHeader) {\n  <div class=\"ngm-card-header flex justify-between items-center\">\n    <div class=\"ngm-card-header__title\">{{ title }}</div>\n    \n    <div class=\"flex-1 flex justify-end items-center\">\n\n      <ng-content></ng-content>\n\n      <mat-button-toggle-group *ngIf=\"chartSettings?.chartTypes?.length\" displayDensity=\"compact\" ngmAppearance=\"color\" color=\"primary\"\n        [(ngModel)]=\"chartType\"  \n      >\n        <mat-button-toggle *ngIf=\"_dataSettings()?.chartAnnotation?.chartType\"\n          [value]=\"_dataSettings().chartAnnotation.chartType\">\n          {{ _dataSettings().chartAnnotation.chartType.name || _dataSettings().chartAnnotation.chartType.type }}\n        </mat-button-toggle>\n        <mat-button-toggle *ngFor=\"let chartType of chartSettings.chartTypes\" [value]=\"chartType\">\n          {{ chartType?.name || chartType?.type }}\n        </mat-button-toggle>\n      </mat-button-toggle-group>\n    </div>\n\n    <div class=\"actions flex justify-around items-center\">\n\n      <ng-content select=\"[ngmAction]\"></ng-content>\n\n      <!-- data download -->\n      <button mat-icon-button *ngIf=\"!options?.hideDataDownload\" displayDensity=\"cosy\" [matTooltip]=\" 'Ngm.AnalyticalCard.DataDownload' | translate: {Default: 'Data Download'} \"\n        (click)=\"downloadData()\">\n        <mat-icon fontSet=\"material-icons-outlined\">file_download</mat-icon>\n      </button>\n\n      <!-- screenshot -->\n      <button mat-icon-button *ngIf=\"!options?.hideScreenshot\" displayDensity=\"cosy\" [matTooltip]=\" 'Ngm.AnalyticalCard.Screenshot' | translate: {Default: 'Screenshot'} \"\n        (click)=\"screenshot()\">\n        <mat-icon fontSet=\"material-icons-outlined\">photo_camera</mat-icon>\n      </button>\n\n      <!-- Refresh & Loading icon -->\n      <button mat-icon-button class=\"ngm-analytical-card__refresh\" displayDensity=\"cosy\"\n        [matTooltip]=\" 'Ngm.AnalyticalCard.Refresh' | translate: {Default: 'Refresh'} \"\n        [style.visibility]=\"(isLoading$ | async) ? 'hidden' : 'visible'\"\n        (click)=\"refresh()\">\n        <mat-icon fontSet=\"material-icons-outlined\">refresh</mat-icon>\n      </button>\n      <mat-spinner *ngIf=\"isLoading$ | async\" class=\"ngm-analytical-card__loading\"\n        [diameter]=\"20\"\n        [strokeWidth]=\"1\"\n      >\n      </mat-spinner>\n    </div>\n  </div>\n}\n\n@if (breadcrumbs$ | async; as breadcrumbs) {\n  <ngm-breadcrumb-bar class=\"shrink-0\" [displayDensity]=\"appearance?.displayDensity ?? DisplayDensity.compact\"\n    [steps]=\"breadcrumbs\"\n    (selectedChange)=\"reselectDrill($event)\"\n    (close)=\"clearDrill()\">\n  </ngm-breadcrumb-bar>\n}\n\n<div class=\"ngm-card-content\">\n  <div *ngIf=\"error$ | async as error\" class=\"ngm-card-error\">\n    <span class=\"title-icon text-2xl font-notoColorEmoji\">\uD83D\uDC1E</span>\n    <span>\n      {{ error }}\n    </span>\n  </div>\n\n  <div *ngIf=\"empty$ | async\" class=\"ngm-card-error\">\n    <span class=\"title-icon text-2xl font-notoColorEmoji\">\uD83D\uDED2</span>\n    <span>\n      {{ 'Ngm.AnalyticalCard.DataEmpty' | translate: {Default: \"Data Empty\"} }}\n    </span>\n  </div>\n\n  <ng-container *ngIf=\"!((error$ | async) || (empty$ | async))\">\n    <div echarts class=\"echarts-chart\"\n      [options]=\"options$ | async\"\n      [theme]=\"chartSettings?.theme ?? 'default'\"\n      (chartInit)=\"onChartInit($event)\"\n      (optionsError)=\"onOptionsError($event)\"\n    >\n    </div>\n  </ng-container>\n    \n</div>\n\n\n<div style=\"visibility: hidden; position: absolute;\"\n  #contextMenuTrigger=\"matMenuTrigger\"\n    [style.left]=\"contextMenuPosition.x\"\n    [style.top]=\"contextMenuPosition.y\"\n    [matMenuTriggerFor]=\"contextMenu\">\n</div>\n\n<!-- [hasBackdrop]=\"false\" -->\n<mat-menu #contextMenu=\"matMenu\" class=\"ngm-density__compact\">\n\t<ng-template matMenuContent let-slicers=\"slicers\">\n\n    <button mat-menu-item (click)=\"onLinkAnalysis(slicers)\">\n      <mat-icon displayDensity=\"cosy\">add_link</mat-icon>\n      {{ 'Ngm.AnalyticalCard.LinkAnalysis' | translate: {Default: \"Link Analysis\"} }}\n    </button>\n\n    <ng-container *ngIf=\"canDrillLevels$ | async\">\n      <mat-divider></mat-divider>\n      <button mat-menu-item disableRipple disabled>\n        {{ 'Ngm.AnalyticalCard.DrillLevel' | translate: {Default: \"Drill Level\"} }}\n      </button>\n      <button mat-menu-item *ngFor=\"let drill of drillLevels$ | async\"\n        [matMenuTriggerFor]=\"drillLevelsMenu\"\n        [matMenuTriggerData]=\"{slicer: drill.slicer, levels: drill.levels}\">\n        <mat-icon displayDensity=\"cosy\">format_list_numbered</mat-icon>\n        <div class=\"flex-1 overflow-hidden whitespace-nowrap text-ellipsis\">\n          {{drill.property.caption || drill.property.name}}:{{drill.slicerCaption}}\n        </div>\n      </button>\n    </ng-container>\n\n    <ng-container *ngIf=\"canDrillDimensions$ | async\">\n      <mat-divider></mat-divider>\n      <button mat-menu-item disableRipple disabled>\n        {{ 'Ngm.AnalyticalCard.DrillDimension' | translate: {Default: \"Drill Dimension\"} }}\n      </button>\n\n      <button mat-menu-item *ngFor=\"let item of dillSlicers$ | async\"\n        [matMenuTriggerFor]=\"drillDimensionsMenu\"\n        [matMenuTriggerData]=\"{slicer: item.value}\">\n        <mat-icon displayDensity=\"cosy\">tag</mat-icon>{{ item.label }}\n      </button>\n\n    </ng-container>\n\n    <ng-container *ngIf=\"dilldown$ | async as slicer\">\n      <mat-divider></mat-divider>\n      <button mat-menu-item  (click)=\"drillDown(slicer)\">\n        <mat-icon displayDensity=\"cosy\">arrow_drop_down</mat-icon>\n        {{ 'Ngm.AnalyticalCard.DrillDown' | translate: {Default: \"Drill Down\"} }}\n      </button>\n    </ng-container>\n\t\t\n\t</ng-template>\n</mat-menu>\n\n<mat-menu #drillLevelsMenu=\"matMenu\" class=\"ngm-density__compact\">\n  <ng-template matMenuContent let-levels=\"levels\" let-slicer=\"slicer\">\n    <button mat-menu-item *ngFor=\"let item of levels\" \n      [disabled]=\"item.disabled\"\n      (click)=\"drillLevel({property: item.property, slicer})\">\n      <ngm-entity-property [property]=\"item.property\"></ngm-entity-property>\n    </button>\n  </ng-template>\n</mat-menu>\n\n<mat-menu #drillDimensionsMenu=\"matMenu\" class=\"ngm-density__compact\">\n  <ng-template matMenuContent let-slicer=\"slicer\">\n    <button mat-menu-item *ngFor=\"let item of drillDimensions$ | async\" \n      [disabled]=\"item.disabled\"\n      (click)=\"drill({parent: slicer.dimension, dimension: item.dimension, slicer})\">\n      <ngm-entity-property [property]=\"item.property\"></ngm-entity-property>\n    </button>\n  </ng-template>\n</mat-menu>\n", styles: [":host{display:flex;flex-direction:column;position:relative}:host .ngm-card-header .actions{position:relative}:host .ngm-card-header .actions>*{opacity:.1}:host:hover .ngm-card-header .actions>*{opacity:1}:host.ngm-analytical-card__drilled .ngm-card-content{height:calc(100% - 60px);max-height:calc(100% - 60px)}:host.ngm-density__compact.ngm-analytical-card__drilled .ngm-card-content{height:calc(100% - 55px);max-height:calc(100% - 55px)}:host.ngm-density__cosy.ngm-analytical-card__drilled .ngm-card-content{height:calc(100% - 60px);max-height:calc(100% - 60px)}.ngm-card-header__title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ngm-card-content{height:calc(100% - 30px);max-height:calc(100% - 30px);margin-bottom:0}.echarts-chart{height:100%;max-height:100%}.ngm-analytical-card__loading{position:absolute;right:0;margin:5px}.ngm-card-error{position:absolute;width:100%;height:100%}\n"], dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i5.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i5.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i5.MatMenuContent, selector: "ng-template[matMenuContent]" }, { kind: "directive", type: i5.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: i6.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: i7.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: i9.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i9.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "directive", type: i10.NgxEchartsDirective, selector: "echarts, [echarts]", inputs: ["options", "theme", "loading", "initOpts", "merge", "autoResize", "loadingType", "loadingOpts"], outputs: ["chartInit", "optionsError", "chartClick", "chartDblClick", "chartMouseDown", "chartMouseMove", "chartMouseUp", "chartMouseOver", "chartMouseOut", "chartGlobalOut", "chartContextMenu", "chartLegendSelectChanged", "chartLegendSelected", "chartLegendUnselected", "chartLegendScroll", "chartDataZoom", "chartDataRangeSelected", "chartTimelineChanged", "chartTimelinePlayChanged", "chartRestore", "chartDataViewChanged", "chartMagicTypeChanged", "chartPieSelectChanged", "chartPieSelected", "chartPieUnselected", "chartMapSelectChanged", "chartMapSelected", "chartMapUnselected", "chartAxisAreaSelected", "chartFocusNodeAdjacency", "chartUnfocusNodeAdjacency", "chartBrush", "chartBrushEnd", "chartBrushSelected", "chartRendered", "chartFinished"], exportAs: ["echarts"] }, { kind: "component", type: i11.NgmBreadcrumbBarComponent, selector: "ngm-breadcrumb-bar", inputs: ["steps", "disabled"], outputs: ["selectedChange", "close"] }, { kind: "directive", type: i1.DensityDirective, selector: "[displayDensity]", inputs: ["displayDensity"] }, { kind: "directive", type: i1.AppearanceDirective, selector: "[ngmAppearance]", inputs: ["color", "ngmAppearance", "outline", "hero", "acrylic", "opacity", "dashed", "danger"] }, { kind: "component", type: i13.NgmEntityPropertyComponent, selector: "ngm-entity-property", inputs: ["property", "displayBehaviour", "displayDensity", "hiddenIcon", "highlight", "role"] }, { kind: "pipe", type: i1$1.AsyncPipe, name: "async" }, { kind: "pipe", type: i14.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.10", ngImport: i0, type: AnalyticalCardComponent, decorators: [{
            type: Component,
            args: [{ changeDetection: ChangeDetectionStrategy.OnPush, selector: 'ngm-analytical-card', providers: [AnalyticalCardService], host: {
                        '[class.ngm-density__compact]': `!displayDensity||displayDensity==='compact'`,
                        '[class.ngm-density__cosy]': `displayDensity==='cosy'`
                    }, template: "@if (!options?.hideHeader) {\n  <div class=\"ngm-card-header flex justify-between items-center\">\n    <div class=\"ngm-card-header__title\">{{ title }}</div>\n    \n    <div class=\"flex-1 flex justify-end items-center\">\n\n      <ng-content></ng-content>\n\n      <mat-button-toggle-group *ngIf=\"chartSettings?.chartTypes?.length\" displayDensity=\"compact\" ngmAppearance=\"color\" color=\"primary\"\n        [(ngModel)]=\"chartType\"  \n      >\n        <mat-button-toggle *ngIf=\"_dataSettings()?.chartAnnotation?.chartType\"\n          [value]=\"_dataSettings().chartAnnotation.chartType\">\n          {{ _dataSettings().chartAnnotation.chartType.name || _dataSettings().chartAnnotation.chartType.type }}\n        </mat-button-toggle>\n        <mat-button-toggle *ngFor=\"let chartType of chartSettings.chartTypes\" [value]=\"chartType\">\n          {{ chartType?.name || chartType?.type }}\n        </mat-button-toggle>\n      </mat-button-toggle-group>\n    </div>\n\n    <div class=\"actions flex justify-around items-center\">\n\n      <ng-content select=\"[ngmAction]\"></ng-content>\n\n      <!-- data download -->\n      <button mat-icon-button *ngIf=\"!options?.hideDataDownload\" displayDensity=\"cosy\" [matTooltip]=\" 'Ngm.AnalyticalCard.DataDownload' | translate: {Default: 'Data Download'} \"\n        (click)=\"downloadData()\">\n        <mat-icon fontSet=\"material-icons-outlined\">file_download</mat-icon>\n      </button>\n\n      <!-- screenshot -->\n      <button mat-icon-button *ngIf=\"!options?.hideScreenshot\" displayDensity=\"cosy\" [matTooltip]=\" 'Ngm.AnalyticalCard.Screenshot' | translate: {Default: 'Screenshot'} \"\n        (click)=\"screenshot()\">\n        <mat-icon fontSet=\"material-icons-outlined\">photo_camera</mat-icon>\n      </button>\n\n      <!-- Refresh & Loading icon -->\n      <button mat-icon-button class=\"ngm-analytical-card__refresh\" displayDensity=\"cosy\"\n        [matTooltip]=\" 'Ngm.AnalyticalCard.Refresh' | translate: {Default: 'Refresh'} \"\n        [style.visibility]=\"(isLoading$ | async) ? 'hidden' : 'visible'\"\n        (click)=\"refresh()\">\n        <mat-icon fontSet=\"material-icons-outlined\">refresh</mat-icon>\n      </button>\n      <mat-spinner *ngIf=\"isLoading$ | async\" class=\"ngm-analytical-card__loading\"\n        [diameter]=\"20\"\n        [strokeWidth]=\"1\"\n      >\n      </mat-spinner>\n    </div>\n  </div>\n}\n\n@if (breadcrumbs$ | async; as breadcrumbs) {\n  <ngm-breadcrumb-bar class=\"shrink-0\" [displayDensity]=\"appearance?.displayDensity ?? DisplayDensity.compact\"\n    [steps]=\"breadcrumbs\"\n    (selectedChange)=\"reselectDrill($event)\"\n    (close)=\"clearDrill()\">\n  </ngm-breadcrumb-bar>\n}\n\n<div class=\"ngm-card-content\">\n  <div *ngIf=\"error$ | async as error\" class=\"ngm-card-error\">\n    <span class=\"title-icon text-2xl font-notoColorEmoji\">\uD83D\uDC1E</span>\n    <span>\n      {{ error }}\n    </span>\n  </div>\n\n  <div *ngIf=\"empty$ | async\" class=\"ngm-card-error\">\n    <span class=\"title-icon text-2xl font-notoColorEmoji\">\uD83D\uDED2</span>\n    <span>\n      {{ 'Ngm.AnalyticalCard.DataEmpty' | translate: {Default: \"Data Empty\"} }}\n    </span>\n  </div>\n\n  <ng-container *ngIf=\"!((error$ | async) || (empty$ | async))\">\n    <div echarts class=\"echarts-chart\"\n      [options]=\"options$ | async\"\n      [theme]=\"chartSettings?.theme ?? 'default'\"\n      (chartInit)=\"onChartInit($event)\"\n      (optionsError)=\"onOptionsError($event)\"\n    >\n    </div>\n  </ng-container>\n    \n</div>\n\n\n<div style=\"visibility: hidden; position: absolute;\"\n  #contextMenuTrigger=\"matMenuTrigger\"\n    [style.left]=\"contextMenuPosition.x\"\n    [style.top]=\"contextMenuPosition.y\"\n    [matMenuTriggerFor]=\"contextMenu\">\n</div>\n\n<!-- [hasBackdrop]=\"false\" -->\n<mat-menu #contextMenu=\"matMenu\" class=\"ngm-density__compact\">\n\t<ng-template matMenuContent let-slicers=\"slicers\">\n\n    <button mat-menu-item (click)=\"onLinkAnalysis(slicers)\">\n      <mat-icon displayDensity=\"cosy\">add_link</mat-icon>\n      {{ 'Ngm.AnalyticalCard.LinkAnalysis' | translate: {Default: \"Link Analysis\"} }}\n    </button>\n\n    <ng-container *ngIf=\"canDrillLevels$ | async\">\n      <mat-divider></mat-divider>\n      <button mat-menu-item disableRipple disabled>\n        {{ 'Ngm.AnalyticalCard.DrillLevel' | translate: {Default: \"Drill Level\"} }}\n      </button>\n      <button mat-menu-item *ngFor=\"let drill of drillLevels$ | async\"\n        [matMenuTriggerFor]=\"drillLevelsMenu\"\n        [matMenuTriggerData]=\"{slicer: drill.slicer, levels: drill.levels}\">\n        <mat-icon displayDensity=\"cosy\">format_list_numbered</mat-icon>\n        <div class=\"flex-1 overflow-hidden whitespace-nowrap text-ellipsis\">\n          {{drill.property.caption || drill.property.name}}:{{drill.slicerCaption}}\n        </div>\n      </button>\n    </ng-container>\n\n    <ng-container *ngIf=\"canDrillDimensions$ | async\">\n      <mat-divider></mat-divider>\n      <button mat-menu-item disableRipple disabled>\n        {{ 'Ngm.AnalyticalCard.DrillDimension' | translate: {Default: \"Drill Dimension\"} }}\n      </button>\n\n      <button mat-menu-item *ngFor=\"let item of dillSlicers$ | async\"\n        [matMenuTriggerFor]=\"drillDimensionsMenu\"\n        [matMenuTriggerData]=\"{slicer: item.value}\">\n        <mat-icon displayDensity=\"cosy\">tag</mat-icon>{{ item.label }}\n      </button>\n\n    </ng-container>\n\n    <ng-container *ngIf=\"dilldown$ | async as slicer\">\n      <mat-divider></mat-divider>\n      <button mat-menu-item  (click)=\"drillDown(slicer)\">\n        <mat-icon displayDensity=\"cosy\">arrow_drop_down</mat-icon>\n        {{ 'Ngm.AnalyticalCard.DrillDown' | translate: {Default: \"Drill Down\"} }}\n      </button>\n    </ng-container>\n\t\t\n\t</ng-template>\n</mat-menu>\n\n<mat-menu #drillLevelsMenu=\"matMenu\" class=\"ngm-density__compact\">\n  <ng-template matMenuContent let-levels=\"levels\" let-slicer=\"slicer\">\n    <button mat-menu-item *ngFor=\"let item of levels\" \n      [disabled]=\"item.disabled\"\n      (click)=\"drillLevel({property: item.property, slicer})\">\n      <ngm-entity-property [property]=\"item.property\"></ngm-entity-property>\n    </button>\n  </ng-template>\n</mat-menu>\n\n<mat-menu #drillDimensionsMenu=\"matMenu\" class=\"ngm-density__compact\">\n  <ng-template matMenuContent let-slicer=\"slicer\">\n    <button mat-menu-item *ngFor=\"let item of drillDimensions$ | async\" \n      [disabled]=\"item.disabled\"\n      (click)=\"drill({parent: slicer.dimension, dimension: item.dimension, slicer})\">\n      <ngm-entity-property [property]=\"item.property\"></ngm-entity-property>\n    </button>\n  </ng-template>\n</mat-menu>\n", styles: [":host{display:flex;flex-direction:column;position:relative}:host .ngm-card-header .actions{position:relative}:host .ngm-card-header .actions>*{opacity:.1}:host:hover .ngm-card-header .actions>*{opacity:1}:host.ngm-analytical-card__drilled .ngm-card-content{height:calc(100% - 60px);max-height:calc(100% - 60px)}:host.ngm-density__compact.ngm-analytical-card__drilled .ngm-card-content{height:calc(100% - 55px);max-height:calc(100% - 55px)}:host.ngm-density__cosy.ngm-analytical-card__drilled .ngm-card-content{height:calc(100% - 60px);max-height:calc(100% - 60px)}.ngm-card-header__title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ngm-card-content{height:calc(100% - 30px);max-height:calc(100% - 30px);margin-bottom:0}.echarts-chart{height:100%;max-height:100%}.ngm-analytical-card__loading{position:absolute;right:0;margin:5px}.ngm-card-error{position:absolute;width:100%;height:100%}\n"] }]
        }], ctorParameters: () => [], propDecorators: { _isAnalyticalCard: [{
                type: HostBinding,
                args: ['class.ngm-analytical-card']
            }], title: [{
                type: Input
            }], appearance: [{
                type: Input
            }], dataSettings: [{
                type: Input
            }], chartSettings: [{
                type: Input
            }], chartOptions: [{
                type: Input
            }], options: [{
                type: Input
            }], slicers: [{
                type: Input
            }], slicersChange: [{
                type: Output
            }], slicersChanging: [{
                type: Output
            }], chartClick: [{
                type: Output
            }], chartHighlight: [{
                type: Output
            }], chartContextMenu: [{
                type: Output
            }], explain: [{
                type: Output
            }], contextMenu: [{
                type: ViewChild,
                args: ['contextMenuTrigger']
            }], _drilled: [{
                type: HostBinding,
                args: ['class.ngm-analytical-card__drilled']
            }] } });

class AnalyticalCardModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.10", ngImport: i0, type: AnalyticalCardModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.3.10", ngImport: i0, type: AnalyticalCardModule, declarations: [AnalyticalCardComponent], imports: [CommonModule,
            FormsModule,
            MatCardModule,
            MatButtonModule,
            MatIconModule,
            MatMenuModule,
            MatProgressSpinnerModule,
            MatDividerModule,
            MatTooltipModule,
            MatButtonToggleModule,
            NgxEchartsModule,
            TranslateModule,
            NgmCommonModule,
            NgmEntityPropertyComponent,
            OcapCoreModule], exports: [AnalyticalCardComponent] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.3.10", ngImport: i0, type: AnalyticalCardModule, imports: [CommonModule,
            FormsModule,
            MatCardModule,
            MatButtonModule,
            MatIconModule,
            MatMenuModule,
            MatProgressSpinnerModule,
            MatDividerModule,
            MatTooltipModule,
            MatButtonToggleModule,
            NgxEchartsModule,
            TranslateModule,
            NgmCommonModule,
            NgmEntityPropertyComponent,
            OcapCoreModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.10", ngImport: i0, type: AnalyticalCardModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [
                        CommonModule,
                        FormsModule,
                        MatCardModule,
                        MatButtonModule,
                        MatIconModule,
                        MatMenuModule,
                        MatProgressSpinnerModule,
                        MatDividerModule,
                        MatTooltipModule,
                        MatButtonToggleModule,
                        NgxEchartsModule,
                        TranslateModule,
                        NgmCommonModule,
                        NgmEntityPropertyComponent,
                        OcapCoreModule
                    ],
                    declarations: [AnalyticalCardComponent],
                    exports: [AnalyticalCardComponent]
                }]
        }] });

/**
 * Generated bundle index. Do not edit.
 */

export { AnalyticalCardComponent, AnalyticalCardModule, AnalyticalCardService };
//# sourceMappingURL=metad-ocap-angular-analytical-card.mjs.map
