@c8y/ngx-components 1021.64.0 → 1021.67.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. package/auth-configuration/sso-configuration/template-parts/signature-configuration.component.d.ts +7 -2
  2. package/auth-configuration/sso-configuration/template-parts/signature-configuration.component.d.ts.map +1 -1
  3. package/core/breadcrumb/breadcrumb-item.component.d.ts +1 -1
  4. package/core/breadcrumb/breadcrumb-item.component.d.ts.map +1 -1
  5. package/core/breadcrumb/breadcrumb-outlet.component.d.ts +1 -1
  6. package/core/breadcrumb/breadcrumb-outlet.component.d.ts.map +1 -1
  7. package/core/breadcrumb/breadcrumb.component.d.ts +1 -1
  8. package/core/breadcrumb/breadcrumb.component.d.ts.map +1 -1
  9. package/core/breadcrumb/breadcrumb.module.d.ts +7 -7
  10. package/core/breadcrumb/breadcrumb.module.d.ts.map +1 -1
  11. package/core/common/common.module.d.ts +38 -38
  12. package/core/common/date-format.service.d.ts +30 -0
  13. package/core/common/date-format.service.d.ts.map +1 -0
  14. package/core/common/date.pipe.d.ts +7 -3
  15. package/core/common/date.pipe.d.ts.map +1 -1
  16. package/core/common/index.d.ts +1 -0
  17. package/core/common/index.d.ts.map +1 -1
  18. package/core/common/outlet.directive.d.ts +1 -1
  19. package/core/common/outlet.directive.d.ts.map +1 -1
  20. package/core/common/user-preferences/user-preferences-store-current-user.d.ts +11 -0
  21. package/core/common/user-preferences/user-preferences-store-current-user.d.ts.map +1 -0
  22. package/core/common/user-preferences/user-preferences.service.d.ts +40 -1
  23. package/core/common/user-preferences/user-preferences.service.d.ts.map +1 -1
  24. package/core/date-picker/date-picker.component.d.ts +3 -1
  25. package/core/date-picker/date-picker.component.d.ts.map +1 -1
  26. package/core/date-time-picker/date-time-picker.component.d.ts +6 -3
  27. package/core/date-time-picker/date-time-picker.component.d.ts.map +1 -1
  28. package/core/dynamic-forms/date/date.type.component.d.ts +3 -0
  29. package/core/dynamic-forms/date/date.type.component.d.ts.map +1 -1
  30. package/core/plugins/plugins.service.d.ts +3 -1
  31. package/core/plugins/plugins.service.d.ts.map +1 -1
  32. package/core/time-interval/time-interval.component.d.ts +4 -2
  33. package/core/time-interval/time-interval.component.d.ts.map +1 -1
  34. package/ecosystem/ecosystem.module.d.ts +2 -1
  35. package/ecosystem/ecosystem.module.d.ts.map +1 -1
  36. package/ecosystem/packages/package-changelog-tab/package-changelog-tab.component.d.ts +15 -0
  37. package/ecosystem/packages/package-changelog-tab/package-changelog-tab.component.d.ts.map +1 -0
  38. package/ecosystem/packages/package-changelog.guard.d.ts +10 -0
  39. package/ecosystem/packages/package-changelog.guard.d.ts.map +1 -0
  40. package/ecosystem/packages/package-versions/package-contents/packages-contents.component.d.ts +2 -0
  41. package/ecosystem/packages/package-versions/package-contents/packages-contents.component.d.ts.map +1 -1
  42. package/ecosystem/shared/index.d.ts +1 -0
  43. package/ecosystem/shared/index.d.ts.map +1 -1
  44. package/ecosystem/shared/package-changelog/package-changelog.component.d.ts +24 -0
  45. package/ecosystem/shared/package-changelog/package-changelog.component.d.ts.map +1 -0
  46. package/ecosystem/shared/shared-ecosystem.module.d.ts +2 -1
  47. package/ecosystem/shared/shared-ecosystem.module.d.ts.map +1 -1
  48. package/esm2022/auth-configuration/sso-configuration/template-parts/signature-configuration.component.mjs +11 -7
  49. package/esm2022/core/breadcrumb/breadcrumb-item.component.mjs +3 -3
  50. package/esm2022/core/breadcrumb/breadcrumb-outlet.component.mjs +19 -9
  51. package/esm2022/core/breadcrumb/breadcrumb.component.mjs +3 -3
  52. package/esm2022/core/breadcrumb/breadcrumb.module.mjs +16 -5
  53. package/esm2022/core/common/common.module.mjs +6 -6
  54. package/esm2022/core/common/date-format.service.mjs +81 -0
  55. package/esm2022/core/common/date.pipe.mjs +29 -6
  56. package/esm2022/core/common/index.mjs +2 -1
  57. package/esm2022/core/common/outlet.directive.mjs +4 -3
  58. package/esm2022/core/common/user-preferences/user-preferences-store-current-user.mjs +22 -0
  59. package/esm2022/core/common/user-preferences/user-preferences.service.mjs +106 -16
  60. package/esm2022/core/date-picker/date-picker.component.mjs +11 -4
  61. package/esm2022/core/date-time-picker/date-time-picker.component.mjs +20 -11
  62. package/esm2022/core/dynamic-forms/date/date.type.component.mjs +12 -4
  63. package/esm2022/core/plugins/plugins.service.mjs +14 -8
  64. package/esm2022/core/time-interval/time-interval.component.mjs +9 -2
  65. package/esm2022/ecosystem/application-plugins/application-plugins.component.mjs +4 -4
  66. package/esm2022/ecosystem/application-plugins/update-plugin-of-app/update-plugin-of-app.component.mjs +3 -3
  67. package/esm2022/ecosystem/ecosystem.module.mjs +21 -5
  68. package/esm2022/ecosystem/packages/package-changelog-tab/package-changelog-tab.component.mjs +33 -0
  69. package/esm2022/ecosystem/packages/package-changelog.guard.mjs +22 -0
  70. package/esm2022/ecosystem/packages/package-versions/package-contents/packages-contents.component.mjs +17 -5
  71. package/esm2022/ecosystem/shared/index.mjs +2 -1
  72. package/esm2022/ecosystem/shared/package-changelog/package-changelog.component.mjs +82 -0
  73. package/esm2022/ecosystem/shared/package-version-select/package-version-select.component.mjs +3 -3
  74. package/esm2022/ecosystem/shared/shared-ecosystem.module.mjs +12 -6
  75. package/esm2022/operations/bulk-operation-scheduler/operation-scheduler.component.mjs +9 -7
  76. package/esm2022/operations/bulk-operations-list/bulk-operations-list.component.mjs +1 -1
  77. package/esm2022/upgrade/ng1/downgraded.services.mjs +3 -2
  78. package/esm2022/upgrade/ng1/index.mjs +3 -2
  79. package/esm2022/widgets/cockpit/index.mjs +3 -1
  80. package/esm2022/widgets/cockpit-exports/index.mjs +8 -1
  81. package/esm2022/widgets/definitions/index.mjs +2 -1
  82. package/esm2022/widgets/definitions/radial-gauge/c8y-ngx-components-widgets-definitions-radial-gauge.mjs +5 -0
  83. package/esm2022/widgets/definitions/radial-gauge/index.mjs +33 -0
  84. package/esm2022/widgets/implementations/info-gauge/index.mjs +2 -2
  85. package/esm2022/widgets/implementations/info-gauge/info-gauge-widget-config/gauge.model.mjs +295 -0
  86. package/esm2022/widgets/implementations/info-gauge/info-gauge-widget-config/info-gauge-widget-config.component.mjs +141 -11
  87. package/esm2022/widgets/implementations/info-gauge/info-gauge-widget-config/preset-preview/preset-preview.component.mjs +67 -0
  88. package/esm2022/widgets/implementations/info-gauge/info-gauge-widget-view/info-gauge-widget-view.component.mjs +34 -6
  89. package/esm2022/widgets/implementations/info-gauge/info-gauge-widget.module.mjs +9 -4
  90. package/esm2022/widgets/implementations/info-gauge/radial-gauge/radial-gauge.component.mjs +97 -0
  91. package/esm2022/widgets/implementations/info-gauge/radial-gauge/radial-gauge.service.mjs +369 -0
  92. package/fesm2022/c8y-ngx-components-auth-configuration.mjs +9 -5
  93. package/fesm2022/c8y-ngx-components-auth-configuration.mjs.map +1 -1
  94. package/fesm2022/c8y-ngx-components-ecosystem-application-plugins.mjs +5 -5
  95. package/fesm2022/c8y-ngx-components-ecosystem-application-plugins.mjs.map +1 -1
  96. package/fesm2022/c8y-ngx-components-ecosystem-shared.mjs +94 -11
  97. package/fesm2022/c8y-ngx-components-ecosystem-shared.mjs.map +1 -1
  98. package/fesm2022/c8y-ngx-components-ecosystem.mjs +83 -14
  99. package/fesm2022/c8y-ngx-components-ecosystem.mjs.map +1 -1
  100. package/fesm2022/c8y-ngx-components-operations-bulk-operation-scheduler.mjs +7 -5
  101. package/fesm2022/c8y-ngx-components-operations-bulk-operation-scheduler.mjs.map +1 -1
  102. package/fesm2022/c8y-ngx-components-operations-bulk-operations-list.mjs +1 -1
  103. package/fesm2022/c8y-ngx-components-operations-bulk-operations-list.mjs.map +1 -1
  104. package/fesm2022/c8y-ngx-components-upgrade.mjs +3 -1
  105. package/fesm2022/c8y-ngx-components-upgrade.mjs.map +1 -1
  106. package/fesm2022/c8y-ngx-components-widgets-cockpit-exports.mjs +7 -0
  107. package/fesm2022/c8y-ngx-components-widgets-cockpit-exports.mjs.map +1 -1
  108. package/fesm2022/c8y-ngx-components-widgets-cockpit.mjs +2 -0
  109. package/fesm2022/c8y-ngx-components-widgets-cockpit.mjs.map +1 -1
  110. package/fesm2022/c8y-ngx-components-widgets-definitions-radial-gauge.mjs +40 -0
  111. package/fesm2022/c8y-ngx-components-widgets-definitions-radial-gauge.mjs.map +1 -0
  112. package/fesm2022/c8y-ngx-components-widgets-definitions.mjs +1 -0
  113. package/fesm2022/c8y-ngx-components-widgets-definitions.mjs.map +1 -1
  114. package/fesm2022/c8y-ngx-components-widgets-implementations-info-gauge.mjs +991 -28
  115. package/fesm2022/c8y-ngx-components-widgets-implementations-info-gauge.mjs.map +1 -1
  116. package/fesm2022/c8y-ngx-components.mjs +809 -552
  117. package/fesm2022/c8y-ngx-components.mjs.map +1 -1
  118. package/locales/de.po +42 -6
  119. package/locales/es.po +42 -6
  120. package/locales/fr.po +42 -6
  121. package/locales/ja_JP.po +42 -6
  122. package/locales/ko.po +42 -6
  123. package/locales/locales.pot +40 -4
  124. package/locales/nl.po +42 -6
  125. package/locales/pl.po +42 -6
  126. package/locales/pt_BR.po +42 -6
  127. package/locales/zh_CN.po +42 -6
  128. package/locales/zh_TW.po +42 -6
  129. package/operations/bulk-operation-scheduler/operation-scheduler.component.d.ts +4 -2
  130. package/operations/bulk-operation-scheduler/operation-scheduler.component.d.ts.map +1 -1
  131. package/package.json +1 -1
  132. package/upgrade/ng1/downgraded.services.d.ts +1 -0
  133. package/upgrade/ng1/downgraded.services.d.ts.map +1 -1
  134. package/upgrade/ng1/index.d.ts.map +1 -1
  135. package/widgets/cockpit/index.d.ts +29 -0
  136. package/widgets/cockpit/index.d.ts.map +1 -1
  137. package/widgets/cockpit-exports/index.d.ts +6 -0
  138. package/widgets/cockpit-exports/index.d.ts.map +1 -1
  139. package/widgets/definitions/index.d.ts +1 -0
  140. package/widgets/definitions/index.d.ts.map +1 -1
  141. package/widgets/definitions/radial-gauge/c8y-ngx-components-widgets-definitions-radial-gauge.d.ts.map +1 -0
  142. package/widgets/definitions/radial-gauge/index.d.ts +33 -0
  143. package/widgets/definitions/radial-gauge/index.d.ts.map +1 -0
  144. package/widgets/implementations/info-gauge/index.d.ts +1 -1
  145. package/widgets/implementations/info-gauge/index.d.ts.map +1 -1
  146. package/widgets/implementations/info-gauge/info-gauge-widget-config/gauge.model.d.ts +339 -0
  147. package/widgets/implementations/info-gauge/info-gauge-widget-config/gauge.model.d.ts.map +1 -0
  148. package/widgets/implementations/info-gauge/info-gauge-widget-config/info-gauge-widget-config.component.d.ts +27 -7
  149. package/widgets/implementations/info-gauge/info-gauge-widget-config/info-gauge-widget-config.component.d.ts.map +1 -1
  150. package/widgets/implementations/info-gauge/info-gauge-widget-config/preset-preview/preset-preview.component.d.ts +33 -0
  151. package/widgets/implementations/info-gauge/info-gauge-widget-config/preset-preview/preset-preview.component.d.ts.map +1 -0
  152. package/widgets/implementations/info-gauge/info-gauge-widget-view/info-gauge-widget-view.component.d.ts +7 -3
  153. package/widgets/implementations/info-gauge/info-gauge-widget-view/info-gauge-widget-view.component.d.ts.map +1 -1
  154. package/widgets/implementations/info-gauge/info-gauge-widget.module.d.ts +2 -1
  155. package/widgets/implementations/info-gauge/info-gauge-widget.module.d.ts.map +1 -1
  156. package/widgets/implementations/info-gauge/radial-gauge/radial-gauge.component.d.ts +37 -0
  157. package/widgets/implementations/info-gauge/radial-gauge/radial-gauge.component.d.ts.map +1 -0
  158. package/widgets/implementations/info-gauge/radial-gauge/radial-gauge.service.d.ts +146 -0
  159. package/widgets/implementations/info-gauge/radial-gauge/radial-gauge.service.d.ts.map +1 -0
  160. package/esm2022/widgets/implementations/info-gauge/info-gauge.model.mjs +0 -2
  161. package/widgets/implementations/info-gauge/info-gauge.model.d.ts +0 -7
  162. package/widgets/implementations/info-gauge/info-gauge.model.d.ts.map +0 -1
