From d39be089744ab694114130d23441f51a24097a10 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Thu, 7 Mar 2024 17:50:28 +0200 Subject: [PATCH] UI: Improve time series bar width strategy: calculate width as percentage of time window. --- ...e-series-chart-basic-config.component.html | 31 +--- ...ime-series-chart-basic-config.component.ts | 31 +--- .../lib/chart/time-series-chart-bar.models.ts | 16 +- .../lib/chart/time-series-chart.models.ts | 40 ++++- .../widget/lib/chart/time-series-chart.ts | 3 +- ...eries-chart-widget-settings.component.html | 31 +--- ...-series-chart-widget-settings.component.ts | 38 +---- ...me-series-chart-axis-settings.component.ts | 5 +- ...regation-bar-width-settings.component.html | 75 +++++++++ ...ggregation-bar-width-settings.component.ts | 147 ++++++++++++++++++ .../common/widget-settings-common.module.ts | 5 + .../assets/locale/locale.constant-en_US.json | 6 +- ui-ngx/src/form.scss | 6 +- 13 files changed, 295 insertions(+), 139 deletions(-) create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-no-aggregation-bar-width-settings.component.html create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-no-aggregation-bar-width-settings.component.ts diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/time-series-chart-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/time-series-chart-basic-config.component.html index 5b14146d0f..3d099c2645 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/time-series-chart-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/time-series-chart-basic-config.component.html @@ -114,33 +114,10 @@ axisType="xAxis"> -
-
-
widgets.time-series-chart.no-aggregation-bar-width-strategy
- - - {{ timeSeriesChartNoAggregationBarWidthStrategyTranslations.get(strategy) | translate }} - - -
-
-
widgets.time-series-chart.bar-group-interval-width
- - - ms - -
-
-
widgets.time-series-chart.separate-bar-width
- - - ms - -
-
+ +
diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/time-series-chart-basic-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/time-series-chart-basic-config.component.ts index 79aa52fdb6..5307147b0e 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/time-series-chart-basic-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/time-series-chart-basic-config.component.ts @@ -45,12 +45,7 @@ import { TimeSeriesChartWidgetSettings } from '@home/components/widget/lib/chart/time-series-chart-widget.models'; import { EChartsTooltipTrigger } from '@home/components/widget/lib/chart/echarts-widget.models'; -import { - timeSeriesChartNoAggregationBarWidthStrategies, - TimeSeriesChartNoAggregationBarWidthStrategy, - timeSeriesChartNoAggregationBarWidthStrategyTranslations, - TimeSeriesChartType -} from '@home/components/widget/lib/chart/time-series-chart.models'; +import { TimeSeriesChartType } from '@home/components/widget/lib/chart/time-series-chart.models'; @Component({ selector: 'tb-time-series-chart-basic-config', @@ -76,12 +71,6 @@ export class TimeSeriesChartBasicConfigComponent extends BasicWidgetConfigCompon legendPositionTranslationMap = legendPositionTranslationMap; - TimeSeriesChartNoAggregationBarWidthStrategy = TimeSeriesChartNoAggregationBarWidthStrategy; - - timeSeriesChartNoAggregationBarWidthStrategies = timeSeriesChartNoAggregationBarWidthStrategies; - - timeSeriesChartNoAggregationBarWidthStrategyTranslations = timeSeriesChartNoAggregationBarWidthStrategyTranslations; - timeSeriesChartWidgetConfigForm: UntypedFormGroup; tooltipValuePreviewFn = this._tooltipValuePreviewFn.bind(this); @@ -140,11 +129,7 @@ export class TimeSeriesChartBasicConfigComponent extends BasicWidgetConfigCompon yAxis: [settings.yAxis, []], xAxis: [settings.xAxis, []], - noAggregationBarWidthSettings: this.fb.group({ - strategy: [settings.noAggregationBarWidthSettings.strategy, []], - groupIntervalWidth: [settings.noAggregationBarWidthSettings.groupIntervalWidth, [Validators.min(100)]], - separateBarWidth: [settings.noAggregationBarWidthSettings.separateBarWidth, [Validators.min(100)]], - }), + noAggregationBarWidthSettings: [settings.noAggregationBarWidthSettings, []], showLegend: [settings.showLegend, []], legendLabelFont: [settings.legendLabelFont, []], @@ -227,7 +212,7 @@ export class TimeSeriesChartBasicConfigComponent extends BasicWidgetConfigCompon } protected validatorTriggers(): string[] { - return ['showTitle', 'showIcon', 'showLegend', 'showTooltip', 'tooltipShowDate', 'noAggregationBarWidthSettings.strategy']; + return ['showTitle', 'showIcon', 'showLegend', 'showTooltip', 'tooltipShowDate']; } protected updateValidators(emitEvent: boolean, trigger?: string) { @@ -236,8 +221,6 @@ export class TimeSeriesChartBasicConfigComponent extends BasicWidgetConfigCompon const showLegend: boolean = this.timeSeriesChartWidgetConfigForm.get('showLegend').value; const showTooltip: boolean = this.timeSeriesChartWidgetConfigForm.get('showTooltip').value; const tooltipShowDate: boolean = this.timeSeriesChartWidgetConfigForm.get('tooltipShowDate').value; - const noAggregationBarWidthSettingsStrategy: TimeSeriesChartNoAggregationBarWidthStrategy = - this.timeSeriesChartWidgetConfigForm.get('noAggregationBarWidthSettings').get('strategy').value; if (showTitle) { this.timeSeriesChartWidgetConfigForm.get('title').enable(); @@ -266,14 +249,6 @@ export class TimeSeriesChartBasicConfigComponent extends BasicWidgetConfigCompon this.timeSeriesChartWidgetConfigForm.get('iconColor').disable(); } - if (noAggregationBarWidthSettingsStrategy === TimeSeriesChartNoAggregationBarWidthStrategy.group) { - this.timeSeriesChartWidgetConfigForm.get('noAggregationBarWidthSettings').get('groupIntervalWidth').enable(); - this.timeSeriesChartWidgetConfigForm.get('noAggregationBarWidthSettings').get('separateBarWidth').disable(); - } else if (noAggregationBarWidthSettingsStrategy === TimeSeriesChartNoAggregationBarWidthStrategy.separate) { - this.timeSeriesChartWidgetConfigForm.get('noAggregationBarWidthSettings').get('groupIntervalWidth').disable(); - this.timeSeriesChartWidgetConfigForm.get('noAggregationBarWidthSettings').get('separateBarWidth').enable(); - } - if (showLegend) { this.timeSeriesChartWidgetConfigForm.get('legendLabelFont').enable(); this.timeSeriesChartWidgetConfigForm.get('legendLabelColor').enable(); diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart-bar.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart-bar.models.ts index e5dfd6944e..bf7f6cf764 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart-bar.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart-bar.models.ts @@ -19,7 +19,6 @@ import { Interval, IntervalMath } from '@shared/models/time/time.models'; import { LabelFormatterCallback, SeriesLabelOption } from 'echarts/types/src/util/types'; import { TimeSeriesChartDataItem, - TimeSeriesChartNoAggregationBarWidthSettings, TimeSeriesChartNoAggregationBarWidthStrategy } from '@home/components/widget/lib/chart/time-series-chart.models'; import { CustomSeriesRenderItemParams } from 'echarts'; @@ -38,7 +37,9 @@ export interface BarRenderContext { barsCount?: number; barIndex?: number; noAggregation: boolean; - noAggregationBarWidthSettings: TimeSeriesChartNoAggregationBarWidthSettings; + noAggregationBarWidthStrategy: TimeSeriesChartNoAggregationBarWidthStrategy; + noAggregationWidthRelative?: boolean; + noAggregationWidth?: number; timeInterval?: Interval; visualSettings?: BarVisualSettings; labelOption?: SeriesLabelOption; @@ -54,16 +55,15 @@ export const renderTimeSeriesBar = (params: CustomSeriesRenderItemParams, api: C let interval = end - start; const ts = start ? start : time; - const noAggregationGroup = renderCtx.noAggregation && - renderCtx.noAggregationBarWidthSettings.strategy === TimeSeriesChartNoAggregationBarWidthStrategy.group; const separateBar = renderCtx.noAggregation && - renderCtx.noAggregationBarWidthSettings.strategy === TimeSeriesChartNoAggregationBarWidthStrategy.separate; + renderCtx.noAggregationBarWidthStrategy === TimeSeriesChartNoAggregationBarWidthStrategy.separate; if (renderCtx.noAggregation) { - if (noAggregationGroup) { - interval = renderCtx.noAggregationBarWidthSettings.groupIntervalWidth; + if (renderCtx.noAggregationWidthRelative) { + const scaleWidth = api.getWidth() / api.size([1,0])[0]; + interval = scaleWidth * (renderCtx.noAggregationWidth / 100); } else { - interval = renderCtx.noAggregationBarWidthSettings.separateBarWidth; + interval = renderCtx.noAggregationWidth; } start = time - interval / 2; end = time + interval / 2; 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 6aac959cbe..fa349252b7 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 @@ -391,10 +391,16 @@ export const timeSeriesChartNoAggregationBarWidthStrategyTranslations = new Map< ] ); +export interface TimeSeriesChartBarWidth { + relative?: boolean; + relativeWidth?: number; + absoluteWidth?: number; +} + export interface TimeSeriesChartNoAggregationBarWidthSettings { strategy: TimeSeriesChartNoAggregationBarWidthStrategy; - groupIntervalWidth?: number; - separateBarWidth?: number; + groupWidth?: TimeSeriesChartBarWidth; + barWidth?: TimeSeriesChartBarWidth; } export interface TimeSeriesChartSettings extends EChartsTooltipWidgetSettings { @@ -474,8 +480,16 @@ export const timeSeriesChartDefaultSettings: TimeSeriesChartSettings = { }, noAggregationBarWidthSettings: { strategy: TimeSeriesChartNoAggregationBarWidthStrategy.group, - groupIntervalWidth: 1000, - separateBarWidth: 1000 + groupWidth: { + relative: true, + relativeWidth: 2, + absoluteWidth: 1000 + }, + barWidth: { + relative: true, + relativeWidth: 2, + absoluteWidth: 1000 + } }, showTooltip: true, tooltipTrigger: EChartsTooltipTrigger.axis, @@ -757,12 +771,12 @@ export const createTimeSeriesXAxisOption = (settings: TimeSeriesChartAxisSetting export const generateChartData = (dataItems: TimeSeriesChartDataItem[], thresholdItems: TimeSeriesChartThresholdItem[], timeInterval: Interval, + stack: boolean, noAggregation: boolean, noAggregationBarWidthSettings: TimeSeriesChartNoAggregationBarWidthSettings, - stack: boolean, darkMode: boolean): Array => { let series = generateChartSeries(dataItems, timeInterval, - noAggregation, noAggregationBarWidthSettings, stack, darkMode); + stack, noAggregation, noAggregationBarWidthSettings, darkMode); if (thresholdItems.length) { const thresholds = generateChartThresholds(thresholdItems, darkMode); series = series.concat(thresholds); @@ -874,9 +888,9 @@ const createThresholdData = (val: string | number, item: TimeSeriesChartThreshol const generateChartSeries = (dataItems: TimeSeriesChartDataItem[], timeInterval: Interval, + stack: boolean, noAggregation: boolean, noAggregationBarWidthSettings: TimeSeriesChartNoAggregationBarWidthSettings, - stack: boolean, darkMode: boolean): Array => { const series: Array = []; const enabledDataItems = dataItems.filter(d => d.enabled); @@ -895,7 +909,17 @@ const generateChartSeries = (dataItems: TimeSeriesChartDataItem[], for (const item of enabledDataItems) { if (item.dataKey.settings.type === TimeSeriesChartSeriesType.bar) { if (!item.barRenderContext) { - item.barRenderContext = {noAggregation, noAggregationBarWidthSettings}; + item.barRenderContext = {noAggregation, + noAggregationBarWidthStrategy: noAggregationBarWidthSettings.strategy}; + const targetWidth = noAggregationBarWidthSettings.strategy === TimeSeriesChartNoAggregationBarWidthStrategy.group ? + noAggregationBarWidthSettings.groupWidth : noAggregationBarWidthSettings.barWidth; + if (targetWidth.relative) { + item.barRenderContext.noAggregationWidthRelative = true; + item.barRenderContext.noAggregationWidth = targetWidth.relativeWidth; + } else { + item.barRenderContext.noAggregationWidthRelative = false; + item.barRenderContext.noAggregationWidth = targetWidth.absoluteWidth; + } } item.barRenderContext.noAggregation = noAggregation; item.barRenderContext.barsCount = barsCount; 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 e5d4cb8f46..6d790d5439 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 @@ -492,8 +492,9 @@ export class TbTimeSeriesChart { private updateSeries(): Array { return generateChartData(this.dataItems, this.thresholdItems, this.ctx.timeWindow.interval, + this.settings.stack, this.noAggregation, - this.settings.noAggregationBarWidthSettings, this.settings.stack, this.darkMode); + this.settings.noAggregationBarWidthSettings, this.darkMode); } private updateAxes() { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/time-series-chart-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/time-series-chart-widget-settings.component.html index f3a9a610c3..a754dec0b4 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/time-series-chart-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/time-series-chart-widget-settings.component.html @@ -48,33 +48,10 @@ axisType="xAxis">
-
-
-
widgets.time-series-chart.no-aggregation-bar-width-strategy
- - - {{ timeSeriesChartNoAggregationBarWidthStrategyTranslations.get(strategy) | translate }} - - -
-
-
widgets.time-series-chart.bar-group-interval-width
- - - ms - -
-
-
widgets.time-series-chart.separate-bar-width
- - - ms - -
-
+ +
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/time-series-chart-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/time-series-chart-widget-settings.component.ts index a520933f1b..b793e8c3eb 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/time-series-chart-widget-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/time-series-chart-widget-settings.component.ts @@ -22,23 +22,17 @@ import { WidgetSettings, WidgetSettingsComponent } from '@shared/models/widget.models'; -import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; +import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; import { formatValue, isDefinedAndNotNull, mergeDeep } from '@core/utils'; import { DateFormatProcessor, DateFormatSettings } from '@shared/models/widget-settings.models'; -import { - barChartWithLabelsDefaultSettings -} from '@home/components/widget/lib/chart/bar-chart-with-labels-widget.models'; import { EChartsTooltipTrigger } from '../../chart/echarts-widget.models'; import { - timeSeriesChartWidgetDefaultSettings, TimeSeriesChartWidgetSettings + timeSeriesChartWidgetDefaultSettings, + TimeSeriesChartWidgetSettings } from '@home/components/widget/lib/chart/time-series-chart-widget.models'; -import { - timeSeriesChartNoAggregationBarWidthStrategies, - TimeSeriesChartNoAggregationBarWidthStrategy, - timeSeriesChartNoAggregationBarWidthStrategyTranslations, TimeSeriesChartType -} from '@home/components/widget/lib/chart/time-series-chart.models'; +import { TimeSeriesChartType } from '@home/components/widget/lib/chart/time-series-chart.models'; import { WidgetConfigComponentData } from '@home/models/widget-component.models'; @Component({ @@ -65,12 +59,6 @@ export class TimeSeriesChartWidgetSettingsComponent extends WidgetSettingsCompon legendPositionTranslationMap = legendPositionTranslationMap; - TimeSeriesChartNoAggregationBarWidthStrategy = TimeSeriesChartNoAggregationBarWidthStrategy; - - timeSeriesChartNoAggregationBarWidthStrategies = timeSeriesChartNoAggregationBarWidthStrategies; - - timeSeriesChartNoAggregationBarWidthStrategyTranslations = timeSeriesChartNoAggregationBarWidthStrategyTranslations; - timeSeriesChartWidgetSettingsForm: UntypedFormGroup; tooltipValuePreviewFn = this._tooltipValuePreviewFn.bind(this); @@ -111,11 +99,7 @@ export class TimeSeriesChartWidgetSettingsComponent extends WidgetSettingsCompon yAxis: [settings.yAxis, []], xAxis: [settings.xAxis, []], - noAggregationBarWidthSettings: this.fb.group({ - strategy: [settings.noAggregationBarWidthSettings.strategy, []], - groupIntervalWidth: [settings.noAggregationBarWidthSettings.groupIntervalWidth, [Validators.min(100)]], - separateBarWidth: [settings.noAggregationBarWidthSettings.separateBarWidth, [Validators.min(100)]], - }), + noAggregationBarWidthSettings: [settings.noAggregationBarWidthSettings, []], showLegend: [settings.showLegend, []], legendLabelFont: [settings.legendLabelFont, []], @@ -140,23 +124,13 @@ export class TimeSeriesChartWidgetSettingsComponent extends WidgetSettingsCompon } protected validatorTriggers(): string[] { - return ['showLegend', 'showTooltip', 'tooltipShowDate', 'noAggregationBarWidthSettings.strategy']; + return ['showLegend', 'showTooltip', 'tooltipShowDate']; } protected updateValidators(emitEvent: boolean) { const showLegend: boolean = this.timeSeriesChartWidgetSettingsForm.get('showLegend').value; const showTooltip: boolean = this.timeSeriesChartWidgetSettingsForm.get('showTooltip').value; const tooltipShowDate: boolean = this.timeSeriesChartWidgetSettingsForm.get('tooltipShowDate').value; - const noAggregationBarWidthSettingsStrategy: TimeSeriesChartNoAggregationBarWidthStrategy = - this.timeSeriesChartWidgetSettingsForm.get('noAggregationBarWidthSettings').get('strategy').value; - - if (noAggregationBarWidthSettingsStrategy === TimeSeriesChartNoAggregationBarWidthStrategy.group) { - this.timeSeriesChartWidgetSettingsForm.get('noAggregationBarWidthSettings').get('groupIntervalWidth').enable(); - this.timeSeriesChartWidgetSettingsForm.get('noAggregationBarWidthSettings').get('separateBarWidth').disable(); - } else if (noAggregationBarWidthSettingsStrategy === TimeSeriesChartNoAggregationBarWidthStrategy.separate) { - this.timeSeriesChartWidgetSettingsForm.get('noAggregationBarWidthSettings').get('groupIntervalWidth').disable(); - this.timeSeriesChartWidgetSettingsForm.get('noAggregationBarWidthSettings').get('separateBarWidth').enable(); - } if (showLegend) { this.timeSeriesChartWidgetSettingsForm.get('legendLabelFont').enable(); diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-axis-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-axis-settings.component.ts index 2ae330c276..ab20727bdf 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-axis-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-axis-settings.component.ts @@ -22,8 +22,6 @@ import { TimeSeriesChartAxisSettings, TimeSeriesChartYAxisSettings } from '@home/components/widget/lib/chart/time-series-chart.models'; -import { Store } from '@ngrx/store'; -import { AppState } from '@core/core.state'; import { merge } from 'rxjs'; @Component({ @@ -60,8 +58,7 @@ export class TimeSeriesChartAxisSettingsComponent implements OnInit, ControlValu public axisSettingsFormGroup: UntypedFormGroup; - constructor(protected store: Store, - private fb: UntypedFormBuilder) { + constructor(private fb: UntypedFormBuilder) { } ngOnInit(): void { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-no-aggregation-bar-width-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-no-aggregation-bar-width-settings.component.html new file mode 100644 index 0000000000..239c6ea18c --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-no-aggregation-bar-width-settings.component.html @@ -0,0 +1,75 @@ + +
+
+
widgets.time-series-chart.no-aggregation-bar-width-strategy
+ + + {{ timeSeriesChartNoAggregationBarWidthStrategyTranslations.get(strategy) | translate }} + + +
+ + + + + + + + +
+ +
+
{{ label }}
+
+ + + + {{ (formGroup.get('relative').value ? + 'widgets.time-series-chart.bar-width-relative' : + 'widgets.time-series-chart.bar-width-absolute') | translate }} + + + {{ 'widgets.time-series-chart.bar-width-relative' | translate }} + + + {{ 'widgets.time-series-chart.bar-width-absolute' | translate }} + + + + + + % + + + + ms + +
+
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-no-aggregation-bar-width-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-no-aggregation-bar-width-settings.component.ts new file mode 100644 index 0000000000..36d8cb917a --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-no-aggregation-bar-width-settings.component.ts @@ -0,0 +1,147 @@ +/// +/// Copyright © 2016-2024 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { Component, forwardRef, Input, OnInit } from '@angular/core'; +import { + ControlValueAccessor, + NG_VALUE_ACCESSOR, + UntypedFormBuilder, + UntypedFormGroup, + Validators +} from '@angular/forms'; +import { + TimeSeriesChartNoAggregationBarWidthSettings, + timeSeriesChartNoAggregationBarWidthStrategies, + TimeSeriesChartNoAggregationBarWidthStrategy, + timeSeriesChartNoAggregationBarWidthStrategyTranslations +} from '@home/components/widget/lib/chart/time-series-chart.models'; +import { merge } from 'rxjs'; + +@Component({ + selector: 'tb-time-series-no-aggregation-bar-width-settings', + templateUrl: './time-series-no-aggregation-bar-width-settings.component.html', + styleUrls: ['./../../widget-settings.scss'], + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => TimeSeriesNoAggregationBarWidthSettingsComponent), + multi: true + } + ] +}) +export class TimeSeriesNoAggregationBarWidthSettingsComponent implements OnInit, ControlValueAccessor { + + TimeSeriesChartNoAggregationBarWidthStrategy = TimeSeriesChartNoAggregationBarWidthStrategy; + + timeSeriesChartNoAggregationBarWidthStrategies = timeSeriesChartNoAggregationBarWidthStrategies; + + timeSeriesChartNoAggregationBarWidthStrategyTranslations = timeSeriesChartNoAggregationBarWidthStrategyTranslations; + + @Input() + disabled: boolean; + + private modelValue: TimeSeriesChartNoAggregationBarWidthSettings; + + private propagateChange = null; + + public barWidthSettingsFormGroup: UntypedFormGroup; + + constructor(private fb: UntypedFormBuilder) { + } + + ngOnInit(): void { + this.barWidthSettingsFormGroup = this.fb.group({ + strategy: [null, []], + groupWidth: this.fb.group({ + relative: [null, []], + relativeWidth: [null, [Validators.required, Validators.min(0.1), Validators.max(100)]], + absoluteWidth: [null, [Validators.required, Validators.min(100)]] + }), + barWidth: this.fb.group({ + relative: [null, []], + relativeWidth: [null, [Validators.required, Validators.min(0.1), Validators.max(100)]], + absoluteWidth: [null, [Validators.required, Validators.min(100)]] + }) + }); + this.barWidthSettingsFormGroup.valueChanges.subscribe(() => { + this.updateModel(); + }); + merge(this.barWidthSettingsFormGroup.get('strategy').valueChanges, + this.barWidthSettingsFormGroup.get('groupWidth.relative').valueChanges, + this.barWidthSettingsFormGroup.get('barWidth.relative').valueChanges) + .subscribe(() => { + this.updateValidators(); + }); + } + + registerOnChange(fn: any): void { + this.propagateChange = fn; + } + + registerOnTouched(_fn: any): void { + } + + setDisabledState(isDisabled: boolean): void { + this.disabled = isDisabled; + if (isDisabled) { + this.barWidthSettingsFormGroup.disable({emitEvent: false}); + } else { + this.barWidthSettingsFormGroup.enable({emitEvent: false}); + this.updateValidators(); + } + } + + writeValue(value: TimeSeriesChartNoAggregationBarWidthSettings): void { + this.modelValue = value; + this.barWidthSettingsFormGroup.patchValue( + value, {emitEvent: false} + ); + this.updateValidators(); + } + + private updateValidators() { + const strategy: TimeSeriesChartNoAggregationBarWidthStrategy = + this.barWidthSettingsFormGroup.get('strategy').value; + const groupWidthRelative: boolean = this.barWidthSettingsFormGroup.get('groupWidth.relative').value; + const barWidthRelative: boolean = this.barWidthSettingsFormGroup.get('barWidth.relative').value; + if (strategy === TimeSeriesChartNoAggregationBarWidthStrategy.group) { + this.barWidthSettingsFormGroup.get('groupWidth').enable({emitEvent: false}); + this.barWidthSettingsFormGroup.get('barWidth').disable({emitEvent: false}); + if (groupWidthRelative) { + this.barWidthSettingsFormGroup.get('groupWidth').get('relativeWidth').enable({emitEvent: false}); + this.barWidthSettingsFormGroup.get('groupWidth').get('absoluteWidth').disable({emitEvent: false}); + } else { + this.barWidthSettingsFormGroup.get('groupWidth').get('relativeWidth').disable({emitEvent: false}); + this.barWidthSettingsFormGroup.get('groupWidth').get('absoluteWidth').enable({emitEvent: false}); + } + } else if (strategy === TimeSeriesChartNoAggregationBarWidthStrategy.separate) { + this.barWidthSettingsFormGroup.get('groupWidth').disable({emitEvent: false}); + this.barWidthSettingsFormGroup.get('barWidth').enable({emitEvent: false}); + if (barWidthRelative) { + this.barWidthSettingsFormGroup.get('barWidth').get('relativeWidth').enable({emitEvent: false}); + this.barWidthSettingsFormGroup.get('barWidth').get('absoluteWidth').disable({emitEvent: false}); + } else { + this.barWidthSettingsFormGroup.get('barWidth').get('relativeWidth').disable({emitEvent: false}); + this.barWidthSettingsFormGroup.get('barWidth').get('absoluteWidth').enable({emitEvent: false}); + } + } + } + + private updateModel() { + this.modelValue = this.barWidthSettingsFormGroup.getRawValue(); + this.propagateChange(this.modelValue); + } +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/widget-settings-common.module.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/widget-settings-common.module.ts index e741314315..b741a8e358 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/widget-settings-common.module.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/widget-settings-common.module.ts @@ -106,6 +106,9 @@ import { EntityAliasInputComponent } from '@home/components/widget/lib/settings/ import { TimeSeriesChartThresholdSettingsPanelComponent } from '@home/components/widget/lib/settings/common/chart/time-series-chart-threshold-settings-panel.component'; +import { + TimeSeriesNoAggregationBarWidthSettingsComponent +} from '@home/components/widget/lib/settings/common/chart/time-series-no-aggregation-bar-width-settings.component'; @NgModule({ declarations: [ @@ -146,6 +149,7 @@ import { TimeSeriesChartThresholdsPanelComponent, TimeSeriesChartThresholdRowComponent, TimeSeriesChartThresholdSettingsPanelComponent, + TimeSeriesNoAggregationBarWidthSettingsComponent, DataKeyInputComponent, EntityAliasInputComponent ], @@ -192,6 +196,7 @@ import { TimeSeriesChartThresholdsPanelComponent, TimeSeriesChartThresholdRowComponent, TimeSeriesChartThresholdSettingsPanelComponent, + TimeSeriesNoAggregationBarWidthSettingsComponent, DataKeyInputComponent, EntityAliasInputComponent ], diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index b32cfb7d38..1cef32ac6b 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -6629,8 +6629,10 @@ "no-aggregation-bar-width-strategy": "Bar width strategy for non-aggregated data", "no-aggregation-bar-width-strategy-group": "Group", "no-aggregation-bar-width-strategy-separate": "Separate", - "bar-group-interval-width": "Bar group interval width", - "separate-bar-width": "Separate bar width", + "bar-group-width": "Bar group width", + "bar-width": "Bar width", + "bar-width-relative": "Percentage of time window", + "bar-width-absolute": "Absolute (ms)", "threshold": { "thresholds": "Thresholds", "source": "Source", diff --git a/ui-ngx/src/form.scss b/ui-ngx/src/form.scss index dfe6667afd..e2390c795d 100644 --- a/ui-ngx/src/form.scss +++ b/ui-ngx/src/form.scss @@ -29,9 +29,11 @@ @media #{$breakpoint} { @include form-row-column; .mat-mdc-form-field, tb-unit-input { - width: auto; - &.medium-width { + &:not(.fixed-width) { width: auto; + &.medium-width { + width: auto; + } } } }