import { Component, ViewChild, ElementRef, HostListener, ChangeDetectionStrategy, } from '@angular/core'; import { nameof, XMimeType, downloadFile, generateUuid, getXColorValue, downloadFileByUrl, isNullOrUndefined, isNullOrEmptyString, XColorWithBrightness, downloadArrayBufferedFile, } from 'x-framework-core'; import { isChartType, XChartAction, XChartOptions, XChartEventOpts, XChartTextAlign, XChartSeriesType, isChartTextAlign, XChartActionBarItem, XChartDrilldownEvent, XChartContainerComponent, XChartStoryboardBeatInfo, } from './x-chart.typings'; import { fromEvent, Subject, Subscription } from 'rxjs'; import ApexCharts from 'apexcharts'; import { XActionBarItem, XActionBarItemSlot, XActionBarActionFiredModel, } from '../x-action-bar/x-action-bar.typings'; import { XIconNames } from '../x-icon/x-icon.typings'; import { XCardAction } from '../x-card/x-card.typings'; import { debounceTime, takeUntil } from 'rxjs/operators'; import { XCardComponent } from '../x-card/x-card.component'; @Component({ selector: 'x-chart', templateUrl: './x-chart.component.html', styleUrls: ['./x-chart.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, }) export class XChartComponent extends XChartContainerComponent { // //#region Props ... // private CHART_CONTAINER: ElementRef = undefined; @ViewChild('chartContainer', { static: false }) set chartContainer(el: ElementRef) { // if (isNullOrUndefined(el)) { // this.destroyComponent(); return; } // this.CHART_CONTAINER = el; this.initializeComponent(); } get chartContainer() { return this.CHART_CONTAINER; } // private CHART_CARD: ElementRef = undefined; @ViewChild('chartCard', { static: false }) set chartCard(el: ElementRef) { this.CHART_CARD = el; } get chartCard() { return this.CHART_CARD;; } // private RESIZE_SUBJECT = new Subject(); // private CHART_OPTIONS: XChartOptions = null; // private chartInstance: ApexCharts = null; // private ACTION_PROVIDER_SUBSCRIPTION: Subscription; // readonly IconNames = Object.assign({}, XIconNames); readonly ActionBarItems = Object.assign({}, XChartActionBarItem); readonly ActionBarItemSlots = Object.assign({}, XActionBarItemSlot); //#endregion // //#region LifeCycles ... async afterViewInit() { super.afterViewInit(); // await this.initializeComponent(); this.registerResizeHandler(); } async onChange(changeKeys: string[]) { super.onChange(changeKeys); // let isChanged = false; // // Action Provider Changed ... isChanged = changeKeys.includes(nameof('actionProvider')); if (isChanged) { // if (isNullOrUndefined(this.actionProvider)) { this.actionProvider = this.propertyProvider.actionProvider; } // this.registerActionProvider(); } // // Available Action Bar Items Changed ... isChanged = changeKeys.includes( nameof('availableActionBarItems'), ); if (isChanged) { // if (isNullOrUndefined(this.availableActionBarItems)) { this.availableActionBarItems = this.propertyProvider.availableActionBarItems; } // await this.prepareActionBar(); } // // Zoom Step ... isChanged = changeKeys.includes(nameof('zoomStep')); if (isChanged) { // let zoomStep = await this.getValueAsync(this.zoomStep); if (isNullOrUndefined(zoomStep) || zoomStep < 0 || zoomStep > 1) { this.zoomStep = 0.125; } // zoomStep = await this.getValueAsync(this.zoomStep); } // // Chart Title ... isChanged = changeKeys.includes(nameof('title')); if (isChanged) { // if (isNullOrUndefined(this.title)) { this.title = this.propertyProvider.title; } // this.handleChartUpdate(); } // // Chart Title Align ... isChanged = changeKeys.includes(nameof('titleAlign')); if (isChanged) { // const align = await this.getValueAsync(this.titleAlign); if ( isNullOrUndefined(this.titleAlign) || isNullOrEmptyString(align) || !isChartTextAlign(align) ) { this.titleAlign = this.propertyProvider.titleAlign; } // this.handleChartUpdate(); } // // Chart SubTitle ... isChanged = changeKeys.includes(nameof('subTitle')); if (isChanged) { // if (isNullOrUndefined(this.subTitle)) { this.subTitle = this.propertyProvider.subTitle; } // this.handleChartUpdate(); } // // Chart Sub Title Align ... isChanged = changeKeys.includes(nameof('subTitleAlign')); if (isChanged) { // const align = await this.getValueAsync(this.subTitleAlign); if ( isNullOrUndefined(this.subTitleAlign) || isNullOrEmptyString(align) || !isChartTextAlign(align) ) { this.subTitleAlign = this.propertyProvider.subTitleAlign; } // this.handleChartUpdate(); } // // Foreground Color Changed ... isChanged = changeKeys.includes(nameof('foregroundColor')); if (isChanged) { // if (isNullOrUndefined(this.foregroundColor)) { this.foregroundColor = this.propertyProvider.foregroundColor; } // await this.handleChartUpdate(); } // // Background Color Changed ... isChanged = changeKeys.includes(nameof('backgroundColor')); if (isChanged) { // if (isNullOrUndefined(this.backgroundColor)) { this.backgroundColor = this.propertyProvider.backgroundColor; } // await this.handleChartUpdate(); } // // Grid Color Changed ... isChanged = changeKeys.includes(nameof('gridColor')); if (isChanged) { // if (isNullOrUndefined(this.gridColor)) { this.gridColor = this.propertyProvider.gridColor; } // await this.handleChartUpdate(); } // // Chart Title Color ... isChanged = changeKeys.includes(nameof('titleColor')); if (isChanged) { // if (isNullOrUndefined(this.titleColor)) { this.titleColor = this.propertyProvider.titleColor; } // this.handleChartUpdate(); } // // Chart SubTitle Color ... isChanged = changeKeys.includes(nameof('subTitleColor')); if (isChanged) { // if (isNullOrUndefined(this.subTitleColor)) { this.subTitleColor = this.propertyProvider.subTitleColor; } // this.handleChartUpdate(); } // // Options Changed ... isChanged = changeKeys.includes(nameof('options')); if (isChanged) { // if (isNullOrUndefined(this.options)) { this.options = this.propertyProvider.options; } // await this.handleChartUpdate(); } // // Chart Type ... isChanged = changeKeys.includes(nameof('type')); if (isChanged) { // if (isNullOrUndefined(this.type)) { this.type = this.propertyProvider.type; } // var type = await this.getValueAsync(this.type); if (!isChartType(type)) { // type = await this.getValueAsync(this.propertyProvider.type); this.type = type; } // await this.handleChartUpdate(); } // // Series Changed ... isChanged = changeKeys.includes(nameof('series')); if (isChanged) { // if (isNullOrUndefined(this.series)) { this.series = this.propertyProvider.series; } // await this.handleChartUpdate(); } // this.detectChanges(); } onDestroy() { super.onDestroy(); // this.RESIZE_SUBJECT.next(); this.RESIZE_SUBJECT.complete(); // this.destroyComponent(); this.unregisterActionProvider(); } //#endregion // //#region UI Handler ... async handleActionBarActionFired(model: XActionBarActionFiredModel) { // if (isNullOrUndefined(model) || isNullOrEmptyString(model.action)) { return; } // switch (model.action) { // // Print ... case XChartActionBarItem.Print: await this.handlePrint(); break; // // Export As CSV ... case XChartActionBarItem.ExportAsCSV: await this.handleExportAsCSV(); break; // // Export As PNG ... case XChartActionBarItem.ExportAsPNG: await this.handleExportAsPng(); break; // // Export As SVG ... case XChartActionBarItem.ExportAsSVG: await this.handleExportAsSVG(); break; // // Zoom In ... case XChartActionBarItem.ZoomIn: await this.handleZoomIn(); break; // // Zoom Out ... case XChartActionBarItem.ZoomOut: await this.handleZoomOut(); break; // // Zoom Selection ... case XChartActionBarItem.ZoomSelection: break; // // X Selection ... case XChartActionBarItem.XSelection: break; // // Y Selection ... case XChartActionBarItem.YSelection: break; // // XY Selection ... case XChartActionBarItem.XYSelection: break; // // Pan ... case XChartActionBarItem.Pan: await this.handlePan(); break; // // ResetChart ... case XChartActionBarItem.ResetChart: await this.handleResetChart(); break; // // ToggleFullScreen ... case XChartActionBarItem.ToggleFullScreen: await this.handleToggleFullscreen(); 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 Toolbar Actions ... async handleExportAsPng() { // if (isNullOrUndefined(this.chartInstance)) { return; } // await this.export('png'); } async handleExportAsSVG() { // if (isNullOrUndefined(this.chartInstance)) { return; } // await this.export('svg'); } async handleExportAsCSV() { // if (isNullOrUndefined(this.chartInstance)) { return; } // await this.export('csv'); } async handleZoomIn() { // if (isNullOrUndefined(this.chartInstance)) { return; } // var zoomStep = await this.getValueAsync(this.zoomStep); // const state = this.chartInstance.getState(); const minX = state.minX; const maxX = state.maxX; const rangeIn = maxX - minX; // await this.chartInstance.zoomX( minX + rangeIn * zoomStep, maxX - rangeIn * zoomStep, ); } async handleZoomOut() { // if (isNullOrUndefined(this.chartInstance)) { return; } // var zoomStep = await this.getValueAsync(this.zoomStep); // const state = this.chartInstance.getState(); const minX = state.minX; const maxX = state.maxX; const rangeIn = maxX - minX; // await this.chartInstance.zoomX( minX - rangeIn * zoomStep, maxX + rangeIn * zoomStep, ); } async handlePan() { // if (isNullOrUndefined(this.chartInstance)) { return; } // await this.chartInstance.updateOptions({ chart: { zoom: { enabled: false, }, selection: { type: 'x', enabled: true, }, }, }); } async handleResetChart() { // if (isNullOrUndefined(this.chartInstance)) { return; } // this.chartInstance.resetSeries(true, true); } async handlePrint() { // if (isNullOrUndefined(this.chartInstance)) { return; } // try { // const result = await this.chartInstance.dataURI(); if ('imgURI' in result) { // const imgURI = result.imgURI; const printWindow = window.open('', '_blank'); if (printWindow) { // // Write Data Uri on a Page for Printing ... printWindow.document.write(` Print Chart Chart `); // printWindow.document.close(); } } } catch (error) { } } async handleToggleFullscreen() { // if ( isNullOrUndefined(this.chartInstance) || isNullOrUndefined(this.chartContainer) || isNullOrUndefined(this.chartContainer.nativeElement) ) { return; } // // Handle Fullscreen Toggle using Card ... this.cardActionProvider.next({ action: XCardAction.ToggleFullScreen }); } //#endregion // //#region Private ... private async initializeComponent() { // if (isNullOrUndefined(this.CHART_CONTAINER)) { return; } // // Reading Requirement Properties ... const type = await this.getValueAsync(this.type); const chartId = await this.getValueAsync(this.uuid); const series = await this.getValueAsync(this.series); const cOptions = await this.getValueAsync(this.options); // const title = await this.getResourceValueAsync(this.title); const titleAlignProp = await this.getValueAsync(this.titleAlign); let titleAlign: 'left' | 'center' | 'right' = 'center'; // const subTitle = await this.getResourceValueAsync(this.subTitle); const subTitleAlignProp = await this.getValueAsync(this.subTitleAlign); let subTitleAlign: 'left' | 'center' | 'right' = 'center'; // const gridColorName = await this.getValueAsync(this.gridColor); const gridColorValue = getXColorValue(gridColorName); // const titleColorName = await this.getValueAsync(this.titleColor); const titleColorValue = getXColorValue(titleColorName); // const subTitleColorName = await this.getValueAsync(this.subTitleColor); const subTitleColorValue = getXColorValue(subTitleColorName); // const foregroundColorName = await this.getValueAsync(this.foregroundColor); const foregroundColorValue = getXColorValue(foregroundColorName); // const backgroundColorName = await this.getValueAsync(this.backgroundColor); const backgroundColorValue = getXColorValue(backgroundColorName); // const primaryColorValue = getXColorValue(XColorWithBrightness.Primary); // // Normalize Directional Properties .... if (this.managerService.uiDirection == 'ltr') { // titleAlign = titleAlignProp == XChartTextAlign.Start ? 'left' : titleAlignProp == XChartTextAlign.End ? 'right' : 'center'; // subTitleAlign = subTitleAlignProp == XChartTextAlign.Start ? 'left' : subTitleAlignProp == XChartTextAlign.End ? 'right' : 'center'; } else if (this.managerService.uiDirection == 'rtl') { // titleAlign = titleAlignProp == XChartTextAlign.Start ? 'right' : titleAlignProp == XChartTextAlign.End ? 'left' : 'center'; // subTitleAlign = subTitleAlignProp == XChartTextAlign.Start ? 'right' : subTitleAlignProp == XChartTextAlign.End ? 'left' : 'center'; } // this.CHART_OPTIONS = { ...cOptions, series: series || cOptions.series, title: { ...cOptions.title, text: title, align: titleAlign, style: { ...cOptions.title?.style, color: titleColorValue, }, }, subtitle: { ...cOptions.subtitle, text: subTitle, align: subTitleAlign, style: { ...cOptions.subtitle?.style, color: subTitleColorValue, }, }, chart: { ...cOptions.chart, id: chartId, type: type as any, foreColor: foregroundColorValue, background: backgroundColorValue, toolbar: { show: false, autoSelected: 'pan', }, events: { ...cOptions.chart?.events, // //#region Attach Events ... // animationEnd: (chart: ApexCharts, options?: XChartEventOpts) => { // if (!this.loading && !this.uiDisabled) { this.animationEnd.emit(options); } // cOptions.chart?.events?.animationEnd?.(chart, options); }, // beforeMount: (chart: ApexCharts, options?: XChartEventOpts) => { // if (!this.loading && !this.uiDisabled) { this.beforeMount.emit(options); } // cOptions.chart?.events?.beforeMount?.(chart, options); }, // mounted: (chart: ApexCharts, options?: XChartEventOpts) => { // if (!this.loading && !this.uiDisabled) { this.mounted.emit(options); } // cOptions.chart?.events?.mounted?.(chart, options); }, // updated: (chart: ApexCharts, options?: XChartEventOpts) => { // if (!this.loading && !this.uiDisabled) { this.updated.emit(options); } // cOptions.chart?.events?.updated?.(chart, options); }, // mouseMove: ( e: MouseEvent, chart?: ApexCharts, options?: XChartEventOpts, ) => { // if (!this.loading && !this.uiDisabled) { this.mouseMove.emit({ e: e, options: options }); } // cOptions.chart?.events?.mouseMove?.(e, chart, options); }, // mouseLeave: ( e: MouseEvent, chart?: ApexCharts, options?: XChartEventOpts, ) => { // if (!this.loading && !this.uiDisabled) { this.mouseLeave.emit({ e: e, options: options }); } // cOptions.chart?.events?.mouseLeave?.(e, chart, options); }, // click: ( e: MouseEvent, chart?: ApexCharts, options?: XChartEventOpts, ) => { // if (!this.loading && !this.uiDisabled) { this.click.emit({ e: e, options: options }); } // cOptions.chart?.events?.click?.(e, chart, options); }, // xAxisLabelClick: ( e: MouseEvent, chart?: ApexCharts, options?: XChartEventOpts, ) => { // if (!this.loading && !this.uiDisabled) { this.xAxisLabelClick.emit({ e: e, options: options }); } // cOptions.chart?.events?.xAxisLabelClick?.(e, chart, options); }, // legendClick: ( chart: ApexCharts, seriesIndex?: number, options?: XChartEventOpts, ) => { // if (!this.loading && !this.uiDisabled) { this.legendClick.emit({ seriesIndex: seriesIndex, options: options, }); } // cOptions.chart?.events?.legendClick?.(chart, seriesIndex, options); }, // markerClick: ( e: MouseEvent, chart?: ApexCharts, options?: XChartEventOpts, ) => { // if (!this.loading && !this.uiDisabled) { this.markerClick.emit({ e: e, options: options }); } // cOptions.chart?.events?.markerClick?.(e, chart, options); }, // selection: ( chart: ApexCharts, options?: { xaxis?: { min: number; max: number }; yaxis?: { min: number; max: number }; }, ) => { // if (!this.loading && !this.uiDisabled) { this.selection.emit(options); } // cOptions.chart?.events?.selection?.(chart, options); }, // dataPointSelection: ( e: MouseEvent, chart?: ApexCharts, options?: XChartEventOpts, ) => { // if (!this.loading && !this.uiDisabled) { this.dataPointSelection.emit({ e: e, options: options }); } // cOptions.chart?.events?.dataPointSelection?.(e, chart, options); }, // dataPointMouseEnter: ( e: MouseEvent, chart?: ApexCharts, options?: XChartEventOpts, ) => { // if (!this.loading && !this.uiDisabled) { this.dataPointMouseEnter.emit({ e: e, options: options }); } // cOptions.chart?.events?.dataPointMouseEnter?.(e, chart, options); }, // dataPointMouseLeave: ( e: MouseEvent, chart?: ApexCharts, options?: XChartEventOpts, ) => { // if (!this.loading && !this.uiDisabled) { this.dataPointMouseLeave.emit({ e: e, options: options }); } // cOptions.chart?.events?.dataPointMouseLeave?.(e, chart, options); }, // beforeZoom: ( chart: ApexCharts, options?: { xaxis: { min: number; max: number } }, ) => { // if (!this.loading && !this.uiDisabled) { this.beforeZoom.emit(options); } // cOptions.chart?.events?.beforeZoom?.(chart, options); }, // beforeResetZoom: (chart: ApexCharts, options?: XChartEventOpts) => { // if (!this.loading && !this.uiDisabled) { this.beforeResetZoom.emit(options); } // cOptions.chart?.events?.beforeResetZoom?.(chart, options); }, // zoomed: ( chart: ApexCharts, options?: { xaxis: { min: number; max: number }; yaxis?: { min: number; max: number }[]; }, ) => { // if (!this.loading && !this.uiDisabled) { this.zoomed.emit(options); } // cOptions.chart?.events?.zoomed?.(chart, options); }, // scrolled: ( chart: ApexCharts, options?: { xaxis: { min: number; max: number } }, ) => { // if (!this.loading && !this.uiDisabled) { this.scrolled.emit(options); } // cOptions.chart?.events?.scrolled?.(chart, options); }, // brushScrolled: ( chart: ApexCharts, options?: { xaxis: { min: number; max: number }; yaxis?: { min: number; max: number }[]; }, ) => { // if (!this.loading && !this.uiDisabled) { this.brushScrolled.emit(options); } // cOptions.chart?.events?.brushScrolled?.(chart, options); }, // crossFilter: ( chart: ApexCharts, options?: { xaxis: { min: number; max: number }; sourceChartID?: string; }, ) => { // if (!this.loading && !this.uiDisabled) { this.crossFilter.emit(options); } // cOptions.chart?.events?.crossFilter?.(chart, options); }, // filterChange: ( chart: ApexCharts, options?: { filters: Record; filteredCount: number; total: number; sourceChartID?: string; key?: any; }, ) => { // if (!this.loading && !this.uiDisabled) { this.filterChange.emit(options); } // cOptions.chart?.events?.filterChange?.(chart, options); }, // annotationDragged: ( chart: ApexCharts, options?: { type?: 'point' | 'xaxis' | 'yaxis'; id?: string; index: number; x: any; y: any; x2?: any; y2?: any; }, ) => { // if (!this.loading && !this.uiDisabled) { this.annotationDragged.emit(options); } // cOptions.chart?.events?.annotationDragged?.(chart, options); }, // annotationEdited: ( chart: ApexCharts, options?: { type?: 'point' | 'xaxis' | 'yaxis'; id?: string; index: number; text: string; }, ) => { // if (!this.loading && !this.uiDisabled) { this.annotationEdited.emit(options); } // cOptions.chart?.events?.annotationEdited?.(chart, options); }, // annotationCreated: ( chart: ApexCharts, options?: { type?: 'point' | 'xaxis' | 'yaxis'; id?: string; index: number; x?: any; y?: any; }, ) => { // if (!this.loading && !this.uiDisabled) { this.annotationCreated.emit(options); } // cOptions.chart?.events?.annotationCreated?.(chart, options); }, // annotationStyled: ( chart: ApexCharts, options?: { type?: 'point' | 'xaxis' | 'yaxis'; id?: string; index: number; label?: any; marker?: any; }, ) => { // if (!this.loading && !this.uiDisabled) { this.annotationStyled.emit(options); } // cOptions.chart?.events?.annotationStyled?.(chart, options); }, // annotationDeleted: ( chart: ApexCharts, options?: { type?: 'point' | 'xaxis' | 'yaxis'; id?: string; index: number; }, ) => { // if (!this.loading && !this.uiDisabled) { this.annotationDeleted.emit(options); } // cOptions.chart?.events?.annotationDeleted?.(chart, options); }, // measured: ( chart: ApexCharts, options?: { from: { x: any; y: any }; to: { x: any; y: any }; dx: number; dy: number; percentChange: number; slope: number; }, ) => { // if (!this.loading && !this.uiDisabled) { this.measured.emit(options); } // cOptions.chart?.events?.measured?.(chart, options); }, // beatChange: ( chart: ApexCharts, options?: XChartStoryboardBeatInfo, ) => { // if (!this.loading && !this.uiDisabled) { this.beatChange.emit(options); } // cOptions.chart?.events?.beatChange?.(chart, options); }, // keyDown: ( e: KeyboardEvent, chart?: ApexCharts, options?: XChartEventOpts, ) => { // if (!this.loading && !this.uiDisabled) { this.keyDown.emit({ e: e, options: options }); } // cOptions.chart?.events?.keyDown?.(e, chart, options); }, // keyUp: ( e: KeyboardEvent, chart?: ApexCharts, options?: XChartEventOpts, ) => { // if (!this.loading && !this.uiDisabled) { this.keyUp.emit({ e: e, options: options }); } // cOptions.chart?.events?.keyUp?.(e, chart, options); }, // drillDownStart: ( info: XChartDrilldownEvent, chart?: ApexCharts, options?: XChartEventOpts, ) => { // if (!this.loading && !this.uiDisabled) { this.drillDownStart.emit({ info: info, options: options }); } // cOptions.chart?.events?.drillDownStart?.(info, chart, options); }, // drillDownEnd: ( info: XChartDrilldownEvent, chart?: ApexCharts, options?: XChartEventOpts, ) => { // if (!this.loading && !this.uiDisabled) { this.drillDownEnd.emit({ info: info, options: options }); } // cOptions.chart?.events?.drillDownEnd?.(info, chart, options); }, // drillUp: ( info: XChartDrilldownEvent, chart?: ApexCharts, options?: XChartEventOpts, ) => { // if (!this.loading && !this.uiDisabled) { this.drillUp.emit({ info: info, options: options }); } // cOptions.chart?.events?.drillUp?.(info, chart, options); }, // drillDownError: ( info: { id: string | number | null; error: any }, chart?: ApexCharts, options?: XChartEventOpts, ) => { // if (!this.loading && !this.uiDisabled) { this.drillDownError.emit({ info: info, options: options }); } // cOptions.chart?.events?.drillDownError?.(info, chart, options); }, //#endregion }, }, theme: { ...cOptions.theme, palette: cOptions.theme?.palette || 'palette1', }, colors: cOptions.colors || [primaryColorValue], grid: { ...cOptions.grid, borderColor: gridColorValue, }, dataLabels: { ...cOptions.dataLabels, }, }; // this.chartInstance = new ApexCharts( this.chartContainer.nativeElement, this.CHART_OPTIONS, ); // await this.prepareActionBar(); // await this.chartInstance.render(); } private async prepareActionBar() { // if (isNullOrUndefined(this.chartInstance)) { return; } // const showActionBar = await this.getValueAsync(this.showActionBar); if (!showActionBar) { return; } // //#region DefaultActionBarActions ... // // Reset ... 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, }; // // Print ... 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, }; // // Export As PNG ... const defaultExportPNGItem: XActionBarItem = { onlyIcon: true, icon: this.IconNames.png, disabled: this.uiDisabled, slot: this.ActionBarItemSlots.END, title: this.ResourceIDs.export_png, id: this.ActionBarItems.ExportAsPNG, iconColor: this.defaultActionBarItemColor, }; // // Export as SVG ... const defaultExportSVGItem: XActionBarItem = { onlyIcon: true, icon: this.IconNames.image, disabled: this.uiDisabled, slot: this.ActionBarItemSlots.END, title: this.ResourceIDs.export_svg, id: this.ActionBarItems.ExportAsSVG, iconColor: this.defaultActionBarItemColor, }; // // Export as CSV ... const defaultExportCSVItem: XActionBarItem = { onlyIcon: true, icon: this.IconNames.csv, disabled: this.uiDisabled, slot: this.ActionBarItemSlots.END, title: this.ResourceIDs.export_csv, id: this.ActionBarItems.ExportAsCSV, iconColor: this.defaultActionBarItemColor, }; // // Zoom In ... const defaultZoomInItem: XActionBarItem = { onlyIcon: true, disabled: this.uiDisabled, icon: this.IconNames.zoom_in, id: this.ActionBarItems.ZoomIn, title: this.ResourceIDs.zoom_in, slot: this.ActionBarItemSlots.START, iconColor: this.defaultActionBarItemColor, }; // // Zoom Out ... const defaultZoomOutItem: XActionBarItem = { onlyIcon: true, disabled: this.uiDisabled, icon: this.IconNames.zoom_out, id: this.ActionBarItems.ZoomOut, title: this.ResourceIDs.zoom_out, slot: this.ActionBarItemSlots.START, iconColor: this.defaultActionBarItemColor, }; // // Zoom Selection ... const defaultZoomSelectionItem: XActionBarItem = { onlyIcon: true, disabled: this.uiDisabled, slot: this.ActionBarItemSlots.START, icon: this.IconNames.range_selection, id: this.ActionBarItems.ZoomSelection, title: this.ResourceIDs.zoom_selection, iconColor: this.defaultActionBarItemColor, }; // // X Axis Selection ... const defaultXAxisSelectionItem: XActionBarItem = { onlyIcon: true, disabled: this.uiDisabled, icon: this.IconNames.x_axis, title: this.ResourceIDs.x_axis, id: this.ActionBarItems.XSelection, slot: this.ActionBarItemSlots.START, iconColor: this.defaultActionBarItemColor, }; // // Y Axis Selection ... 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, }; // // XY Axis Selection ... 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, }; // // Pan ... 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, }; // // Toggle Full Screen ... 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 ( isNullOrUndefined(this.chartInstance) || isNullOrUndefined(this.CHART_OPTIONS) || isNullOrUndefined(this.chartContainer) || isNullOrUndefined(this.chartContainer.nativeElement) ) { return; } // // Reading Requirement Properties ... const type = await this.getValueAsync(this.type); const series = await this.getValueAsync(this.series); // const options = await this.getValueAsync(this.options); this.CHART_OPTIONS = { ...options, ...this.CHART_OPTIONS, chart: { ...this.CHART_OPTIONS.chart, type: type as any, }, }; // await this.chartInstance.updateOptions(this.CHART_OPTIONS); await this.chartInstance.updateSeries(series); } private destroyComponent() { // if (isNullOrUndefined(this.chartInstance)) { return; } // this.chartInstance.destroy(); this.chartInstance = null; } private registerResizeHandler() { // fromEvent(window, 'resize') .pipe( debounceTime(200), takeUntil(this.RESIZE_SUBJECT) ) .subscribe(() => { // if (isNullOrUndefined(this.chartInstance) || isNullOrUndefined(this.chartCard) || isNullOrUndefined(this.chartCard.nativeElement) || !this.chartCard.nativeElement.isFullscreen) { return; } // var height = this.chartCard.nativeElement.calculateContentSize(); // // Reading Height ... this.CHART_OPTIONS = { ...this.CHART_OPTIONS, chart: { height: `${height}px` } }; // // TODO: // Only Apply when Full Screen Mode ... // Add FullScreen Event Handler in XCard Component ... console.log('chart resize: ', height); // this.chartInstance.updateOptions(this.CHART_OPTIONS, false, false); }); } private registerActionProvider() { // this.unregisterActionProvider(); // if (!this.actionProvider) { this.actionProvider = this.propertyProvider.actionProvider; } // this.ACTION_PROVIDER_SUBSCRIPTION = this.actionProvider .asObservable() .subscribe(async (model) => { // switch (model.action) { // case XChartAction.Refresh: this.detectChanges(); break; // case XChartAction.Destroy: this.onDestroy(); break; // case XChartAction.UpdateSeries: // if ( !isNullOrUndefined(model.payload) || !isNullOrUndefined(this.chartInstance) ) { // this.series = await this.getValueAsync( model.payload as XChartSeriesType, ); await this.chartInstance.updateSeries(this.series); this.detectChanges(); } break; // case XChartAction.UpdateOptions: // if ( !isNullOrUndefined(model.payload) || !isNullOrUndefined(this.chartInstance) ) { // this.options = await this.getValueAsync( model.payload as XChartOptions, ); await this.chartInstance.updateOptions(this.options); this.detectChanges(); } break; } }); } private unregisterActionProvider() { // if (!this.ACTION_PROVIDER_SUBSCRIPTION) { return; } // this.ACTION_PROVIDER_SUBSCRIPTION.unsubscribe(); this.ACTION_PROVIDER_SUBSCRIPTION = null; } //#endregion }