@@ -1,16 +1,22 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Pipe, Component, Optional, Input, NgModule } from '@angular/core';
3
- import * as i3 from '@c8y/ngx-components';
4
- import { MeasurementRealtimeService, DatePipe, CoreModule } from '@c8y/ngx-components';
5
- import * as i4 from '@angular/common';
6
- import { NgIf, NgFor, NgStyle, AsyncPipe, DecimalPipe } from '@angular/common';
7
- import { of } from 'rxjs';
2
+ import { Pipe, Injectable, inject, Component, Input, ViewChild, Optional, EventEmitter, forwardRef, Output, NgModule } from '@angular/core';
3
+ import * as i1 from '@c8y/ngx-components';
4
+ import { gettext, ThemeSwitcherService, MeasurementRealtimeService, DatePipe, CommonModule, FormGroupComponent, MessagesComponent, FormsModule } from '@c8y/ngx-components';
5
+ import * as i2 from '@angular/common';
6
+ import { AsyncPipe, NgIf, NgFor, NgStyle, DecimalPipe } from '@angular/common';
7
+ import { of, BehaviorSubject, switchMap, tap, Subject, takeUntil } from 'rxjs';
8
8
  import { map, catchError } from 'rxjs/operators';
9
- import * as i1 from '@c8y/ngx-components/context-dashboard';
10
- import * as i1$1 from '@angular/forms';
11
- import { Validators, ReactiveFormsModule, ControlContainer, NgForm } from '@angular/forms';
12
- import * as i5 from '@c8y/ngx-components/datapoint-selector';
9
+ import * as i1$2 from '@c8y/ngx-components/context-dashboard';
10
+ import { defaultWidgetIds } from '@c8y/ngx-components/widgets/definitions';
11
+ import * as i1$1 from 'ngx-echarts';
12
+ import { NGX_ECHARTS_CONFIG, NgxEchartsModule } from 'ngx-echarts';
13
+ import * as i1$3 from '@angular/forms';
14
+ import { NG_VALUE_ACCESSOR, Validators, ReactiveFormsModule, ControlContainer, NgForm } from '@angular/forms';
15
+ import * as i6 from '@c8y/ngx-components/datapoint-selector';
13
16
  import { DatapointSelectorModule } from '@c8y/ngx-components/datapoint-selector';
17
+ import { EditorComponent, MonacoEditorMarkerValidatorDirective } from '@c8y/ngx-components/editor';
18
+ import * as i5 from 'ngx-bootstrap/collapse';
19
+ import { CollapseModule } from 'ngx-bootstrap/collapse';
14
20
 
15
21
  const INFO_GAUGE_COLORS = {
16
22
  GREEN: 'var(--c8y-brand-50)',
@@ -71,7 +77,7 @@ class InfoGaugeCurrentMeasurementPipe {
71
77
  }
72
78
  return { color, strokeDashOffset };
73
79
  }
74
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: InfoGaugeCurrentMeasurementPipe, deps: [{ token: i3.MeasurementRealtimeService }, { token: i3.AlertService }], target: i0.ɵɵFactoryTarget.Pipe }); }
80
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: InfoGaugeCurrentMeasurementPipe, deps: [{ token: i1.MeasurementRealtimeService }, { token: i1.AlertService }], target: i0.ɵɵFactoryTarget.Pipe }); }
75
81
  static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: InfoGaugeCurrentMeasurementPipe, isStandalone: true, name: "infoGaugeCurrentMeasurement" }); }
76
82
  }
77
83
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: InfoGaugeCurrentMeasurementPipe, decorators: [{
@@ -81,14 +87,767 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
81
87
  pure: true,
82
88
  standalone: true
83
89
  }]
