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 26f0f222d9..4fd7de467f 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 @@ -100,13 +100,15 @@
-
widgets.time-series-chart.axes
-
- TODO: Y Axis -
-
- TODO: X Axis -
+
widgets.time-series-chart.axis.axes
+ + + +
( + [ + [AxisPosition.left, 'widgets.time-series-chart.axis.position-left'], + [AxisPosition.right, 'widgets.time-series-chart.axis.position-right'], + [AxisPosition.top, 'widgets.time-series-chart.axis.position-top'], + [AxisPosition.bottom, 'widgets.time-series-chart.axis.position-bottom'] + ] +); + export enum TimeSeriesChartShape { emptyCircle = 'emptyCircle', circle = 'circle', diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-axis-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-axis-settings.component.html new file mode 100644 index 0000000000..8a77a92b19 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-axis-settings.component.html @@ -0,0 +1,122 @@ + + +
+ + + + + {{ axisTitle | translate }} + + + + +
+
widgets.time-series-chart.axis.label
+
+ + + + + + + +
+
+
+
widgets.time-series-chart.axis.position
+ + + + {{ timeSeriesAxisPositionTranslations.get(position) | translate }} + + + +
+
+ +
widgets.time-series-chart.axis.tick-labels
+
+
+ + + + +
+
+
+ + {{ 'widgets.time-series-chart.axis.show-ticks' | translate }} + + + +
+
+ + {{ 'widgets.time-series-chart.axis.show-line' | translate }} + + + +
+
+ +
+ {{ 'widgets.time-series-chart.axis.show-split-lines' | translate }} +
+
+ + +
+
+
+
+
+
widgets.time-series-chart.axis.scale
+
+
widgets.time-series-chart.axis.scale-min
+ + + +
widgets.time-series-chart.axis.scale-max
+ + + +
+
+
+
+
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 new file mode 100644 index 0000000000..2ae330c276 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-axis-settings.component.ts @@ -0,0 +1,179 @@ +/// +/// 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 } from '@angular/forms'; +import { + AxisPosition, + timeSeriesAxisPositionTranslations, + 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({ + selector: 'tb-time-series-chart-axis-settings', + templateUrl: './time-series-chart-axis-settings.component.html', + styleUrls: ['./../../widget-settings.scss'], + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => TimeSeriesChartAxisSettingsComponent), + multi: true + } + ] +}) +export class TimeSeriesChartAxisSettingsComponent implements OnInit, ControlValueAccessor { + + settingsExpanded = false; + + axisTitle: string; + + axisPositions: AxisPosition[]; + + timeSeriesAxisPositionTranslations = timeSeriesAxisPositionTranslations; + + @Input() + disabled: boolean; + + @Input() + axisType: 'xAxis' | 'yAxis' = 'xAxis'; + + private modelValue: TimeSeriesChartAxisSettings | TimeSeriesChartYAxisSettings; + + private propagateChange = null; + + public axisSettingsFormGroup: UntypedFormGroup; + + constructor(protected store: Store, + private fb: UntypedFormBuilder) { + } + + ngOnInit(): void { + + this.axisTitle = this.axisType === 'xAxis' ? 'widgets.time-series-chart.axis.x-axis' : 'widgets.time-series-chart.axis.y-axis'; + + this.axisPositions = this.axisType === 'xAxis' ? [AxisPosition.top, AxisPosition.bottom] : + [AxisPosition.left, AxisPosition.right]; + + this.axisSettingsFormGroup = this.fb.group({ + show: [null, []], + label: [null, []], + labelFont: [null, []], + labelColor: [null, []], + position: [null, []], + showTickLabels: [null, []], + tickLabelFont: [null, []], + tickLabelColor: [null, []], + showTicks: [null, []], + ticksColor: [null, []], + showLine: [null, []], + lineColor: [null, []], + showSplitLines: [null, []], + splitLinesColor: [null, []] + }); + if (this.axisType === 'yAxis') { + this.axisSettingsFormGroup.addControl('min', this.fb.control(null, [])); + this.axisSettingsFormGroup.addControl('max', this.fb.control(null, [])); + } + this.axisSettingsFormGroup.valueChanges.subscribe(() => { + this.updateModel(); + }); + merge(this.axisSettingsFormGroup.get('show').valueChanges, + this.axisSettingsFormGroup.get('showTickLabels').valueChanges, + this.axisSettingsFormGroup.get('showTicks').valueChanges, + this.axisSettingsFormGroup.get('showLine').valueChanges, + this.axisSettingsFormGroup.get('showSplitLines').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.axisSettingsFormGroup.disable({emitEvent: false}); + } else { + this.axisSettingsFormGroup.enable({emitEvent: false}); + this.updateValidators(); + } + } + + writeValue(value: TimeSeriesChartAxisSettings | TimeSeriesChartYAxisSettings): void { + this.modelValue = value; + this.axisSettingsFormGroup.patchValue( + value, {emitEvent: false} + ); + this.updateValidators(); + this.axisSettingsFormGroup.get('show').valueChanges.subscribe((show) => { + this.settingsExpanded = show; + }); + } + + private updateValidators() { + const show: boolean = this.axisSettingsFormGroup.get('show').value; + const showTickLabels: boolean = this.axisSettingsFormGroup.get('showTickLabels').value; + const showTicks: boolean = this.axisSettingsFormGroup.get('showTicks').value; + const showLine: boolean = this.axisSettingsFormGroup.get('showLine').value; + const showSplitLines: boolean = this.axisSettingsFormGroup.get('showSplitLines').value; + if (show) { + this.axisSettingsFormGroup.enable({emitEvent: false}); + if (showTickLabels) { + this.axisSettingsFormGroup.get('tickLabelFont').enable({emitEvent: false}); + this.axisSettingsFormGroup.get('tickLabelColor').enable({emitEvent: false}); + } else { + this.axisSettingsFormGroup.get('tickLabelFont').disable({emitEvent: false}); + this.axisSettingsFormGroup.get('tickLabelColor').disable({emitEvent: false}); + } + if (showTicks) { + this.axisSettingsFormGroup.get('ticksColor').enable({emitEvent: false}); + } else { + this.axisSettingsFormGroup.get('ticksColor').disable({emitEvent: false}); + } + if (showLine) { + this.axisSettingsFormGroup.get('lineColor').enable({emitEvent: false}); + } else { + this.axisSettingsFormGroup.get('lineColor').disable({emitEvent: false}); + } + if (showSplitLines) { + this.axisSettingsFormGroup.get('splitLinesColor').enable({emitEvent: false}); + } else { + this.axisSettingsFormGroup.get('splitLinesColor').disable({emitEvent: false}); + } + } else { + this.axisSettingsFormGroup.disable({emitEvent: false}); + this.axisSettingsFormGroup.get('show').enable({emitEvent: false}); + if (this.axisType === 'yAxis') { + this.axisSettingsFormGroup.get('min').enable({emitEvent: false}); + this.axisSettingsFormGroup.get('max').enable({emitEvent: false}); + } + } + } + + private updateModel() { + this.modelValue = this.axisSettingsFormGroup.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 e39c079f75..a7922dfdc4 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 @@ -92,6 +92,9 @@ import { import { WidgetButtonCustomStylePanelComponent } from '@home/components/widget/lib/settings/common/button/widget-button-custom-style-panel.component'; +import { + TimeSeriesChartAxisSettingsComponent +} from '@home/components/widget/lib/settings/common/chart/time-series-chart-axis-settings.component'; @NgModule({ declarations: [ @@ -127,7 +130,8 @@ import { WidgetActionSettingsPanelComponent, WidgetButtonAppearanceComponent, WidgetButtonCustomStyleComponent, - WidgetButtonCustomStylePanelComponent + WidgetButtonCustomStylePanelComponent, + TimeSeriesChartAxisSettingsComponent ], imports: [ CommonModule, @@ -167,7 +171,8 @@ import { WidgetActionSettingsPanelComponent, WidgetButtonAppearanceComponent, WidgetButtonCustomStyleComponent, - WidgetButtonCustomStylePanelComponent + WidgetButtonCustomStylePanelComponent, + TimeSeriesChartAxisSettingsComponent ], providers: [ ColorSettingsComponentService, 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 1e3370ab84..4a05e1c3c1 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -6615,6 +6615,27 @@ "shape-pin": "Pin", "shape-arrow": "Arrow", "shape-none": "None", + "axis": { + "axes": "Axes", + "x-axis": "X axis", + "y-axis": "Y axis", + "label": "Label", + "position": "Position", + "position-left": "Left", + "position-right": "Right", + "position-top": "Top", + "position-bottom": "Bottom", + "tick-labels": "Tick labels", + "show-ticks": "Show ticks", + "show-line": "Show line", + "show-split-lines": "Show split lines", + "show-split-lines-x-axis-hint": "If enabled, the vertical lines on the chart will be shown.", + "show-split-lines-y-axis-hint": "If enabled, the horizontal lines on the chart will be shown.", + "scale": "Scale", + "scale-min": "min", + "scale-max": "max", + "scale-auto": "Auto" + }, "series": { "legend-settings": "Legend settings", "show-in-legend": "Show in legend", diff --git a/ui-ngx/src/form.scss b/ui-ngx/src/form.scss index c3e2599bd9..dfe6667afd 100644 --- a/ui-ngx/src/form.scss +++ b/ui-ngx/src/form.scss @@ -55,6 +55,9 @@ &.no-padding-bottom { padding-bottom: 0; } + &.no-padding-top { + padding-top: 0; + } &.no-padding { padding: 0; }