@record-evolution/widget-value 1.0.11 → 1.0.16

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/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "REWidget widget-value",
4
4
  "license": "MIT",
5
5
  "author": "widget-value",
6
- "version": "1.0.11",
6
+ "version": "1.0.16",
7
7
  "type": "module",
8
8
  "main": "dist/widget-value.js",
9
9
  "types": "dist/src/widget-value.d.ts",
@@ -14,8 +14,8 @@
14
14
  "scripts": {
15
15
  "analyze": "cem analyze --litelement",
16
16
  "start": "tsc && concurrently -k -r \"tsc --watch --preserveWatchOutput\" \"wds\"",
17
- "build": "rollup -c rollup.config.js --bundleConfigAsCjs",
18
- "watch": "rollup -w -c rollup.config.js --bundleConfigAsCjs",
17
+ "build": "rollup -c rollup.config.js",
18
+ "watch": "rollup -w -c rollup.config.js",
19
19
  "types": "cat src/definition-schema.json | json2ts > src/definition-schema.d.ts",
20
20
  "start:build": "npm run build && es-dev-server --root-dir dist --app-index index.html --compatibility none --open",
21
21
  "lint": "eslint --ext .ts,.html . --ignore-path .gitignore && prettier \"**/*.ts\" --check --ignore-path .gitignore",
@@ -23,6 +23,7 @@
23
23
  "release": "npm version patch --tag-version-prefix='' && git push && git push --tag"
24
24
  },
25
25
  "dependencies": {
26
+ "@material/web": "^1.0.1",
26
27
  "lit": "^3.1.0"
27
28
  },
28
29
  "devDependencies": {
@@ -57,7 +58,7 @@
57
58
  },
58
59
  "keywords": [
59
60
  "widget",
60
- "value"
61
+ "table"
61
62
  ],
62
63
  "bugs": {
63
64
  "url": "https://github.com/RecordEvolution/widget-value/issues"
@@ -1,23 +1,30 @@
1
1
  {
2
- "settings": {
3
- },
4
- "dataseries": [{
5
- "label": "Temperature",
6
- "unit": "°C",
7
- "valueColor": "#e15656",
8
- "labelColor": "#ff9b9b",
9
- "averageLatest": 1,
10
- "data": [{
11
- "value": 90
12
- }]
13
- },{
14
- "label": "Humidity",
15
- "unit": "Pa",
16
- "valueColor": "#5898d0",
17
- "labelColor": "#96caf8",
18
- "averageLatest": 1,
19
- "data": [{
20
- "value": 80
21
- }]
22
- }]
23
- }
2
+ "settings": {},
3
+ "dataseries": [
4
+ {
5
+ "label": "Temperature",
6
+ "unit": "°C",
7
+ "precision": 2,
8
+ "valueColor": "#e15656",
9
+ "labelColor": "#ff9b9b",
10
+ "averageLatest": 1,
11
+ "data": [
12
+ {
13
+ "value": 90
14
+ }
15
+ ]
16
+ },
17
+ {
18
+ "label": "Humidity",
19
+ "unit": "Pa",
20
+ "valueColor": "#5898d0",
21
+ "labelColor": "#96caf8",
22
+ "averageLatest": 1,
23
+ "data": [
24
+ {
25
+ "value": 80
26
+ }
27
+ ]
28
+ }
29
+ ]
30
+ }
@@ -15,6 +15,10 @@ export type Label = string;
15
15
  * The unit of the value. e.g. °C or km/h
16
16
  */
17
17
  export type Unit = string;
18
+ /**
19
+ * Number of digits after the decimal point
20
+ */
21
+ export type Precision = number;
18
22
  export type LabelColor = string;
19
23
  export type ValueColor = string;
20
24
  /**
@@ -30,13 +34,14 @@ export type PivotColumn = string;
30
34
  * The data used to draw this data series.
31
35
  */
32
36
  export type Data = {
33
- value: Value;
37
+ value?: Value;
34
38
  pivot?: PivotColumn;
35
39
  [k: string]: unknown;
36
40
  }[];