84
- }], ctorParameters: () => [{ type: i3.MeasurementRealtimeService }, { type: i3.AlertService }] });
90
+ }], ctorParameters: () => [{ type: i1.MeasurementRealtimeService }, { type: i1.AlertService }] });
91
+
92
+ const GAUGE_PRESET_NAMES = {
93
+ DEFAULT: gettext('Default'),
94
+ CUSTOM: gettext('Custom preset'),
95
+ POINTER: gettext('Pointer'),
96
+ PROGRESS_BAR: gettext('Progress bar'),
97
+ PROGRESS_INDICATOR: gettext('Progress indicator'),
98
+ GRADE_RATING: gettext('Grade rating')
99
+ };
100
+ const GAUGE_PRESETS = [
101
+ {
102
+ // General properties
103
+ name: GAUGE_PRESET_NAMES.DEFAULT,
104
+ id: 'default',
105
+ radius: '90%',
106
+ startAngle: 240,
107
+ endAngle: 300,
108
+ // Split properties
109
+ splitNumber: 10,
110
+ splitLineLengthRatio: 0.3,
111
+ splitLineColor: '#fff',
112
+ splitLineWidth: 4,
113
+ splitLineDistanceRatio: -0.3,
114
+ // Tick properties
115
+ tickShow: true,
116
+ tickDistanceRatio: -0.16,
117
+ tickWidth: 2,
118
+ tickColor: '#fff',
119
+ tickLengthRatio: 0.16,
120
+ // Axis properties
121
+ axisLabelDistanceRatio: 0.25,
122
+ axisLabelColor: 'black',
123
+ axisLabelFontSizeMin: 8,
124
+ axisLabelFontSizeRatio: 0.04,
125
+ axisLabelFontSizeMax: 32,
126
+ axisLineWidthRatio: 0.125,
127
+ // Pointer properties
128
+ showPointer: true,
129
+ pointerColor: '#222',
130
+ pointerStyle: 'triangle',
131
+ pointerWidthRatio: 2,
132
+ pointerLength: '55%',
133
+ pointerOffset: 0,
134
+ // Progress bar properties
135
+ progressBar: false,
136
+ progressBarColor: '#119d11',
137
+ // Detail properties
138
+ showDetail: false,
139
+ showMarkPoint: true,
140
+ // Typography & Anchor
141
+ measurementValueFontRatio: 0.08,
142
+ measurementValueFontMin: 16,
143
+ measurementValueFontMax: 56,
144
+ measurementValueColor: 'white',
145
+ unitFontSize: 18,
146
+ unitFontRatio: 0.045,
147
+ unitFontMin: 14,
148
+ unitFontMax: 40,
149
+ unitColor: 'white',
150
+ dateFontSize: 0.001,
151
+ dateFontRatio: 0.03,
152
+ dateFontMin: 10,
153
+ dateFontMax: 16,
154
+ dateColor: 'gray',
155
+ anchor: {
156
+ show: true,
157
+ sizeRatio: 0.5,
158
+ itemStyle: {
159
+ color: '#222' // Color of the anchor
160
+ }
161
+ }
162
+ },
163
+ {
164
+ // General properties
165
+ name: GAUGE_PRESET_NAMES.POINTER,
166
+ id: 'pointer',
167
+ radius: '90%',
168
+ startAngle: 240,
169
+ endAngle: 300,
170
+ // Split properties
171
+ splitNumber: 10,
172
+ splitLineLengthRatio: 1,
173
+ splitLineColor: '#fff',
174
+ splitLineWidth: 4,
175
+ splitLineDistanceRatio: -1,
176
+ // Tick properties
177
+ tickShow: true,
178
+ tickDistanceRatio: -1,
179
+ tickWidth: 2,
180
+ tickColor: '#fff',
181
+ tickLengthRatio: 0.2666666667,
182
+ // Axis properties
183
+ axisLabelColor: '#212121',
184
+ axisLabelFontSizeMin: 8,
185
+ axisLabelFontSizeRatio: 0.04,
186
+ axisLabelFontSizeMax: 32,
187
+ axisLineWidthRatio: 0.075,
188
+ axisLabelDistanceRatio: 1.1666666667,
189
+ // Pointer properties
190
+ showPointer: true,
191
+ pointerStyle: 'default',
192
+ pointerColor: 'black',
193
+ pointerWidthRatio: 0.2666666667,
194
+ pointerLength: '70%',
195
+ pointerOffset: 5,
196
+ // Progress bar properties
197
+ progressBar: false,
198
+ progressBarColor: '#119d11',
199
+ // Detail properties
200
+ showDetail: true,
201
+ detailOffsetCenter: ['0%', '35%'],
202
+ showMarkPoint: false,
203
+ // Typography specs
204
+ measurementValueFontRatio: 0.08,
205
+ measurementValueFontMin: 16,
206
+ measurementValueFontMax: 56,
207
+ measurementValueColor: 'black',
208
+ unitFontSize: 18,
209
+ unitFontRatio: 0.045,
210
+ unitFontMin: 8,
211
+ unitFontMax: 40,
212
+ unitColor: 'black',
213
+ dateFontRatio: 0.03,
214
+ dateFontMin: 10,
215
+ dateFontMax: 16,
216
+ dateColor: 'black'
217
+ },
218
+ {
219
+ // General properties
220
+ name: GAUGE_PRESET_NAMES.PROGRESS_BAR,
221
+ id: 'progress-bar',
222
+ radius: '85%',
223
+ center: ['50%', '57%'],
224
+ startAngle: 200,
225
+ endAngle: -20,
226
+ // Split properties
227
+ splitNumber: 10,
228
+ splitLineLengthRatio: 1,
229
+ splitLineColor: '#fff',
230
+ splitLineWidth: 3,
231
+ splitLineDistanceRatio: -1,
232
+ // Tick properties
233
+ tickShow: false,
234
+ // Axis properties
235
+ axisLabelColor: '#212121',
236
+ axisLabelFontSizeMin: 8,
237
+ axisLabelFontSizeRatio: 0.04,
238
+ axisLabelFontSizeMax: 32,
239
+ axisLineWidthRatio: 0.075,
240
+ axisLabelDistanceRatio: -0.8,
241
+ // Pointer properties
242
+ showPointer: false,
243
+ // Progress bar properties
244
+ progressBar: true,
245
+ progressBarWidthRatio: 0.3333,
246
+ progressBarRoundCap: false,
247
+ progressBarColor: '#119d11',
248
+ additionalGaugeColors: ['#FFAB91', '#FD7347'],
249
+ // Detail properties
250
+ showDetail: true,
251
+ detailOffsetCenter: ['0%', '0%'],
252
+ showMarkPoint: false,
253
+ // Typography specs
254
+ measurementValueFontRatio: 0.12,
255
+ measurementValueFontMin: 16,
256
+ measurementValueFontMax: 72,
257
+ measurementValueColor: 'black',
258
+ unitFontSize: 18,
259
+ unitFontRatio: 0.085,
260
+ unitFontMin: 10,
261
+ unitFontMax: 40,
262
+ unitColor: 'black',
263
+ dateFontRatio: 0.03,
264
+ dateFontMin: 10,
265
+ dateFontMax: 16,
266
+ dateColor: 'black'
267
+ },
268
+ {
269
+ // General properties
270
+ name: GAUGE_PRESET_NAMES.PROGRESS_INDICATOR,
271
+ id: 'progress-indicator',
272
+ radius: '85%',
273
+ startAngle: 240,
274
+ endAngle: 300,
275
+ // Split line properties
276
+ splitNumber: 4,
277
+ splitLineLengthRatio: 1,
278
+ splitLineColor: '#fff',
279
+ splitLineWidth: 2,
280
+ splitLineDistanceRatio: -1,
281
+ // Tick properties
282
+ tickShow: false,
283
+ // Axis properties
284
+ axisLabelColor: '#212121',
285
+ axisLabelFontSizeMin: 7,
286
+ axisLabelFontSizeRatio: 0.04,
287
+ axisLabelFontSizeMax: 32,
288
+ axisLineWidthRatio: 0.075,
289
+ axisLabelDistanceRatio: -1,
290
+ // Pointer properties
291
+ showPointer: true,
292
+ pointerStyle: 'default',
293
+ pointerColor: 'black',
294
+ pointerWidthRatio: 0.2,
295
+ pointerLength: '100%',
296
+ pointerOffset: 5,
297
+ // Progress bar properties
298
+ progressBar: true,
299
+ progressBarWidthRatio: 0.3333,
300
+ progressBarRoundCap: false,
301
+ progressBarColor: '#119d11',
302
+ // Detail properties
303
+ showDetail: true,
304
+ detailOffsetCenter: ['0%', '35%'],
305
+ showMarkPoint: false,
306
+ // Typography & Anchor
307
+ measurementValueFontRatio: 0.08,
308
+ measurementValueFontMin: 12,
309
+ measurementValueFontMax: 56,
310
+ measurementValueColor: 'black',
311
+ unitFontSize: 18,
312
+ unitFontRatio: 0.045,
313
+ unitFontMin: 10,
314
+ unitFontMax: 40,
315
+ unitColor: 'black',
316
+ dateFontRatio: 0.03,
317
+ dateFontMin: 10,
318
+ dateFontMax: 16,
319
+ dateColor: 'black',
320
+ anchor: {
321
+ show: true,
322
+ showAbove: true,
323
+ sizeRatio: 0.1,
324
+ itemStyle: {
325
+ borderWidth: 10
326
+ }
327
+ }
328
+ },
329
+ {
330
+ // General properties
331
+ name: GAUGE_PRESET_NAMES.GRADE_RATING,
332
+ id: 'grade-rating',
333
+ radius: '75%',
334
+ startAngle: 180,
335
+ endAngle: 360,
336
+ center: ['50%', '65%'],
337
+ // Split line properties
338
+ splitNumber: 4,
339
+ splitLineLengthRatio: 3,
340
+ splitLineColor: 'auto',
341
+ splitLineWidth: 6,
342
+ splitLineDistanceRatio: -3,
343
+ // Tick properties
344
+ tickShow: true,
345
+ tickDistanceRatio: -2,
346
+ tickWidth: 2,
347
+ tickColor: 'auto',
348
+ tickLengthRatio: 2,
349
+ // Axis properties
350
+ axisLabelDistanceRatio: -6,
351
+ axisLabelColor: 'auto',
352
+ axisLabelFontSizeMin: 6,
353
+ axisLabelFontSizeRatio: 0.04,
354
+ axisLabelFontSizeMax: 32,
355
+ axisLineWidthRatio: 0.02,
356
+ // Pointer properties
357
+ showPointer: true,
358
+ pointerColor: 'black',
359
+ pointerStyle: 'triangle',
360
+ pointerWidthRatio: 2,
361
+ pointerLength: '12%',
362
+ pointerOffset: '-50%',
363
+ // Progress bar properties
364
+ progressBar: false,
365
+ progressBarColor: '#119d11',
366
+ // Detail properties
367
+ showDetail: true,
368
+ detailOffsetCenter: ['0%', '0%'],
369
+ showMarkPoint: false,
370
+ // Typography
371
+ measurementValueFontRatio: 0.08,
372
+ measurementValueFontMin: 16,
373
+ measurementValueFontMax: 56,
374
+ measurementValueColor: 'black',
375
+ unitFontRatio: 0.045,
376
+ unitFontMin: 8,
377
+ unitFontMax: 40,
378
+ unitColor: 'black',
379
+ dateFontRatio: 0.03,
380
+ dateFontMin: 10,
381
+ dateFontMax: 16,
382
+ dateColor: 'black'
383
+ }
384
+ ];
385
+
386
+ class RadialGaugeService {
387
+ constructor(c8yDatePipe) {
388
+ this.c8yDatePipe = c8yDatePipe;
389
+ this.containerSize = 400;
390
+ }
391
+ setChart(chart) {
392
+ this.chart = chart;
393
+ }
394
+ getChartOptions(gaugeOptions, activeDatapointGauge, selectedPresetId, gaugeOptionsColors, rangeColors, measurement, fractionSize) {
395
+ const colorArray = this.getColorArray(activeDatapointGauge, rangeColors);
396
+ return {
397
+ series: [
398
+ {
399
+ type: 'gauge',
400
+ radius: gaugeOptions?.radius || '90%',
401
+ center: gaugeOptions?.center || ['50%', '50%'],
402
+ startAngle: gaugeOptions?.startAngle || 240,
403
+ endAngle: gaugeOptions?.endAngle || 300,
404
+ min: activeDatapointGauge?.min || 0,
405
+ max: activeDatapointGauge?.max !== undefined && activeDatapointGauge?.max !== null
406
+ ? activeDatapointGauge.max
407
+ : 100,
408
+ // Split properties
409
+ splitNumber: gaugeOptions?.splitNumber || 10,
410
+ splitLine: {
411
+ distance: gaugeOptions?.splitLineDistanceRatio
412
+ ? this.containerSize *
413
+ gaugeOptions?.axisLineWidthRatio *
414
+ gaugeOptions?.splitLineDistanceRatio
415
+ : gaugeOptions?.splitLineDistance || -30,
416
+ length: gaugeOptions?.splitLineLengthRatio
417
+ ? this.containerSize *
418
+ gaugeOptions?.axisLineWidthRatio *
419
+ gaugeOptions?.splitLineLengthRatio
420
+ : gaugeOptions?.splitLineLength || 30,
421
+ lineStyle: {
422
+ color: selectedPresetId === 'custom' || selectedPresetId === 'grade-rating'
423
+ ? gaugeOptions?.splitLineColor
424
+ : gaugeOptionsColors?.splitLineColor || '#fff',
425
+ width: gaugeOptions?.splitLineWidth || 4
426
+ }
427
+ },
428
+ // Tick properties
429
+ axisTick: {
430
+ show: gaugeOptions?.tickShow || false,
431
+ distance: gaugeOptions?.tickDistanceRatio
432
+ ? this.containerSize *
433
+ gaugeOptions?.axisLineWidthRatio *
434
+ gaugeOptions?.tickDistanceRatio
435
+ : gaugeOptions?.tickDistance || -30,
436
+ length: gaugeOptions?.tickLengthRatio
437
+ ? this.containerSize *
438
+ gaugeOptions?.axisLineWidthRatio *
439
+ gaugeOptions?.tickLengthRatio
440
+ : gaugeOptions?.tickLength || 8,
441
+ lineStyle: {
442
+ color: selectedPresetId === 'custom' || selectedPresetId === 'grade-rating'
443
+ ? gaugeOptions.tickColor
444
+ : gaugeOptionsColors?.tickColor || '#fff',
445
+ width: gaugeOptions?.tickWidth || 2
446
+ }
447
+ },
448
+ // Axis properties
449
+ axisLine: {
450
+ lineStyle: {
451
+ width: gaugeOptions?.axisLineWidthRatio
452
+ ? this.containerSize * gaugeOptions?.axisLineWidthRatio
453
+ : gaugeOptions?.axisLineWidth || 30,
454
+ color: colorArray
455
+ }
456
+ },
457
+ axisLabel: {
458
+ color: selectedPresetId === 'custom' || selectedPresetId === 'grade-rating'
459
+ ? gaugeOptions.axisLabelColor
460
+ : gaugeOptionsColors?.axisLabelColor || 'inherit',
461
+ distance: gaugeOptions?.axisLabelDistanceRatio
462
+ ? this.containerSize *
463
+ gaugeOptions?.axisLineWidthRatio *
464
+ gaugeOptions?.axisLabelDistanceRatio
465
+ : gaugeOptions?.axisLabelDistance || 40,
466
+ fontSize: gaugeOptions?.axisLabelFontSizeRatio
467
+ ? this.clampRelative(gaugeOptions?.axisLabelFontSizeRatio, gaugeOptions?.axisLabelFontSizeMin, gaugeOptions?.axisLabelFontSizeMax)
468
+ : gaugeOptions?.axisLabelFontSize || 16,
469
+ fontWeight: 'bold',
470
+ fontFamily: gaugeOptionsColors?.fontFamily
471
+ },
472
+ // pointer properties
473
+ pointer: {
474
+ ...(gaugeOptions?.pointerStyle !== 'default' && {
475
+ icon: gaugeOptions?.pointerStyle
476
+ }),
477
+ show: gaugeOptions?.showPointer || false,
478
+ length: gaugeOptions?.pointerLengthRatio
479
+ ? gaugeOptions?.pointerLengthRatio *
480
+ (this.containerSize * gaugeOptions?.axisLineWidthRatio)
481
+ : gaugeOptions?.pointerLength || '65%',
482
+ width: gaugeOptions?.pointerWidthRatio
483
+ ? this.containerSize *
484
+ gaugeOptions?.axisLineWidthRatio *
485
+ gaugeOptions?.pointerWidthRatio
486
+ : gaugeOptions?.pointerWidth || 40,
487
+ offsetCenter: selectedPresetId === 'default'
488
+ ? [0, this.containerSize * gaugeOptions?.axisLineWidthRatio * -1]
489
+ : [0, gaugeOptions?.pointerOffset || -30],
490
+ itemStyle: {
491
+ color: selectedPresetId === 'custom'
492
+ ? gaugeOptions.pointerColor
493
+ : gaugeOptionsColors?.pointerColor || 'inherit'
494
+ }
495
+ },
496
+ // Progress bar properties
497
+ progress: {
498
+ show: gaugeOptions?.progressBar || false,
499
+ roundCap: gaugeOptions?.progressBarRoundCap || false,
500
+ width: gaugeOptions?.progressBarWidthRatio
501
+ ? this.containerSize *
502
+ gaugeOptions?.axisLineWidthRatio *
503
+ gaugeOptions?.progressBarWidthRatio
504
+ : gaugeOptions?.progressBarWidth || 18,
505
+ itemStyle: {
506
+ color: selectedPresetId === 'custom'
507
+ ? gaugeOptions.progressBarColor
508
+ : gaugeOptionsColors?.progressBarColor || 'inherit'
509
+ }
510
+ },
511
+ // Anchor properties
512
+ anchor: gaugeOptions?.anchor
513
+ ? {
514
+ ...gaugeOptions.anchor,
515
+ size: gaugeOptions?.anchor?.sizeRatio
516
+ ? this.containerSize * gaugeOptions?.anchor?.sizeRatio
517
+ : gaugeOptions?.anchor?.size || 45,
518
+ itemStyle: {
519
+ color: selectedPresetId === 'custom'
520
+ ? gaugeOptions.pointerColor
521
+ : gaugeOptionsColors?.pointerColor
522
+ }
523
+ }
524
+ : undefined,
525
+ // Detail properties
526
+ detail: {
527
+ show: gaugeOptions?.showDetail || false,
528
+ valueAnimation: true,
529
+ offsetCenter: gaugeOptions?.detailOffsetCenterYRatio
530
+ ? [0, gaugeOptions?.detailOffsetCenterYRatio * this.containerSize]
531
+ : gaugeOptions?.detailOffsetCenter || [0, 0],
532
+ formatter: () => {
533
+ const value = measurement?.value.toFixed(fractionSize) || 0;
534
+ const unit = activeDatapointGauge?.unit || measurement?.unit || '';
535
+ const date = new Date(measurement?.date);
536
+ const formattedDate = this.c8yDatePipe.transform(date);
537
+ return `{value|${value}}{unit|${unit}} \n {date|${formattedDate}} `;
538
+ },
539
+ color: 'inherit',
540
+ lineHeight: gaugeOptions?.measurementValueFontRatio
541
+ ? this.clampRelative(gaugeOptions?.measurementValueFontRatio * 0.9, gaugeOptions?.measurementValueFontSizeMin, gaugeOptions?.measurementValueFontSizeMax)
542
+ : gaugeOptions?.measurementValueFontSize || 32,
543
+ rich: {
544
+ value: {
545
+ fontSize: gaugeOptions?.measurementValueFontRatio
546
+ ? this.clampRelative(fractionSize > 5 || measurement?.value > 9999
547
+ ? gaugeOptions?.measurementValueFontRatio * 0.5
548
+ : gaugeOptions?.measurementValueFontRatio, gaugeOptions?.measurementValueFontSizeMin, gaugeOptions?.measurementValueFontSizeMax)
549
+ : gaugeOptions?.measurementValueFontSize || 32,
550
+ fontWeight: 'bolder',
551
+ fontFamily: gaugeOptionsColors?.fontFamily,
552
+ color: selectedPresetId === 'custom'
553
+ ? gaugeOptions.measurementValueColor
554
+ : gaugeOptionsColors?.measurementValueColor || '#777'
555
+ },
556
+ unit: {
557
+ fontSize: gaugeOptions?.unitFontRatio
558
+ ? this.clampRelative(gaugeOptions?.unitFontRatio, gaugeOptions?.unitFontMin, gaugeOptions?.unitFontMax)
559
+ : gaugeOptions?.unitFontSize || 20,
560
+ fontFamily: gaugeOptionsColors?.fontFamily,
561
+ color: selectedPresetId === 'custom'
562
+ ? gaugeOptions?.unitColor
563
+ : gaugeOptionsColors?.unitColor || '#999'
564
+ },
565
+ date: {
566
+ fontSize: gaugeOptions?.dateFontRatio
567
+ ? this.clampRelative(gaugeOptions?.dateFontRatio, gaugeOptions?.dateFontSizeMin, gaugeOptions?.dateFontSizeMax)
568
+ : gaugeOptions?.dateFontSize || 12,
569
+ fontFamily: gaugeOptionsColors?.fontFamily,
570
+ color: selectedPresetId === 'custom'
571
+ ? gaugeOptions?.dateColor
572
+ : gaugeOptionsColors?.dateColor || '#555'
573
+ }
574
+ }
575
+ },
576
+ markPoint: {
577
+ symbolSize: 0,
578
+ offsetCenter: gaugeOptions?.detailOffsetCenter || [0, 0],
579
+ data: [
580
+ {
581
+ x: '50%',
582
+ y: '50%',
583
+ label: {
584
+ show: gaugeOptions?.showMarkPoint,
585
+ formatter: () => {
586
+ const value = measurement?.value.toFixed(fractionSize) || 0;
587
+ const unit = activeDatapointGauge?.unit || measurement?.unit || '';
588
+ const date = new Date(measurement?.date);
589
+ const formattedDate = this.c8yDatePipe.transform(date);
590
+ return `{value|${value}}{unit|${unit}} \n {date|${formattedDate}} `;
591
+ },
592
+ color: '#fff',
593
+ align: 'center',
594
+ rich: {
595
+ value: {
596
+ fontSize: gaugeOptions?.measurementValueFontRatio
597
+ ? this.clampRelative(fractionSize > 5
598
+ ? gaugeOptions?.measurementValueFontRatio * 0.5
599
+ : gaugeOptions?.measurementValueFontRatio, fractionSize > 5
600
+ ? gaugeOptions.measurementValueFontMin * 0.5
601
+ : gaugeOptions?.measurementValueFontSizeMin, gaugeOptions?.measurementValueFontSizeMax)
602
+ : gaugeOptions?.measurementValueFontSize || 32,
603
+ fontFamily: gaugeOptionsColors?.fontFamily,
604
+ fontWeight: 'bolder',
605
+ color: gaugeOptionsColors?.knobFontColor || '#777'
606
+ },
607
+ unit: {
608
+ fontSize: gaugeOptions?.unitFontRatio
609
+ ? this.clampRelative(gaugeOptions?.unitFontRatio, gaugeOptions?.unitFontSizeMin, gaugeOptions?.unitFontSizeMax)
610
+ : gaugeOptions?.unitFontSize || 20,
611
+ fontFamily: gaugeOptionsColors?.fontFamily,
612
+ color: gaugeOptionsColors?.knobFontColor || '#999'
613
+ },
614
+ date: {
615
+ fontSize: gaugeOptions?.dateFontRatio
616
+ ? this.clampRelative(gaugeOptions?.dateFontRatio, gaugeOptions?.dateFontSizeMin, gaugeOptions?.dateFontSizeMax)
617
+ : gaugeOptions?.dateFontSize || 12,
618
+ fontFamily: gaugeOptionsColors?.fontFamily,
619
+ color: gaugeOptionsColors?.knobFontColor || '#555'
620
+ }
621
+ }
622
+ }
623
+ }
624
+ ]
625
+ },
626
+ data: [
627
+ {
628
+ value: 0 || measurement?.value
629
+ }
630
+ ]
631
+ }
632
+ ]
633
+ };
634
+ }
635
+ updateRangeColors() {
636
+ if (!this.chart) {
637
+ return;
638
+ }
639
+ return {
640
+ default: getComputedStyle(this.chart.nativeElement).getPropertyValue('--c8y-form-control-border-color-default'),
641
+ yellow: getComputedStyle(this.chart.nativeElement).getPropertyValue('--c8y-palette-status-warning'),
642
+ red: getComputedStyle(this.chart.nativeElement).getPropertyValue('--c8y-palette-status-danger')
643
+ };
644
+ }
645
+ updateGaugeOptionsColors() {
646
+ if (!this.chart) {
647
+ return;
648
+ }
649
+ return {
650
+ splitLineColor: getComputedStyle(this.chart.nativeElement).getPropertyValue('--c8y-root-component-background-default'),
651
+ tickColor: getComputedStyle(this.chart.nativeElement).getPropertyValue('--c8y-root-component-background-default'),
652
+ axisLabelColor: getComputedStyle(this.chart.nativeElement).getPropertyValue('--c8y-root-component-color-default'),
653
+ pointerColor: getComputedStyle(this.chart.nativeElement).getPropertyValue('--c8y-root-component-color-default'),
654
+ knobColor: getComputedStyle(this.chart.nativeElement).getPropertyValue('--c8y-root-component-color-default'),
655
+ knobFontColor: getComputedStyle(this.chart.nativeElement).getPropertyValue('--c8y-root-component-background-default'),
656
+ measurementValueColor: getComputedStyle(this.chart.nativeElement).getPropertyValue('--c8y-root-component-color-default'),
657
+ unitColor: getComputedStyle(this.chart.nativeElement).getPropertyValue('--c8y-root-component-color-default'),
658
+ dateColor: getComputedStyle(this.chart.nativeElement).getPropertyValue('--c8y-root-component-text-muted'),
659
+ progressBarColor: getComputedStyle(this.chart.nativeElement).getPropertyValue('--c8y-root-component-brand-primary'),
660
+ fontFamily: getComputedStyle(document.body).getPropertyValue('font-family')
661
+ };
662
+ }
663
+ getColorArray(activeDatapointGauge, rangeColors) {
664
+ const min = activeDatapointGauge?.min ?? 0;
665
+ const max = activeDatapointGauge?.max ?? 100;
666
+ const range = max - min;
667
+ const yellowMin = activeDatapointGauge?.yellowRangeMin;
668
+ const yellowMax = activeDatapointGauge?.yellowRangeMax;
669
+ const redMin = activeDatapointGauge?.redRangeMin;
670
+ const redMax = activeDatapointGauge?.redRangeMax;
671
+ const ranges = [];
672
+ // First add red range
673
+ if (redMin != null && redMax != null && redMin < redMax) {
674
+ ranges.push({ start: redMin, end: redMax, color: rangeColors.red });
675
+ }
676
+ // Then add yellow, but clip out any overlap with red
677
+ if (yellowMin != null && yellowMax != null && yellowMin < yellowMax) {
678
+ const redRange = ranges.find(r => r.color === rangeColors.red);
679
+ if (!redRange ||
680
+ yellowMax <= redRange.start || // yellow ends before red
681
+ yellowMin >= redRange.end // yellow starts after red
682
+ ) {
683
+ // no overlap
684
+ ranges.push({ start: yellowMin, end: yellowMax, color: rangeColors.yellow });
685
+ }
686
+ else {
687
+ // partial overlap – split yellow into non-overlapping parts
688
+ if (yellowMin < redRange.start) {
689
+ ranges.push({
690
+ start: yellowMin,
691
+ end: Math.min(yellowMax, redRange.start),
692
+ color: rangeColors.yellow
693
+ });
694
+ }
695
+ if (yellowMax > redRange.end) {
696
+ ranges.push({
697
+ start: Math.max(yellowMin, redRange.end),
698
+ end: yellowMax,
699
+ color: rangeColors.yellow
700
+ });
701
+ }
702
+ }
703
+ }
704
+ // Sort by start position
705
+ ranges.sort((a, b) => a.start - b.start);
706
+ // Build segments
707
+ const segments = [];
708
+ let current = min;
709
+ for (const { start, end, color } of ranges) {
710
+ if (start > current) {
711
+ // Default fill before this range
712
+ segments.push([(start - min) / range, rangeColors.default]);
713
+ }
714
+ // Start color
715
+ segments.push([(start - min) / range, color]);
716
+ // End color
717
+ segments.push([(end - min) / range, color]);
718
+ current = Math.max(current, end);
719
+ }
720
+ // Fill remaining with default
721
+ if (current < max) {
722
+ segments.push([(current - min) / range, rangeColors.default]);
723
+ }
724
+ if (segments.length === 0 || segments[segments.length - 1][0] < 1) {
725
+ segments.push([1, rangeColors.default]);
726
+ }
727
+ return segments;
728
+ }
729
+ clampRelative(ratio, min, max) {
730
+ const clampedValue = this.containerSize * ratio;
731
+ if (clampedValue < min) {
732
+ return min;
733
+ }
734
+ else if (clampedValue > max) {
735
+ return max;
736
+ }
737
+ else {
738
+ return clampedValue;
739
+ }
740
+ }
741
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RadialGaugeService, deps: [{ token: i1.DatePipe }], target: i0.ɵɵFactoryTarget.Injectable }); }
742
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RadialGaugeService, providedIn: 'root' }); }
743
+ }
744
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RadialGaugeService, decorators: [{
745
+ type: Injectable,
746
+ args: [{
747
+ providedIn: 'root'
748
+ }]
749
+ }], ctorParameters: () => [{ type: i1.DatePipe }] });
750
+
751
+ class RadialGaugeViewComponent {
752
+ constructor() {
753
+ this.fractionSize = 2;
754
+ this.selectedPresetId = '';
755
+ this.rangeColors = { default: '#E8EBED', yellow: '#ff8800', red: '#d70f0f' };
756
+ this.configChangedSubject = new BehaviorSubject(null);
757
+ this.themeSwitcherService = inject(ThemeSwitcherService);
758
+ this.radialGaugeService = inject(RadialGaugeService);
759
+ this.chartOptions$ = this.configChangedSubject.pipe(switchMap(() => of(this.radialGaugeService.getChartOptions(this.gaugeOptions, this.activeDatapointGauge, this.selectedPresetId, this.gaugeOptionsColors, this.rangeColors, this.measurement, this.fractionSize))), tap(options => {
760
+ if (this.echartsInstance) {
761
+ this.echartsInstance.setOption(options, false, true);
762
+ }
763
+ }));
764
+ }
765
+ ngOnInit() {
766
+ if (!this.gaugeOptions) {
767
+ this.gaugeOptions = GAUGE_PRESETS[0];
768
+ }
769
+ this.themeSubscription = this.themeSwitcherService.currentlyAppliedTheme$.subscribe(() => {
770
+ queueMicrotask(() => {
771
+ this.radialGaugeService.setChart(this.chart);
772
+ this.rangeColors = this.radialGaugeService.updateRangeColors();
773
+ this.gaugeOptionsColors = this.radialGaugeService.updateGaugeOptionsColors();
774
+ requestAnimationFrame(() => {
775
+ this.configChangedSubject.next();
776
+ });
777
+ });
778
+ });
779
+ }
780
+ ngAfterViewInit() {
781
+ this.resizeObserver = new ResizeObserver(entries => {
782
+ for (const entry of entries) {
783
+ if (entry.contentRect.width > 0 && entry.contentRect.height > 0) {
784
+ this.radialGaugeService.containerSize =
785
+ entry.contentRect.width >= entry.contentRect.height
786
+ ? entry.contentRect.height
787
+ : entry.contentRect.width;
788
+ this.configChangedSubject.next();
789
+ }
790
+ }
791
+ });
792
+ this.resizeObserver.observe(this.chart.nativeElement);
793
+ }
794
+ ngOnDestroy() {
795
+ if (this.themeSubscription) {
796
+ this.themeSubscription.unsubscribe();
797
+ }
798
+ if (this.resizeObserver) {
799
+ this.resizeObserver.disconnect();
800
+ }
801
+ }
802
+ ngOnChanges(changes) {
803
+ if (changes.gaugeOptions || changes.measurement || changes.activeDatapointGauge) {
804
+ this.configChangedSubject.next();
805
+ }
806
+ }
807
+ onChartInit(ec) {
808
+ this.echartsInstance = ec;
809
+ }
810
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RadialGaugeViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
811
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: RadialGaugeViewComponent, isStandalone: true, selector: "c8y-radial-gauge", inputs: { activeDatapointGauge: "activeDatapointGauge", measurement: "measurement", fractionSize: "fractionSize", gaugeOptions: "gaugeOptions", selectedPresetId: "selectedPresetId" }, host: { classAttribute: "c8y-radial-gauge" }, providers: [
812
+ MeasurementRealtimeService,
813
+ RadialGaugeService,
814
+ { provide: NGX_ECHARTS_CONFIG, useFactory: () => ({ echarts: () => import('echarts') }) }
815
+ ], viewQueries: [{ propertyName: "chart", first: true, predicate: ["chart"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n class=\"p-absolute fit-w fit-h\"\n data-cy=\"c8y-radial-gauge--chart\"\n #chart\n echarts\n [options]=\"chartOptions$ | async\"\n (chartInit)=\"onChartInit($event)\"\n></div>\n", dependencies: [{ kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "ngmodule", type: NgxEchartsModule }, { kind: "directive", type: i1$1.NgxEchartsDirective, selector: "echarts, [echarts]", inputs: ["options", "theme", "initOpts", "merge", "autoResize", "loading", "loadingType", "loadingOpts"], outputs: ["chartInit", "optionsError", "chartClick", "chartDblClick", "chartMouseDown", "chartMouseMove", "chartMouseUp", "chartMouseOver", "chartMouseOut", "chartGlobalOut", "chartContextMenu", "chartHighlight", "chartDownplay", "chartSelectChanged", "chartLegendSelectChanged", "chartLegendSelected", "chartLegendUnselected", "chartLegendLegendSelectAll", "chartLegendLegendInverseSelect", "chartLegendScroll", "chartDataZoom", "chartDataRangeSelected", "chartGraphRoam", "chartGeoRoam", "chartTreeRoam", "chartTimelineChanged", "chartTimelinePlayChanged", "chartRestore", "chartDataViewChanged", "chartMagicTypeChanged", "chartGeoSelectChanged", "chartGeoSelected", "chartGeoUnselected", "chartAxisAreaSelected", "chartBrush", "chartBrushEnd", "chartBrushSelected", "chartGlobalCursorTaken", "chartRendered", "chartFinished"], exportAs: ["echarts"] }] }); }
816
+ }
817
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RadialGaugeViewComponent, decorators: [{
818
+ type: Component,
819
+ args: [{ selector: 'c8y-radial-gauge', host: { class: 'c8y-radial-gauge' }, providers: [
820
+ MeasurementRealtimeService,
821
+ RadialGaugeService,
822
+ { provide: NGX_ECHARTS_CONFIG, useFactory: () => ({ echarts: () => import('echarts') }) }
823
+ ], standalone: true, imports: [AsyncPipe, NgxEchartsModule], template: "<div\n class=\"p-absolute fit-w fit-h\"\n data-cy=\"c8y-radial-gauge--chart\"\n #chart\n echarts\n [options]=\"chartOptions$ | async\"\n (chartInit)=\"onChartInit($event)\"\n></div>\n" }]
824
+ }], ctorParameters: () => [], propDecorators: { activeDatapointGauge: [{
825
+ type: Input
826
+ }], measurement: [{
827
+ type: Input
828
+ }], fractionSize: [{
829
+ type: Input
830
+ }], gaugeOptions: [{
831
+ type: Input
832
+ }], selectedPresetId: [{
833
+ type: Input
834
+ }], chart: [{
835
+ type: ViewChild,
836
+ args: ['chart', { static: false }]
837
+ }] } });
85
838
 
