@record-evolution/widget-value 1.0.10 → 1.0.12

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.
@@ -0,0 +1,56 @@
1
+ /* eslint-disable */
2
+ /**
3
+ * This file was automatically generated by json-schema-to-typescript.
4
+ * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
5
+ * and run json-schema-to-typescript to regenerate this file.
6
+ */
7
+
8
+ export type Title = string;
9
+ export type Subtitle = string;
10
+ /**
11
+ * The label for the value.
12
+ */
13
+ export type Label = string;
14
+ /**
15
+ * The unit of the value. e.g. °C or km/h
16
+ */
17
+ export type Unit = string;
18
+ export type LabelColor = string;
19
+ export type ValueColor = string;
20
+ /**
21
+ * Calculate the average over the given number of newest values. (If pivoted, then per each of the pivot dataseries.) If not specified then the latest value is shown without modification.
22
+ */
23
+ export type AverageLatestValues = number;
24
+ export type Value = number;
25
+ /**
26
+ * You can specify a column in the input data to autogenerate dataseries for each distinct entry in this column. E.g. if you have a table with columns [city, timestamp, temperature] and specify 'city' as pivot column, then you will get a gauge for each city.
27
+ */
28
+ export type PivotColumn = string;
29
+ /**
30
+ * The data used to draw this data series.
31
+ */
32
+ export type Data = {
33
+ value: Value;
34
+ pivot?: PivotColumn;
35
+ [k: string]: unknown;
36
+ }[];
37
+ export type ValueDisplays = {
38
+ label: Label;
39
+ unit?: Unit;
40
+ labelColor?: LabelColor;
41
+ valueColor?: ValueColor;
42
+ averageLatest?: AverageLatestValues;
43
+ data?: Data;
44
+ [k: string]: unknown;
45
+ }[];
46
+
47
+ export interface ValueChartConfiguration {
48
+ settings?: GlobalSettings;
49
+ dataseries?: ValueDisplays;
50
+ [k: string]: unknown;
51
+ }
52
+ export interface GlobalSettings {
53
+ title?: Title;
54
+ subTitle?: Subtitle;
55
+ [k: string]: unknown;
56
+ }
@@ -25,6 +25,7 @@
25
25
  "order": 2,
