@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.
- package/dist/src/widget-value.d.ts +2 -2
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/widget-value.js +168 -139
- package/dist/widget-value.js.map +1 -1
- package/package.json +4 -2
- package/src/definition-schema.d.ts +56 -0
- package/src/definition-schema.json +6 -2
- package/src/widget-value.ts +305 -241
- package/dist/src/types.d.ts +0 -28
- package/src/types.ts +0 -32
|
@@ -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": "
|
|
45
|
+
"type": "string",
|
|
46
|
+
"color": true,
|
|
45
47
|
"order": 3
|
|
46
48
|
},
|
|
47
49
|
"valueColor": {
|
|
48
50
|
"title": "Value Color",
|
|
49
|
-
"type": "
|
|
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",
|
package/src/widget-value.ts
CHANGED
|
@@ -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 {
|
|
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
|
-
|
|
9
|
-
inputData?: InputData = undefined
|
|
10
|
+
@property({ type: Object })
|
|
11
|
+
inputData?: ValueChartConfiguration
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
@state()
|
|
14
|
+
private dataSets: Map<string, Dataseries> = new Map()
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
+
@state()
|
|
17
|
+
private textActive: boolean = true
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
@state()
|
|
20
|
+
private numberText?: HTMLDivElement[]
|
|
19
21
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
+
@state()
|
|
23
|
+
private labelText?: HTMLDivElement[]
|
|
22
24
|
|
|
23
|
-
|
|
25
|
+
version: string = 'versionplaceholder'
|
|
24
26
|
|
|
25
|
-
|
|
27
|
+
resizeObserver: ResizeObserver
|
|
26
28
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
valueContainer?: HTMLDivElement
|
|
30
|
+
boxes?: HTMLDivElement[]
|
|
31
|
+
origWidth: number = 0
|
|
32
|
+
origHeight: number = 0
|
|
33
|
+
constructor() {
|
|
34
|
+
super()
|
|
33
35
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
this.resizeObserver = new ResizeObserver((ev) => this.adjustSizes())
|
|
37
|
+
this.resizeObserver.observe(this)
|
|
38
|
+
}
|
|
37
39
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
40
|
+
protected firstUpdated(_changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>) {
|
|
41
|
+
this.valueContainer = this?.shadowRoot?.querySelector('.value-container') as HTMLDivElement
|
|
41
42
|
|
|
42
|
-
|
|
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
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
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
|
-
|
|
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
|
-
|
|
56
|
+
sizingSetup() {
|
|
57
|
+
if (this.origWidth !== 0 && this.origHeight !== 0) return
|
|
171
58
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
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
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
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
|
-
|
|
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
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
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
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
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
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
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)
|