86
839
  class InfoGaugeWidgetViewComponent {
87
- constructor(dashboard) {
840
+ constructor(dashboard, dynamicComponent) {
88
841
  this.dashboard = dashboard;
842
+ this.dynamicComponent = dynamicComponent;
89
843
  this.activeDatapointLabels = [];
90
844
  this.fractionSize = '1.1-1';
91
845
  }
846
+ ngOnInit() {
847
+ if (this.config?.datapoints && !this.config.datapointsGauge) {
848
+ this.config.datapointsGauge = this.config.datapoints;
849
+ }
850
+ }
92
851
  ngOnChanges() {
93
852
  if (this.config?.datapointsLabels && Array.isArray(this.config?.datapointsLabels)) {
94
853
  this.config.datapointsLabels.forEach(dp => this.assignContextFromContextDashboard(dp));
@@ -98,9 +857,17 @@ class InfoGaugeWidgetViewComponent {
98
857
  this.config.datapointsGauge.forEach(dp => this.assignContextFromContextDashboard(dp));
99
858
  this.activeDatapointGauge = this.config?.datapointsGauge.find(dp => dp.__active);
100
859
  }
860
+ if (this.config?.datapoints &&
861
+ Array.isArray(this.config?.datapoints) &&
862
+ this.config?.datapoints.length > 0 &&
863
+ !this.config?.datapointsGauge) {
864
+ this.config.datapoints.forEach(dp => this.assignContextFromContextDashboard(dp));
865
+ this.activeDatapointGauge = this.config?.datapoints.find(dp => dp.__active);
866
+ }
101
867
  if (typeof this.config.fractionSize === 'number' && !Number.isNaN(this.config.fractionSize)) {
102
868
  this.fractionSize = `1.${this.config.fractionSize}-${this.config.fractionSize}`;
103
869
  }
870
+ this.isInfoGauge = this.dynamicComponent?.componentId === defaultWidgetIds.INFO_GAUGE;
104
871
  }
105
872
  assignContextFromContextDashboard(datapoint) {
106
873
  if (!this.dashboard?.isDeviceTypeDashboard) {
@@ -112,18 +879,89 @@ class InfoGaugeWidgetViewComponent {
112
879
  datapoint.__target = { name, id };
113
880
  }
114
881
  }
115
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: InfoGaugeWidgetViewComponent, deps: [{ token: i1.ContextDashboardComponent, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
116
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: InfoGaugeWidgetViewComponent, isStandalone: true, selector: "c8y-info-gauge-widget-view", inputs: { config: "config" }, host: { classAttribute: "d-contents" }, providers: [MeasurementRealtimeService], usesOnChanges: true, ngImport: i0, template: "<div class=\"label-value-unit-gauge\">\n <div\n class=\"gauge-legend\"\n *ngIf=\"activeDatapointLabels?.length\"\n >\n <ng-container *ngFor=\"let dp of activeDatapointLabels\">\n <ng-container *ngIf=\"dp | infoGaugeCurrentMeasurement | async as measurement\">\n <label\n class=\"text-truncate\"\n title=\"{{ dp.label }}\"\n >\n {{ dp.label }}\n </label>\n <h3\n class=\"text-truncate\"\n title=\"{{ measurement.value | number: fractionSize }} {{ dp.unit || measurement.unit }}\"\n *ngIf=\"!measurement.notFound; else notFound\"\n >\n {{ measurement.value | number: fractionSize }} {{ dp.unit || measurement.unit }}\n </h3>\n <ng-template #notFound>\n <h3>--</h3>\n </ng-template>\n <p class=\"text-muted m-b-8\">\n <small>\n <em>{{ measurement.date | c8yDate: 'short' }}</em>\n </small>\n </p>\n </ng-container>\n </ng-container>\n </div>\n\n <ng-container *ngIf=\"activeDatapointGauge\">\n <div\n class=\"gauge-svg\"\n *ngIf=\"activeDatapointGauge | infoGaugeCurrentMeasurement: true | async as measurement\"\n >\n <svg\n height=\"214px\"\n width=\"214px\"\n viewBox=\"0 0 214 214\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <desc>radial gauge</desc>\n <g\n id=\"scale\"\n stroke=\"none\"\n stroke-width=\"1\"\n fill=\"none\"\n fill-rule=\"evenodd\"\n stroke-dasharray=\"1,5\"\n >\n <circle\n id=\"Oval\"\n stroke=\"#CACECE\"\n stroke-width=\"7\"\n cx=\"107\"\n cy=\"107\"\n r=\"103\"\n ></circle>\n <rect\n id=\"mask\"\n height=\"214\"\n stroke=\"none\"\n fill-rule=\"evenodd\"\n x=\"0\"\n y=\"0\"\n width=\"214\"\n transform=\"rotate(-45 290 182)\"\n ></rect>\n </g>\n <path\n class=\"track\"\n d=\"M 107 27 a 80 80 0 1 0.1 0 Z\"\n transform=\"rotate(-135 107 107)\"\n ></path>\n <path\n class=\"track-value\"\n [ngStyle]=\"{\n stroke: measurement.color,\n 'stroke-dashoffset': -measurement.strokeDashOffset\n }\"\n d=\"M 107 27 a 80 80 0 1 0.1 0 Z\"\n transform=\"rotate(-135 107 107)\"\n ></path>\n <foreignObject\n class=\"d-flex a-i-center j-c-center\"\n height=\"100%\"\n width=\"100%\"\n requiredFeatures=\"http://www.w3.org/TR/SVG11/feature#Extensibility\"\n >\n <div\n class=\"d-flex d-col fit-h a-i-center j-c-center\"\n style=\"padding: 3rem\"\n xmlns=\"http://www.w3.org/1999/xhtml\"\n >\n <p\n class=\"text-truncate text-center\"\n title=\"{{ activeDatapointGauge.label }}\"\n >\n {{ activeDatapointGauge.label }}\n </p>\n <p\n class=\"center-value text-truncate\"\n title=\"{{ measurement.value | number: fractionSize }}\"\n *ngIf=\"!measurement.notFound; else notFoundSVG\"\n >\n {{ measurement.value | number: fractionSize }}\n </p>\n <ng-template #notFoundSVG>\n <p class=\"center-value\">--</p>\n </ng-template>\n <p class=\"center-unit strong\">{{ activeDatapointGauge.unit || measurement.unit }}</p>\n <p class=\"center-date-time\">{{ measurement.date | c8yDate: 'short' }}</p>\n </div>\n </foreignObject>\n </svg>\n </div>\n </ng-container>\n <div class=\"clearfix\"></div>\n</div>\n", dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: InfoGaugeCurrentMeasurementPipe, name: "infoGaugeCurrentMeasurement" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: DecimalPipe, name: "number" }, { kind: "pipe", type: DatePipe, name: "c8yDate" }] }); }
882
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: InfoGaugeWidgetViewComponent, deps: [{ token: i1$2.ContextDashboardComponent, optional: true }, { token: i1.DynamicComponentComponent, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
883
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: InfoGaugeWidgetViewComponent, isStandalone: true, selector: "c8y-info-gauge-widget-view", inputs: { config: "config" }, host: { classAttribute: "d-contents" }, providers: [MeasurementRealtimeService], usesOnChanges: true, ngImport: i0, template: "<div\n class=\"label-value-unit-gauge new-radial\"\n *ngIf=\"isInfoGauge\"\n>\n <div\n class=\"gauge-legend\"\n *ngIf=\"activeDatapointLabels?.length && isInfoGauge\"\n >\n <ng-container *ngFor=\"let dp of activeDatapointLabels\">\n <ng-container *ngIf=\"dp | infoGaugeCurrentMeasurement | async as measurement\">\n <label\n class=\"text-truncate\"\n title=\"{{ dp.label }}\"\n >\n {{ dp.label }}\n </label>\n <h3\n class=\"text-truncate\"\n title=\"{{ measurement.value | number: fractionSize }} {{ dp.unit || measurement.unit }}\"\n *ngIf=\"!measurement.notFound; else notFound\"\n >\n {{ measurement.value | number: fractionSize }} {{ dp.unit || measurement.unit }}\n </h3>\n <ng-template #notFound>\n <h3>--</h3>\n </ng-template>\n <p class=\"text-muted m-b-8\">\n <small>\n <em>{{ measurement.date | c8yDate: 'short' }}</em>\n </small>\n </p>\n </ng-container>\n </ng-container>\n </div>\n\n <ng-container *ngIf=\"activeDatapointGauge && isInfoGauge\">\n <div\n class=\"gauge-svg\"\n *ngIf=\"activeDatapointGauge | infoGaugeCurrentMeasurement: true | async as measurement\"\n >\n <svg\n height=\"214px\"\n width=\"214px\"\n viewBox=\"0 0 214 214\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <desc>radial gauge</desc>\n <g\n id=\"scale\"\n stroke=\"none\"\n stroke-width=\"1\"\n fill=\"none\"\n fill-rule=\"evenodd\"\n stroke-dasharray=\"1,5\"\n >\n <circle\n id=\"Oval\"\n stroke=\"#CACECE\"\n stroke-width=\"7\"\n cx=\"107\"\n cy=\"107\"\n r=\"103\"\n ></circle>\n <rect\n id=\"mask\"\n height=\"214\"\n stroke=\"none\"\n fill-rule=\"evenodd\"\n x=\"0\"\n y=\"0\"\n width=\"214\"\n transform=\"rotate(-45 290 182)\"\n ></rect>\n </g>\n <path\n class=\"track\"\n d=\"M 107 27 a 80 80 0 1 0.1 0 Z\"\n transform=\"rotate(-135 107 107)\"\n ></path>\n <path\n class=\"track-value\"\n [ngStyle]=\"{\n stroke: measurement.color,\n 'stroke-dashoffset': -measurement.strokeDashOffset\n }\"\n d=\"M 107 27 a 80 80 0 1 0.1 0 Z\"\n transform=\"rotate(-135 107 107)\"\n ></path>\n <foreignObject\n class=\"d-flex a-i-center j-c-center\"\n height=\"100%\"\n width=\"100%\"\n requiredFeatures=\"http://www.w3.org/TR/SVG11/feature#Extensibility\"\n >\n <div\n class=\"d-flex d-col fit-h a-i-center j-c-center\"\n style=\"padding: 3rem\"\n xmlns=\"http://www.w3.org/1999/xhtml\"\n >\n <p\n class=\"text-truncate text-center\"\n title=\"{{ activeDatapointGauge.label }}\"\n >\n {{ activeDatapointGauge.label }}\n </p>\n <p\n class=\"center-value text-truncate\"\n title=\"{{ measurement.value | number: fractionSize }}\"\n *ngIf=\"!measurement.notFound; else notFoundSVG\"\n >\n {{ measurement.value | number: fractionSize }}\n </p>\n <ng-template #notFoundSVG>\n <p class=\"center-value\">--</p>\n </ng-template>\n <p class=\"center-unit strong\">{{ activeDatapointGauge.unit || measurement.unit }}</p>\n <p class=\"center-date-time\">{{ measurement.date | c8yDate: 'short' }}</p>\n </div>\n </foreignObject>\n </svg>\n </div>\n </ng-container>\n\n <div class=\"clearfix\"></div>\n</div>\n<ng-container *ngIf=\"!isInfoGauge\">\n <c8y-radial-gauge\n *ngIf=\"activeDatapointGauge | infoGaugeCurrentMeasurement | async as measurement\"\n [activeDatapointGauge]=\"activeDatapointGauge\"\n [measurement]=\"measurement\"\n [fractionSize]=\"config.fractionSize\"\n [gaugeOptions]=\"config.gaugeOptions\"\n [selectedPresetId]=\"config.selectedPresetId\"\n ></c8y-radial-gauge>\n</ng-container>\n", dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: InfoGaugeCurrentMeasurementPipe, name: "infoGaugeCurrentMeasurement" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: DecimalPipe, name: "number" }, { kind: "pipe", type: DatePipe, name: "c8yDate" }, { kind: "component", type: RadialGaugeViewComponent, selector: "c8y-radial-gauge", inputs: ["activeDatapointGauge", "measurement", "fractionSize", "gaugeOptions", "selectedPresetId"] }] }); }
117
884
  }
