From ba6d84c40bebe4b16cb2381420de506654d7d61d Mon Sep 17 00:00:00 2001 From: Maksym Tsymbarov Date: Wed, 3 Dec 2025 17:32:21 +0200 Subject: [PATCH] fixed latest limit type display --- .../chart/bar-chart-basic-config.component.ts | 32 +-- .../latest-chart-basic-config.component.html | 132 ++++------ ...polar-area-chart-basic-config.component.ts | 32 +-- .../lib/chart/bar-chart-widget.models.ts | 5 +- .../widget/lib/chart/bars-chart.models.ts | 5 +- .../components/widget/lib/chart/bars-chart.ts | 225 +----------------- .../widget/lib/chart/latest-chart.ts | 1 + .../lib/chart/time-series-chart.models.ts | 12 +- .../widget/lib/chart/time-series-chart.ts | 133 +++++------ .../bar-chart-widget-settings.component.ts | 30 --- ...atest-chart-widget-settings.component.html | 94 +++----- .../latest-chart-widget-settings.component.ts | 10 - ...ar-area-chart-widget-settings.component.ts | 22 +- .../common/axis-scale-row.component.html | 4 +- .../common/axis-scale-row.component.ts | 129 +++++----- ...ime-series-chart-y-axes-panel.component.ts | 104 +++++++- 16 files changed, 328 insertions(+), 642 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/bar-chart-basic-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/bar-chart-basic-config.component.ts index a58ddd8302..4c7da10bc6 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/bar-chart-basic-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/bar-chart-basic-config.component.ts @@ -29,8 +29,6 @@ import { import { LatestChartBasicConfigComponent } from '@home/components/widget/config/basic/chart/latest-chart-basic-config.component'; -import { AxisLimitConfig } from '@home/components/widget/lib/chart/time-series-chart.models'; -import { ValueSourceType } from '@shared/models/widget-settings.models'; @Component({ selector: 'tb-bar-chart-basic-config', @@ -43,7 +41,7 @@ export class BarChartBasicConfigComponent extends LatestChartBasicConfigComponen barChartConfigTemplate: TemplateRef; predefinedValues = widgetTitleAutocompleteValues; - + constructor(protected store: Store, protected widgetConfigComponent: WidgetConfigComponent, protected fb: UntypedFormBuilder) { @@ -81,32 +79,4 @@ export class BarChartBasicConfigComponent extends LatestChartBasicConfigComponen this.widgetConfig.config.settings.axisTickLabelFont = config.axisTickLabelFont; this.widgetConfig.config.settings.axisTickLabelColor = config.axisTickLabelColor; } - - protected onConfigSet(configData: WidgetConfigComponentData) { - configData.config.settings.axisMin = this.normalizeAxisLimit(configData.config.settings.axisMin); - configData.config.settings.axisMax = this.normalizeAxisLimit(configData.config.settings.axisMax); - super.onConfigSet(configData); - } - - private normalizeAxisLimit(limit: any): AxisLimitConfig { - if (limit && typeof limit === 'object' && 'type' in limit) { - return { - type: limit.type || ValueSourceType.constant, - value: limit.value ?? null, - entityAlias: limit.entityAlias ?? null - }; - } - if (typeof limit === 'number') { - return { - type: ValueSourceType.constant, - value: limit, - entityAlias: null - }; - } - return { - type: ValueSourceType.constant, - value: null, - entityAlias: null - }; - } } diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/latest-chart-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/latest-chart-basic-config.component.html index 27c173bd17..d72a8d6083 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/latest-chart-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/latest-chart-basic-config.component.html @@ -21,27 +21,27 @@ formControlName="timewindowConfig"> + [configMode]="basicMode" + hideDatasourceLabel + hideDataKeys + forceSingleDatasource + formControlName="datasources"> + panelTitle="{{ 'widgets.chart.series' | translate }}" + addKeyTitle="{{ 'widgets.chart.add-series' | translate }}" + keySettingsTitle="{{ 'widgets.chart.series-settings' | translate }}" + removeKeyTitle="{{ 'widgets.chart.remove-series' | translate }}" + noKeysText="{{ 'widgets.chart.no-series' | translate }}" + requiredKeysText="{{ 'widgets.chart.no-series-error' | translate }}" + hideUnits + hideDecimals + hideDataKeyUnits + hideDataKeyDecimals + [datasourceType]="datasource?.type" + [deviceId]="datasource?.deviceId" + [entityAliasId]="datasource?.entityAliasId" + formControlName="series">
widget-config.appearance
@@ -210,7 +210,7 @@
+ formControlName="animation">
widget-config.card-appearance
@@ -239,7 +239,7 @@
+ formControlName="actions"> @@ -346,15 +346,25 @@
widgets.bar-chart.bar-appearance
+ formControlName="barSettings" + [series]="false">
widgets.bar-chart.bar-axis
-
widgets.chart.chart-axis.scale-appearance
+
widgets.chart.chart-axis.scale
+
widgets.chart.chart-axis.scale-min
+ + + +
widgets.chart.chart-axis.scale-max
+ + +
-
-
widgets.chart.chart-axis.scale-limits
-
-
-
widgets.chart.chart-axis.limit
-
widgets.chart.chart-axis.source
-
widgets.chart.chart-axis.key-value
-
-
- - - - - -
-
-
@@ -402,16 +385,26 @@
widgets.bar-chart.bar-appearance
+ formControlName="barSettings" + pieLabelPosition + [series]="false">
widgets.polar-area-chart.polar-axis
-
widgets.chart.chart-axis.scale-appearance
+
widgets.chart.chart-axis.scale
+
widgets.chart.chart-axis.scale-min
+ + + +
widgets.chart.chart-axis.scale-max
+ + +
-
-
widgets.chart.chart-axis.scale-limits
-
-
-
widgets.chart.chart-axis.limit
-
widgets.chart.chart-axis.source
-
widgets.chart.chart-axis.key-value
-
-
- - - - - -
-
-
@@ -542,7 +508,7 @@
+ formControlName="fillAreaSettings">
diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/polar-area-chart-basic-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/polar-area-chart-basic-config.component.ts index d29af73b75..f60f8d2417 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/polar-area-chart-basic-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/polar-area-chart-basic-config.component.ts @@ -29,8 +29,6 @@ import { import { LatestChartBasicConfigComponent } from '@home/components/widget/config/basic/chart/latest-chart-basic-config.component'; -import { AxisLimitConfig } from '@home/components/widget/lib/chart/time-series-chart.models'; -import { ValueSourceType } from '@shared/models/widget-settings.models'; @Component({ selector: 'tb-polar-area-chart-basic-config', @@ -43,7 +41,7 @@ export class PolarAreaChartBasicConfigComponent extends LatestChartBasicConfigCo polarAreaChartConfigTemplate: TemplateRef; predefinedValues = widgetTitleAutocompleteValues; - + constructor(protected store: Store, protected widgetConfigComponent: WidgetConfigComponent, protected fb: UntypedFormBuilder) { @@ -83,32 +81,4 @@ export class PolarAreaChartBasicConfigComponent extends LatestChartBasicConfigCo this.widgetConfig.config.settings.axisTickLabelColor = config.axisTickLabelColor; this.widgetConfig.config.settings.angleAxisStartAngle = config.angleAxisStartAngle; } - - protected onConfigSet(configData: WidgetConfigComponentData) { - configData.config.settings.axisMin = this.normalizeAxisLimit(configData.config.settings.axisMin); - configData.config.settings.axisMax = this.normalizeAxisLimit(configData.config.settings.axisMax); - super.onConfigSet(configData); - } - - private normalizeAxisLimit(limit: any): AxisLimitConfig { - if (limit && typeof limit === 'object' && 'type' in limit) { - return { - type: limit.type || ValueSourceType.constant, - value: limit.value ?? null, - entityAlias: limit.entityAlias ?? null - }; - } - if (typeof limit === 'number') { - return { - type: ValueSourceType.constant, - value: limit, - entityAlias: null - }; - } - return { - type: ValueSourceType.constant, - value: null, - entityAlias: null - }; - } } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-widget.models.ts index 0fd3b027ab..3f76eb18cf 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-widget.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/bar-chart-widget.models.ts @@ -31,11 +31,10 @@ import { ChartBarSettings, chartColorScheme } from '@home/components/widget/lib/chart/chart.models'; -import { AxisLimitConfig } from '@home/components/widget/lib/chart/time-series-chart.models'; export interface BarChartWidgetSettings extends LatestChartWidgetSettings { - axisMin?: number | string | AxisLimitConfig; - axisMax?: number | string | AxisLimitConfig; + axisMin?: number; + axisMax?: number; axisTickLabelFont: Font; axisTickLabelColor: string; barSettings: ChartBarSettings; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/bars-chart.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/bars-chart.models.ts index 860f4da5b9..2808d9f7e5 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/bars-chart.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/bars-chart.models.ts @@ -24,12 +24,11 @@ import { chartColorScheme } from '@home/components/widget/lib/chart/chart.models'; import { Font } from '@shared/models/widget-settings.models'; -import { AxisLimitConfig } from '@home/components/widget/lib/chart/time-series-chart.models'; export interface BarsChartSettings extends LatestChartSettings { polar: boolean; - axisMin?: number | string | AxisLimitConfig; - axisMax?: number | string | AxisLimitConfig; + axisMin?: number | string; + axisMax?: number | string; axisTickLabelFont: Font; axisTickLabelColor: string; angleAxisStartAngle?: number; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/bars-chart.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/bars-chart.ts index 61adae9c20..92df6dd363 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/bars-chart.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/bars-chart.ts @@ -25,7 +25,7 @@ import { ComponentStyle } from '@shared/models/widget-settings.models'; import { LinearGradientObject } from 'zrender/lib/graphic/LinearGradient'; import tinycolor from 'tinycolor2'; import { BarDataItemOption, BarSeriesLabelOption } from 'echarts/types/src/chart/bar/BarSeries'; -import { isDefinedAndNotNull, isNumber, isString } from '@core/utils'; +import { isDefinedAndNotNull } from '@core/utils'; import { ChartFillType, ChartLabelPosition, @@ -35,19 +35,9 @@ import { } from '@home/components/widget/lib/chart/chart.models'; import { ValueAxisBaseOption } from 'echarts/types/src/coord/axisCommonTypes'; import { RadiusAxisOption, YAXisOption } from 'echarts/types/dist/shared'; -import { DataKey, Datasource, DatasourceType, widgetType } from '@shared/models/widget.models'; -import { WidgetSubscriptionOptions } from '@core/api/widget-api.models'; -import { ValueSourceType } from '@shared/models/widget-settings.models'; -import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; -import { AxisLimitConfig } from '@home/components/widget/lib/chart/time-series-chart.models'; export class TbBarsChart extends TbLatestChart { - private dynamicAxisMin: number | string = null; - private dynamicAxisMax: number | string = null; - private minLatestDataKey: DataKey = null; - private maxLatestDataKey: DataKey = null; - constructor(ctx: WidgetContext, inputSettings: DeepPartial, chartElement: HTMLElement, @@ -62,212 +52,6 @@ export class TbBarsChart extends TbLatestChart { return barsChartDefaultSettings; } - protected initSettings() { - super.initSettings(); - this.setupAxisLimits(); - } - - private setupAxisLimits(): void { - const axisLimitDatasources: Datasource[] = []; - - if (isDefinedAndNotNull(this.settings.axisMin)) { - this.processAxisLimit(this.settings.axisMin, 'min', axisLimitDatasources); - } - if (isDefinedAndNotNull(this.settings.axisMax)) { - this.processAxisLimit(this.settings.axisMax, 'max', axisLimitDatasources); - } - - this.subscribeForAxisLimits(axisLimitDatasources); - } - - private processAxisLimit( - limit: any, - limitType: 'min' | 'max', - axisLimitDatasources: Datasource[] - ): void { - if (limit && typeof limit === 'object' && 'type' in limit) { - const axisLimit = limit as AxisLimitConfig; - - if (axisLimit.type === ValueSourceType.latestKey) { - let latestDataKey: DataKey = null; - if (this.ctx.datasources.length) { - for (const datasource of this.ctx.datasources) { - latestDataKey = datasource.latestDataKeys?.find(d => - (d.type === DataKeyType.function && d.label === (axisLimit.value as DataKey).label) || - (d.type !== DataKeyType.function && d.name === (axisLimit.value as DataKey).name && - d.type === (axisLimit.value as DataKey).type)); - if (latestDataKey) { - break; - } - } - } - - if (latestDataKey) { - if (limitType === 'min') { - this.minLatestDataKey = latestDataKey; - } else { - this.maxLatestDataKey = latestDataKey; - } - } - } else if (axisLimit.type === ValueSourceType.entity) { - const entityAliasId = this.ctx.aliasController.getEntityAliasId(axisLimit.entityAlias); - if (entityAliasId) { - let datasource = axisLimitDatasources.find(d => d.entityAliasId === entityAliasId); - const entityDataKey: DataKey = { - type: (axisLimit.value as DataKey).type, - name: (axisLimit.value as DataKey).name, - label: (axisLimit.value as DataKey).name, - settings: { - axisLimit: limitType - } - }; - - if (datasource) { - datasource.dataKeys.push(entityDataKey); - } else { - datasource = { - type: DatasourceType.entity, - name: axisLimit.entityAlias, - aliasName: axisLimit.entityAlias, - entityAliasId, - dataKeys: [entityDataKey] - }; - axisLimitDatasources.push(datasource); - } - } - } else if (axisLimit.type === ValueSourceType.constant) { - const value = axisLimit.value as number; - if (limitType === 'min') { - this.dynamicAxisMin = value; - } else { - this.dynamicAxisMax = value; - } - } - } else if (typeof limit === 'number' || typeof limit === 'string') { - if (limitType === 'min') { - this.dynamicAxisMin = limit; - } else { - this.dynamicAxisMax = limit; - } - } - } - - private subscribeForAxisLimits(datasources: Datasource[]) { - if (datasources.length) { - const axisLimitsSubscriptionOptions: WidgetSubscriptionOptions = { - datasources, - useDashboardTimewindow: false, - type: widgetType.latest, - callbacks: { - onDataUpdated: (subscription) => { - let update = false; - if (subscription.data) { - for (const data of subscription.data) { - const limitType = data.dataKey.settings.axisLimit as ('min' | 'max'); - if (data.data[0]) { - const value = this.parseAxisLimitData(data.data[0][1]); - if (limitType === 'min') { - if (this.dynamicAxisMin !== value) { - this.dynamicAxisMin = value; - update = true; - } - } else { - if (this.dynamicAxisMax !== value) { - this.dynamicAxisMax = value; - update = true; - } - } - } - } - } - if (this.latestChart && update) { - this.updateAxisLimits(); - } - } - } - }; - this.ctx.subscriptionApi.createSubscription(axisLimitsSubscriptionOptions, true).subscribe(); - } - } - - private parseAxisLimitData(data: any): number | null { - let value: number; - if (isDefinedAndNotNull(data)) { - if (isNumber(data)) { - value = data; - } else if (isString(data)) { - value = Number(data); - } - } - if (isDefinedAndNotNull(value) && !isNaN(value)) { - return value; - } - return null; - } - - private updateAxisLimitsFromLatest(): boolean { - let update = false; - - if (this.ctx.latestData) { - if (this.minLatestDataKey) { - const data = this.ctx.latestData.find(d => d.dataKey === this.minLatestDataKey); - if (data?.data[0]) { - const value = this.parseAxisLimitData(data.data[0][1]); - if (this.dynamicAxisMin !== value) { - this.dynamicAxisMin = value; - update = true; - } - } - } - - if (this.maxLatestDataKey) { - const data = this.ctx.latestData.find(d => d.dataKey === this.maxLatestDataKey); - if (data?.data[0]) { - const value = this.parseAxisLimitData(data.data[0][1]); - if (this.dynamicAxisMax !== value) { - this.dynamicAxisMax = value; - update = true; - } - } - } - } - return update; - } - - private updateAxisLimits(): void { - if (this.latestChart && !this.latestChart.isDisposed()) { - const axisTickLabelStyle = createChartTextStyle(this.settings.axisTickLabelFont, - this.settings.axisTickLabelColor, false, 'axis.tickLabel'); - const valueAxis: ValueAxisBaseOption = { - type: 'value', - min: this.dynamicAxisMin, - max: this.dynamicAxisMax, - axisLabel: { - color: axisTickLabelStyle.color, - fontStyle: axisTickLabelStyle.fontStyle, - fontWeight: axisTickLabelStyle.fontWeight, - fontFamily: axisTickLabelStyle.fontFamily, - fontSize: axisTickLabelStyle.fontSize, - formatter: (value: any) => this.valueFormatter.format(value) - } - }; - - if (this.settings.polar) { - this.latestChartOption.radiusAxis = valueAxis as RadiusAxisOption; - } else { - this.latestChartOption.yAxis = valueAxis as YAXisOption; - } - - this.latestChart.setOption(this.latestChartOption); - } - } - - public latestUpdated() { - if (this.updateAxisLimitsFromLatest()) { - this.updateAxisLimits(); - } - } - protected prepareLatestChartOption() { let labelStyle: ComponentStyle = {}; if (this.settings.barSettings.showLabel) { @@ -305,12 +89,10 @@ export class TbBarsChart extends TbLatestChart { const axisTickLabelStyle = createChartTextStyle(this.settings.axisTickLabelFont, this.settings.axisTickLabelColor, false, 'axis.tickLabel'); - const minValue = isDefinedAndNotNull(this.dynamicAxisMin) ? this.dynamicAxisMin : undefined; - const maxValue = isDefinedAndNotNull(this.dynamicAxisMax) ? this.dynamicAxisMax : undefined; const valueAxis: ValueAxisBaseOption = { type: 'value', - min: minValue, - max: maxValue, + min: this.settings.axisMin, + max: this.settings.axisMax, axisLabel: { color: axisTickLabelStyle.color, fontStyle: axisTickLabelStyle.fontStyle, @@ -320,7 +102,6 @@ export class TbBarsChart extends TbLatestChart { formatter: (value: any) => this.valueFormatter.format(value) } }; - if (this.settings.polar) { this.latestChartOption.polar = { radius: '100%' diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/latest-chart.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/latest-chart.ts index 9e525cd794..5911a60215 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/latest-chart.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/latest-chart.ts @@ -142,6 +142,7 @@ export abstract class TbLatestChart { public update(): void { for (const dsData of this.ctx.data) { + console.log("this.ctx.data",this.ctx.data) let value = 0; const tsValue = dsData.data[0]; const dataItem = this.dataItems.find(item => item.dataKey === dsData.dataKey); diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.models.ts index e5987e9664..5585496ede 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.models.ts @@ -381,18 +381,12 @@ export interface TimeSeriesChartYAxisSettings extends TimeSeriesChartAxisSetting decimals?: number; interval?: number; splitNumber?: number; - min?: number | string | AxisLimitConfig; - max?: number | string | AxisLimitConfig; + min?: string | ValueSourceConfig; + max?: string | ValueSourceConfig; ticksGenerator?: TimeSeriesChartTicksGenerator | string; ticksFormatter?: TimeSeriesChartTicksFormatter | string; } -export interface AxisLimitConfig { - entityAlias: string; - type: ValueSourceType; - value: number | DataKey; -} - export const timeSeriesChartYAxisValid = (axis: TimeSeriesChartYAxisSettings): boolean => !(!axis.id || isUndefinedOrNull(axis.order)); @@ -873,8 +867,6 @@ export interface TimeSeriesChartAxis { id: string; settings: TimeSeriesChartAxisSettings; option: CartesianAxisOption; - dynamicMin?: string| number; - dynamicMax?: string| number; minLatestDataKey?: DataKey; maxLatestDataKey?: DataKey; unitConvertor?: (value: number) => number; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.ts index 7954352bb4..d429438f43 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.ts @@ -17,7 +17,6 @@ import { WidgetContext } from '@home/models/widget-component.models'; import { adjustTimeAxisExtentToData, - AxisLimitConfig, calculateThresholdsOffset, createTimeSeriesVisualMapOption, createTimeSeriesXAxis, @@ -55,7 +54,7 @@ import { getFocusedSeriesIndex, measureAxisNameSize } from '@home/components/widget/lib/chart/echarts-widget.models'; -import { DateFormatProcessor, ValueSourceType } from '@shared/models/widget-settings.models'; +import { DateFormatProcessor, ValueSourceConfig, ValueSourceType } from '@shared/models/widget-settings.models'; import { formattedDataFormDatasourceData, formatValue, @@ -289,15 +288,36 @@ export class TbTimeSeriesChart { } } } - } - if (this.updateAxisLimitsFromLatest()) { - update = true; + + for (const yAxis of this.yAxisList) { + const minType = (yAxis.settings.min as ValueSourceConfig).type; + const maxType = (yAxis.settings.max as ValueSourceConfig).type; + if (minType === ValueSourceType.latestKey && yAxis.minLatestDataKey) { + const data = this.ctx.latestData.find(d => d.dataKey === yAxis.minLatestDataKey); + if (data?.data[0]) { + const value = this.parseAxisLimitData(data.data[0][1], yAxis.unitConvertor); + if (yAxis.option.min !== value) { + yAxis.option.min = value; + update = true; + } + } + } + + if (maxType === ValueSourceType.latestKey && yAxis.maxLatestDataKey) { + const data = this.ctx.latestData.find(d => d.dataKey === yAxis.maxLatestDataKey); + if (data?.data[0]) { + const value = this.parseAxisLimitData(data.data[0][1], yAxis.unitConvertor); + if (yAxis.option.max !== value) { + yAxis.option.max = value; + update = true; + } + } + } + } } if (this.timeSeriesChart && update) { this.updateSeriesData(); - if (this.updateAxisLimitsFromLatest()) { - this.updateAxisLimits(); - } + this.updateAxisLimits(); } } @@ -574,20 +594,17 @@ export class TbTimeSeriesChart { } const yAxis = createTimeSeriesYAxis(unitSymbol, decimals, axisSettings, this.ctx.utilsService, this.darkMode, unitConvertor); if (isDefinedAndNotNull(axisSettings.min)) { - this.processAxisLimit(axisSettings.min, 'min', yAxis, axisLimitDatasources, unitConvertor); + this.processYAxisLimit(axisSettings.min, 'min', yAxis, axisLimitDatasources, unitConvertor); } if (isDefinedAndNotNull(axisSettings.max)) { - this.processAxisLimit(axisSettings.max, 'max', yAxis, axisLimitDatasources, unitConvertor); - } - if (yAxis.minLatestDataKey || yAxis.maxLatestDataKey) { - yAxis.unitConvertor = unitConvertor; + this.processYAxisLimit(axisSettings.max, 'max', yAxis, axisLimitDatasources, unitConvertor); } this.yAxisList.push(yAxis); } this.subscribeForAxisLimits(axisLimitDatasources); } - private processAxisLimit( + private processYAxisLimit( limit: any, limitType: 'min' | 'max', yAxis: TimeSeriesChartYAxis, @@ -595,15 +612,15 @@ export class TbTimeSeriesChart { unitConvertor?: (value: number) => number ): void { if (limit && typeof limit === 'object' && 'type' in limit) { - const axisLimit = limit as AxisLimitConfig; + const axisLimit = limit as ValueSourceConfig; if (axisLimit.type === ValueSourceType.latestKey) { let latestDataKey: DataKey = null; if (this.ctx.datasources.length) { for (const datasource of this.ctx.datasources) { latestDataKey = datasource.latestDataKeys?.find(d => - (d.type === DataKeyType.function && d.label === (axisLimit.value as DataKey).label) || - (d.type !== DataKeyType.function && d.name === (axisLimit.value as DataKey).name && - d.type === (axisLimit.value as DataKey).type)); + (d.type === DataKeyType.function && d.label === axisLimit.latestKey) || + (d.type !== DataKeyType.function && d.name === axisLimit.latestKey && + d.type === axisLimit.latestKeyType)); if (latestDataKey) { break; } @@ -621,9 +638,9 @@ export class TbTimeSeriesChart { if (entityAliasId) { let datasource = axisLimitDatasources.find(d => d.entityAliasId === entityAliasId); const entityDataKey: DataKey = { - type: (axisLimit.value as DataKey).type, - name: (axisLimit.value as DataKey).name, - label: (axisLimit.value as DataKey).name, + type: limit.entityKeyType, + name: limit.entityKey, + label: limit.entityKey, settings: { yAxisId: yAxis.id, axisLimit: limitType @@ -643,27 +660,14 @@ export class TbTimeSeriesChart { } } } else if (axisLimit.type === ValueSourceType.constant) { - const value = unitConvertor ? unitConvertor(axisLimit.value as number) : axisLimit.value as number; + const value = unitConvertor ? unitConvertor(axisLimit.value) : axisLimit.value; if (limitType === 'min') { - yAxis.dynamicMin = value; yAxis.option.min = value; } else { - yAxis.dynamicMax = value; yAxis.option.max = value; } } - } else if (typeof limit === 'number' || typeof limit === 'string') { - let value = limit; - if (typeof value === 'number' && unitConvertor) { - value = unitConvertor(value); - } - if (limitType === 'min') { - yAxis.dynamicMin = value; - yAxis.option.min = value; - } else { - yAxis.dynamicMax = value; - yAxis.option.max = value; - } + return; } } @@ -738,25 +742,30 @@ export class TbTimeSeriesChart { const limitType = data.dataKey.settings.axisLimit as ('min' | 'max'); if (data.data[0]) { const value = this.parseAxisLimitData(data.data[0][1], yAxis.unitConvertor); + if (isDefinedAndNotNull(value)) { if (limitType === 'min') { - yAxis.dynamicMin = value; - yAxis.option.min = value; + if (yAxis.option.min !== value) { + yAxis.option.min = value; + update = true; + } } else { - yAxis.dynamicMax = value; - yAxis.option.max = value; + if (yAxis.option.max !== value) { + yAxis.option.max = value; + update = true; + } } - update = true; } } } } } - if (this.timeSeriesChart && update) { - this.updateAxisLimits(); - } + } + if (this.timeSeriesChart && update) { + this.updateAxisLimits(); } } - }; + } + }; this.ctx.subscriptionApi.createSubscription(axisLimitsSubscriptionOptions, true).subscribe(); } } @@ -853,40 +862,6 @@ export class TbTimeSeriesChart { } } - private updateAxisLimitsFromLatest(): boolean { - let update = false; - - if (this.ctx.latestData) { - for (const yAxis of this.yAxisList) { - if (yAxis.minLatestDataKey) { - const data = this.ctx.latestData.find(d => d.dataKey === yAxis.minLatestDataKey); - if (data?.data[0]) { - const value = this.parseAxisLimitData(data.data[0][1], yAxis.unitConvertor); - - if (yAxis.dynamicMin !== value) { - yAxis.dynamicMin = value; - yAxis.option.min = value; - update = true; - } - } - } - - if (yAxis.maxLatestDataKey) { - const data = this.ctx.latestData.find(d => d.dataKey === yAxis.maxLatestDataKey); - if (data?.data[0]) { - const value = this.parseAxisLimitData(data.data[0][1], yAxis.unitConvertor); - if (yAxis.dynamicMax !== value) { - yAxis.dynamicMax = value; - yAxis.option.max = value; - update = true; - } - } - } - } - } - return update; - } - private parseAxisLimitData = (data: any, unitConvertor?: (value: number) => number): number => { let value: number; if (isDefinedAndNotNull(data)) { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/bar-chart-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/bar-chart-widget-settings.component.ts index b1734ff45a..8826e9afda 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/bar-chart-widget-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/bar-chart-widget-settings.component.ts @@ -26,8 +26,6 @@ import { import { LatestChartWidgetSettingsComponent } from '@home/components/widget/lib/settings/chart/latest-chart-widget-settings.component'; -import { AxisLimitConfig } from '@home/components/widget/lib/chart/time-series-chart.models'; -import { ValueSourceType } from '@shared/models/widget-settings.models'; @Component({ selector: 'tb-bar-chart-widget-settings', @@ -59,32 +57,4 @@ export class BarChartWidgetSettingsComponent extends LatestChartWidgetSettingsCo latestChartWidgetSettingsForm.addControl('axisTickLabelFont', this.fb.control(settings.axisTickLabelFont, [])); latestChartWidgetSettingsForm.addControl('axisTickLabelColor', this.fb.control(settings.axisTickLabelColor, [])); } - - protected prepareInputSettings(settings: WidgetSettings): WidgetSettings { - settings.axisMin = this.normalizeAxisLimit(settings.axisMin); - settings.axisMax = this.normalizeAxisLimit(settings.axisMax); - return super.prepareInputSettings(settings); - } - - private normalizeAxisLimit(limit: any): AxisLimitConfig { - if (limit && typeof limit === 'object' && 'type' in limit) { - return { - type: limit.type || ValueSourceType.constant, - value: limit.value ?? null, - entityAlias: limit.entityAlias ?? null - }; - } - if (typeof limit === 'number') { - return { - type: ValueSourceType.constant, - value: limit, - entityAlias: null - }; - } - return { - type: ValueSourceType.constant, - value: null, - entityAlias: null - }; - } } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/latest-chart-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/latest-chart-widget-settings.component.html index 6bbb996e93..3f1e96ca84 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/latest-chart-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/latest-chart-widget-settings.component.html @@ -120,7 +120,7 @@
+ formControlName="animation">
widget-config.card-appearance
@@ -256,15 +256,25 @@
widgets.bar-chart.bar-appearance
+ formControlName="barSettings" + [series]="false">
widgets.bar-chart.bar-axis
-
widgets.chart.chart-axis.scale-appearance
+
widgets.chart.chart-axis.scale
+
widgets.chart.chart-axis.scale-min
+ + + +
widgets.chart.chart-axis.scale-max
+ + +
-
-
widgets.chart.chart-axis.scale-limits
-
-
-
widgets.chart.chart-axis.limit
-
widgets.chart.chart-axis.source
-
widgets.chart.chart-axis.key-value
-
-
-
- - - - - -
-
-
-
@@ -322,16 +303,26 @@
widgets.bar-chart.bar-appearance
+ formControlName="barSettings" + pieLabelPosition + [series]="false">
widgets.polar-area-chart.polar-axis
-
widgets.chart.chart-axis.scale-appearance
+
widgets.chart.chart-axis.scale
+
widgets.chart.chart-axis.scale-min
+ + + +
widgets.chart.chart-axis.scale-max
+ + +
-
-
widgets.chart.chart-axis.scale-limits
-
-
-
widgets.chart.chart-axis.limit
-
widgets.chart.chart-axis.source
-
widgets.chart.chart-axis.key-value
-
-
- - - - - -
-
-
@@ -470,7 +434,7 @@ + formControlName="fillAreaSettings">
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/latest-chart-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/latest-chart-widget-settings.component.ts index fadee36370..ff7641bf1a 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/latest-chart-widget-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/latest-chart-widget-settings.component.ts @@ -22,7 +22,6 @@ import { LatestChartWidgetSettings } from '@home/components/widget/lib/chart/latest-chart.models'; import { - Datasource, legendPositions, legendPositionTranslationMap, WidgetSettings, @@ -104,15 +103,6 @@ export abstract class LatestChartWidgetSettingsComponent, protected fb: UntypedFormBuilder) { super(store); diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/polar-area-chart-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/polar-area-chart-widget-settings.component.ts index 61c533a377..355dc55207 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/polar-area-chart-widget-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/polar-area-chart-widget-settings.component.ts @@ -26,8 +26,7 @@ import { import { LatestChartWidgetSettingsComponent } from '@home/components/widget/lib/settings/chart/latest-chart-widget-settings.component'; -import { AxisLimitConfig } from '@home/components/widget/lib/chart/time-series-chart.models'; -import { ValueSourceType } from '@shared/models/widget-settings.models'; +import { ValueSourceConfig, ValueSourceType } from '@shared/models/widget-settings.models'; @Component({ selector: 'tb-polar-area-chart-widget-settings', @@ -66,25 +65,20 @@ export class PolarAreaChartWidgetSettingsComponent extends LatestChartWidgetSett return super.prepareInputSettings(settings); } - private normalizeAxisLimit(limit: any): AxisLimitConfig { - if (limit && typeof limit === 'object' && 'type' in limit) { + private normalizeAxisLimit(limit: any): ValueSourceConfig { + if (!limit) { return { - type: limit.type || ValueSourceType.constant, - value: limit.value ?? null, - entityAlias: limit.entityAlias ?? null + type: ValueSourceType.constant, + value: null, + entityAlias: null }; - } - if (typeof limit === 'number') { + } else if (typeof limit === 'number') { return { type: ValueSourceType.constant, value: limit, entityAlias: null }; } - return { - type: ValueSourceType.constant, - value: null, - entityAlias: null - }; + return limit; } } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/axis-scale-row.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/axis-scale-row.component.html index eed985187d..37c2838a21 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/axis-scale-row.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/axis-scale-row.component.html @@ -53,7 +53,7 @@ [dataKeyTypes]="[DataKeyType.attribute, DataKeyType.timeseries]" [callbacks]="callbacks" [editable]="false" - formControlName="value"> + [formControl]="latestKeyFormControl"> + [formControl]="entityKeyFormControl">
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/axis-scale-row.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/axis-scale-row.component.ts index b8103dd008..165857eac3 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/axis-scale-row.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/axis-scale-row.component.ts @@ -18,18 +18,22 @@ import { Component, DestroyRef, forwardRef, Input, OnInit } from '@angular/core' import { ControlValueAccessor, NG_VALIDATORS, NG_VALUE_ACCESSOR, - UntypedFormBuilder, + UntypedFormBuilder, UntypedFormControl, UntypedFormGroup, ValidationErrors, Validator, Validators, } from '@angular/forms'; -import { ValueSourceType, ValueSourceTypes, ValueSourceTypeTranslation } from '@shared/models/widget-settings.models'; +import { + ValueSourceConfig, + ValueSourceType, + ValueSourceTypes, + ValueSourceTypeTranslation +} from '@shared/models/widget-settings.models'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { AxisLimitConfig } from '@home/components/widget/lib/chart/time-series-chart.models'; -import { Datasource, DatasourceType, } from '@shared/models/widget.models'; +import { DataKey, Datasource, DatasourceType, } from '@shared/models/widget.models'; import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; import { IAliasController } from '@core/api/widget-api.models'; import { DataKeysCallbacks } from '@home/components/widget/lib/settings/common/key/data-keys.component.models'; -import { isEqual } from '@core/utils'; +import { merge } from 'rxjs'; @Component({ selector: 'tb-axis-scale-row', @@ -77,9 +81,13 @@ export class AxisScaleRowComponent implements ControlValueAccessor, OnInit, Vali limitForm: UntypedFormGroup; + latestKeyFormControl: UntypedFormControl; + + entityKeyFormControl: UntypedFormControl; + private propagateChanges: (value: any) => void = () => {}; - private modelValue: AxisLimitConfig | null = null; + private modelValue: ValueSourceConfig | null = null; constructor(private fb: UntypedFormBuilder, private destroyRef: DestroyRef) { @@ -91,42 +99,44 @@ export class AxisScaleRowComponent implements ControlValueAccessor, OnInit, Vali value: [null], entityAlias: [null] }); + this.latestKeyFormControl = this.fb.control(null, [Validators.required]); + this.entityKeyFormControl = this.fb.control(null, [Validators.required]); this.subscribeToTypeChanges(); - - this.limitForm.valueChanges - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(value => { + merge( + this.latestKeyFormControl.valueChanges, + this.entityKeyFormControl.valueChanges, + this.limitForm.valueChanges + ).pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe(() => { this.updateValidators(); - this.updateView(value); + this.updateModel(); }); } - writeValue(value: AxisLimitConfig) { + writeValue(value: ValueSourceConfig) { + console.log("value", value); this.modelValue = value; - - if (!this.limitForm) { - return; - } - - if (value) { - this.limitForm.patchValue({ - type: value.type ?? ValueSourceType.constant, - value: value.value ?? null, - entityAlias: value.entityAlias ?? null - }, - { emitEvent: false } - ); - } else { - this.limitForm.patchValue({ - type: ValueSourceType.constant, - value: null, - entityAlias: null - }, - { emitEvent: false } - ); + this.limitForm.patchValue( + { + type: value.type || ValueSourceType.constant, + value: value.value, + entityAlias: value.entityAlias, + }, {emitEvent: false} + ); + if (value.type === ValueSourceType.latestKey) { + this.latestKeyFormControl.patchValue({ + type: value.latestKeyType, + name: value.latestKey + }, {emitEvent: false}); + } else if (value.type === ValueSourceType.entity) { + this.entityKeyFormControl.patchValue({ + type: value.entityKeyType, + name: value.entityKey + }, {emitEvent: false}); } this.updateValidators(); + this.limitForm.markAllAsTouched(); } registerOnChange(fn: any) { @@ -158,28 +168,22 @@ export class AxisScaleRowComponent implements ControlValueAccessor, OnInit, Vali private updateValidators() { const axisTypeControl = this.limitForm.get('type'); - const axisValueControl = this.limitForm.get('value'); - const axisEntityAliasControl = this.limitForm.get('entityAlias'); - - if (axisTypeControl && axisValueControl && axisEntityAliasControl) { + if (axisTypeControl && this.entityKeyFormControl && this.latestKeyFormControl) { const type = axisTypeControl.value; - if (type === ValueSourceType.latestKey || type === ValueSourceType.entity) { - axisValueControl.setValidators([Validators.required]); - } else { - axisValueControl.clearValidators(); - } - - if (type === ValueSourceType.entity) { - axisEntityAliasControl.setValidators([Validators.required]); + if (type === ValueSourceType.latestKey) { + this.latestKeyFormControl.setValidators([Validators.required]); + this.entityKeyFormControl.clearValidators(); + } else if (type === ValueSourceType.entity) { + this.latestKeyFormControl.clearValidators(); + this.entityKeyFormControl.setValidators([Validators.required]); } else { - axisEntityAliasControl.clearValidators(); + this.latestKeyFormControl.clearValidators(); + this.entityKeyFormControl.clearValidators(); } - - axisValueControl.updateValueAndValidity({ emitEvent: false }); - axisEntityAliasControl.updateValueAndValidity({ emitEvent: false }); + this.latestKeyFormControl.updateValueAndValidity({ emitEvent: false }); + this.entityKeyFormControl.updateValueAndValidity({ emitEvent: false }); } } - private subscribeToTypeChanges() { this.limitForm.controls.type.valueChanges .pipe(takeUntilDestroyed(this.destroyRef)) @@ -187,18 +191,31 @@ export class AxisScaleRowComponent implements ControlValueAccessor, OnInit, Vali const axisValueControl = this.limitForm.get('value'); const axisEntityAliasControl = this.limitForm.get('entityAlias'); if (axisValueControl) { - axisValueControl.setValue(null, { emitEvent: true }); + axisValueControl.setValue(null, { emitEvent: false }); } if (axisEntityAliasControl) { - axisEntityAliasControl.setValue(null, { emitEvent: true }); + axisEntityAliasControl.setValue(null, { emitEvent: false }); } + this.latestKeyFormControl.setValue(null, { emitEvent: false }); + this.entityKeyFormControl.setValue(null, { emitEvent: false }); + }); } - private updateView(value: AxisLimitConfig) { - if (!isEqual(this.modelValue, value)) { - this.modelValue = value; - this.propagateChanges(value); + private updateModel() { + const value = this.limitForm.value; + this.modelValue.type = value.type ?? ValueSourceType.constant; + this.modelValue.value = value?.value; + this.modelValue.entityAlias = value?.entityAlias; + if (value.type === ValueSourceType.latestKey) { + const latestKey: DataKey = this.latestKeyFormControl.value; + this.modelValue.latestKey = latestKey?.name; + this.modelValue.latestKeyType = (latestKey?.type as any); + } else if (value.type === ValueSourceType.entity) { + const entityKey: DataKey = this.entityKeyFormControl.value; + this.modelValue.entityKey = entityKey?.name; + this.modelValue.entityKeyType = (entityKey?.type as any); } + this.propagateChanges(this.modelValue); } } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-y-axes-panel.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-y-axes-panel.component.ts index 4af0f5f613..3159a27abd 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-y-axes-panel.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-y-axes-panel.component.ts @@ -38,7 +38,8 @@ import { import { defaultTimeSeriesChartYAxisSettings, getNextTimeSeriesYAxisId, - TimeSeriesChartYAxes, TimeSeriesChartYAxisId, + TimeSeriesChartYAxes, + TimeSeriesChartYAxisId, TimeSeriesChartYAxisSettings, timeSeriesChartYAxisValid, timeSeriesChartYAxisValidator @@ -49,7 +50,7 @@ import { coerceBoolean } from '@shared/decorators/coercion'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { IAliasController } from '@app/core/public-api'; import { DataKeysCallbacks } from '@home/components/widget/lib/settings/common/key/data-keys.component.models'; -import { Datasource } from '@app/shared/public-api'; +import { DataKey, DataKeyType, Datasource, ValueSourceConfig, ValueSourceType } from '@app/shared/public-api'; @Component({ selector: 'tb-time-series-chart-y-axes-panel', @@ -125,6 +126,7 @@ export class TimeSeriesChartYAxesPanelComponent implements ControlValueAccessor, for (const axis of axes) { yAxes[axis.id] = axis; } + this.updateLatestDataKeys(Object.values(yAxes)); this.propagateChange(yAxes); } ); @@ -147,7 +149,7 @@ export class TimeSeriesChartYAxesPanelComponent implements ControlValueAccessor, } writeValue(value: TimeSeriesChartYAxes | undefined): void { - const yAxes: TimeSeriesChartYAxes = value || {}; + const yAxes: TimeSeriesChartYAxes = this.checkLatestDataKeys(value || {}); if (!yAxes.default) { yAxes.default = mergeDeep({} as TimeSeriesChartYAxisSettings, defaultTimeSeriesChartYAxisSettings, {id: 'default', order: 0} as TimeSeriesChartYAxisSettings); @@ -202,8 +204,104 @@ export class TimeSeriesChartYAxesPanelComponent implements ControlValueAccessor, private prepareAxesFormArray(axes: TimeSeriesChartYAxisSettings[]): UntypedFormArray { const axesControls: Array = []; axes.forEach((axis) => { + axis.min = this.normalizeAxisLimit(axis.min); + axis.max = this.normalizeAxisLimit(axis.max); axesControls.push(this.fb.control(axis, [timeSeriesChartYAxisValidator])); }); return this.fb.array(axesControls); } + + private checkLatestDataKeys(yAxes: TimeSeriesChartYAxes): TimeSeriesChartYAxes { + const latestKeys = this.datasource?.latestDataKeys || []; + const result: TimeSeriesChartYAxes = {}; + + for (const [id, axis] of Object.entries(yAxes)) { + + const minCfg = axis.min as unknown as ValueSourceConfig; + const maxCfg = axis.max as unknown as ValueSourceConfig; + + const minValid = + minCfg?.type !== ValueSourceType.latestKey || + latestKeys.some(k => this.isYAxisKey(k, minCfg)); + + const maxValid = + maxCfg?.type !== ValueSourceType.latestKey || + latestKeys.some(k => this.isYAxisKey(k, maxCfg)); + + if (minValid && maxValid) { + result[id] = axis; + } + } + + return result; + } + + private updateLatestDataKeys(yAxes: TimeSeriesChartYAxisSettings[]) { + if (this.datasource) { + let latestKeys = this.datasource.latestDataKeys; + if (!latestKeys) { + latestKeys = []; + this.datasource.latestDataKeys = latestKeys; + } + const existingYAxisKeys = latestKeys.filter(k => k.settings?.__yAxisMinKey === true || k.settings?.__yAxisMaxKey === true); + const foundYAxisKeys: DataKey[] = []; + + for(const yAxis of yAxes) { + const min = yAxis.min as ValueSourceConfig; + const max = yAxis.max as ValueSourceConfig; + if (min.type === ValueSourceType.latestKey) { + const found = existingYAxisKeys.find(k => this.isYAxisKey(k, min)); + if (!found) { + const newKey = this.dataKeyCallbacks.generateDataKey(min.latestKey, min.latestKeyType, + null, true, null); + newKey.settings.__yAxisMinKey = true; + latestKeys.push(newKey); + } else if (foundYAxisKeys.indexOf(found) === -1) { + foundYAxisKeys.push(found); + } + } + if (max.type === ValueSourceType.latestKey) { + const found = existingYAxisKeys.find(k => this.isYAxisKey(k, max)); + if (!found) { + const newKey = this.dataKeyCallbacks.generateDataKey(max.latestKey, max.latestKeyType, + null, true, null); + newKey.settings.__yAxisMaxKey = true; + latestKeys.push(newKey); + } else if (foundYAxisKeys.indexOf(found) === -1) { + foundYAxisKeys.push(found); + } + } + } + const toRemove = existingYAxisKeys.filter(k => foundYAxisKeys.indexOf(k) === -1); + for (const key of toRemove) { + const index = latestKeys.indexOf(key); + if (index > -1) { + latestKeys.splice(index, 1); + } + } + } + } + + private isYAxisKey(d: DataKey, limit: ValueSourceConfig): boolean { + return (d.type === DataKeyType.function && d.label === limit.latestKey) || + (d.type !== DataKeyType.function && d.name === limit.latestKey && + d.type === limit.latestKeyType); + } + + private normalizeAxisLimit(limit: any): ValueSourceConfig { + if (!limit) { + return { + type: ValueSourceType.constant, + value: null, + entityAlias: null + }; + } else if (typeof limit === 'number') { + return { + type: ValueSourceType.constant, + value: limit, + entityAlias: null + }; + } + return limit; + } }