26
26
  "items": {
27
27
  "type": "object",
28
+ "required": ["label"],
28
29
  "properties": {
29
30
  "label": {
30
31
  "title": "Label",
@@ -41,12 +42,14 @@
41
42
  },
42
43
  "labelColor": {
43
44
  "title": "Label Color",
44
- "type": "color",
45
+ "type": "string",
46
+ "color": true,
45
47
  "order": 3
46
48
  },
47
49
  "valueColor": {
48
50
  "title": "Value Color",
49
- "type": "color",
51
+ "type": "string",
52
+ "color": true,
50
53
  "order": 4
51
54
  },
52
55
  "averageLatest": {
@@ -63,6 +66,7 @@
63
66
  "buffersize": 100,
64
67
  "items": {
65
68
  "type": "object",
69
+ "required": ["value"],
66
70
  "properties": {
67
71
  "value": {
68
72
  "title": "Value",
@@ -1,272 +1,336 @@
1
- import { html, css, LitElement, PropertyValueMap } from 'lit';
1
+ import { html, css, LitElement, PropertyValueMap } from 'lit'
2
2
  import { repeat } from 'lit/directives/repeat.js'
3
- import { property, state } from 'lit/decorators.js';
4
- import { InputData, Data, Dataseries } from './types.js'
3
+ import { property, state } from 'lit/decorators.js'
4
+ import { ValueChartConfiguration } from './definition-schema.js'
5
+
6
+ type Dataseries = Exclude<ValueChartConfiguration['dataseries'], undefined>[number]
7
+ type Data = Exclude<Dataseries['data'], undefined>[number]
5
8
 
6
9
  export class WidgetValue extends LitElement {
7
-
8
- @property({type: Object})
9
- inputData?: InputData = undefined
10
+ @property({ type: Object })
11
+ inputData?: ValueChartConfiguration
10
12
 
11
- @state()
12
- private dataSets: Map<string, Dataseries> = new Map()
13
+ @state()
14
+ private dataSets: Map<string, Dataseries> = new Map()
13
15
 
14
- @state()
15
- private textActive: boolean = true
16
+ @state()
17
+ private textActive: boolean = true
16
18
 
17
- @state()
18
- private numberText?: HTMLDivElement[]
19
+ @state()
20
+ private numberText?: HTMLDivElement[]
19
21
 
20
- @state()
21
- private labelText?: HTMLDivElement[]
22
+ @state()
23
+ private labelText?: HTMLDivElement[]
22
24
 
23
- version: string = 'versionplaceholder'
25
+ version: string = 'versionplaceholder'
24
26
 
25
- resizeObserver: ResizeObserver
27
+ resizeObserver: ResizeObserver
26
28
 
27
- valueContainer?: HTMLDivElement
28
- boxes?: HTMLDivElement[]
29
- origWidth: number = 0
30
- origHeight: number = 0
31
- constructor() {
32
- super()
29
+ valueContainer?: HTMLDivElement
30
+ boxes?: HTMLDivElement[]
31
+ origWidth: number = 0
32
+ origHeight: number = 0
33
+ constructor() {
34
+ super()
33
35
 
34
- this.resizeObserver = new ResizeObserver((ev) => this.adjustSizes())
35
- this.resizeObserver.observe(this)
36
- }
36
+ this.resizeObserver = new ResizeObserver((ev) => this.adjustSizes())
37
+ this.resizeObserver.observe(this)
38
+ }
37
39
 
38
- protected firstUpdated(_changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>) {
39
- this.applyInputData()
40
- }
40
+ protected firstUpdated(_changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>) {
41
+ this.valueContainer = this?.shadowRoot?.querySelector('.value-container') as HTMLDivElement
41
42
 
42
- update(changedProperties: Map<string, any>) {
43
- changedProperties.forEach((oldValue, propName) => {
44
- if (propName === 'inputData') {
43
+ this.sizingSetup()
45
44
  this.applyInputData()
46
- }
47
- })
48
-
49
- this.sizingSetup()
50
-
51
- super.update(changedProperties)
52
- }
53
-
54
- sizingSetup() {
55
- if (this.origWidth !== 0 && this.origHeight !== 0) return
56
-
57
- this.boxes = Array.from(this?.shadowRoot?.querySelectorAll('.single-value') as NodeListOf<HTMLDivElement>)
58
- this.numberText = Array.from(this?.shadowRoot?.querySelectorAll('.current-value') as NodeListOf<HTMLDivElement>)
59
- this.labelText = Array.from(this?.shadowRoot?.querySelectorAll('.label') as NodeListOf<HTMLDivElement>)
60
- this.valueContainer = this?.shadowRoot?.querySelector('.value-container') as HTMLDivElement
61
-
62
- this.origWidth = this.boxes?.map(b => b.getBoundingClientRect().width).reduce((p, c) => c > p ? c : p, 0 ) ?? 0
63
- this.origHeight = this.boxes?.map(b => b.getBoundingClientRect().height).reduce((p, c) => c > p ? c : p, 0 ) ?? 0
64
- if (this.origWidth > 0) this.origWidth += 16
65
- if (this.origHeight > 0) this.origHeight += 16
66
-
67
- this.adjustSizes()
68
-
69
- }
70
-
71
- adjustSizes() {
72
- const userWidth = this.valueContainer?.getBoundingClientRect().width
73
- const userHeight = this.valueContainer?.getBoundingClientRect().height
74
- const count = this.dataSets.size
75
-
76
- const width = this.origWidth
77
- const height = this.origHeight
78
- if (!userWidth || !userHeight || !width || !height) return
79
-
80
- const fits = []
81
- for (let c = 1; c <= count; c++) {
82
- const r = Math.ceil(count/c)
83
- const uwgap = (userWidth - 12 * (c-1))
84
- const uhgap = (userHeight - 12 * (r-1))
85
- const m = uwgap / width / c
86
- const size = m * m * width * height * count
87
- if (r * m * height < uhgap) fits.push({c, m, size, width, height, userWidth, userHeight})
88
45
  }
89
46
 
90
- for (let r = 1; r <= count; r++) {
91
- const c = Math.ceil(count/r)
92
- const uwgap = (userWidth - 12 * (c-1))
93
- const uhgap = (userHeight - 12 * (r-1))
94
- const m = uhgap / height / r
95
- const size = m * m * width * height * count
96
- if (c * m * width < uwgap) fits.push({r, m, size, width, height, userWidth, userHeight})
97
- }
47
+ update(changedProperties: Map<string, any>) {
48
+ if (changedProperties.has('inputData')) {
49
+ this.sizingSetup()
50
+ this.applyInputData()
51
+ }
98
52
 
99
- const maxSize = fits.reduce((p, c) => c.size < p ? p : c.size, 0)
100
- const fit = fits.find(f => f.size === maxSize)
101
- const modifier = (fit?.m ?? 1)
102
- // console.log('FITS', fits, 'modifier', modifier, 'cols',fit?.c, 'rows', fit?.r, 'new size', fit?.size.toFixed(0), 'total space', (userWidth* userHeight).toFixed(0))
103
-
104
- this.boxes?.forEach(box => box.setAttribute("style", `width:${modifier*width}px; height:${modifier*height}px; padding:${modifier*6}px`))
105
- this.numberText?.forEach(n => {
106
- const label: string | null = n.getAttribute('label')
107
- const ds: Dataseries | undefined = this.dataSets.get(label ?? '')
108
- n.setAttribute("style", `font-size: ${(ds?.valueFontSize ?? 32) * modifier}px; ${ds?.valueColor ? "color: " + ds?.valueColor: ''}`)
109
- })
110
-
111
- this.labelText?.forEach(n => {
112
- const label: string | null = n.getAttribute('label')
113
- const ds: Dataseries | undefined = this.dataSets.get(label ?? '')
114
- n.setAttribute("style", `font-size: ${(ds?.labelFontSize ?? 26) * modifier}px; ${ds?.labelColor ? "color: " + ds?.labelColor: ''}`)
115
- })
116
-
117
- this.textActive = true
118
-
119
- }
120
-
121
- async applyInputData() {
122
-
123
- if(!this.inputData) return
124
-
125
- this.dataSets = new Map()
126
- this.inputData.dataseries.sort((a, b) => a.order - b.order).forEach(ds => {
127
-
128
- // pivot data
129
- const distincts = [...new Set(ds.data.map((d: Data) => d.pivot))]
130
- if (distincts.length > 1 || distincts[0] !== undefined) {
131
- distincts.forEach((piv) => {
132
- const pds: any = {
133
- label: `${ds.label} ${piv}`,
134
- order: ds.order,
135
- unit: ds.unit,
136
- averageLatest: ds.averageLatest,
137
- labelColor: ds.labelColor,
138
- valueColor: ds.valueColor,
139
- data: ds.data.filter(d => d.pivot === piv)
140
- }
141
- this.dataSets.set(pds.label, pds)
142
- })
143
- } else {
144
- this.dataSets.set(ds.label, ds)
145
- }
146
- })
147
-
148
- // filter latest values and calculate average
149
- this.dataSets.forEach((ds, label) => {
150
- if (typeof ds.averageLatest !== 'number' || !isNaN(ds.averageLatest)) ds.averageLatest = 1
151
- ds.data = ds.data.splice(-ds.averageLatest ?? -1)
152
- ds.needleValue = ds.data.map(d => d.value).reduce(( p, c ) => p + c, 0) / ds.data.length
153
- })
154
-
155
- this.requestUpdate(); await this.updateComplete
156
-
157
- // console.log('Value Datasets', this.dataSets)
158
-
159
- }
160
-
161
- static styles = css`
162
- :host {
163
- display: block;
164
- font-family: sans-serif;
165
- box-sizing: border-box;
166
- position: relative;
167
- margin: auto;
53
+ super.update(changedProperties)
168
54
  }
169
55
 
170
- .paging:not([active]) { display: none !important; }
56
+ sizingSetup() {
57
+ if (this.origWidth !== 0 && this.origHeight !== 0) return
171
58
 
172
- .wrapper {
173
- display: flex;
174
- flex-direction: column;
175
- height: 100%;
176
- width: 100%;
177
- padding: 16px;
178
- box-sizing: border-box;
179
- }
59
+ const boxes = Array.from(
60
+ this?.shadowRoot?.querySelectorAll(
61
+ '.sizing-container > .single-value'
62
+ ) as NodeListOf<HTMLDivElement>
63
+ )
180
64
 
181
- h3 {
182
- margin: 0;
183
- max-width: 300px;
184
- overflow: hidden;
185
- text-overflow: ellipsis;
186
- white-space: nowrap;
187
- color: var(--re-text-color, #000) !important;
188
- }
189
- p {
190
- margin: 10px 0 0 0;
191
- max-width: 300px;
192
- font-size: 14px;
193
- line-height: 17px;
194
- overflow: hidden;
195
- text-overflow: ellipsis;
196
- white-space: nowrap;
197
- color: var(--re-text-color, #000) !important;
198
- }
65
+ this.origWidth =
66
+ boxes?.map((b) => b.getBoundingClientRect().width).reduce((p, c) => (c > p ? c : p), 0) ?? 0
67
+ this.origHeight =
68
+ boxes?.map((b) => b.getBoundingClientRect().height).reduce((p, c) => (c > p ? c : p), 0) ?? 0
199
69
 
200
- .value-container {
201
- display: flex;
202
- flex-wrap: wrap;
203
- align-items: center;
204
- justify-content: center;
205
- flex: 1;
206
- overflow: hidden;
207
- position: relative;
208
- gap: 12px;
70
+ this.adjustSizes()
209
71
  }
210
72
 
211
- .single-value {
212
- overflow: hidden;
213
- position: relative;
214
- align-items: end;
215
- font-size: 26px;
216
- padding: 6px;
217
- box-sizing: border-box;
218
- /* border-left: 4px solid #ddd; */
73
+ adjustSizes() {
74
+ const userWidth = (this.valueContainer?.getBoundingClientRect().width ?? 32) - 32
75
+ const userHeight = (this.valueContainer?.getBoundingClientRect().height ?? 32) - 32
76
+ const count = this.dataSets.size
77
+
78
+ const width = this.origWidth
79
+ const height = this.origHeight
80
+ if (!userWidth || !userHeight || !width || !height) return
81
+
82
+ const fits = []
83
+ for (let c = 1; c <= count; c++) {
84
+ const r = Math.ceil(count / c)
85
+ const uwgap = userWidth - 12 * (c - 1)
86
+ const uhgap = userHeight - 12 * (r - 1)
87
+ const m = uwgap / width / c
88
+ const size = m * m * width * height * count
89
+ if (r * m * height < uhgap) fits.push({ c, m, size, width, height, userWidth, userHeight })
90
+ }
91
+
92
+ for (let r = 1; r <= count; r++) {
93
+ const c = Math.ceil(count / r)
94
+ const uwgap = userWidth - 12 * (c - 1)
95
+ const uhgap = userHeight - 12 * (r - 1)
96
+ const m = uhgap / height / r
97
+ const size = m * m * width * height * count
98
+ if (c * m * width < uwgap) fits.push({ r, m, size, width, height, userWidth, userHeight })
99
+ }
100
+ const maxSize = fits.reduce((p, c) => (c.size < p ? p : c.size), 0)
101
+ const fit = fits.find((f) => f.size === maxSize)
102
+ const modifier = fit?.m ?? 1
103
+ // console.log('FITS', fits, 'modifier', modifier, 'cols',fit?.c, 'rows', fit?.r, 'new size', fit?.size.toFixed(0), 'total space', (userWidth* userHeight).toFixed(0))
104
+
105
+ const boxes = Array.from(
106
+ this?.shadowRoot?.querySelectorAll(
107
+ '.value-container > .single-value'
108
+ ) as NodeListOf<HTMLDivElement>
109
+ )
110
+
111
+ boxes?.forEach((box) =>
112
+ box.setAttribute(
113
+ 'style',
114
+ `width:${modifier * width}px; height:${modifier * height}px; padding:${modifier * 6}px`
115
+ )
116
+ )
117
+
118
+ boxes?.forEach((n) => {
119
+ const label: string | null = n.getAttribute('label')
120
+ const ds: Dataseries | undefined = this.dataSets.get(label ?? '')
121
+ const numberText = n.querySelector('.current-value') as HTMLDivElement
122
+ numberText.setAttribute(
123
+ 'style',
124
+ `font-size: ${32 * modifier}px; ${ds?.valueColor ? 'color: ' + ds?.valueColor : ''}`
125
+ )
126
+ })
127
+
128
+ boxes?.forEach((n) => {
129
+ const label: string | null = n.getAttribute('label')
130
+ const ds: Dataseries | undefined = this.dataSets.get(label ?? '')
131
+ const labelText = n.querySelector('.label') as HTMLDivElement
132
+ labelText.setAttribute(
133
+ 'style',
134
+ `font-size: ${26 * modifier}px; ${ds?.labelColor ? 'color: ' + ds?.labelColor : ''}`
135
+ )
136
+ const unitText = n.querySelector('.unit') as HTMLDivElement
137
+ unitText.setAttribute(
138
+ 'style',
139
+ `font-size: ${26 * modifier}px; ${ds?.labelColor ? 'color: ' + ds?.labelColor : ''}`
140
+ )
141
+ })
142
+
143
+ this.textActive = true
219
144
  }
220
145
 
221
- .current-value {
222
- font-size: 32px;
223
- font-weight: 600;
224
- white-space: nowrap;
225
- color: var(--re-text-color, #000);
146
+ async applyInputData() {
147
+ if (!this.inputData) return
148
+
149
+ this.dataSets = new Map()
150
+ this.inputData?.dataseries
151
+ // ?.sort((a, b) => a.order - b.order)
152
+ ?.forEach((ds) => {
153
+ // pivot data
154
+ const distincts = [...new Set(ds.data?.map((d: Data) => d.pivot))]
155
+ if (distincts.length > 1 || distincts[0] !== undefined) {
156
+ distincts.forEach((piv) => {
157
+ const pds: any = {
158
+ label: `${ds.label} ${piv}`,
159
+ order: ds.order,
160
+ unit: ds.unit,
161
+ averageLatest: ds.averageLatest,
162
+ labelColor: ds.labelColor,
163
+ valueColor: ds.valueColor,
164
+ data: ds.data?.filter((d) => d.pivot === piv)
165
+ }
166
+ this.dataSets.set(pds.label, pds)
167
+ })
168
+ } else {
169
+ this.dataSets.set(ds.label, ds)
170
+ }
171
+ })
172
+
173
+ // filter latest values and calculate average
174
+ this.dataSets.forEach((ds, label) => {
175
+ if (typeof ds.averageLatest !== 'number' || !isNaN(ds.averageLatest)) ds.averageLatest = 1
176
+
177
+ ds.data = ds?.data?.splice(-ds.averageLatest || -1)
178
+ const values = (ds?.data?.map((d) => d.value)?.filter((p) => p !== undefined) ?? []) as number[]
179
+ const average = values.reduce((p, c) => p + c, 0) / values.length
180
+
181
+ ds.needleValue = average
182
+ })
183
+
184
+ this.requestUpdate()
185
+ await this.updateComplete
186
+
187
+ // console.log('Value Datasets', this.dataSets)
226
188
  }
227
189
 
228
- .label {
229
- font-weight: 300;
230
- font-size: 26px;
231
- color: var(--re-text-color, #000);
232
- white-space: nowrap;
190
+ static styles = css`
191
+ :host {
192
+ display: block;
193
+ font-family: sans-serif;
194
+ box-sizing: border-box;
195
+ position: relative;
196
+ margin: auto;
197
+ }
198
+
199
+ .paging:not([active]) {
200
+ display: none !important;
201
+ }
202
+
203
+ .wrapper {
204
+ display: flex;
205
+ flex-direction: column;
206
+ height: 100%;
207
+ line-height: 0.9;
208
+ width: 100%;
209
+ padding: 16px;
210
+ box-sizing: border-box;
211
+ }
212
+
213
+ h3 {
214
+ margin: 0;
215
+ max-width: 300px;
216
+ overflow: hidden;
217
+ text-overflow: ellipsis;
218
+ white-space: nowrap;
219
+ color: var(--re-text-color, #000) !important;
220
+ }
221
+ p {
222
+ margin: 10px 0 0 0;
223
+ max-width: 300px;
224
+ font-size: 14px;
225
+ line-height: 17px;
226
+ overflow: hidden;
227
+ text-overflow: ellipsis;
228
+ white-space: nowrap;
229
+ color: var(--re-text-color, #000) !important;
230
+ }
231
+
232
+ .value-container {
233
+ display: flex;
234
+ flex-wrap: wrap;
235
+ align-items: center;
236
+ justify-content: center;
237
+ flex: 1;
238
+ overflow: hidden;
239
+ position: relative;
240
+ gap: 12px;
241
+ }
242
+
243
+ .single-value {
244
+ overflow: hidden;
245
+ position: relative;
246
+ align-items: end;
247
+ padding: 6px;
248
+ box-sizing: border-box;
249
+ /* border-left: 4px solid #ddd; */
250
+ }
251
+
252
+ .current-value {
253
+ font-size: 32px;
254
+ font-weight: 600;
255
+ white-space: nowrap;
256
+ color: var(--re-text-color, #000);
257
+ }
258
+
259
+ .label,
260
+ .unit {
261
+ font-weight: 300;
262
+ font-size: 26px;
263
+ color: var(--re-text-color, #000);
264
+ white-space: nowrap;
265
+ }
266
+
267
+ .sizing-container {
268
+ position: absolute;
269
+ left: 10000px;
270
+ display: flex;
271
+ flex-wrap: wrap;
272
+ align-items: center;
273
+ justify-content: center;
274
+ flex: 1;
275
+ overflow: hidden;
276
+ gap: 12px;
277
+ }
278
+ `
279
+
280
+ render() {
281
+ return html`
282
+ <div class="wrapper">
283
+ <header>
284
+ <h3 class="paging" ?active=${this.inputData?.settings?.title}>
285
+ ${this.inputData?.settings?.title}
286
+ </h3>
287
+ <p class="paging" ?active=${this.inputData?.settings?.subTitle}>
288
+ ${this.inputData?.settings?.subTitle}
289
+ </p>
290
+ </header>
291
+ <div class="sizing-container">
292
+ ${repeat(
293
+ this.dataSets,
294
+ ([label]) => label,
295
+ ([label, ds]) => {
296
+ return html`
297
+ <div class="single-value" label="${label}">
298
+ <div class="label paging" ?active=${this.textActive}>${label}</div>
299
+ <div class="horizontal">
300
+ <div class="current-value paging" ?active=${this.textActive}>
301
+ ${isNaN(ds.needleValue as number)
302
+ ? ''
303
+ : (ds.needleValue as number).toFixed(0)}
304
+ </div>
305
+ <div class="unit paging" ?active=${this.textActive}>${ds.unit}</div>
306
+ </div>
307
+ </div>
308
+ `
309
+ }
310
+ )}
311
+ </div>
312
+ <div class="value-container">
313
+ ${repeat(
314
+ this.dataSets,
315
+ ([label]) => label,
316
+ ([label, ds]) => {
317
+ return html`
318
+ <div class="single-value" label="${label}">
319
+ <div class="label paging" ?active=${this.textActive}>${label}</div>
320
+ <span class="current-value paging" ?active=${this.textActive}>
321
+ ${isNaN(ds.needleValue as number)
322
+ ? ''
323
+ : (ds.needleValue as number).toFixed(0)}
324
+ </span>
325
+ <span class="unit paging" ?active=${this.textActive}>${ds.unit}</span>
326
+ </div>
327
+ `
328
+ }
329
+ )}
330
+ </div>
331
+ </div>
332
+ `
233
333
  }
234
- `;
235
-
236
- render() {
237
- return html`
238
- <div class="wrapper">
239
- <header>
240
- <h3 class="paging" ?active=${this.inputData?.settings?.title}>${this.inputData?.settings?.title}</h3>
241
- <p class="paging" ?active=${this.inputData?.settings?.subTitle}>${this.inputData?.settings?.subTitle}</p>
242
- </header>
243
- <div class="value-container">
244
- ${repeat(// @ts-ignore
245
- this.dataSets, ([label]) => label, ([label, ds]) => {
246
- return html`
247
- <div class="single-value">
248
- <div
249
- class="label paging"
250
- ?active=${this.textActive}
251
- label="${label}"
252
- >
253
- ${label}
254
- </div>
255
- <span
256
- class="current-value paging"
257
- ?active=${this.textActive}
258
- label="${label}">
259
- ${isNaN(ds.needleValue) ? '' : ds.needleValue.toFixed(0)}
260
- </span>
261
- <span class="label paging" label="${label}" ?active=${this.textActive} >
262
- ${ds.unit}
263
- </span>
264
- </div>
265
- `})}
266
- </div>
267
- </div>
268
- `;
269
- }
270
334
  }
271
335
 
272
- window.customElements.define('widget-value-versionplaceholder', WidgetValue);
336
+ window.customElements.define('widget-value-versionplaceholder', WidgetValue)