118
885
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: InfoGaugeWidgetViewComponent, decorators: [{
119
886
  type: Component,
120
- args: [{ selector: 'c8y-info-gauge-widget-view', host: { class: 'd-contents' }, providers: [MeasurementRealtimeService], standalone: true, imports: [NgIf, NgFor, NgStyle, InfoGaugeCurrentMeasurementPipe, AsyncPipe, DecimalPipe, DatePipe], template: "<div class=\"label-value-unit-gauge\">\n <div\n class=\"gauge-legend\"\n *ngIf=\"activeDatapointLabels?.length\"\n >\n <ng-container *ngFor=\"let dp of activeDatapointLabels\">\n <ng-container *ngIf=\"dp | infoGaugeCurrentMeasurement | async as measurement\">\n <label\n class=\"text-truncate\"\n title=\"{{ dp.label }}\"\n >\n {{ dp.label }}\n </label>\n <h3\n class=\"text-truncate\"\n title=\"{{ measurement.value | number: fractionSize }} {{ dp.unit || measurement.unit }}\"\n *ngIf=\"!measurement.notFound; else notFound\"\n >\n {{ measurement.value | number: fractionSize }} {{ dp.unit || measurement.unit }}\n </h3>\n <ng-template #notFound>\n <h3>--</h3>\n </ng-template>\n <p class=\"text-muted m-b-8\">\n <small>\n <em>{{ measurement.date | c8yDate: 'short' }}</em>\n </small>\n </p>\n </ng-container>\n </ng-container>\n </div>\n\n <ng-container *ngIf=\"activeDatapointGauge\">\n <div\n class=\"gauge-svg\"\n *ngIf=\"activeDatapointGauge | infoGaugeCurrentMeasurement: true | async as measurement\"\n >\n <svg\n height=\"214px\"\n width=\"214px\"\n viewBox=\"0 0 214 214\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <desc>radial gauge</desc>\n <g\n id=\"scale\"\n stroke=\"none\"\n stroke-width=\"1\"\n fill=\"none\"\n fill-rule=\"evenodd\"\n stroke-dasharray=\"1,5\"\n >\n <circle\n id=\"Oval\"\n stroke=\"#CACECE\"\n stroke-width=\"7\"\n cx=\"107\"\n cy=\"107\"\n r=\"103\"\n ></circle>\n <rect\n id=\"mask\"\n height=\"214\"\n stroke=\"none\"\n fill-rule=\"evenodd\"\n x=\"0\"\n y=\"0\"\n width=\"214\"\n transform=\"rotate(-45 290 182)\"\n ></rect>\n </g>\n <path\n class=\"track\"\n d=\"M 107 27 a 80 80 0 1 0.1 0 Z\"\n transform=\"rotate(-135 107 107)\"\n ></path>\n <path\n class=\"track-value\"\n [ngStyle]=\"{\n stroke: measurement.color,\n 'stroke-dashoffset': -measurement.strokeDashOffset\n }\"\n d=\"M 107 27 a 80 80 0 1 0.1 0 Z\"\n transform=\"rotate(-135 107 107)\"\n ></path>\n <foreignObject\n class=\"d-flex a-i-center j-c-center\"\n height=\"100%\"\n width=\"100%\"\n requiredFeatures=\"http://www.w3.org/TR/SVG11/feature#Extensibility\"\n >\n <div\n class=\"d-flex d-col fit-h a-i-center j-c-center\"\n style=\"padding: 3rem\"\n xmlns=\"http://www.w3.org/1999/xhtml\"\n >\n <p\n class=\"text-truncate text-center\"\n title=\"{{ activeDatapointGauge.label }}\"\n >\n {{ activeDatapointGauge.label }}\n </p>\n <p\n class=\"center-value text-truncate\"\n title=\"{{ measurement.value | number: fractionSize }}\"\n *ngIf=\"!measurement.notFound; else notFoundSVG\"\n >\n {{ measurement.value | number: fractionSize }}\n </p>\n <ng-template #notFoundSVG>\n <p class=\"center-value\">--</p>\n </ng-template>\n <p class=\"center-unit strong\">{{ activeDatapointGauge.unit || measurement.unit }}</p>\n <p class=\"center-date-time\">{{ measurement.date | c8yDate: 'short' }}</p>\n </div>\n </foreignObject>\n </svg>\n </div>\n </ng-container>\n <div class=\"clearfix\"></div>\n</div>\n" }]
121
- }], ctorParameters: () => [{ type: i1.ContextDashboardComponent, decorators: [{
887
+ args: [{ selector: 'c8y-info-gauge-widget-view', host: { class: 'd-contents' }, providers: [MeasurementRealtimeService], standalone: true, imports: [
888
+ NgIf,
889
+ NgFor,
890
+ NgStyle,
891
+ InfoGaugeCurrentMeasurementPipe,
892
+ AsyncPipe,
893
+ DecimalPipe,
894
+ DatePipe,
895
+ RadialGaugeViewComponent
896
+ ], template: "<div\n class=\"label-value-unit-gauge new-radial\"\n *ngIf=\"isInfoGauge\"\n>\n <div\n class=\"gauge-legend\"\n *ngIf=\"activeDatapointLabels?.length && isInfoGauge\"\n >\n <ng-container *ngFor=\"let dp of activeDatapointLabels\">\n <ng-container *ngIf=\"dp | infoGaugeCurrentMeasurement | async as measurement\">\n <label\n class=\"text-truncate\"\n title=\"{{ dp.label }}\"\n >\n {{ dp.label }}\n </label>\n <h3\n class=\"text-truncate\"\n title=\"{{ measurement.value | number: fractionSize }} {{ dp.unit || measurement.unit }}\"\n *ngIf=\"!measurement.notFound; else notFound\"\n >\n {{ measurement.value | number: fractionSize }} {{ dp.unit || measurement.unit }}\n </h3>\n <ng-template #notFound>\n <h3>--</h3>\n </ng-template>\n <p class=\"text-muted m-b-8\">\n <small>\n <em>{{ measurement.date | c8yDate: 'short' }}</em>\n </small>\n </p>\n </ng-container>\n </ng-container>\n </div>\n\n <ng-container *ngIf=\"activeDatapointGauge && isInfoGauge\">\n <div\n class=\"gauge-svg\"\n *ngIf=\"activeDatapointGauge | infoGaugeCurrentMeasurement: true | async as measurement\"\n >\n <svg\n height=\"214px\"\n width=\"214px\"\n viewBox=\"0 0 214 214\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n >\n <desc>radial gauge</desc>\n <g\n id=\"scale\"\n stroke=\"none\"\n stroke-width=\"1\"\n fill=\"none\"\n fill-rule=\"evenodd\"\n stroke-dasharray=\"1,5\"\n >\n <circle\n id=\"Oval\"\n stroke=\"#CACECE\"\n stroke-width=\"7\"\n cx=\"107\"\n cy=\"107\"\n r=\"103\"\n ></circle>\n <rect\n id=\"mask\"\n height=\"214\"\n stroke=\"none\"\n fill-rule=\"evenodd\"\n x=\"0\"\n y=\"0\"\n width=\"214\"\n transform=\"rotate(-45 290 182)\"\n ></rect>\n </g>\n <path\n class=\"track\"\n d=\"M 107 27 a 80 80 0 1 0.1 0 Z\"\n transform=\"rotate(-135 107 107)\"\n ></path>\n <path\n class=\"track-value\"\n [ngStyle]=\"{\n stroke: measurement.color,\n 'stroke-dashoffset': -measurement.strokeDashOffset\n }\"\n d=\"M 107 27 a 80 80 0 1 0.1 0 Z\"\n transform=\"rotate(-135 107 107)\"\n ></path>\n <foreignObject\n class=\"d-flex a-i-center j-c-center\"\n height=\"100%\"\n width=\"100%\"\n requiredFeatures=\"http://www.w3.org/TR/SVG11/feature#Extensibility\"\n >\n <div\n class=\"d-flex d-col fit-h a-i-center j-c-center\"\n style=\"padding: 3rem\"\n xmlns=\"http://www.w3.org/1999/xhtml\"\n >\n <p\n class=\"text-truncate text-center\"\n title=\"{{ activeDatapointGauge.label }}\"\n >\n {{ activeDatapointGauge.label }}\n </p>\n <p\n class=\"center-value text-truncate\"\n title=\"{{ measurement.value | number: fractionSize }}\"\n *ngIf=\"!measurement.notFound; else notFoundSVG\"\n >\n {{ measurement.value | number: fractionSize }}\n </p>\n <ng-template #notFoundSVG>\n <p class=\"center-value\">--</p>\n </ng-template>\n <p class=\"center-unit strong\">{{ activeDatapointGauge.unit || measurement.unit }}</p>\n <p class=\"center-date-time\">{{ measurement.date | c8yDate: 'short' }}</p>\n </div>\n </foreignObject>\n </svg>\n </div>\n </ng-container>\n\n <div class=\"clearfix\"></div>\n</div>\n<ng-container *ngIf=\"!isInfoGauge\">\n <c8y-radial-gauge\n *ngIf=\"activeDatapointGauge | infoGaugeCurrentMeasurement | async as measurement\"\n [activeDatapointGauge]=\"activeDatapointGauge\"\n [measurement]=\"measurement\"\n [fractionSize]=\"config.fractionSize\"\n [gaugeOptions]=\"config.gaugeOptions\"\n [selectedPresetId]=\"config.selectedPresetId\"\n ></c8y-radial-gauge>\n</ng-container>\n" }]
897
+ }], ctorParameters: () => [{ type: i1$2.ContextDashboardComponent, decorators: [{
898
+ type: Optional
899
+ }] }, { type: i1.DynamicComponentComponent, decorators: [{
122
900
  type: Optional
123
901
  }] }], propDecorators: { config: [{
124
902
  type: Input
125
903
  }] } });
