@record-evolution/widget-value 1.0.26 → 1.1.4
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 +4 -3
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/widget-value.js +337 -329
- package/dist/widget-value.js.map +1 -1
- package/package.json +27 -25
- package/src/default-data.json +14 -6
- package/src/definition-schema.d.ts +23 -15
- package/src/definition-schema.json +51 -42
- package/src/widget-value.ts +26 -20
package/package.json
CHANGED
|
@@ -3,7 +3,11 @@
|
|
|
3
3
|
"description": "REWidget widget-value",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "widget-value",
|
|
6
|
-
"version": "1.
|
|
6
|
+
"version": "1.1.4",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": "18.18.2",
|
|
9
|
+
"npm": ">=10.0.2"
|
|
10
|
+
},
|
|
7
11
|
"type": "module",
|
|
8
12
|
"main": "dist/widget-value.js",
|
|
9
13
|
"types": "dist/src/widget-value.d.ts",
|
|
@@ -23,34 +27,32 @@
|
|
|
23
27
|
"release": "npm version patch --tag-version-prefix='' && git push && git push --tag"
|
|
24
28
|
},
|
|
25
29
|
"dependencies": {
|
|
26
|
-
"@material/web": "^
|
|
27
|
-
"lit": "^3.
|
|
30
|
+
"@material/web": "^2.2.0",
|
|
31
|
+
"lit": "^3.2.0"
|
|
28
32
|
},
|
|
29
33
|
"devDependencies": {
|
|
30
|
-
"@custom-elements-manifest/analyzer": "^0.
|
|
31
|
-
"@open-wc/building-rollup": "^3.0.2",
|
|
32
|
-
"@open-wc/eslint-config": "^12.0.2",
|
|
34
|
+
"@custom-elements-manifest/analyzer": "^0.10.3",
|
|
33
35
|
"@rollup/plugin-babel": "^6.0.4",
|
|
34
|
-
"@rollup/plugin-commonjs": "^
|
|
35
|
-
"@rollup/plugin-node-resolve": "^15.
|
|
36
|
-
"@rollup/plugin-replace": "^
|
|
37
|
-
"@rollup/plugin-typescript": "^
|
|
38
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
39
|
-
"@typescript-eslint/parser": "^
|
|
40
|
-
"@web/dev-server": "^0.4.
|
|
41
|
-
"concurrently": "^
|
|
36
|
+
"@rollup/plugin-commonjs": "^28.0.0",
|
|
37
|
+
"@rollup/plugin-node-resolve": "^15.3.0",
|
|
38
|
+
"@rollup/plugin-replace": "^6.0.1",
|
|
39
|
+
"@rollup/plugin-typescript": "^12.1.0",
|
|
40
|
+
"@typescript-eslint/eslint-plugin": "^8.8.0",
|
|
41
|
+
"@typescript-eslint/parser": "^8.8.0",
|
|
42
|
+
"@web/dev-server": "^0.4.6",
|
|
43
|
+
"concurrently": "^9.0.1",
|
|
42
44
|
"deepmerge": "^4.3.1",
|
|
43
45
|
"es-dev-server": "^2.1.0",
|
|
44
|
-
"eslint": "^
|
|
45
|
-
"eslint-config-prettier": "^9.
|
|
46
|
-
"husky": "^
|
|
47
|
-
"json-schema-to-typescript": "^
|
|
48
|
-
"lint-staged": "^15.
|
|
49
|
-
"prettier": "^3.
|
|
50
|
-
"rimraf": "^
|
|
51
|
-
"rollup": "^
|
|
52
|
-
"tslib": "^2.
|
|
53
|
-
"typescript": "^5.
|
|
46
|
+
"eslint": "^9.11.1",
|
|
47
|
+
"eslint-config-prettier": "^9.1.0",
|
|
48
|
+
"husky": "^9.1.6",
|
|
49
|
+
"json-schema-to-typescript": "^15.0.2",
|
|
50
|
+
"lint-staged": "^15.2.10",
|
|
51
|
+
"prettier": "^3.3.3",
|
|
52
|
+
"rimraf": "^6.0.1",
|
|
53
|
+
"rollup": "^4.24.0",
|
|
54
|
+
"tslib": "^2.7.0",
|
|
55
|
+
"typescript": "^5.6.2"
|
|
54
56
|
},
|
|
55
57
|
"repository": {
|
|
56
58
|
"type": "git",
|
|
@@ -58,7 +60,7 @@
|
|
|
58
60
|
},
|
|
59
61
|
"keywords": [
|
|
60
62
|
"widget",
|
|
61
|
-
"
|
|
63
|
+
"value"
|
|
62
64
|
],
|
|
63
65
|
"bugs": {
|
|
64
66
|
"url": "https://github.com/RecordEvolution/widget-value/issues"
|
package/src/default-data.json
CHANGED
|
@@ -5,9 +5,13 @@
|
|
|
5
5
|
"label": "Temperature",
|
|
6
6
|
"unit": "°C",
|
|
7
7
|
"precision": 2,
|
|
8
|
-
"
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
"styling": {
|
|
9
|
+
"labelColor": "#ff9b9b",
|
|
10
|
+
"valueColor": "#e15656"
|
|
11
|
+
},
|
|
12
|
+
"advanced": {
|
|
13
|
+
"averageLatest": 1
|
|
14
|
+
},
|
|
11
15
|
"data": [
|
|
12
16
|
{
|
|
13
17
|
"value": 90
|
|
@@ -17,9 +21,13 @@
|
|
|
17
21
|
{
|
|
18
22
|
"label": "Pressure",
|
|
19
23
|
"unit": "Pa",
|
|
20
|
-
"
|
|
21
|
-
|
|
22
|
-
|
|
24
|
+
"styling": {
|
|
25
|
+
"labelColor": "#96caf8",
|
|
26
|
+
"valueColor": "#5898d0"
|
|
27
|
+
},
|
|
28
|
+
"advanced": {
|
|
29
|
+
"averageLatest": 1
|
|
30
|
+
},
|
|
23
31
|
"data": [
|
|
24
32
|
{
|
|
25
33
|
"value": 80
|
|
@@ -19,10 +19,8 @@ export type Unit = string;
|
|
|
19
19
|
* Number of digits after the decimal point. (Default 0)
|
|
20
20
|
*/
|
|
21
21
|
export type Precision = number;
|
|
22
|
-
export type LabelColor = string;
|
|
23
|
-
export type ValueColor = string;
|
|
24
22
|
/**
|
|
25
|
-
* Calculate the average over the given number of newest values. (If
|
|
23
|
+
* Calculate the average over the given number of newest values. (If you use "Split data by", then per each of the pivot dataseries.) If not specified then the latest value is shown without modification.
|
|
26
24
|
*/
|
|
27
25
|
export type AverageLatestValues = number;
|
|
28
26
|
/**
|
|
@@ -35,37 +33,47 @@ export type MaximumLatency = number;
|
|
|
35
33
|
export type Timestamp = string;
|
|
36
34
|
export type Value = number;
|
|
37
35
|
/**
|
|
38
|
-
* 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
|
|
36
|
+
* 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 split column, then you will get a value field for each city.
|
|
39
37
|
*/
|
|
40
|
-
export type
|
|
38
|
+
export type SplitDataBy = string;
|
|
41
39
|
/**
|
|
42
40
|
* The data used to draw this data series.
|
|
43
41
|
*/
|
|
44
42
|
export type Data = {
|
|
45
43
|
tsp?: Timestamp;
|
|
46
44
|
value?: Value;
|
|
47
|
-
pivot?:
|
|
45
|
+
pivot?: SplitDataBy;
|
|
48
46
|
[k: string]: unknown;
|
|
49
47
|
}[];
|
|
50
48
|
export type ValueDisplays = {
|
|
51
49
|
label?: Label;
|
|
52
50
|
unit?: Unit;
|
|
53
51
|
precision?: Precision;
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
averageLatest?: AverageLatestValues;
|
|
57
|
-
maxLatency?: MaximumLatency;
|
|
52
|
+
styling?: Styling;
|
|
53
|
+
advanced?: AdvancedSettings;
|
|
58
54
|
data?: Data;
|
|
59
55
|
[k: string]: unknown;
|
|
60
56
|
}[];
|
|
61
57
|
|
|
62
|
-
export interface
|
|
63
|
-
|
|
58
|
+
export interface InputData {
|
|
59
|
+
title?: Title;
|
|
60
|
+
subTitle?: Subtitle;
|
|
64
61
|
dataseries?: ValueDisplays;
|
|
65
62
|
[k: string]: unknown;
|
|
66
63
|
}
|
|
67
|
-
export interface
|
|
68
|
-
|
|
69
|
-
|
|
64
|
+
export interface Styling {
|
|
65
|
+
labelColor?: LabelColor;
|
|
66
|
+
valueColor?: ValueColor;
|
|
67
|
+
[k: string]: unknown;
|
|
68
|
+
}
|
|
69
|
+
export interface LabelColor {
|
|
70
|
+
[k: string]: unknown;
|
|
71
|
+
}
|
|
72
|
+
export interface ValueColor {
|
|
73
|
+
[k: string]: unknown;
|
|
74
|
+
}
|
|
75
|
+
export interface AdvancedSettings {
|
|
76
|
+
averageLatest?: AverageLatestValues;
|
|
77
|
+
maxLatency?: MaximumLatency;
|
|
70
78
|
[k: string]: unknown;
|
|
71
79
|
}
|
|
@@ -1,23 +1,16 @@
|
|
|
1
1
|
{
|
|
2
|
-
"title": "
|
|
2
|
+
"title": "InputData",
|
|
3
3
|
"type": "object",
|
|
4
4
|
"properties": {
|
|
5
|
-
"
|
|
6
|
-
"title": "
|
|
7
|
-
"type": "
|
|
8
|
-
"order": 1
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
},
|
|
15
|
-
"subTitle": {
|
|
16
|
-
"title": "Subtitle",
|
|
17
|
-
"type": "string",
|
|
18
|
-
"order": 2
|
|
19
|
-
}
|
|
20
|
-
}
|
|
5
|
+
"title": {
|
|
6
|
+
"title": "Title",
|
|
7
|
+
"type": "string",
|
|
8
|
+
"order": 1
|
|
9
|
+
},
|
|
10
|
+
"subTitle": {
|
|
11
|
+
"title": "Subtitle",
|
|
12
|
+
"type": "string",
|
|
13
|
+
"order": 2
|
|
21
14
|
},
|
|
22
15
|
"dataseries": {
|
|
23
16
|
"title": "Value Displays",
|
|
@@ -45,35 +38,51 @@
|
|
|
45
38
|
"type": "number",
|
|
46
39
|
"order": 3
|
|
47
40
|
},
|
|
48
|
-
"
|
|
49
|
-
"title": "
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"order":
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
41
|
+
"styling": {
|
|
42
|
+
"title": "Styling",
|
|
43
|
+
"description": "",
|
|
44
|
+
"type": "object",
|
|
45
|
+
"order": 6,
|
|
46
|
+
"properties": {
|
|
47
|
+
"labelColor": {
|
|
48
|
+
"title": "Label Color",
|
|
49
|
+
"type": "color",
|
|
50
|
+
"color": true,
|
|
51
|
+
"order": 4
|
|
52
|
+
},
|
|
53
|
+
"valueColor": {
|
|
54
|
+
"title": "Value Color",
|
|
55
|
+
"type": "color",
|
|
56
|
+
"color": true,
|
|
57
|
+
"order": 5
|
|
58
|
+
}
|
|
59
|
+
}
|
|
65
60
|
},
|
|
66
|
-
"
|
|
67
|
-
"title": "
|
|
68
|
-
"description": "
|
|
69
|
-
"type": "
|
|
70
|
-
"order": 7
|
|
61
|
+
"advanced": {
|
|
62
|
+
"title": "Advanced Settings",
|
|
63
|
+
"description": "",
|
|
64
|
+
"type": "object",
|
|
65
|
+
"order": 7,
|
|
66
|
+
"properties": {
|
|
67
|
+
"averageLatest": {
|
|
68
|
+
"title": "Average Latest Values",
|
|
69
|
+
"description": "Calculate the average over the given number of newest values. (If you use \"Split data by\", then per each of the pivot dataseries.) If not specified then the latest value is shown without modification.",
|
|
70
|
+
"type": "number",
|
|
71
|
+
"order": 6
|
|
72
|
+
},
|
|
73
|
+
"maxLatency": {
|
|
74
|
+
"title": "Maximum Latency",
|
|
75
|
+
"description": "If you provide timestamp data, the delivered value is only shown in the gauge when the age of the data is not older than the given maximum Latency in seconds.",
|
|
76
|
+
"type": "number",
|
|
77
|
+
"order": 7
|
|
78
|
+
}
|
|
79
|
+
}
|
|
71
80
|
},
|
|
72
81
|
"data": {
|
|
73
82
|
"title": "Data",
|
|
74
83
|
"description": "The data used to draw this data series.",
|
|
75
84
|
"type": "array",
|
|
76
|
-
"order":
|
|
85
|
+
"order": 4,
|
|
77
86
|
"buffersize": 100,
|
|
78
87
|
"items": {
|
|
79
88
|
"type": "object",
|
|
@@ -91,8 +100,8 @@
|
|
|
91
100
|
"order": 1
|
|
92
101
|
},
|
|
93
102
|
"pivot": {
|
|
94
|
-
"title": "
|
|
95
|
-
"description": "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
|
|
103
|
+
"title": "Split Data by",
|
|
104
|
+
"description": "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 split column, then you will get a value field for each city.",
|
|
96
105
|
"type": "string",
|
|
97
106
|
"order": 2
|
|
98
107
|
}
|
package/src/widget-value.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { html, css, LitElement, PropertyValueMap } from 'lit'
|
|
2
2
|
import { repeat } from 'lit/directives/repeat.js'
|
|
3
3
|
import { property, state } from 'lit/decorators.js'
|
|
4
|
-
import {
|
|
4
|
+
import { InputData } from './definition-schema.js'
|
|
5
5
|
|
|
6
|
-
type Dataseries = Exclude<
|
|
6
|
+
type Dataseries = Exclude<InputData['dataseries'], undefined>[number] & { needleValue?: number }
|
|
7
7
|
type Data = Exclude<Dataseries['data'], undefined>[number]
|
|
8
8
|
|
|
9
9
|
export class WidgetValue extends LitElement {
|
|
10
10
|
@property({ type: Object })
|
|
11
|
-
inputData?:
|
|
11
|
+
inputData?: InputData
|
|
12
12
|
|
|
13
13
|
@state()
|
|
14
14
|
private dataSets: Map<string, Dataseries> = new Map()
|
|
@@ -24,7 +24,7 @@ export class WidgetValue extends LitElement {
|
|
|
24
24
|
|
|
25
25
|
version: string = 'versionplaceholder'
|
|
26
26
|
|
|
27
|
-
resizeObserver: ResizeObserver
|
|
27
|
+
private resizeObserver: ResizeObserver
|
|
28
28
|
|
|
29
29
|
valueContainer?: HTMLDivElement
|
|
30
30
|
boxes?: HTMLDivElement[]
|
|
@@ -32,11 +32,17 @@ export class WidgetValue extends LitElement {
|
|
|
32
32
|
origHeight: number = 0
|
|
33
33
|
constructor() {
|
|
34
34
|
super()
|
|
35
|
-
|
|
36
|
-
this.resizeObserver = new ResizeObserver((ev) => this.adjustSizes())
|
|
35
|
+
this.resizeObserver = new ResizeObserver(this.adjustSizes.bind(this))
|
|
37
36
|
this.resizeObserver.observe(this)
|
|
38
37
|
}
|
|
39
38
|
|
|
39
|
+
disconnectedCallback() {
|
|
40
|
+
super.disconnectedCallback()
|
|
41
|
+
if(this.resizeObserver) {
|
|
42
|
+
this.resizeObserver.disconnect()
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
40
46
|
protected firstUpdated(_changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>) {
|
|
41
47
|
this.valueContainer = this?.shadowRoot?.querySelector('.value-container') as HTMLDivElement
|
|
42
48
|
|
|
@@ -121,7 +127,7 @@ export class WidgetValue extends LitElement {
|
|
|
121
127
|
const numberText = n.querySelector('.current-value') as HTMLDivElement
|
|
122
128
|
numberText.setAttribute(
|
|
123
129
|
'style',
|
|
124
|
-
`font-size: ${32 * modifier}px; ${ds?.valueColor ? 'color: ' + ds?.valueColor : ''}`
|
|
130
|
+
`font-size: ${32 * modifier}px; ${ds?.styling?.valueColor ? 'color: ' + ds?.styling?.valueColor : ''}`
|
|
125
131
|
)
|
|
126
132
|
})
|
|
127
133
|
|
|
@@ -131,12 +137,12 @@ export class WidgetValue extends LitElement {
|
|
|
131
137
|
const labelText = n.querySelector('.label') as HTMLDivElement
|
|
132
138
|
labelText.setAttribute(
|
|
133
139
|
'style',
|
|
134
|
-
`font-size: ${26 * modifier}px; ${ds?.labelColor ? 'color: ' + ds?.labelColor : ''}`
|
|
140
|
+
`font-size: ${26 * modifier}px; ${ds?.styling?.labelColor ? 'color: ' + ds?.styling?.labelColor : ''}`
|
|
135
141
|
)
|
|
136
142
|
const unitText = n.querySelector('.unit') as HTMLDivElement
|
|
137
143
|
unitText.setAttribute(
|
|
138
144
|
'style',
|
|
139
|
-
`font-size: ${26 * modifier}px; ${ds?.labelColor ? 'color: ' + ds?.labelColor : ''}`
|
|
145
|
+
`font-size: ${26 * modifier}px; ${ds?.styling?.labelColor ? 'color: ' + ds?.styling?.labelColor : ''}`
|
|
140
146
|
)
|
|
141
147
|
})
|
|
142
148
|
|
|
@@ -158,13 +164,12 @@ export class WidgetValue extends LitElement {
|
|
|
158
164
|
distincts.forEach((piv) => {
|
|
159
165
|
const prefix = piv ? `${piv} - ` : ''
|
|
160
166
|
const pds: Dataseries = {
|
|
161
|
-
label: prefix + ds.label
|
|
167
|
+
label: prefix + ds.label,
|
|
162
168
|
order: ds.order,
|
|
163
169
|
unit: ds.unit,
|
|
164
170
|
precision: ds.precision,
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
valueColor: ds.valueColor,
|
|
171
|
+
advanced: ds.advanced,
|
|
172
|
+
styling: ds.styling,
|
|
168
173
|
data: distincts.length === 1 ? ds.data : ds.data?.filter((d) => d.pivot === piv),
|
|
169
174
|
needleValue: undefined
|
|
170
175
|
}
|
|
@@ -174,9 +179,10 @@ export class WidgetValue extends LitElement {
|
|
|
174
179
|
|
|
175
180
|
// filter latest values and calculate average
|
|
176
181
|
this.dataSets.forEach((ds, label) => {
|
|
177
|
-
|
|
182
|
+
ds.advanced ??= {}
|
|
183
|
+
if (typeof ds.advanced?.averageLatest !== 'number' || !isNaN(ds.advanced?.averageLatest)) ds.advanced.averageLatest = 1
|
|
178
184
|
|
|
179
|
-
const data = ds?.data?.slice(0, ds?.averageLatest ?? 1) ?? []
|
|
185
|
+
const data = ds?.data?.slice(0, ds?.advanced?.averageLatest ?? 1) ?? []
|
|
180
186
|
const values = (data?.map((d) => d.value)?.filter((p) => p !== undefined) ?? []) as number[]
|
|
181
187
|
const average = values.reduce((p, c) => p + c, 0) / values.length
|
|
182
188
|
|
|
@@ -184,7 +190,7 @@ export class WidgetValue extends LitElement {
|
|
|
184
190
|
const tsp = Date.parse(data?.[0]?.tsp ?? '')
|
|
185
191
|
if (isNaN(tsp)) {
|
|
186
192
|
const now = new Date().getTime()
|
|
187
|
-
if (now - tsp > (ds.maxLatency ?? Infinity) * 1000) ds.needleValue = undefined
|
|
193
|
+
if (now - tsp > (ds.advanced?.maxLatency ?? Infinity) * 1000) ds.needleValue = undefined
|
|
188
194
|
}
|
|
189
195
|
|
|
190
196
|
ds.needleValue = average
|
|
@@ -291,11 +297,11 @@ export class WidgetValue extends LitElement {
|
|
|
291
297
|
return html`
|
|
292
298
|
<div class="wrapper">
|
|
293
299
|
<header>
|
|
294
|
-
<h3 class="paging" ?active=${this.inputData?.
|
|
295
|
-
${this.inputData?.
|
|
300
|
+
<h3 class="paging" ?active=${this.inputData?.title}>
|
|
301
|
+
${this.inputData?.title}
|
|
296
302
|
</h3>
|
|
297
|
-
<p class="paging" ?active=${this.inputData?.
|
|
298
|
-
${this.inputData?.
|
|
303
|
+
<p class="paging" ?active=${this.inputData?.subTitle}>
|
|
304
|
+
${this.inputData?.subTitle}
|
|
299
305
|
</p>
|
|
300
306
|
</header>
|
|
301
307
|
<div class="sizing-container">
|