From e768ba219c783bdb81d222d14c5fd03dac67957d Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Sat, 22 Aug 2026 00:07:04 +0330 Subject: [PATCH] try to implement Chart Toolbars using XActionBar implementation like XIDEComponent ... --- .../src/lib/x-chart/x-chart.component.html | 16 + .../src/lib/x-chart/x-chart.component.ts | 761 +++++++++++++++++- .../src/lib/x-chart/x-chart.module.ts | 3 + .../src/lib/x-chart/x-chart.typings.ts | 321 +++++++- 4 files changed, 1056 insertions(+), 45 deletions(-) diff --git a/projects/x-framework-components/src/lib/x-chart/x-chart.component.html b/projects/x-framework-components/src/lib/x-chart/x-chart.component.html index 8e7d5c3..ce82a43 100644 --- a/projects/x-framework-components/src/lib/x-chart/x-chart.component.html +++ b/projects/x-framework-components/src/lib/x-chart/x-chart.component.html @@ -39,6 +39,22 @@ [class.mobile]="isMobileUi$ | async" [ngClass]="getValue(cssClass) | async" > + + + +
diff --git a/projects/x-framework-components/src/lib/x-chart/x-chart.component.ts b/projects/x-framework-components/src/lib/x-chart/x-chart.component.ts index 9511d5e..adeb05d 100644 --- a/projects/x-framework-components/src/lib/x-chart/x-chart.component.ts +++ b/projects/x-framework-components/src/lib/x-chart/x-chart.component.ts @@ -10,10 +10,26 @@ import { XChartOptions, XChartSeriesType, XChartContainerComponent, + XChartActionBarItem, } from './x-chart.typings'; import { Subscription } from 'rxjs'; import ApexCharts from 'apexcharts'; -import { isNullOrUndefined, nameof } from 'x-framework-core'; +import { + downloadArrayBufferedFile, + downloadFile, + downloadFileByUrl, + generateUuid, + isNullOrEmptyString, + isNullOrUndefined, + nameof, + XMimeType, +} from 'x-framework-core'; +import { + XActionBarActionFiredModel, + XActionBarItem, + XActionBarItemSlot, +} from '../x-action-bar/x-action-bar.typings'; +import { XIconNames } from '../x-icon/x-icon.typings'; @Component({ selector: 'x-chart', @@ -53,6 +69,11 @@ export class XChartComponent extends XChartContainerComponent { // private ACTION_PROVIDER_SUBSCRIPTION: Subscription; + + // + readonly IconNames = Object.assign({}, XIconNames); + readonly ActionBarItems = Object.assign({}, XChartActionBarItem); + readonly ActionBarItemSlots = Object.assign({}, XActionBarItemSlot); //#endregion // @@ -164,6 +185,116 @@ export class XChartComponent extends XChartContainerComponent { } //#endregion + // + //#region UI Handler ... + async handleActionBarActionFired(model: XActionBarActionFiredModel) { + // + if (isNullOrUndefined(model) || isNullOrEmptyString(model.action)) { + return; + } + + // + switch ( + model.action + // + // case this.ActionBarItems.ChangeMode: + // this.handleActionModeFired(model.event); + // break; + + // // + // case this.ActionBarItems.ChangeTheme: + // this.handleActionThemFired(model.event); + // break; + + // // + // case this.ActionBarItems.Close: + // this.closeTab(this.currentTab); + // break; + + // // + // case this.ActionBarItems.Undo: + // this.undo(); + // break; + + // // + // case this.ActionBarItems.Redo: + // this.redo(); + // break; + + // // + // case this.ActionBarItems.Beautify: + // await this.beautifyCode(); + // break; + + // // + // case this.ActionBarItems.Save: + // // + // this.updateCurrentTabDescriptor({ + // canSave: false, + // }); + // this.prepareActionBar(); + // break; + ) { + } + + // + this.actionBarActionFired.emit(model); + } + //#endregion + + // + //#region Actions ... + /** + * Export Chart Data in Specified Format ... + * + * @param format Export Format ... + * @param fileName Provided File Name without Extension ... + */ + async export(format: 'png' | 'svg' | 'csv' = 'png', fileName: string = '') { + // + // Normalize File Name ... + if (isNullOrEmptyString(fileName)) { + fileName = generateUuid('XChart'); + } + + // + fileName += '.' + format; + + // + switch (format) { + // + case 'png': + // + const dataObject = await this.chartInstance.dataURI(); + + // + if ('imgURI' in dataObject) { + downloadFileByUrl(dataObject.imgURI, fileName); + } else if ('blob' in dataObject) { + downloadArrayBufferedFile(fileName, dataObject.blob); + } + break; + + // + case 'svg': + // + const svgString = this.chartInstance.exports.exportToSVG(); + downloadFile(svgString, XMimeType.ImageSVG, fileName); + break; + + // + case 'csv': + // + this.chartInstance.exports.exportToCSV({ + fileName: fileName, + columnDelimiter: ',', + lineDelimiter: '\n', + }); + break; + } + } + //#endregion + // //#region Private ... private async initializeComponent() { @@ -199,6 +330,9 @@ export class XChartComponent extends XChartContainerComponent { id: chartId, type: type as any, foreColor: textColor, + toolbar: { + show: false, + }, events: { ...options.chart?.events, mounted: (chartContext, config) => { @@ -240,6 +374,627 @@ export class XChartComponent extends XChartContainerComponent { await this.chartInstance.render(); } + private async prepareActionBar() { + // + if (isNullOrUndefined(this.chartInstance)) { + return; + } + + // + const showActionBar = await this.getValueAsync(this.showActionBar); + if (!showActionBar) { + return; + } + + // + //#region DefaultActionBarActions ... + // + const defaultPrintItem: XActionBarItem = { + onlyIcon: true, + disabled: this.uiDisabled, + icon: this.IconNames.print, + title: this.ResourceIDs.print, + id: this.ActionBarItems.Print, + slot: this.ActionBarItemSlots.END, + iconColor: this.defaultActionBarItemColor, + }; + + // + const defaultExportPNGItem: XActionBarItem = { + onlyIcon: true, + disabled: this.uiDisabled, + icon: this.IconNames.image, + slot: this.ActionBarItemSlots.END, + title: this.ResourceIDs.export_png, + id: this.ActionBarItems.ExportAsPNG, + iconColor: this.defaultActionBarItemColor, + }; + + // + const defaultExportSVGItem: XActionBarItem = { + onlyIcon: true, + disabled: this.uiDisabled, + icon: this.IconNames.image, + slot: this.ActionBarItemSlots.END, + title: this.ResourceIDs.export_svg, + id: this.ActionBarItems.ExportAsSVG, + iconColor: this.defaultActionBarItemColor, + }; + + // + const defaultExportCSVItem: XActionBarItem = { + onlyIcon: true, + disabled: this.uiDisabled, + icon: this.IconNames.data_table, + slot: this.ActionBarItemSlots.END, + title: this.ResourceIDs.export_csv, + id: this.ActionBarItems.ExportAsCSV, + iconColor: this.defaultActionBarItemColor, + }; + + // + const defaultZoomInItem: XActionBarItem = { + onlyIcon: true, + disabled: this.uiDisabled, + icon: this.IconNames.add, + id: this.ActionBarItems.ZoomIn, + title: this.ResourceIDs.zoom_in, + slot: this.ActionBarItemSlots.START, + iconColor: this.defaultActionBarItemColor, + }; + + // + const defaultZoomOutItem: XActionBarItem = { + onlyIcon: true, + disabled: this.uiDisabled, + id: this.ActionBarItems.ZoomOut, + title: this.ResourceIDs.zoom_out, + slot: this.ActionBarItemSlots.START, + icon: this.IconNames.friendship_reject, + iconColor: this.defaultActionBarItemColor, + }; + + // + const defaultZoomSelectionItem: XActionBarItem = { + onlyIcon: true, + disabled: this.uiDisabled, + slot: this.ActionBarItemSlots.START, + id: this.ActionBarItems.ZoomSelection, + title: this.ResourceIDs.zoom_selection, + icon: this.IconNames.friendship_reject, + iconColor: this.defaultActionBarItemColor, + }; + + // + const defaultXAxisSelectionItem: XActionBarItem = { + onlyIcon: true, + disabled: this.uiDisabled, + icon: this.IconNames.x_axist, + title: this.ResourceIDs.x_axis, + id: this.ActionBarItems.XSelection, + slot: this.ActionBarItemSlots.START, + iconColor: this.defaultActionBarItemColor, + }; + + // + const defaultYAxisSelectionItem: XActionBarItem = { + onlyIcon: true, + disabled: this.uiDisabled, + icon: this.IconNames.y_axis, + title: this.ResourceIDs.y_axis, + id: this.ActionBarItems.YSelection, + slot: this.ActionBarItemSlots.START, + iconColor: this.defaultActionBarItemColor, + }; + + // + const defaultXYAxisSelectionItem: XActionBarItem = { + onlyIcon: true, + disabled: this.uiDisabled, + icon: this.IconNames.xy_axis, + title: this.ResourceIDs.xy_axis, + id: this.ActionBarItems.XYSelection, + slot: this.ActionBarItemSlots.START, + iconColor: this.defaultActionBarItemColor, + }; + + // + const defaultPanItem: XActionBarItem = { + onlyIcon: true, + disabled: this.uiDisabled, + icon: this.IconNames.touch, + title: this.ResourceIDs.pan, + id: this.ActionBarItems.Pan, + slot: this.ActionBarItemSlots.START, + iconColor: this.defaultActionBarItemColor, + }; + + // + const defaultResetItem: XActionBarItem = { + onlyIcon: true, + disabled: this.uiDisabled, + icon: this.IconNames.refresh, + title: this.ResourceIDs.reset, + slot: this.ActionBarItemSlots.END, + id: this.ActionBarItems.ResetChart, + iconColor: this.defaultActionBarItemColor, + }; + + // + const defaultFullscreenItem: XActionBarItem = { + onlyIcon: true, + disabled: this.uiDisabled, + icon: this.IconNames.fullscreen, + title: this.ResourceIDs.full_screen, + slot: this.ActionBarItemSlots.START, + id: this.ActionBarItems.ToggleFullScreen, + iconColor: this.defaultActionBarItemColor, + }; + //#endregion + + // + this.actionBarActions = []; + this.detectChanges(); + + // + const availableItems = await this.getArrayValueAsync( + this.availableActionBarItems, + ); + if (!this.hasChild(availableItems)) { + return; + } + + // + let hasItem = false; + const actionBarItems: XActionBarItem[] = []; + + // + //#region Print ... + hasItem = availableItems + .map((ai) => ai.actionId) + .includes(this.ActionBarItems.Print); + + // + if (hasItem) { + // + const selectedItem = availableItems.find( + (ai) => ai.actionId === this.ActionBarItems.Print, + ); + const providedItem = selectedItem.descriptor; + let item = { + ...defaultPrintItem, + }; + if (!isNullOrUndefined(providedItem)) { + item = { + ...item, + ...providedItem, + }; + } + + // + item = { + ...item, + disabled: this.uiDisabled, + }; + + // + actionBarItems.push(item); + } + //#endregion + + // + //#region ExportAsPNG ... + hasItem = availableItems + .map((ai) => ai.actionId) + .includes(this.ActionBarItems.ExportAsPNG); + + // + if (hasItem) { + // + const selectedItem = availableItems.find( + (ai) => ai.actionId === this.ActionBarItems.ExportAsPNG, + ); + const providedItem = selectedItem.descriptor; + let item = { + ...defaultExportPNGItem, + }; + if (!isNullOrUndefined(providedItem)) { + item = { + ...item, + ...providedItem, + }; + } + + // + item = { + ...item, + disabled: this.uiDisabled, + }; + + // + actionBarItems.push(item); + } + //#endregion + + // + //#region ExportAsSVG ... + hasItem = availableItems + .map((ai) => ai.actionId) + .includes(this.ActionBarItems.ExportAsSVG); + + // + if (hasItem) { + // + const selectedItem = availableItems.find( + (ai) => ai.actionId === this.ActionBarItems.ExportAsSVG, + ); + const providedItem = selectedItem.descriptor; + let item = { + ...defaultExportSVGItem, + }; + if (!isNullOrUndefined(providedItem)) { + item = { + ...item, + ...providedItem, + }; + } + + // + item = { + ...item, + disabled: this.uiDisabled, + }; + + // + actionBarItems.push(item); + } + //#endregion + + // + //#region ExportAsCSV ... + hasItem = availableItems + .map((ai) => ai.actionId) + .includes(this.ActionBarItems.ExportAsCSV); + + // + if (hasItem) { + // + const selectedItem = availableItems.find( + (ai) => ai.actionId === this.ActionBarItems.ExportAsCSV, + ); + const providedItem = selectedItem.descriptor; + let item = { + ...defaultExportCSVItem, + }; + if (!isNullOrUndefined(providedItem)) { + item = { + ...item, + ...providedItem, + }; + } + + // + item = { + ...item, + disabled: this.uiDisabled, + }; + + // + actionBarItems.push(item); + } + //#endregion + + // + //#region ZoomIn ... + hasItem = availableItems + .map((ai) => ai.actionId) + .includes(this.ActionBarItems.ZoomIn); + + // + if (hasItem) { + // + const selectedItem = availableItems.find( + (ai) => ai.actionId === this.ActionBarItems.ZoomIn, + ); + const providedItem = selectedItem.descriptor; + let item = { + ...defaultZoomInItem, + }; + if (!isNullOrUndefined(providedItem)) { + item = { + ...item, + ...providedItem, + }; + } + + // + item = { + ...item, + disabled: this.uiDisabled, + }; + + // + actionBarItems.push(item); + } + //#endregion + + // + //#region ZoomOut ... + hasItem = availableItems + .map((ai) => ai.actionId) + .includes(this.ActionBarItems.ZoomOut); + + // + if (hasItem) { + // + const selectedItem = availableItems.find( + (ai) => ai.actionId === this.ActionBarItems.ZoomOut, + ); + const providedItem = selectedItem.descriptor; + let item = { + ...defaultZoomOutItem, + }; + if (!isNullOrUndefined(providedItem)) { + item = { + ...item, + ...providedItem, + }; + } + + // + item = { + ...item, + disabled: this.uiDisabled, + }; + + // + actionBarItems.push(item); + } + //#endregion + + // + //#region ZoomSelection ... + hasItem = availableItems + .map((ai) => ai.actionId) + .includes(this.ActionBarItems.ZoomSelection); + + // + if (hasItem) { + // + const selectedItem = availableItems.find( + (ai) => ai.actionId === this.ActionBarItems.ZoomSelection, + ); + const providedItem = selectedItem.descriptor; + let item = { + ...defaultZoomSelectionItem, + }; + if (!isNullOrUndefined(providedItem)) { + item = { + ...item, + ...providedItem, + }; + } + + // + item = { + ...item, + disabled: this.uiDisabled, + }; + + // + actionBarItems.push(item); + } + //#endregion + + // + //#region XSelection ... + hasItem = availableItems + .map((ai) => ai.actionId) + .includes(this.ActionBarItems.XSelection); + + // + if (hasItem) { + // + const selectedItem = availableItems.find( + (ai) => ai.actionId === this.ActionBarItems.XSelection, + ); + const providedItem = selectedItem.descriptor; + let item = { + ...defaultXAxisSelectionItem, + }; + if (!isNullOrUndefined(providedItem)) { + item = { + ...item, + ...providedItem, + }; + } + + // + item = { + ...item, + disabled: this.uiDisabled, + }; + + // + actionBarItems.push(item); + } + //#endregion + + // + //#region YSelection ... + hasItem = availableItems + .map((ai) => ai.actionId) + .includes(this.ActionBarItems.YSelection); + + // + if (hasItem) { + // + const selectedItem = availableItems.find( + (ai) => ai.actionId === this.ActionBarItems.YSelection, + ); + const providedItem = selectedItem.descriptor; + let item = { + ...defaultYAxisSelectionItem, + }; + if (!isNullOrUndefined(providedItem)) { + item = { + ...item, + ...providedItem, + }; + } + + // + item = { + ...item, + disabled: this.uiDisabled, + }; + + // + actionBarItems.push(item); + } + //#endregion + + // + //#region XYSelection ... + hasItem = availableItems + .map((ai) => ai.actionId) + .includes(this.ActionBarItems.XYSelection); + + // + if (hasItem) { + // + const selectedItem = availableItems.find( + (ai) => ai.actionId === this.ActionBarItems.XYSelection, + ); + const providedItem = selectedItem.descriptor; + let item = { + ...defaultXYAxisSelectionItem, + }; + if (!isNullOrUndefined(providedItem)) { + item = { + ...item, + ...providedItem, + }; + } + + // + item = { + ...item, + disabled: this.uiDisabled, + }; + + // + actionBarItems.push(item); + } + //#endregion + + // + //#region Pan ... + hasItem = availableItems + .map((ai) => ai.actionId) + .includes(this.ActionBarItems.Pan); + + // + if (hasItem) { + // + const selectedItem = availableItems.find( + (ai) => ai.actionId === this.ActionBarItems.Pan, + ); + const providedItem = selectedItem.descriptor; + let item = { + ...defaultPanItem, + }; + if (!isNullOrUndefined(providedItem)) { + item = { + ...item, + ...providedItem, + }; + } + + // + item = { + ...item, + disabled: this.uiDisabled, + }; + + // + actionBarItems.push(item); + } + //#endregion + + // + //#region Reset ... + hasItem = availableItems + .map((ai) => ai.actionId) + .includes(this.ActionBarItems.ResetChart); + + // + if (hasItem) { + // + const selectedItem = availableItems.find( + (ai) => ai.actionId === this.ActionBarItems.ResetChart, + ); + const providedItem = selectedItem.descriptor; + let item = { + ...defaultResetItem, + }; + if (!isNullOrUndefined(providedItem)) { + item = { + ...item, + ...providedItem, + }; + } + + // + item = { + ...item, + disabled: this.uiDisabled, + }; + + // + actionBarItems.push(item); + } + //#endregion + + // + //#region FullScreen ... + hasItem = availableItems + .map((ai) => ai.actionId) + .includes(this.ActionBarItems.ToggleFullScreen); + + // + if (hasItem) { + // + const selectedItem = availableItems.find( + (ai) => ai.actionId === this.ActionBarItems.ToggleFullScreen, + ); + const providedItem = selectedItem.descriptor; + let item = { + ...defaultFullscreenItem, + }; + if (!isNullOrUndefined(providedItem)) { + item = { + ...item, + ...providedItem, + }; + } + + // + item = { + ...item, + disabled: this.uiDisabled, + }; + + // + actionBarItems.push(item); + } + //#endregion + + // + this.actionBarActions = [...actionBarItems]; + this.detectChanges(); + } + private async handleChartUpdate() { // if ( @@ -261,6 +1016,10 @@ export class XChartComponent extends XChartContainerComponent { this.CHART_OPTIONS = { ...options, ...this.CHART_OPTIONS, + chart: { + ...this.CHART_OPTIONS.chart, + type: type as any, + }, }; // diff --git a/projects/x-framework-components/src/lib/x-chart/x-chart.module.ts b/projects/x-framework-components/src/lib/x-chart/x-chart.module.ts index c63a6af..9286d3e 100644 --- a/projects/x-framework-components/src/lib/x-chart/x-chart.module.ts +++ b/projects/x-framework-components/src/lib/x-chart/x-chart.module.ts @@ -3,6 +3,7 @@ import { CommonModule } from '@angular/common'; import { XCardModule } from '../x-card/x-card.module'; import { XIconModule } from '../x-icon/x-icon.module'; import { XChartComponent } from './x-chart.component'; +import { XActionBarModule } from 'x-framework-components'; import { XSlotterModule } from '../x-slotter/x-slotter.module'; import { XBaseComponentModule } from '../modules/x-base-component.module'; @@ -15,6 +16,7 @@ import { XBaseComponentModule } from '../modules/x-base-component.module'; XIconModule, CommonModule, XSlotterModule, + XActionBarModule, XBaseComponentModule, ], exports: [ @@ -23,6 +25,7 @@ import { XBaseComponentModule } from '../modules/x-base-component.module'; CommonModule, XSlotterModule, XChartComponent, + XActionBarModule, XBaseComponentModule, ], }) diff --git a/projects/x-framework-components/src/lib/x-chart/x-chart.typings.ts b/projects/x-framework-components/src/lib/x-chart/x-chart.typings.ts index 377b216..66c7c0a 100644 --- a/projects/x-framework-components/src/lib/x-chart/x-chart.typings.ts +++ b/projects/x-framework-components/src/lib/x-chart/x-chart.typings.ts @@ -16,6 +16,7 @@ import { XOneOrManyType, XColorIdentifier, XResourceIdentifier, + XColorWithBrightness, } from 'x-framework-core'; import { XCardActionModel, @@ -30,6 +31,18 @@ import { XManagerService } from 'x-framework-services'; import { XBaseActionModel } from '../classes/x-base-action.model'; import { X_FRAMEWORK_COMPONENTS_CONFIG } from '../tokens/x-injectable-tokens'; import { XFrameworkComponentsConfig } from '../config/x-framework-components.config'; +import { + IXComponentActionBarContainer, + XActionBarActionFiredModel, + XActionBarActionModel, + XActionBarItem, + XComponentActionBarContainer, +} from '../x-action-bar/x-action-bar.typings'; +import { XPopoverPresentOptions } from '../dialogs/x-popover/x-popover.typings'; +import { + XBaseContainer, + XBaseContainerComponent, +} from '../classes/i-x-base.container'; // //#region Chart ... @@ -3216,7 +3229,67 @@ export type XChartActionIdentifier = XChartAction | string; export interface XChartActionModel extends XBaseActionModel {} export type XChartSeriesType = XChartAxisChartSeries | XChartNonAxisChartSeries; -export interface IXChartContainer extends IXComponentCardContainer { + +export enum XChartActionBarItem { + // TODO: Implement this ... + + // + //#region Exports ... + ExportAsPNG = 'export_as_png', + ExportAsSVG = 'export_as_svg', + ExportAsCSV = 'export_as_csv', + Print = 'print_chart', + //#endregion + + // + //#region Zoom ... + ZoomIn = 'zoom_in', + ZoomOut = 'zoom_out', + ZoomSelection = 'zoom_selection', + //#endregion + + // + //#region Selection ... + XSelection = 'x-axis-selection', + YSelection = 'y-axis-selection', + XYSelection = 'xy-axis-selection', + //#endregion + + // + Pan = 'pan', + ResetChart = 'reset_chart', + ToggleFullScreen = 'toggle_fullscreen_chart', +} + +export type XChartActionBarItemIdentifier = XChartActionBarItem | string; + +export function isChartActionBar(value: string) { + return isValueInEnum(value, Object.assign({}, XChartActionBarItem)); +} + +export type XChartActionBarItemDescriptor = Partial< + Pick< + XActionBarItem, + | 'slot' + | 'icon' + | 'title' + | 'color' + | 'onlyIcon' + | 'iconColor' + | 'titleColor' + > +>; + +export interface XChartAvailableActionBarItem { + itemsColor?: XColorIdentifier; + actionId: XChartActionBarItemIdentifier; + descriptor?: XChartActionBarItemDescriptor; + popoverPresentOptions?: XPopoverPresentOptions; +} + +type TXChartContainer = IXComponentCardContainer & + IXComponentActionBarContainer; +export interface IXChartContainer extends TXChartContainer { // // Commons ... actionProvider: Subject; @@ -3231,6 +3304,14 @@ export interface IXChartContainer extends IXComponentCardContainer { // type: XStandardType; + // + //#region ActionBar ... + defaultActionBarItemColor: XStandardType; + availableActionBarItems: XStandardType< + XOneOrManyType + >; + //#endregion + // // Events ... chartRendered: EventEmitter; @@ -3242,7 +3323,7 @@ export interface IXChartContainer extends IXComponentCardContainer { providedIn: 'root', }) export class XChartContainer - extends XComponentCardContainer + extends XBaseContainer implements Readonly { // @@ -3253,16 +3334,75 @@ export class XChartContainer readonly actionProvider = new Subject(); readonly type: XStandardType = XChartType.Line; + // + readonly availableActionBarItems: XStandardType< + XOneOrManyType + > = []; + readonly defaultActionBarItemColor: XStandardType = + XColorWithBrightness.Dark; + // readonly zoomed = new EventEmitter(); readonly chartRendered = new EventEmitter(); readonly dataPointSelected = new EventEmitter(); + + // + //#region ComponentActionBar Props ... + readonly showActionBar: XStandardType = + this.actionBarPropertyProvider.showActionBar; + readonly actionBarActionProvider: Subject = + this.actionBarPropertyProvider.actionBarActionProvider; + readonly actionBarCssClass: XStandardType> = + this.actionBarPropertyProvider.actionBarCssClass; + readonly actionBarColor: XStandardType = + this.actionBarPropertyProvider.actionBarColor; + readonly actionBarForegroundColor: XStandardType = + this.actionBarPropertyProvider.actionBarForegroundColor; + readonly actionBarActions: XStandardType> = + this.actionBarPropertyProvider.actionBarActions; + readonly actionBarActionFired: EventEmitter = + this.actionBarPropertyProvider.actionBarActionFired; + //#endregion + + // + //#region ComponentCard Props ... + readonly isInPage: XStandardType = + this.cardPropertyProvider.isInPage; + readonly wrapWithCard: XStandardType = + this.cardPropertyProvider.wrapWithCard; + readonly cardActionProvider: Subject = + this.cardPropertyProvider.cardActionProvider; + readonly cardCssClass: XStandardType> = + this.cardPropertyProvider.cardCssClass; + readonly cardColor: XStandardType = + this.cardPropertyProvider.cardColor; + readonly cardForegroundColor: XStandardType = + this.cardPropertyProvider.cardForegroundColor; + readonly cardTitle: XStandardType = + this.cardPropertyProvider.cardTitle; + readonly cardSubTitle: XStandardType = + this.cardPropertyProvider.cardSubTitle; + readonly cardShowFooter: XStandardType = + this.cardPropertyProvider.cardShowFooter; + readonly cardShowActions: XStandardType = + this.cardPropertyProvider.cardShowActions; + //#endregion + + // + //#region Constructor ... + constructor( + protected cardPropertyProvider: XComponentCardContainer, + protected actionBarPropertyProvider: XComponentActionBarContainer, + ) { + super(); + } + //#endregion } @Injectable() @Component({ template: `` }) export abstract class XChartContainerComponent - extends XComponentCardContainerComponent + extends XBaseContainerComponent implements IXChartContainer { // @@ -3290,6 +3430,15 @@ export abstract class XChartContainerComponent @Input() autoUpdate: XStandardType = this.propertyProvider.autoUpdate; + @Input() + defaultActionBarItemColor: XStandardType = + this.propertyProvider.defaultActionBarItemColor; + + @Input() + availableActionBarItems: XStandardType< + XOneOrManyType + > = this.propertyProvider.availableActionBarItems; + // // Events ... @Output() @@ -3339,6 +3488,35 @@ export abstract class XChartContainerComponent cardActionProvider: Subject = this.propertyProvider.cardActionProvider; //#endregion + + // + //#region ComponentActionBar Props ... + @Input() + showActionBar: XStandardType = this.propertyProvider.showActionBar; + + @Input() + actionBarCssClass: XStandardType> = + this.propertyProvider.actionBarCssClass; + + @Input() + actionBarColor: XStandardType = + this.propertyProvider.actionBarColor; + + @Input() + actionBarForegroundColor: XStandardType = + this.propertyProvider.actionBarForegroundColor; + + @Input() + actionBarActionProvider: Subject = + this.propertyProvider.actionBarActionProvider; + + @Output() + actionBarActionFired: EventEmitter = + this.propertyProvider.actionBarActionFired; + + actionBarActions: XStandardType> = + this.propertyProvider.actionBarActions; + //#endregion //#endregion // @@ -3362,7 +3540,6 @@ export abstract class XChartContainerComponent ruler, zone, changeDetector, - propertyProvider, ); } //#endregionّ @@ -3372,47 +3549,103 @@ export abstract class XChartContainerComponent public extractProps( container?: IXChartContainer, ): Observable { - return super - .extractProps(container ? container : this) - .pipe( - concatMap((superData) => { - return forkJoin({ - // - cssClass: this.getArrayValue( - container ? container.cssClass : this.cssClass, - ), + // + return forkJoin({ + // + cssClass: this.getArrayValue( + container ? container.cssClass : this.cssClass, + ), - // - type: this.getValue(container ? container.type : this.type), - options: this.getValue( - container ? container.options : this.options, - ), - series: this.getValue(container ? container.series : this.series), - autoUpdate: this.getValue( - container ? container.autoUpdate : this.autoUpdate, - ), - }).pipe( - map((data) => { - return { - superData, - data, - }; - }), - ); - }), - ) - .pipe( - map((info) => ({ - ...info.data, - ...info.superData, - actionProvider: container - ? container.actionProvider - : this.actionProvider, - chartRendered: this.chartRendered, - dataPointSelected: this.dataPointSelected, - zoomed: this.zoomed, - })), - ); + // + type: this.getValue(container ? container.type : this.type), + options: this.getValue(container ? container.options : this.options), + series: this.getValue(container ? container.series : this.series), + autoUpdate: this.getValue( + container ? container.autoUpdate : this.autoUpdate, + ), + + // + // ActionBar ... + defaultActionBarItemColor: this.getValue( + container + ? container.defaultActionBarItemColor + : this.defaultActionBarItemColor, + ), + availableActionBarItems: this.getArrayValue( + container + ? container.availableActionBarItems + : this.availableActionBarItems, + ), + + // + //#region XComponentCard ... + cardCssClass: this.getArrayValue( + container ? container.cardCssClass : this.cardCssClass, + ), + isInPage: this.getValue(container ? container.isInPage : this.isInPage), + wrapWithCard: this.getValue( + container ? container.wrapWithCard : this.wrapWithCard, + ), + cardShowFooter: this.getValue( + container ? container.cardShowFooter : this.cardShowFooter, + ), + cardShowActions: this.getValue( + container ? container.cardShowActions : this.cardShowActions, + ), + cardColor: this.getValue( + container ? container.cardColor : this.cardColor, + ), + cardForegroundColor: this.getValue( + container ? container.cardForegroundColor : this.cardForegroundColor, + ), + cardTitle: this.getValue( + container ? container.cardTitle : this.cardTitle, + ), + cardSubTitle: this.getValue( + container ? container.cardSubTitle : this.cardSubTitle, + ), + //#endregion + + // + //#region XComponentActionBar ... + showActionBar: this.getValue( + container ? container.showActionBar : this.showActionBar, + ), + actionBarCssClass: this.getValue( + container ? container.actionBarCssClass : this.actionBarCssClass, + ), + actionBarColor: this.getValue( + container ? container.actionBarColor : this.actionBarColor, + ), + actionBarForegroundColor: this.getValue( + container + ? container.actionBarForegroundColor + : this.actionBarForegroundColor, + ), + actionBarActions: this.getValue( + container ? container.actionBarActions : this.actionBarActions, + ), + //#endregion + }).pipe( + map((info) => ({ + ...info, + // + actionProvider: container + ? container.actionProvider + : this.actionProvider, + cardActionProvider: container + ? container.cardActionProvider + : this.cardActionProvider, + actionBarActionProvider: container + ? container.actionBarActionProvider + : this.actionBarActionProvider, + // + zoomed: this.zoomed, + chartRendered: this.chartRendered, + dataPointSelected: this.dataPointSelected, + actionBarActionFired: this.actionBarActionFired, + })), + ); } //#endregion }