126
904
 
905
+ class PresetPreviewComponent {
906
+ constructor() {
907
+ this.onPresetChange = new EventEmitter();
908
+ this.measurement = {
909
+ value: Math.floor(Math.random() * 9) + 1,
910
+ unit: 'ºC',
911
+ date: '2025-04-22T20:07:49.354Z'
912
+ };
913
+ this.activeDatapointGauge = {
914
+ fragment: 'c8y_Kpi',
915
+ series: 'preview',
916
+ unit: 'ºC',
917
+ min: 0,
918
+ max: 10,
919
+ yellowRangeMax: 8,
920
+ yellowRangeMin: 5,
921
+ redRangeMin: 8,
922
+ redRangeMax: 10
923
+ };
924
+ this.selectedPresetId = null;
925
+ }
926
+ writeValue(value) {
927
+ this.selectedPresetId = value;
928
+ }
929
+ registerOnChange(fn) {
930
+ this.onChange = fn;
931
+ }
932
+ registerOnTouched(fn) {
933
+ this.onTouched = fn;
934
+ }
935
+ emitPresetChange(presetId) {
936
+ this.selectedPresetId = presetId;
937
+ this.onChange(presetId);
938
+ this.onTouched();
939
+ this.onPresetChange.emit(presetId);
940
+ }
941
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PresetPreviewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
942
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: PresetPreviewComponent, isStandalone: true, selector: "c8y-preset-preview", inputs: { ALL_GAUGE_PRESETS: "ALL_GAUGE_PRESETS" }, outputs: { onPresetChange: "onPresetChange" }, providers: [
943
+ {
944
+ provide: NG_VALUE_ACCESSOR,
945
+ useExisting: forwardRef(() => PresetPreviewComponent),
946
+ multi: true
947
+ }
948
+ ], ngImport: i0, template: "<div class=\"d-grid grid__col--4-4-4 gap-4\">\n <button\n class=\"c8y-radial-gauge__preset preset-{{ preset.id }}\"\n [class.selected]=\"preset.id === selectedPresetId\"\n [attr.aria-label]=\"preset.name | translate\"\n type=\"button\"\n *ngFor=\"let preset of ALL_GAUGE_PRESETS\"\n (click)=\"emitPresetChange(preset.id)\"\n >\n <c8y-radial-gauge\n class=\"c8y-radial-gauge--square\"\n *ngIf=\"preset.id !== 'custom'\"\n [activeDatapointGauge]=\"activeDatapointGauge\"\n [measurement]=\"measurement\"\n [fractionSize]=\"2\"\n [selectedPresetId]=\"preset.id\"\n [gaugeOptions]=\"preset\"\n ></c8y-radial-gauge>\n <span>{{ preset.name | translate }}</span>\n </button>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i1.C8yTranslatePipe, name: "translate" }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: RadialGaugeViewComponent, selector: "c8y-radial-gauge", inputs: ["activeDatapointGauge", "measurement", "fractionSize", "gaugeOptions", "selectedPresetId"] }] }); }
949
+ }
950
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PresetPreviewComponent, decorators: [{
951
+ type: Component,
952
+ args: [{ selector: 'c8y-preset-preview', standalone: true, imports: [CommonModule, RadialGaugeViewComponent], providers: [
953
+ {
954
+ provide: NG_VALUE_ACCESSOR,
955
+ useExisting: forwardRef(() => PresetPreviewComponent),
956
+ multi: true
957
+ }
958
+ ], template: "<div class=\"d-grid grid__col--4-4-4 gap-4\">\n <button\n class=\"c8y-radial-gauge__preset preset-{{ preset.id }}\"\n [class.selected]=\"preset.id === selectedPresetId\"\n [attr.aria-label]=\"preset.name | translate\"\n type=\"button\"\n *ngFor=\"let preset of ALL_GAUGE_PRESETS\"\n (click)=\"emitPresetChange(preset.id)\"\n >\n <c8y-radial-gauge\n class=\"c8y-radial-gauge--square\"\n *ngIf=\"preset.id !== 'custom'\"\n [activeDatapointGauge]=\"activeDatapointGauge\"\n [measurement]=\"measurement\"\n [fractionSize]=\"2\"\n [selectedPresetId]=\"preset.id\"\n [gaugeOptions]=\"preset\"\n ></c8y-radial-gauge>\n <span>{{ preset.name | translate }}</span>\n </button>\n</div>\n" }]
959
+ }], propDecorators: { ALL_GAUGE_PRESETS: [{
960
+ type: Input
961
+ }], onPresetChange: [{
962
+ type: Output
963
+ }] } });
964
+
127
965
  function ensureAtLeastOneDatapointSelectedAndActive(datapointListAttributes) {
128
966
  return (control) => {
129
967
  const formValue = control.value;
@@ -140,24 +978,37 @@ function ensureAtLeastOneDatapointSelectedAndActive(datapointListAttributes) {
140
978
  };
141
979
  }
142
980
  class InfoGaugeWidgetConfigComponent {
143
- constructor(formBuilder, form, widgetConfig) {
981
+ constructor(formBuilder, form, widgetConfig, dynamicComponent) {
144
982
  this.formBuilder = formBuilder;
145
983
  this.form = form;
146
984
  this.widgetConfig = widgetConfig;
985
+ this.dynamicComponent = dynamicComponent;
147
986
  this.datapointSelectionConfig = {};
148
987
  this.defaultFormOptions = {
149
988
  showRedRange: true,
150
989
  showYellowRange: true,
151
- showRange: true
990
+ showRange: true,
991
+ selectableChartRenderTypes: []
152
992
  };
993
+ this.showAdvancedOptions = false;
994
+ this.gaugeOptionsString = '';
995
+ this.showAdvancedOptionsLabel = gettext('Show advanced options');
996
+ this.hideAdvancedOptionsLabel = gettext('Hide advanced options');
997
+ this.ALL_GAUGE_PRESETS = [...GAUGE_PRESETS];
153
998
  this.limits = {
154
999
  numberOfDecimalPlacesMax: 10,
155
1000
  numberOfDecimalPlacesMin: 0
156
1001
  };
1002
+ this.GAUGE_PRESETS = GAUGE_PRESETS;
1003
+ this.destroy$ = new Subject();
157
1004
  }
158
1005
  onBeforeSave(config) {
159
1006
  if (this.formGroup.valid) {
160
1007
  Object.assign(config, this.formGroup.value);
1008
+ Object.assign(config, {
1009
+ gaugeOptions: this.gaugeOptions,
1010
+ selectedPresetId: this.isInfoGauge ? null : this.getPresetId(this.gaugeOptions)
1011
+ });
161
1012
  return true;
162
1013
  }
163
1014
  return false;
@@ -176,6 +1027,95 @@ class InfoGaugeWidgetConfigComponent {
176
1027
  if (typeof this.config?.fractionSize === 'number' && !Number.isNaN(this.config?.fractionSize)) {
177
1028
  this.formGroup.patchValue({ fractionSize: this.config.fractionSize });
178
1029
  }
1030
+ this.isInfoGauge = this.dynamicComponent?.componentId === defaultWidgetIds.INFO_GAUGE;
1031
+ const isRadialGauge = !this.isInfoGauge;
1032
+ if (isRadialGauge) {
1033
+ this.setupRadialGauge();
1034
+ }
1035
+ this.formGroup.valueChanges.pipe(takeUntil(this.destroy$)).subscribe(value => {
1036
+ if (value.datapointsGauge) {
1037
+ this.activeDatapointGauge = value.datapointsGauge.find(dp => dp.__active);
1038
+ }
1039
+ });
1040
+ }
1041
+ ngOnDestroy() {
1042
+ this.destroy$.next();
1043
+ this.destroy$.complete();
1044
+ }
1045
+ onRadioPresetChange(presetId) {
1046
+ // Find the selected preset
1047
+ const selectedPreset = this.ALL_GAUGE_PRESETS.find(preset => preset.id === presetId);
1048
+ if (selectedPreset) {
1049
+ this.gaugeOptions = { ...selectedPreset }; // Update gaugeOptions with the selected preset
1050
+ this.gaugeOptionsString = JSON.stringify(this.gaugeOptions, null, 2);
1051
+ // If the selected preset is not custom, hide advanced options
1052
+ if (selectedPreset.id !== 'custom') {
1053
+ this.showAdvancedOptions = false;
1054
+ }
1055
+ // Update the form control value
1056
+ this.formGroup.patchValue({ gaugePresetId: selectedPreset.id });
1057
+ }
1058
+ }
1059
+ async assignSchema() {
1060
+ const { schema } = await import('c8y-schema-loader?interfaceName=GaugeOptions!@c8y/ngx-components/widgets/implementations/info-gauge');
1061
+ this.editorComponent.monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
1062
+ validate: true,
1063
+ schemas: [
1064
+ {
1065
+ uri: 'gauge-schema.json',
1066
+ schema: schema,
1067
+ fileMatch: ['*']
1068
+ }
1069
+ ],
1070
+ enableSchemaRequest: false,
1071
+ allowComments: false
1072
+ });
1073
+ }
1074
+ gaugeJSONChange(value) {
1075
+ try {
1076
+ const parsedOptions = JSON.parse(value);
1077
+ // Check if the parsed options match any existing preset
1078
+ const matchingPreset = this.GAUGE_PRESETS.find(preset => JSON.stringify(preset) === JSON.stringify(parsedOptions));
1079
+ if (matchingPreset) {
1080
+ this.formGroup.patchValue({ gaugePresetId: matchingPreset.id });
1081
+ }
1082
+ else {
1083
+ this.gaugeOptions = parsedOptions;
1084
+ this.gaugeOptions.name = GAUGE_PRESET_NAMES.CUSTOM;
1085
+ this.gaugeOptions.id = 'custom';
1086
+ const customPresetExists = this.ALL_GAUGE_PRESETS.some(preset => preset.id === 'custom');
1087
+ if (!customPresetExists) {
1088
+ this.ALL_GAUGE_PRESETS = [...this.ALL_GAUGE_PRESETS, this.gaugeOptions];
1089
+ }
1090
+ else {
1091
+ this.ALL_GAUGE_PRESETS = this.ALL_GAUGE_PRESETS.map(preset => preset.id === 'custom' ? this.gaugeOptions : preset);
1092
+ }
1093
+ this.formGroup.patchValue({ gaugePresetId: 'custom' });
1094
+ }
1095
+ }
1096
+ catch (error) {
1097
+ console.error('Invalid JSON:', error);
1098
+ }
1099
+ }
1100
+ trackByFn(_index, item) {
1101
+ return item.id;
1102
+ }
1103
+ getPresetId(gaugeOptions) {
1104
+ const matchingPreset = this.GAUGE_PRESETS.find(preset => preset.id === gaugeOptions.id);
1105
+ return matchingPreset ? matchingPreset.id : 'custom';
1106
+ }
1107
+ setupRadialGauge() {
1108
+ if (this.config.datapoints && !this.config.datapointsGauge) {
1109
+ this.config.datapointsGauge = this.config.datapoints;
1110
+ }
1111
+ this.gaugeOptions = this.config.gaugeOptions || { ...this.GAUGE_PRESETS[0] };
1112
+ if (this.config.selectedPresetId === 'custom') {
1113
+ this.gaugeOptions.name = GAUGE_PRESET_NAMES.CUSTOM;
1114
+ this.gaugeOptions.id = 'custom';
1115
+ this.ALL_GAUGE_PRESETS = [...this.GAUGE_PRESETS, this.config.gaugeOptions];
1116
+ this.formGroup.patchValue({ gaugePresetId: 'custom' });
1117
+ }
1118
+ this.gaugeOptionsString = JSON.stringify(this.gaugeOptions, null, 2);
179
1119
  }
180
1120
  initForm() {
181
1121
  this.formGroup = this.createForm();
@@ -193,21 +1133,40 @@ class InfoGaugeWidgetConfigComponent {
193
1133
  ]
194
1134
  ],
195
1135
  datapointsLabels: this.formBuilder.control(new Array(), []),
196
- datapointsGauge: this.formBuilder.control(new Array(), [])
1136
+ datapointsGauge: this.formBuilder.control(new Array(), []),
1137
+ gaugePresetId: [this.config.selectedPresetId || 'default']
197
1138
  }, {
198
1139
  validators: [
199
1140
  ensureAtLeastOneDatapointSelectedAndActive(['datapointsLabels', 'datapointsGauge'])
200
1141
  ]
201
1142
  });
