From 76dc91fb4b412fe1fbd096d488378a5918b4fc03 Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Mon, 31 Aug 2026 16:31:31 +0330 Subject: [PATCH] last works on x-chart components, adding separated features ... --- .../src/lib/x-chart/x-chart.component.ts | 680 +++++++++++++++++- .../src/lib/x-chart/x-chart.typings.ts | 426 ++++++----- 2 files changed, 906 insertions(+), 200 deletions(-) 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 b7665d9..9e53af0 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 @@ -6,31 +6,43 @@ import { } from '@angular/core'; import { nameof, + toArray, XMimeType, downloadFile, generateUuid, getXColorValue, + XOneOrManyType, + XColorIdentifier, downloadFileByUrl, isNullOrUndefined, + XResourceIdentifier, isNullOrEmptyString, XColorWithBrightness, downloadArrayBufferedFile, } from 'x-framework-core'; import { isChartType, + XChartXAxis, + XChartYAxis, XChartAction, + XChartTooltip, XChartOptions, XChartEventOpts, XChartTextAlign, XChartSeriesType, isChartTextAlign, + XChartAnnotations, XChartActionBarItem, XChartDrilldownEvent, + XChartAnnotationLabel, + XChartAnnotationStyle, + XChartMarkerAnnotations, + XChartTooltipAnnotations, XChartContainerComponent, XChartStoryboardBeatInfo, } from './x-chart.typings'; import ApexCharts from 'apexcharts'; -import { Subject, Subscription } from 'rxjs'; +import { Subscription } from 'rxjs'; import { XActionBarItem, XActionBarItemSlot, @@ -189,6 +201,58 @@ export class XChartComponent extends XChartContainerComponent { zoomStep = await this.getValueAsync(this.zoomStep); } + // + // Toolbar ... + isChanged = changeKeys.includes(nameof('tooltip')); + if (isChanged) { + // + if (isNullOrUndefined(this.tooltip)) { + this.tooltip = this.propertyProvider.tooltip; + } + + // + await this.handleChartUpdate(); + } + + // + // XAxis ... + isChanged = changeKeys.includes(nameof('xAxis')); + if (isChanged) { + // + if (isNullOrUndefined(this.xAxis)) { + this.xAxis = this.propertyProvider.xAxis; + } + + // + await this.handleChartUpdate(); + } + + // + // YAxis ... + isChanged = changeKeys.includes(nameof('yAxis')); + if (isChanged) { + // + if (isNullOrUndefined(this.yAxis)) { + this.yAxis = this.propertyProvider.yAxis; + } + + // + await this.handleChartUpdate(); + } + + // + // Annotations ... + isChanged = changeKeys.includes(nameof('annotations')); + if (isChanged) { + // + if (isNullOrUndefined(this.annotations)) { + this.annotations = this.propertyProvider.annotations; + } + + // + await this.handleChartUpdate(); + } + // // Chart Title ... isChanged = changeKeys.includes(nameof('title')); @@ -692,7 +756,7 @@ export class XChartComponent extends XChartContainerComponent { printWindow.document.close(); } } - } catch (error) {} + } catch (error) { } } async handleToggleFullscreen() { @@ -724,8 +788,18 @@ export class XChartComponent extends XChartContainerComponent { 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 xAxis = await this.getPreparedXAxis(cOptions?.xaxis); + const yAxis = await this.getPreparedYAxis(cOptions?.yaxis); + + // + const tooltip = await this.getPreparedTooltip(); + const annotations = await this.getPreparedAnnotations(); + // const title = await this.getResourceValueAsync(this.title); const titleAlignProp = await this.getValueAsync(this.titleAlign); @@ -798,7 +872,15 @@ export class XChartComponent extends XChartContainerComponent { // this.CHART_OPTIONS = { ...cOptions, - series: series || cOptions.series, + series: + { + ...cOptions?.series, + ...series as any + }, + annotations: { + ...cOptions?.annotations, + ...annotations + }, title: { ...cOptions.title, text: title, @@ -1371,10 +1453,19 @@ export class XChartComponent extends XChartContainerComponent { palette: cOptions.theme?.palette || 'palette1', }, colors: cOptions.colors || [primaryColorValue], + xaxis: { + ...xAxis + }, + yaxis: [ + ...yAxis + ], grid: { ...cOptions.grid, borderColor: gridColorValue, }, + tooltip: { + ...tooltip + }, dataLabels: { ...cOptions.dataLabels, }, @@ -2100,15 +2191,14 @@ export class XChartComponent extends XChartContainerComponent { // const offset = 24; - height = `${ - window.innerHeight - + height = `${window.innerHeight - offset - (actionBarHeight + (cardImageElement?.clientHeight || 0) + (cardHeaderElement?.clientHeight || 0) + (cardActionsElement?.clientHeight || 0) + (cardFooterElement?.clientHeight || 0)) - }px`; + }px`; } // @@ -2238,5 +2328,583 @@ export class XChartComponent extends XChartContainerComponent { this.CARD_ACTION_PROVIDER_SUBSCRIPTION.unsubscribe(); this.CARD_ACTION_PROVIDER_SUBSCRIPTION = null; } + + // + //#region Preparers ... + private async getPreparedTooltip() { + // + let result: XChartTooltip = undefined; + + // + if (!isNullOrUndefined(this.tooltip)) { + // + result = await this.getValueAsync(this.tooltip); + + // + result = await this.normalizeChartTooltip(result); + } + + // + return result;; + } + + private async getPreparedXAxis(v?: XChartXAxis) { + // + let result: XChartXAxis = undefined; + + // + if (!isNullOrUndefined(this.xAxis)) { + // + result = { + ...(await this.getValueAsync(this.xAxis)) + }; + } + + // + if (!isNullOrUndefined(v)) { + // + result = { + ...v, + ...result + }; + } + + // + if (!isNullOrUndefined(result)) { + // + result = { + ...result, + } + + // + if (!isNullOrUndefined(result.labels)) { + // + result.labels = { + ...result.labels, + } + + // + if (!isNullOrUndefined(result.labels.style)) { + // + result.labels.style = { + ...result.labels.style, + colors: toArray(result.labels.style.colors).map(c => this.normalizeColor(c)) + } + } + } + + // + if (!isNullOrUndefined(result.group)) { + // + result.group = { + ...result.group + } + + // + if (!isNullOrUndefined(result.group.style)) { + // + result.group.style = { + ...result.group.style, + colors: toArray(result.group.style.colors).map(x => this.normalizeColor(x)) + } + } + } + + // + if (!isNullOrUndefined(result.axisBorder)) { + // + result.axisBorder = { + ...result.axisBorder, + color: this.normalizeColor(result.axisBorder.color) + } + } + + // + if (!isNullOrUndefined(result.axisTicks)) { + // + result.axisTicks = { + ...result.axisTicks, + color: this.normalizeColor(result.axisTicks.color) + } + } + + // + if (!isNullOrUndefined(result.title)) { + // + result.title = { + ...result.title, + text: (await this.normalizeText(result.title.text) as string) + } + + // + if (!isNullOrUndefined(result.title.style)) { + // + result.title.style = { + ...result.title.style, + color: this.normalizeColor(result.title.style.color) + } + } + } + + // + if (!isNullOrUndefined(result.crosshairs)) { + // + result.crosshairs = { + ...result.crosshairs + } + + // + if (!isNullOrUndefined(result.crosshairs.stroke)) { + // + result.crosshairs.stroke = { + ...result.crosshairs.stroke, + color: this.normalizeColor(result.crosshairs.stroke.color) + } + } + + // + if (!isNullOrUndefined(result.crosshairs.fill)) { + // + result.crosshairs.fill = { + ...result.crosshairs.fill, + color: this.normalizeColor(result.crosshairs.fill.color) + } + + // + if (!isNullOrUndefined(result.crosshairs.fill.gradient)) { + // + result.crosshairs.fill.gradient = { + ...result.crosshairs.fill.gradient, + colorTo: this.normalizeColor(result.crosshairs.fill.gradient.colorTo), + colorFrom: this.normalizeColor(result.crosshairs.fill.gradient.colorFrom), + } + } + } + } + } + + // + return result; + } + + private async getPreparedYAxis(v?: XOneOrManyType) { + // + let result: XChartYAxis[] = undefined; + + // + if (!isNullOrUndefined(v)) { + // + result = [ + ...toArray(v) + ]; + } + + // + if (!isNullOrUndefined(this.yAxis)) { + // + result = [ + ...(this.hasChild(result) ? result : []), + ...await this.getArrayValueAsync(this.yAxis) + ]; + + // + const mappers = result.map(async x => { + // + if (!isNullOrUndefined(x.labels)) { + // + x.labels = { + ...x.labels + }; + + // + if (!isNullOrUndefined(x.labels.style)) { + // + x.labels.style = { + ...x.labels.style, + colors: toArray(x.labels.style.colors).map(c => this.normalizeColor(c)) + } + } + } + + // + if (!isNullOrUndefined(x.axisBorder)) { + // + x.axisBorder = { + ...x.axisBorder, + color: this.normalizeColor(x.axisBorder.color) + } + } + + // + if (!isNullOrUndefined(x.axisTicks)) { + // + x.axisTicks = { + ...x.axisTicks, + color: this.normalizeColor(x.axisTicks.color) + } + } + + // + if (!isNullOrUndefined(x.title)) { + // + x.title = { + ...x.title, + text: (await this.normalizeText(x.title.text) as string) + } + + // + if (!isNullOrUndefined(x.title.style)) { + // + x.title.style = { + ...x.title.style, + color: this.normalizeColor(x.title.style.color) + } + } + } + + // + if (!isNullOrUndefined(x.crosshairs)) { + // + x.crosshairs = { + ...x.crosshairs, + } + + // + if (!isNullOrUndefined(x.crosshairs.stroke)) { + // + x.crosshairs.stroke = { + ...x.crosshairs.stroke, + color: this.normalizeColor(x.crosshairs.stroke.color) + } + } + } + + // + return x; + }); + + // + const items = await Promise.all(mappers); + + // + result = [ + ...result, + ...items + ]; + } + + // + return result; + } + + private async getPreparedAnnotations() { + // + let result: XChartAnnotations = undefined; + + // + if (!isNullOrUndefined(this.annotations)) { + // + result = await this.getValueAsync(this.annotations); + + // + // Try to Normalize Colors and Resources ... + + // + // Texts ... + if (this.hasChild(result.texts)) { + // + const mappers = result.texts.map(async x => { + // + // Normalizing Text ... + x.text = (await this.normalizeText(x.text)) as string; + + // + // Normalizing Colors ... + x.foreColor = this.normalizeColor(x.foreColor); + x.borderColor = this.normalizeColor(x.borderColor); + x.backgroundColor = this.normalizeColor(x.backgroundColor); + + // + return x; + }); + const items = await Promise.all(mappers); + result.texts = [ + ...items + ]; + } + + // + // Y Axis ... + if (this.hasChild(result.yaxis)) { + // + const mappers = result.yaxis.map(async x => { + // + // Normalizing Text ... + x.label = await this.normalizeLabel(x.label); + + // + // Normalizing Colors ... + x.fillColor = this.normalizeColor(x.fillColor); + x.borderColor = this.normalizeColor(x.borderColor); + + // + return x; + }); + const items = await Promise.all(mappers); + result.yaxis = [ + ...items + ]; + } + + // + // X Axis ... + if (this.hasChild(result.xaxis)) { + // + const mappers = result.xaxis.map(async x => { + // + // Normalizing Text ... + x.label = await this.normalizeLabel(x.label); + + // + // Normalizing Colors ... + x.fillColor = this.normalizeColor(x.fillColor); + x.borderColor = this.normalizeColor(x.borderColor); + + // + return x; + }); + const items = await Promise.all(mappers); + result.yaxis = [ + ...items + ]; + } + + // + // Points ... + if (this.hasChild(result.points)) { + // + const mappers = result.points.map(async x => { + // + x.marker = this.normalizeMarker(x.marker); + x.label = await this.normalizeLabel(x.label); + x.tooltip = await this.normalizeTooltip(x.tooltip); + + // + return x; + }); + const items = await Promise.all(mappers); + result.points = [ + ...items + ]; + } + + // + // Images ... + if (this.hasChild(result.images)) { + // + result.images = [ + ...result.images + ]; + } + } + + // + return result; + } + //#endregion + + // + //#region Normalizers ... + private async normalizeText( + v: XOneOrManyType, + forceLocale: boolean = false + ) { + // + let result: XOneOrManyType = undefined; + + // + if (!isNullOrUndefined(v)) { + // + let items = toArray(v); + if (this.hasChild(items)) { + // + const mappers = items.map(async x => { + // + let r: string = await this.getResourceValueAsync(x); + + // + if (forceLocale && !isNullOrEmptyString(r)) { + r = this.applyLocale(r); + } + + // + return r; + }); + + // + var results = await Promise.all(mappers); + + // + if (this.hasChild(results)) { + // + if (results.length == 1) { + result = results[0]; + } else { + result = [ + ...results + ]; + } + } + } + } + + // + return result; + } + + private normalizeColor(v: XColorIdentifier) { + // + let result = ''; + + // + if (!isNullOrUndefined(v)) { + // + const titleColorValue = getXColorValue(v); + + // + result = titleColorValue || v; + } + + // + return result; + } + + private normalizeMarker(v: XChartMarkerAnnotations) { + // + let result: XChartMarkerAnnotations = undefined; + + // + if (!isNullOrUndefined(v)) { + // + result = { + ...v, + fillColor: this.normalizeColor(v.fillColor), + strokeColor: this.normalizeColor(v.strokeColor), + } + } + + // + return result; + } + + private async normalizeStyle(v: XChartAnnotationStyle) { + // + let result: XChartAnnotationStyle = undefined; + + // + if (!isNullOrUndefined(v)) { + // + result = { + ...v, + + // + color: this.normalizeColor(v.color), + background: this.normalizeColor(v.background), + }; + } + + // + return result; + } + + private async normalizeLabel(v: XChartAnnotationLabel) { + // + let result: XChartAnnotationLabel = undefined; + + // + if (!isNullOrUndefined(v)) { + // + result = { + ...v, + + // + text: await this.normalizeText(v.text), + + // + style: await this.normalizeStyle(v.style), + + // + borderColor: this.normalizeColor(v.borderColor), + }; + } + + // + return result; + } + + private async normalizeTooltip(v: XChartTooltipAnnotations) { + // + let result: XChartTooltipAnnotations = undefined; + + // + if (!isNullOrUndefined(v)) { + // + result = { + ...v, + // + text: await this.normalizeText(v.text), + } + } + + // + return result; + } + + private async normalizeChartTooltip(v: XChartTooltip) { + // + let result: XChartTooltip = undefined; + + // + if (!isNullOrUndefined(v)) { + // + result = { + ...v, + }; + + // + // Style ... + if (!isNullOrUndefined(v.style)) { + // + result.style = { + ...v.style, + background: this.normalizeColor(v.style.background) + }; + } + + // + // Z ... + if (!isNullOrUndefined(v.z)) { + // + result.z = { + ...v.z, + title: (await this.normalizeText(v.z.title) as string) + } + } + + // + // Marker ... + if (!isNullOrUndefined(v.marker)) { + // + result.marker = { + ...v.marker, + fillColors: v.marker.fillColors?.map(fc => this.normalizeColor(fc)) + } + } + } + + // + return result; + } + //#endregion //#endregion } 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 0de2cb9..b844c5e 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 @@ -101,6 +101,41 @@ export type XChartXAxisAnnotations = XCahrtAxisBaseAnnotations & { x2?: null | number | string; }; +export type XChartMarkerAnnotations = { + size?: number; + fillColor?: string; + strokeColor?: string; + strokeWidth?: number; + shape?: string; + offsetX?: number; + offsetY?: number; + cssClass?: string; +}; + +export type XChartTooltipAnnotations = { + enabled?: boolean; + /** + * Static tooltip content (HTML allowed; an array is joined with line + * breaks). Falls back to `label.text` when omitted. + */ + text?: string | string[]; + /** + * Returns the tooltip markup (HTML). Takes precedence over `text`. + */ + formatter?: (opts: { + annotation: XChartPointAnnotations; + seriesIndex?: number; + id?: number | string; + w: any; + }) => string; + /** + * Tooltip theme. Falls back to the global `tooltip.theme`. + */ + theme?: 'light' | 'dark'; + offsetX?: number; + offsetY?: number; +}; + export type XChartPointAnnotations = { id?: number | string; x?: number | string; @@ -115,16 +150,7 @@ export type XChartPointAnnotations = { mouseEnter?: (annotation: XChartPointAnnotations, e: MouseEvent) => void; mouseLeave?: (annotation: XChartPointAnnotations, e: MouseEvent) => void; click?: (annotation: XChartPointAnnotations, e: MouseEvent) => void; - marker?: { - size?: number; - fillColor?: string; - strokeColor?: string; - strokeWidth?: number; - shape?: string; - offsetX?: number; - offsetY?: number; - cssClass?: string; - }; + marker?: XChartMarkerAnnotations; label?: XChartAnnotationLabel; image?: { path?: string; @@ -137,29 +163,7 @@ export type XChartPointAnnotations = { * Show a hover tooltip over the annotation marker, like a regular data * point. Useful for surfacing more detail than fits in the label. */ - tooltip?: { - enabled?: boolean; - /** - * Static tooltip content (HTML allowed; an array is joined with line - * breaks). Falls back to `label.text` when omitted. - */ - text?: string | string[]; - /** - * Returns the tooltip markup (HTML). Takes precedence over `text`. - */ - formatter?: (opts: { - annotation: XChartPointAnnotations; - seriesIndex?: number; - id?: number | string; - w: any; - }) => string; - /** - * Tooltip theme. Falls back to the global `tooltip.theme`. - */ - theme?: 'light' | 'dark'; - offsetX?: number; - offsetY?: number; - }; + tooltip?: XChartTooltipAnnotations; /** * Render arbitrary SVG markup at the annotation's position. Deprecated in * favor of `image`/`marker`, but still supported. @@ -370,71 +374,71 @@ export type XChartAxisChartSeries = { zIndex?: number; parsing?: XChartParsing; data: - | (number | null)[] - | { - /** - * A category label, a timestamp, or a `Date`. On a `datetime` axis all - * three keep millisecond resolution. - */ - x: string | number | Date; - /** - * A plain value for most charts. For `candlestick`/`boxPlot`, the - * summary array (`[O,H,L,C]` / `[min,Q1,median,Q3,max]`). For `violin`, an - * object carrying the precomputed density profile (`[value, weight]` pairs) - * plus the raw observations rendered as jitter. For a `scatter` strip plot - * (`plotOptions.scatter.jitter`), the array of observations in this category. - */ - y: - | number - | null - | number[] - | { density: [number, number][]; points?: number[] }; - /** - * Optional raw observations for a `boxPlot` data point, rendered as jitter - * dots when `plotOptions.boxPlot.points.show` is enabled. - */ - points?: number[]; - fill?: XChartFill; - fillColor?: string; - strokeColor?: string; - meta?: unknown; - /** - * A second metric that drives this point's COLOUR, independent of `y` - * which drives its size (`treemap`). See - * `plotOptions.treemap.colorScale.colorValue` to read a different key. - */ - colorValue?: number; - /** - * Nested hierarchy: this point is a branch containing these children, - * to any depth (`treemap`, `sunburst`). A branch normally omits `y` and - * takes the sum of its children instead. - */ - children?: XChartHierarchyNode[]; - /** - * Drilldown target: the `id` of a `drilldown.series` entry. Clicking this - * point drills into that level. Requires the Drilldown feature. - */ - drilldown?: string | number; - goals?: { - name?: string; - value: number; - strokeHeight?: number; - strokeWidth?: number; - strokeColor?: string; - strokeDashArray?: number; - strokeLineCap?: 'butt' | 'square' | 'round'; - }[]; - barHeightOffset?: number; - columnWidthOffset?: number; - }[] - | [number, number | null][] - | [number, (number | null)[]][] - | number[][] - // A `children` hierarchy for the partition charts, where a branch carries no - // value of its own. Listed before the catch-all so authors get completion on - // the node shape instead of falling through to `Record`. - | XChartHierarchyNode[] - | Record[]; + | (number | null)[] + | { + /** + * A category label, a timestamp, or a `Date`. On a `datetime` axis all + * three keep millisecond resolution. + */ + x: string | number | Date; + /** + * A plain value for most charts. For `candlestick`/`boxPlot`, the + * summary array (`[O,H,L,C]` / `[min,Q1,median,Q3,max]`). For `violin`, an + * object carrying the precomputed density profile (`[value, weight]` pairs) + * plus the raw observations rendered as jitter. For a `scatter` strip plot + * (`plotOptions.scatter.jitter`), the array of observations in this category. + */ + y: + | number + | null + | number[] + | { density: [number, number][]; points?: number[] }; + /** + * Optional raw observations for a `boxPlot` data point, rendered as jitter + * dots when `plotOptions.boxPlot.points.show` is enabled. + */ + points?: number[]; + fill?: XChartFill; + fillColor?: string; + strokeColor?: string; + meta?: unknown; + /** + * A second metric that drives this point's COLOUR, independent of `y` + * which drives its size (`treemap`). See + * `plotOptions.treemap.colorScale.colorValue` to read a different key. + */ + colorValue?: number; + /** + * Nested hierarchy: this point is a branch containing these children, + * to any depth (`treemap`, `sunburst`). A branch normally omits `y` and + * takes the sum of its children instead. + */ + children?: XChartHierarchyNode[]; + /** + * Drilldown target: the `id` of a `drilldown.series` entry. Clicking this + * point drills into that level. Requires the Drilldown feature. + */ + drilldown?: string | number; + goals?: { + name?: string; + value: number; + strokeHeight?: number; + strokeWidth?: number; + strokeColor?: string; + strokeDashArray?: number; + strokeLineCap?: 'butt' | 'square' | 'round'; + }[]; + barHeightOffset?: number; + columnWidthOffset?: number; + }[] + | [number, number | null][] + | [number, (number | null)[]][] + | number[][] + // A `children` hierarchy for the partition charts, where a branch carries no + // value of its own. Listed before the catch-all so authors get completion on + // the node shape instead of falling through to `Record`. + | XChartHierarchyNode[] + | Record[]; }[]; export type XChartNonAxisChartSeries = number[] | XChartAxisChartSeries; @@ -931,11 +935,11 @@ export type XChartPlotOptions = { * property, or an accessor to compute one. */ colorValue?: - | string - | (( - datum: any, - opts: { seriesIndex: number; dataPointIndex: number; w: any }, - ) => number); + | string + | (( + datum: any, + opts: { seriesIndex: number; dataPointIndex: number; w: any }, + ) => number); /** * Continuous interpolation between colour stops, for the metric above. * Active as soon as any datum carries a colour metric; `enabled: false` @@ -1068,13 +1072,13 @@ export type XChartPlotOptions = { * 'custom': positions come from `positions`. */ layout?: - | 'grouped' - | 'packed' - | 'columns' - | 'grid' - | 'scatter' - | 'arc' - | 'custom'; + | 'grouped' + | 'packed' + | 'columns' + | 'grid' + | 'scatter' + | 'arc' + | 'custom'; /** * `layout: 'custom'` only. The layout provider: either a function returning * plot-pixel positions, or the name of one registered with @@ -2102,19 +2106,19 @@ export interface XChartDrilldown { /** Inline child levels referenced by data-point `drilldown` ids. */ series?: XChartDrilldownSeries[]; breadcrumb?: - | false - | { - show?: boolean; - position?: 'top-left' | 'top-right'; - separator?: string; - rootLabel?: string; - offsetX?: number; - offsetY?: number; - formatter?( - label: string, - opts: { index: number; depth: number }, - ): string; - }; + | false + | { + show?: boolean; + position?: 'top-left' | 'top-right'; + separator?: string; + rootLabel?: string; + offsetX?: number; + offsetY?: number; + formatter?( + label: string, + opts: { index: number; depth: number }, + ): string; + }; animation?: { enabled?: boolean; /** @@ -2163,11 +2167,11 @@ export interface XChartDrilldown { * name, so the default ships no user-visible English. */ loading?: - | false - | { - show?: boolean; - text?: string; - }; + | false + | { + show?: boolean; + text?: string; + }; /** * Cache levels resolved by `onDrillDown`, keyed by id, so drilling back down * a branch does not re-fetch. Default true. Clear it with the drilldown @@ -2273,12 +2277,12 @@ export type XChartStates = { export type XChartStroke = { show?: boolean; curve?: - | 'smooth' - | 'straight' - | 'stepline' - | 'linestep' - | 'monotoneCubic' - | ('smooth' | 'straight' | 'stepline' | 'linestep' | 'monotoneCubic')[]; + | 'smooth' + | 'straight' + | 'stepline' + | 'linestep' + | 'monotoneCubic' + | ('smooth' | 'straight' | 'stepline' | 'linestep' | 'monotoneCubic')[]; lineCap?: 'butt' | 'square' | 'round'; colors?: string[]; width?: number | number[]; @@ -2329,11 +2333,11 @@ export type XChartTheme = { }; accessibility?: { colorBlindMode?: - | 'deuteranopia' - | 'protanopia' - | 'tritanopia' - | 'highContrast' - | ''; + | 'deuteranopia' + | 'protanopia' + | 'tritanopia' + | 'highContrast' + | ''; }; }; @@ -2362,14 +2366,14 @@ export type XChartTooltip = { inverseOrder?: boolean; arrow?: boolean; custom?: - | (( - opts: XChartTooltipCustomOpts, - ) => string | number | Element | { nodeName: string }) - | Array< - ( - opts: XChartTooltipCustomOpts, - ) => string | number | Element | { nodeName: string } - >; + | (( + opts: XChartTooltipCustomOpts, + ) => string | number | Element | { nodeName: string }) + | Array< + ( + opts: XChartTooltipCustomOpts, + ) => string | number | Element | { nodeName: string } + >; fillSeriesColor?: boolean; theme?: 'light' | 'dark'; cssClass?: string; @@ -2446,30 +2450,30 @@ export type XChart = { width?: string | number; height?: string | number; type?: - | 'line' - | 'area' - | 'bar' - | 'pie' - | 'donut' - | 'radialBar' - | 'scatter' - | 'bubble' - | 'heatmap' - | 'candlestick' - | 'boxPlot' - | 'violin' - | 'histogram' - | 'radar' - | 'polarArea' - | 'rangeBar' - | 'rangeArea' - | 'treemap' - | 'unit' - | 'waffle' - | 'sunburst' - | 'funnel' - | 'pyramid' - | 'gauge'; + | 'line' + | 'area' + | 'bar' + | 'pie' + | 'donut' + | 'radialBar' + | 'scatter' + | 'bubble' + | 'heatmap' + | 'candlestick' + | 'boxPlot' + | 'violin' + | 'histogram' + | 'radar' + | 'polarArea' + | 'rangeBar' + | 'rangeArea' + | 'treemap' + | 'unit' + | 'waffle' + | 'sunburst' + | 'funnel' + | 'pyramid' + | 'gauge'; /** * Internal — populated when `type` is a first-class alias (`'funnel'`, * `'pyramid'`, `'gauge'`, `'waffle'`, `'histogram'`). The original requested @@ -2752,9 +2756,9 @@ export type XChart = { dimension?: (row: any) => any; /** FILTER mode: reduction over a bucket's rows. @default 'count' */ reduce?: - | 'count' - | { sum?: string; avg?: string; min?: string; max?: string } - | ((rows: any[]) => number); + | 'count' + | { sum?: string; avg?: string; min?: string; max?: string } + | ((rows: any[]) => number); /** * FILTER mode: bucket kind. Else inferred: `bins` present => 'range', a * heatmap chart => 'matrix' (2D), otherwise 'category'. @@ -2872,21 +2876,21 @@ export type XChart = { | 'yline' | 'measure' | { - id?: string; - label?: string; - icon?: string; - onClick?: ( - chart: ApexCharts, - context: { - x: any; - y: any; - seriesIndex: number | null; - dataPointIndex: number | null; - clientX: number; - clientY: number; - }, - ) => void; - } + id?: string; + label?: string; + icon?: string; + onClick?: ( + chart: ApexCharts, + context: { + x: any; + y: any; + seriesIndex: number | null; + dataPointIndex: number | null; + clientX: number; + clientY: number; + }, + ) => void; + } >; /** Override the built-in item labels. */ labels?: { @@ -3225,7 +3229,7 @@ export enum XChartAction { export type XChartActionIdentifier = XChartAction | string; -export interface XChartActionModel extends XBaseActionModel {} +export interface XChartActionModel extends XBaseActionModel { } export type XChartSeriesType = XChartAxisChartSeries | XChartNonAxisChartSeries; @@ -3323,6 +3327,14 @@ export interface IXChartContainer extends TXChartContainer { series: XStandardType; type: XStandardType; + // + xAxis: XStandardType; + yAxis: XStandardType>; + + // + tooltip: XStandardType; + annotations: XStandardType; + // title: XStandardType; titleAlign: XStandardType; @@ -3460,8 +3472,7 @@ export interface IXChartContainer extends TXChartContainer { }) export class XChartContainer extends XBaseContainer - implements Readonly -{ + implements Readonly { // readonly actionProvider = new Subject(); readonly cssClass: XStandardType>; @@ -3473,6 +3484,14 @@ export class XChartContainer readonly series: XStandardType; readonly type: XStandardType = XChartType.Line; + // + readonly xAxis: XStandardType; + readonly yAxis: XStandardType>; + + // + readonly tooltip: XStandardType; + readonly annotations: XStandardType; + // readonly title: XStandardType; readonly titleAlign: XStandardType = @@ -3671,8 +3690,7 @@ export class XChartContainer @Component({ template: `` }) export abstract class XChartContainerComponent extends XBaseContainerComponent - implements IXChartContainer -{ + implements IXChartContainer { // //#region Props ... @Input() @@ -3698,6 +3716,18 @@ export abstract class XChartContainerComponent @Input() zoomStep: XStandardType = this.propertyProvider.zoomStep; + @Input() + xAxis: XStandardType = this.propertyProvider.xAxis; + + @Input() + yAxis: XStandardType> = this.propertyProvider.yAxis; + + @Input() + tooltip: XStandardType = this.propertyProvider.tooltip; + + @Input() + annotations: XStandardType = this.propertyProvider.annotations; + @Input() defaultActionBarItemColor: XStandardType = this.propertyProvider.defaultActionBarItemColor; @@ -4034,6 +4064,14 @@ export abstract class XChartContainerComponent series: this.getValue(container ? container.series : this.series), zoomStep: this.getValue(container ? container.zoomStep : this.zoomStep), + // + xAxis: this.getValue(container ? container.xAxis : this.xAxis), + yAxis: this.getValue(container ? container.yAxis : this.yAxis), + + // + tooltip: this.getValue(container ? container.tooltip : this.tooltip), + annotations: this.getValue(container ? container.annotations : this.annotations), + // title: this.getValue(container ? container.title : this.title), titleAlign: this.getValue(