37
41
  export type ValueDisplays = {
38
- label: Label;
42
+ label?: Label;
39
43
  unit?: Unit;
44
+ precision?: Precision;
40
45
  labelColor?: LabelColor;
41
46
  valueColor?: ValueColor;
42
47
  averageLatest?: AverageLatestValues;
@@ -25,7 +25,6 @@
25
25
  "order": 2,
26
26
  "items": {
27
27
  "type": "object",
28
- "required": ["label"],
29
28
  "properties": {
30
29
  "label": {
31
30
  "title": "Label",
@@ -40,17 +39,23 @@
40
39
  "type": "string",
41
40
  "order": 2
42
41
  },
42
+ "precision": {
43
+ "title": "Precision",
44
+ "description": "Number of digits after the decimal point. (Default 0)",
45
+ "type": "number",
46
+ "order": 3
47
+ },
43
48
  "labelColor": {
44
49
  "title": "Label Color",
45
50
  "type": "string",
46
51
  "color": true,
47
- "order": 3
52
+ "order": 4
48
53
  },
49
54
  "valueColor": {
50
55
  "title": "Value Color",
51
56
  "type": "string",
52
57
  "color": true,
53
- "order": 4
58
+ "order": 5
54
59
  },
55
60
  "averageLatest": {
56
61
  "title": "Average Latest Values",
@@ -66,7 +71,6 @@
66
71
  "buffersize": 100,
67
72
  "items": {
68
73
  "type": "object",
69
- "required": ["value"],
70
74
  "properties": {
71
75
  "value": {
72
76
  "title": "Value",
@@ -3,7 +3,7 @@ import { repeat } from 'lit/directives/repeat.js'
3
3
  import { property, state } from 'lit/decorators.js'
4
4
  import { ValueChartConfiguration } from './definition-schema.js'
5
5
 
6
- type Dataseries = Exclude<ValueChartConfiguration['dataseries'], undefined>[number]
6
+ type Dataseries = Exclude<ValueChartConfiguration['dataseries'], undefined>[number] & { needleValue?: number }
7
7
  type Data = Exclude<Dataseries['data'], undefined>[number]
8
8
 
9
9
  export class WidgetValue extends LitElement {
@@ -38,17 +38,17 @@ export class WidgetValue extends LitElement {
38
38
  }
39
39
 
40
40
  protected firstUpdated(_changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>) {
41
+ this.valueContainer = this?.shadowRoot?.querySelector('.value-container') as HTMLDivElement
42
+
43
+ this.sizingSetup()
41
44
  this.applyInputData()
42
45
  }
43
46
 
44
47
  update(changedProperties: Map<string, any>) {
45
- changedProperties.forEach((oldValue, propName) => {
46
- if (propName === 'inputData') {
47
- this.applyInputData()
48
- }
49
- })
50
-
51
- this.sizingSetup()
48
+ if (changedProperties.has('inputData')) {
49
+ this.sizingSetup()
50
+ this.applyInputData()
51
+ }
52
52
 
53
53
  super.update(changedProperties)
54
54
  }
@@ -56,30 +56,23 @@ export class WidgetValue extends LitElement {
56
56
  sizingSetup() {
57
57
  if (this.origWidth !== 0 && this.origHeight !== 0) return
58
58
 
59
- this.boxes = Array.from(
60
- this?.shadowRoot?.querySelectorAll('.single-value') as NodeListOf<HTMLDivElement>
61
- )
62
- this.numberText = Array.from(
63
- this?.shadowRoot?.querySelectorAll('.current-value') as NodeListOf<HTMLDivElement>
59
+ const boxes = Array.from(
60
+ this?.shadowRoot?.querySelectorAll(
61
+ '.sizing-container > .single-value'
62
+ ) as NodeListOf<HTMLDivElement>
64
63
  )
65
- this.labelText = Array.from(
66
- this?.shadowRoot?.querySelectorAll('.label') as NodeListOf<HTMLDivElement>
67
- )
68
- this.valueContainer = this?.shadowRoot?.querySelector('.value-container') as HTMLDivElement
69
64
 
70
65
  this.origWidth =
71
- this.boxes?.map((b) => b.getBoundingClientRect().width).reduce((p, c) => (c > p ? c : p), 0) ?? 0
66
+ boxes?.map((b) => b.getBoundingClientRect().width).reduce((p, c) => (c > p ? c : p), 0) ?? 0
72
67
  this.origHeight =
73
- this.boxes?.map((b) => b.getBoundingClientRect().height).reduce((p, c) => (c > p ? c : p), 0) ?? 0
74
- if (this.origWidth > 0) this.origWidth += 16
75
- if (this.origHeight > 0) this.origHeight += 16
68
+ boxes?.map((b) => b.getBoundingClientRect().height).reduce((p, c) => (c > p ? c : p), 0) ?? 0
76
69
 
77
70
  this.adjustSizes()
78
71
  }
79
72
 
80
73
  adjustSizes() {
81
- const userWidth = this.valueContainer?.getBoundingClientRect().width
82
- const userHeight = this.valueContainer?.getBoundingClientRect().height
74
+ const userWidth = (this.valueContainer?.getBoundingClientRect().width ?? 32) - 32
75
+ const userHeight = (this.valueContainer?.getBoundingClientRect().height ?? 32) - 32
83
76
  const count = this.dataSets.size
84
77
 
85
78
  const width = this.origWidth
@@ -104,31 +97,44 @@ export class WidgetValue extends LitElement {
104
97
  const size = m * m * width * height * count
105
98
  if (c * m * width < uwgap) fits.push({ r, m, size, width, height, userWidth, userHeight })
106
99
  }
107
-
108
100
  const maxSize = fits.reduce((p, c) => (c.size < p ? p : c.size), 0)
109
101
  const fit = fits.find((f) => f.size === maxSize)
110
102
  const modifier = fit?.m ?? 1
111
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))
112
104
 
113
- this.boxes?.forEach((box) =>
105
+ const boxes = Array.from(
106
+ this?.shadowRoot?.querySelectorAll(
107
+ '.value-container > .single-value'
108
+ ) as NodeListOf<HTMLDivElement>
109
+ )
110
+
111
+ boxes?.forEach((box) =>
114
112
  box.setAttribute(
115
113
  'style',
116
114
  `width:${modifier * width}px; height:${modifier * height}px; padding:${modifier * 6}px`
117
115
  )
118
116
  )
119
- this.numberText?.forEach((n) => {
117
+
118
+ boxes?.forEach((n) => {
120
119
  const label: string | null = n.getAttribute('label')
121
120
  const ds: Dataseries | undefined = this.dataSets.get(label ?? '')
122
- n.setAttribute(
121
+ const numberText = n.querySelector('.current-value') as HTMLDivElement
122
+ numberText.setAttribute(
123
123
  'style',
124
124
  `font-size: ${32 * modifier}px; ${ds?.valueColor ? 'color: ' + ds?.valueColor : ''}`
125
125
  )
126
126
  })
127
127
 
128
- this.labelText?.forEach((n) => {
128
+ boxes?.forEach((n) => {
129
129
  const label: string | null = n.getAttribute('label')
130
130
  const ds: Dataseries | undefined = this.dataSets.get(label ?? '')
131
- n.setAttribute(
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(
132
138
  'style',
133
139
  `font-size: ${26 * modifier}px; ${ds?.labelColor ? 'color: ' + ds?.labelColor : ''}`
134
140
  )
@@ -145,22 +151,27 @@ export class WidgetValue extends LitElement {
145
151
  // ?.sort((a, b) => a.order - b.order)
146
152
  ?.forEach((ds) => {
147
153
  // pivot data
148
- const distincts = [...new Set(ds.data?.map((d: Data) => d.pivot))]
154
+ const distincts = [...new Set(ds.data?.map((d: Data) => d.pivot))].filter(
155
+ (d) => d
156
+ ) as string[]
157
+ ds.needleValue = undefined
149
158
  if (distincts.length > 1 || distincts[0] !== undefined) {
150
159
  distincts.forEach((piv) => {
151
- const pds: any = {
152
- label: `${ds.label} ${piv}`,
160
+ const pds: Dataseries = {
161
+ label: `${ds.label ?? ''}-${piv}`,
153
162
  order: ds.order,
154
163
  unit: ds.unit,
164
+ precision: ds.precision,
155
165
  averageLatest: ds.averageLatest,
156
166
  labelColor: ds.labelColor,
157
167
  valueColor: ds.valueColor,
158
- data: ds.data?.filter((d) => d.pivot === piv)
168
+ data: ds.data?.filter((d) => d.pivot === piv),
169
+ needleValue: undefined
159
170
  }
160
- this.dataSets.set(pds.label, pds)
171
+ this.dataSets.set(pds.label ?? '', pds)
161
172
  })
162
173
  } else {
163
- this.dataSets.set(ds.label, ds)
174
+ this.dataSets.set(ds.label ?? '', ds)
164
175
  }
165
176
  })
166
177
 
@@ -198,6 +209,7 @@ export class WidgetValue extends LitElement {
198
209
  display: flex;
199
210
  flex-direction: column;
200
211
  height: 100%;
212
+ line-height: 0.9;
201
213
  width: 100%;
202
214
  padding: 16px;
203
215
  box-sizing: border-box;
@@ -237,7 +249,6 @@ export class WidgetValue extends LitElement {
237
249
  overflow: hidden;
238
250
  position: relative;
239
251
  align-items: end;
240
- font-size: 26px;
241
252
  padding: 6px;
242
253
  box-sizing: border-box;
243
254
  /* border-left: 4px solid #ddd; */
@@ -250,12 +261,25 @@ export class WidgetValue extends LitElement {
250
261
  color: var(--re-text-color, #000);
251
262
  }
252
263
 
253
- .label {
264
+ .label,
265
+ .unit {
254
266
  font-weight: 300;
255
267
  font-size: 26px;
256
268
  color: var(--re-text-color, #000);
257
269
  white-space: nowrap;
258
270
  }
271
+
272
+ .sizing-container {
273
+ position: absolute;
274
+ left: 10000px;
275
+ display: flex;
276
+ flex-wrap: wrap;
277
+ align-items: center;
278
+ justify-content: center;
279
+ flex: 1;
280
+ overflow: hidden;
281
+ gap: 12px;
282
+ }
259
283
  `
260
284
 
261
285
  render() {
@@ -269,29 +293,39 @@ export class WidgetValue extends LitElement {
269
293
  ${this.inputData?.settings?.subTitle}
270
294
  </p>
271
295
  </header>
272
- <div class="value-container">
296
+ <div class="sizing-container">
273
297
  ${repeat(
274
- // @ts-ignore
275
298
  this.dataSets,
276
299
  ([label]) => label,
277
300
  ([label, ds]) => {
278
301
  return html`
279
- <div class="single-value">
280
- <div class="label paging" ?active=${this.textActive} label="${label}">
281
- ${label}
282
- </div>
283
- <span
284
- class="current-value paging"
285
- ?active=${this.textActive}
286
- label="${label}"
287
- >
288
- ${isNaN(ds.needleValue as number)
302
+ <div class="single-value" label="${label}">
303
+ <div class="label paging" ?active=${this.textActive}>${label}</div>
304
+ <span class="current-value paging" ?active=${this.textActive}>
305
+ ${isNaN(ds.needleValue ?? 0) || ds.needleValue === undefined
289
306
  ? ''
290
- : (ds.needleValue as number).toFixed(0)}
307
+ : ds.needleValue.toFixed(Math.max(0, ds.precision ?? 0))}
291
308
  </span>
292
- <span class="label paging" label="${label}" ?active=${this.textActive}>
293
- ${ds.unit}
309
+ <span class="unit paging" ?active=${this.textActive}>${ds.unit}</span>
310
+ </div>
311
+ `
312
+ }
313
+ )}
314
+ </div>
315
+ <div class="value-container">
316
+ ${repeat(
317
+ [...this.dataSets.entries()].sort(),
318
+ ([label]) => label,
319
+ ([label, ds]) => {
320
+ return html`
321
+ <div class="single-value" label="${label}">
322
+ <div class="label paging" ?active=${this.textActive}>${label}</div>
323
+ <span class="current-value paging" ?active=${this.textActive}>
324
+ ${isNaN(ds.needleValue ?? 0) || ds.needleValue === undefined
325
+ ? ''
326
+ : ds.needleValue.toFixed(Math.max(0, ds.precision ?? 0))}
294
327
  </span>
328
+ <span class="unit paging" ?active=${this.textActive}>${ds.unit}</span>
295
329
  </div>
296
330
  `
297
331
  }