202
1143
  }
203
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: InfoGaugeWidgetConfigComponent, deps: [{ token: i1$1.FormBuilder }, { token: i1$1.NgForm }, { token: i1.WidgetConfigComponent }], target: i0.ɵɵFactoryTarget.Component }); }
204
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: InfoGaugeWidgetConfigComponent, isStandalone: true, selector: "c8y-info-gauge-widget-config", inputs: { config: "config" }, ngImport: i0, template: "<div class=\"p-l-24 p-r-24\">\n <form\n class=\"no-card-context\"\n [formGroup]=\"formGroup\"\n >\n <div class=\"row\">\n <div class=\"col-md-6\">\n <c8y-form-group class=\"p-t-8\">\n <label translate>Decimal places</label>\n <input\n class=\"form-control\"\n name=\"fractionSize\"\n type=\"number\"\n formControlName=\"fractionSize\"\n step=\"1\"\n />\n <c8y-messages [show]=\"formGroup.controls.fractionSize.errors\"></c8y-messages>\n </c8y-form-group>\n </div>\n <div class=\"col-md-6 p-t-8\">\n <div\n class=\"alert alert-info\"\n role=\"alert\"\n *ngIf=\"formGroup.errors?.noActiveDatapoint\"\n translate\n >\n At least one data point for the labels or the gauge needs to be selected.\n </div>\n </div>\n </div>\n\n <div class=\"row\">\n <div class=\"col-md-6\">\n <c8y-datapoint-selection-list\n class=\"bg-inherit separator-top p-t-16 d-block\"\n name=\"datapoints\"\n listTitle=\"{{ 'Multiple label and value pairs' | translate }}\"\n [defaultFormOptions]=\"defaultFormOptions\"\n [config]=\"datapointSelectionConfig\"\n [minActiveCount]=\"0\"\n formControlName=\"datapointsLabels\"\n ></c8y-datapoint-selection-list>\n </div>\n <div class=\"col-md-6\">\n <c8y-datapoint-selection-list\n class=\"bg-inherit separator-top p-t-16 d-block\"\n name=\"datapoints\"\n listTitle=\"{{ 'Gauge`display`' | translate }}\"\n [defaultFormOptions]=\"defaultFormOptions\"\n [config]=\"datapointSelectionConfig\"\n [minActiveCount]=\"0\"\n [maxActiveCount]=\"1\"\n formControlName=\"datapointsGauge\"\n ></c8y-datapoint-selection-list>\n </div>\n </div>\n </form>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CoreModule }, { kind: "pipe", type: i3.C8yTranslatePipe, name: "translate" }, { kind: "directive", type: i3.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "component", type: i3.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "component", type: i3.MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage"] }, { kind: "directive", type: i3.RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: DatapointSelectorModule }, { kind: "component", type: i5.DatapointSelectionListComponent, selector: "c8y-datapoint-selection-list", inputs: ["actions", "allowDragAndDrop", "config", "defaultFormOptions", "maxActiveCount", "minActiveCount", "resolveContext", "listTitle"], outputs: ["isValid", "change"] }], viewProviders: [{ provide: ControlContainer, useExisting: NgForm }] }); }
1144
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: InfoGaugeWidgetConfigComponent, deps: [{ token: i1$3.FormBuilder }, { token: i1$3.NgForm }, { token: i1$2.WidgetConfigComponent }, { token: i1.DynamicComponentComponent, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
1145
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: InfoGaugeWidgetConfigComponent, isStandalone: true, selector: "c8y-info-gauge-widget-config", inputs: { config: "config" }, providers: [MeasurementRealtimeService], viewQueries: [{ propertyName: "editorComponent", first: true, predicate: EditorComponent, descendants: true }], ngImport: i0, template: "<form\n class=\"fit-h\"\n [formGroup]=\"formGroup\"\n>\n <div\n class=\"m-l-16 m-r-16\"\n *ngIf=\"isInfoGauge; else radialGauge\"\n >\n <div class=\"row\">\n <div class=\"col-md-6\">\n <c8y-form-group class=\"p-t-8\">\n <label translate>Decimal places</label>\n <input\n class=\"form-control\"\n name=\"fractionSize\"\n type=\"number\"\n formControlName=\"fractionSize\"\n step=\"1\"\n />\n <c8y-messages [show]=\"formGroup.controls.fractionSize.errors\"></c8y-messages>\n </c8y-form-group>\n </div>\n <div class=\"col-md-6 p-t-8\">\n <div\n class=\"alert alert-info\"\n role=\"alert\"\n *ngIf=\"formGroup.errors?.noActiveDatapoint\"\n translate\n >\n At least one data point for the labels or the gauge needs to be selected.\n </div>\n </div>\n </div>\n\n <div class=\"row\">\n <div class=\"col-md-6\">\n <c8y-datapoint-selection-list\n class=\"bg-inherit separator-top p-t-16 d-block\"\n listTitle=\"{{ 'Multiple label and value pairs' | translate }}\"\n name=\"datapoints\"\n [defaultFormOptions]=\"defaultFormOptions\"\n [config]=\"datapointSelectionConfig\"\n [minActiveCount]=\"0\"\n formControlName=\"datapointsLabels\"\n ></c8y-datapoint-selection-list>\n </div>\n <div class=\"col-md-6\">\n <c8y-datapoint-selection-list\n class=\"bg-inherit separator-top p-t-16 d-block\"\n listTitle=\"{{ 'Gauge`display`' | translate }}\"\n name=\"datapoints\"\n [defaultFormOptions]=\"defaultFormOptions\"\n [config]=\"datapointSelectionConfig\"\n [minActiveCount]=\"0\"\n [maxActiveCount]=\"1\"\n formControlName=\"datapointsGauge\"\n ></c8y-datapoint-selection-list>\n </div>\n </div>\n </div>\n\n <ng-template #radialGauge>\n <div class=\"d-flex-md fit-h\">\n <div class=\"col-md-6 inner-scroll p-0 bg-component\">\n <c8y-datapoint-selection-list\n class=\"bg-inherit d-block\"\n listTitle=\"{{ 'Data points`display`' | translate }}\"\n name=\"datapoints\"\n [defaultFormOptions]=\"defaultFormOptions\"\n [config]=\"datapointSelectionConfig\"\n [minActiveCount]=\"0\"\n [maxActiveCount]=\"1\"\n formControlName=\"datapointsGauge\"\n ></c8y-datapoint-selection-list>\n\n <c8y-form-group class=\"p-t-8 p-r-16 p-l-16\">\n <label translate>Decimal places</label>\n <input\n class=\"form-control\"\n name=\"fractionSize\"\n type=\"number\"\n formControlName=\"fractionSize\"\n step=\"1\"\n />\n <c8y-messages [show]=\"formGroup.controls.fractionSize.errors\"></c8y-messages>\n </c8y-form-group>\n\n <div class=\"form-group p-r-16 p-l-16 m-b-0\">\n <legend>\n {{ 'Presets' | translate }}\n </legend>\n <c8y-preset-preview\n formControlName=\"gaugePresetId\"\n [ALL_GAUGE_PRESETS]=\"ALL_GAUGE_PRESETS\"\n (onPresetChange)=\"onRadioPresetChange($event)\"\n ></c8y-preset-preview>\n </div>\n\n <div class=\"p-16\">\n <button\n class=\"btn btn-default\"\n aria-controls=\"advancedCollapse\"\n [attr.aria-expanded]=\"showAdvancedOptions\"\n type=\"button\"\n (click)=\"showAdvancedOptions = !showAdvancedOptions\"\n >\n {{ showAdvancedOptions ? hideAdvancedOptionsLabel : showAdvancedOptionsLabel }}\n </button>\n </div>\n\n <div\n class=\"collapse\"\n id=\"advancedCollapse\"\n [collapse]=\"!showAdvancedOptions\"\n [isAnimated]=\"true\"\n >\n <div\n class=\"fit-h\"\n style=\"min-height: 400px\"\n >\n <c8y-editor\n [ngModel]=\"gaugeOptionsString\"\n (ngModelChange)=\"gaugeJSONChange($event)\"\n (editorInit)=\"assignSchema()\"\n [ngModelOptions]=\"{ standalone: true }\"\n monacoEditorMarkerValidator\n ></c8y-editor>\n </div>\n </div>\n </div>\n <div\n class=\"col-md-6\"\n *ngIf=\"\n this.formGroup.value.datapointsGauge.length > 0 && activeDatapointGauge;\n else emptyState\n \"\n >\n <!-- Radial Gauge -->\n <c8y-radial-gauge\n class=\"c8y-radial-gauge--square\"\n *ngIf=\"activeDatapointGauge | infoGaugeCurrentMeasurement | async as measurement\"\n [activeDatapointGauge]=\"activeDatapointGauge\"\n [measurement]=\"measurement\"\n [fractionSize]=\"formGroup.value.fractionSize\"\n [gaugeOptions]=\"gaugeOptions\"\n [selectedPresetId]=\"formGroup.value.gaugePresetId\"\n ></c8y-radial-gauge>\n </div>\n </div>\n </ng-template>\n</form>\n\n<ng-template #emptyState>\n <div class=\"col-md-6 d-col a-i-start j-c-center\">\n <c8y-ui-empty-state\n [icon]=\"'c8y-data-points'\"\n [title]=\"'Please select a data point first.' | translate\"\n [horizontal]=\"false\"\n ></c8y-ui-empty-state>\n </div>\n</ng-template>\n", dependencies: [{ kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "component", type: MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage"] }, { kind: "ngmodule", type: CommonModule }, { kind: "component", type: i1.EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "pipe", type: i1.C8yTranslatePipe, name: "translate" }, { kind: "directive", type: i1.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1.RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "ngmodule", type: CollapseModule }, { kind: "directive", type: i5.CollapseDirective, selector: "[collapse]", inputs: ["display", "isAnimated", "collapse"], outputs: ["collapsed", "collapses", "expanded", "expands"], exportAs: ["bs-collapse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: EditorComponent, selector: "c8y-editor", inputs: ["editorOptions"], outputs: ["editorInit"] }, { kind: "directive", type: MonacoEditorMarkerValidatorDirective, selector: "c8y-editor [monacoEditorMarkerValidator]" }, { kind: "ngmodule", type: DatapointSelectorModule }, { kind: "component", type: i6.DatapointSelectionListComponent, selector: "c8y-datapoint-selection-list", inputs: ["actions", "allowDragAndDrop", "config", "defaultFormOptions", "maxActiveCount", "minActiveCount", "resolveContext", "listTitle"], outputs: ["isValid", "change"] }, { kind: "component", type: RadialGaugeViewComponent, selector: "c8y-radial-gauge", inputs: ["activeDatapointGauge", "measurement", "fractionSize", "gaugeOptions", "selectedPresetId"] }, { kind: "pipe", type: InfoGaugeCurrentMeasurementPipe, name: "infoGaugeCurrentMeasurement" }, { kind: "component", type: PresetPreviewComponent, selector: "c8y-preset-preview", inputs: ["ALL_GAUGE_PRESETS"], outputs: ["onPresetChange"] }], viewProviders: [{ provide: ControlContainer, useExisting: NgForm }] }); }
205
1146
  }
206
1147
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: InfoGaugeWidgetConfigComponent, decorators: [{
207
1148
  type: Component,
208
- args: [{ selector: 'c8y-info-gauge-widget-config', viewProviders: [{ provide: ControlContainer, useExisting: NgForm }], standalone: true, imports: [CoreModule, ReactiveFormsModule, DatapointSelectorModule], template: "<div class=\"p-l-24 p-r-24\">\n <form\n class=\"no-card-context\"\n [formGroup]=\"formGroup\"\n >\n <div class=\"row\">\n <div class=\"col-md-6\">\n <c8y-form-group class=\"p-t-8\">\n <label translate>Decimal places</label>\n <input\n class=\"form-control\"\n name=\"fractionSize\"\n type=\"number\"\n formControlName=\"fractionSize\"\n step=\"1\"\n />\n <c8y-messages [show]=\"formGroup.controls.fractionSize.errors\"></c8y-messages>\n </c8y-form-group>\n </div>\n <div class=\"col-md-6 p-t-8\">\n <div\n class=\"alert alert-info\"\n role=\"alert\"\n *ngIf=\"formGroup.errors?.noActiveDatapoint\"\n translate\n >\n At least one data point for the labels or the gauge needs to be selected.\n </div>\n </div>\n </div>\n\n <div class=\"row\">\n <div class=\"col-md-6\">\n <c8y-datapoint-selection-list\n class=\"bg-inherit separator-top p-t-16 d-block\"\n name=\"datapoints\"\n listTitle=\"{{ 'Multiple label and value pairs' | translate }}\"\n [defaultFormOptions]=\"defaultFormOptions\"\n [config]=\"datapointSelectionConfig\"\n [minActiveCount]=\"0\"\n formControlName=\"datapointsLabels\"\n ></c8y-datapoint-selection-list>\n </div>\n <div class=\"col-md-6\">\n <c8y-datapoint-selection-list\n class=\"bg-inherit separator-top p-t-16 d-block\"\n name=\"datapoints\"\n listTitle=\"{{ 'Gauge`display`' | translate }}\"\n [defaultFormOptions]=\"defaultFormOptions\"\n [config]=\"datapointSelectionConfig\"\n [minActiveCount]=\"0\"\n [maxActiveCount]=\"1\"\n formControlName=\"datapointsGauge\"\n ></c8y-datapoint-selection-list>\n </div>\n </div>\n </form>\n</div>\n" }]
209
- }], ctorParameters: () => [{ type: i1$1.FormBuilder }, { type: i1$1.NgForm }, { type: i1.WidgetConfigComponent }], propDecorators: { config: [{
1149
+ args: [{ selector: 'c8y-info-gauge-widget-config', viewProviders: [{ provide: ControlContainer, useExisting: NgForm }], providers: [MeasurementRealtimeService], standalone: true, imports: [
1150
+ FormGroupComponent,
1151
+ MessagesComponent,
1152
+ CommonModule,
1153
+ FormsModule,
1154
+ CollapseModule,
1155
+ ReactiveFormsModule,
1156
+ EditorComponent,
1157
+ MonacoEditorMarkerValidatorDirective,
1158
+ DatapointSelectorModule,
1159
+ RadialGaugeViewComponent,
1160
+ InfoGaugeCurrentMeasurementPipe,
1161
+ PresetPreviewComponent
1162
+ ], template: "<form\n class=\"fit-h\"\n [formGroup]=\"formGroup\"\n>\n <div\n class=\"m-l-16 m-r-16\"\n *ngIf=\"isInfoGauge; else radialGauge\"\n >\n <div class=\"row\">\n <div class=\"col-md-6\">\n <c8y-form-group class=\"p-t-8\">\n <label translate>Decimal places</label>\n <input\n class=\"form-control\"\n name=\"fractionSize\"\n type=\"number\"\n formControlName=\"fractionSize\"\n step=\"1\"\n />\n <c8y-messages [show]=\"formGroup.controls.fractionSize.errors\"></c8y-messages>\n </c8y-form-group>\n </div>\n <div class=\"col-md-6 p-t-8\">\n <div\n class=\"alert alert-info\"\n role=\"alert\"\n *ngIf=\"formGroup.errors?.noActiveDatapoint\"\n translate\n >\n At least one data point for the labels or the gauge needs to be selected.\n </div>\n </div>\n </div>\n\n <div class=\"row\">\n <div class=\"col-md-6\">\n <c8y-datapoint-selection-list\n class=\"bg-inherit separator-top p-t-16 d-block\"\n listTitle=\"{{ 'Multiple label and value pairs' | translate }}\"\n name=\"datapoints\"\n [defaultFormOptions]=\"defaultFormOptions\"\n [config]=\"datapointSelectionConfig\"\n [minActiveCount]=\"0\"\n formControlName=\"datapointsLabels\"\n ></c8y-datapoint-selection-list>\n </div>\n <div class=\"col-md-6\">\n <c8y-datapoint-selection-list\n class=\"bg-inherit separator-top p-t-16 d-block\"\n listTitle=\"{{ 'Gauge`display`' | translate }}\"\n name=\"datapoints\"\n [defaultFormOptions]=\"defaultFormOptions\"\n [config]=\"datapointSelectionConfig\"\n [minActiveCount]=\"0\"\n [maxActiveCount]=\"1\"\n formControlName=\"datapointsGauge\"\n ></c8y-datapoint-selection-list>\n </div>\n </div>\n </div>\n\n <ng-template #radialGauge>\n <div class=\"d-flex-md fit-h\">\n <div class=\"col-md-6 inner-scroll p-0 bg-component\">\n <c8y-datapoint-selection-list\n class=\"bg-inherit d-block\"\n listTitle=\"{{ 'Data points`display`' | translate }}\"\n name=\"datapoints\"\n [defaultFormOptions]=\"defaultFormOptions\"\n [config]=\"datapointSelectionConfig\"\n [minActiveCount]=\"0\"\n [maxActiveCount]=\"1\"\n formControlName=\"datapointsGauge\"\n ></c8y-datapoint-selection-list>\n\n <c8y-form-group class=\"p-t-8 p-r-16 p-l-16\">\n <label translate>Decimal places</label>\n <input\n class=\"form-control\"\n name=\"fractionSize\"\n type=\"number\"\n formControlName=\"fractionSize\"\n step=\"1\"\n />\n <c8y-messages [show]=\"formGroup.controls.fractionSize.errors\"></c8y-messages>\n </c8y-form-group>\n\n <div class=\"form-group p-r-16 p-l-16 m-b-0\">\n <legend>\n {{ 'Presets' | translate }}\n </legend>\n <c8y-preset-preview\n formControlName=\"gaugePresetId\"\n [ALL_GAUGE_PRESETS]=\"ALL_GAUGE_PRESETS\"\n (onPresetChange)=\"onRadioPresetChange($event)\"\n ></c8y-preset-preview>\n </div>\n\n <div class=\"p-16\">\n <button\n class=\"btn btn-default\"\n aria-controls=\"advancedCollapse\"\n [attr.aria-expanded]=\"showAdvancedOptions\"\n type=\"button\"\n (click)=\"showAdvancedOptions = !showAdvancedOptions\"\n >\n {{ showAdvancedOptions ? hideAdvancedOptionsLabel : showAdvancedOptionsLabel }}\n </button>\n </div>\n\n <div\n class=\"collapse\"\n id=\"advancedCollapse\"\n [collapse]=\"!showAdvancedOptions\"\n [isAnimated]=\"true\"\n >\n <div\n class=\"fit-h\"\n style=\"min-height: 400px\"\n >\n <c8y-editor\n [ngModel]=\"gaugeOptionsString\"\n (ngModelChange)=\"gaugeJSONChange($event)\"\n (editorInit)=\"assignSchema()\"\n [ngModelOptions]=\"{ standalone: true }\"\n monacoEditorMarkerValidator\n ></c8y-editor>\n </div>\n </div>\n </div>\n <div\n class=\"col-md-6\"\n *ngIf=\"\n this.formGroup.value.datapointsGauge.length > 0 && activeDatapointGauge;\n else emptyState\n \"\n >\n <!-- Radial Gauge -->\n <c8y-radial-gauge\n class=\"c8y-radial-gauge--square\"\n *ngIf=\"activeDatapointGauge | infoGaugeCurrentMeasurement | async as measurement\"\n [activeDatapointGauge]=\"activeDatapointGauge\"\n [measurement]=\"measurement\"\n [fractionSize]=\"formGroup.value.fractionSize\"\n [gaugeOptions]=\"gaugeOptions\"\n [selectedPresetId]=\"formGroup.value.gaugePresetId\"\n ></c8y-radial-gauge>\n </div>\n </div>\n </ng-template>\n</form>\n\n<ng-template #emptyState>\n <div class=\"col-md-6 d-col a-i-start j-c-center\">\n <c8y-ui-empty-state\n [icon]=\"'c8y-data-points'\"\n [title]=\"'Please select a data point first.' | translate\"\n [horizontal]=\"false\"\n ></c8y-ui-empty-state>\n </div>\n</ng-template>\n" }]
1163
+ }], ctorParameters: () => [{ type: i1$3.FormBuilder }, { type: i1$3.NgForm }, { type: i1$2.WidgetConfigComponent }, { type: i1.DynamicComponentComponent, decorators: [{
1164
+ type: Optional
1165
+ }] }], propDecorators: { config: [{
210
1166
  type: Input
1167
+ }], editorComponent: [{
1168
+ type: ViewChild,
1169
+ args: [EditorComponent]
211
1170
  }] } });
212
1171
 
213
1172
  /**
@@ -217,8 +1176,11 @@ class InfoGaugeWidgetModule {
217
1176
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: InfoGaugeWidgetModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
218
1177
  static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: InfoGaugeWidgetModule, imports: [InfoGaugeWidgetViewComponent,
219
1178
  InfoGaugeWidgetConfigComponent,
220
- InfoGaugeCurrentMeasurementPipe] }); }
221
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: InfoGaugeWidgetModule, imports: [InfoGaugeWidgetConfigComponent] }); }
1179
+ InfoGaugeCurrentMeasurementPipe,
1180
+ RadialGaugeViewComponent] }); }
1181
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: InfoGaugeWidgetModule, imports: [InfoGaugeWidgetViewComponent,
1182
+ InfoGaugeWidgetConfigComponent,
1183
+ RadialGaugeViewComponent] }); }
222
1184
  }
223
1185
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: InfoGaugeWidgetModule, decorators: [{
224
1186
  type: NgModule,
@@ -226,7 +1188,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
226
1188
  imports: [
227
1189
  InfoGaugeWidgetViewComponent,
228
1190
  InfoGaugeWidgetConfigComponent,
229
- InfoGaugeCurrentMeasurementPipe
1191
+ InfoGaugeCurrentMeasurementPipe,
1192
+ RadialGaugeViewComponent
230
1193
  ]
231
1194
  }]
232
1195
  }] });
@@ -235,5 +1198,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
235
1198
  * Generated bundle index. Do not edit.
236
1199
  */
237
1200
 
238
- export { InfoGaugeWidgetConfigComponent, InfoGaugeWidgetModule, InfoGaugeWidgetViewComponent };
1201
+ export { GAUGE_PRESETS, GAUGE_PRESET_NAMES, InfoGaugeWidgetConfigComponent, InfoGaugeWidgetModule, InfoGaugeWidgetViewComponent };
239
1202
  //# sourceMappingURL=c8y-ngx-components-widgets-implementations-info-gauge.mjs.map