@record-evolution/widget-linechart 1.5.6 → 1.6.1
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/README.md +2 -2
- package/dist/src/widget-linechart.d.ts +34 -9
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/widget-linechart.js +53076 -22003
- package/dist/widget-linechart.js.map +1 -1
- package/package.json +16 -22
- package/src/default-data.json +20 -16
- package/src/definition-schema.d.ts +50 -58
- package/src/definition-schema.json +30 -24
- package/src/widget-linechart.ts +333 -360
- package/src/widget-linechart_old.old_ts +486 -0
package/src/widget-linechart.ts
CHANGED
|
@@ -1,60 +1,222 @@
|
|
|
1
|
-
import { html, css, LitElement } from 'lit'
|
|
2
|
-
import {
|
|
3
|
-
import { property, state } from 'lit/decorators.js'
|
|
4
|
-
import Chart, { ChartDataset } from 'chart.js/auto'
|
|
5
|
-
import tinycolor, { ColorInput } from 'tinycolor2'
|
|
6
|
-
// This does not work. See comments at the end of the file.
|
|
7
|
-
// import 'chartjs-adapter-dayjs-4/dist/chartjs-adapter-dayjs-4.esm';
|
|
8
|
-
// import 'chartjs-adapter-moment';
|
|
9
|
-
// import 'chartjs-adapter-date-fns';
|
|
10
|
-
import { InputData } from './definition-schema.js'
|
|
1
|
+
import { html, css, LitElement, PropertyValueMap } from 'lit'
|
|
2
|
+
import { customElement, property, state } from 'lit/decorators.js'
|
|
11
3
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
4
|
+
import * as echarts from 'echarts/core'
|
|
5
|
+
import {
|
|
6
|
+
TitleComponent,
|
|
7
|
+
ToolboxComponent,
|
|
8
|
+
TooltipComponent,
|
|
9
|
+
LegendComponent,
|
|
10
|
+
DataZoomComponent,
|
|
11
|
+
GridComponent
|
|
12
|
+
} from 'echarts/components'
|
|
13
|
+
import { LineChart, BarChart, ScatterChart } from 'echarts/charts'
|
|
14
|
+
import { UniversalTransition } from 'echarts/features'
|
|
15
|
+
import { CanvasRenderer } from 'echarts/renderers'
|
|
16
|
+
import tinycolor, { ColorInput } from 'tinycolor2'
|
|
15
17
|
|
|
18
|
+
echarts.use([
|
|
19
|
+
GridComponent,
|
|
20
|
+
TitleComponent,
|
|
21
|
+
ToolboxComponent,
|
|
22
|
+
TooltipComponent,
|
|
23
|
+
LegendComponent,
|
|
24
|
+
DataZoomComponent,
|
|
25
|
+
LineChart,
|
|
26
|
+
BarChart,
|
|
27
|
+
ScatterChart,
|
|
28
|
+
CanvasRenderer,
|
|
29
|
+
UniversalTransition
|
|
30
|
+
])
|
|
31
|
+
|
|
32
|
+
import { InputData } from './definition-schema'
|
|
33
|
+
import { EChartsOption, ScatterSeriesOption, SeriesOption } from 'echarts'
|
|
34
|
+
import { TitleOption } from 'echarts/types/dist/shared'
|
|
35
|
+
|
|
36
|
+
@customElement('widget-linechart-versionplaceholder')
|
|
16
37
|
export class WidgetLinechart extends LitElement {
|
|
17
38
|
@property({ type: Object })
|
|
18
39
|
inputData?: InputData
|
|
19
40
|
|
|
41
|
+
@property({ type: Object })
|
|
42
|
+
themeObject?: any
|
|
43
|
+
|
|
44
|
+
@property({ type: String })
|
|
45
|
+
themeName?: string
|
|
46
|
+
|
|
20
47
|
@state()
|
|
21
|
-
private canvasList: Map<
|
|
48
|
+
private canvasList: Map<
|
|
49
|
+
string,
|
|
50
|
+
{ echart?: echarts.ECharts; series: SeriesOption[]; doomed?: boolean; element?: HTMLDivElement }
|
|
51
|
+
> = new Map()
|
|
22
52
|
|
|
53
|
+
@state()
|
|
54
|
+
private themeBgColor?: string
|
|
55
|
+
|
|
56
|
+
@state()
|
|
57
|
+
private themeColor?: string
|
|
58
|
+
|
|
59
|
+
boxes?: HTMLDivElement[]
|
|
60
|
+
origWidth: number = 0
|
|
61
|
+
origHeight: number = 0
|
|
62
|
+
template: EChartsOption
|
|
63
|
+
modifier: number = 1
|
|
23
64
|
version: string = 'versionplaceholder'
|
|
24
|
-
chartContainer
|
|
65
|
+
chartContainer: HTMLDivElement | null | undefined
|
|
66
|
+
resizeObserver?: ResizeObserver
|
|
67
|
+
|
|
68
|
+
constructor() {
|
|
69
|
+
super()
|
|
70
|
+
|
|
71
|
+
this.template = {
|
|
72
|
+
title: {
|
|
73
|
+
text: 'Temperature Change in the Coming Week',
|
|
74
|
+
left: 'left',
|
|
75
|
+
textStyle: {
|
|
76
|
+
fontSize: 14
|
|
77
|
+
}
|
|
78
|
+
} as TitleOption,
|
|
79
|
+
tooltip: {
|
|
80
|
+
trigger: 'axis'
|
|
81
|
+
},
|
|
82
|
+
legend: {
|
|
83
|
+
right: '10%',
|
|
84
|
+
top: '3%'
|
|
85
|
+
},
|
|
86
|
+
toolbox: {
|
|
87
|
+
show: true,
|
|
88
|
+
feature: {
|
|
89
|
+
// dataZoom: {
|
|
90
|
+
// yAxisIndex: 'none'
|
|
91
|
+
// },
|
|
92
|
+
// dataView: { readOnly: false },
|
|
93
|
+
restore: {}
|
|
94
|
+
// saveAsImage: {}
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
dataZoom: [
|
|
98
|
+
{
|
|
99
|
+
show: false,
|
|
100
|
+
realtime: true,
|
|
101
|
+
// start: 30,
|
|
102
|
+
// end: 70,
|
|
103
|
+
xAxisIndex: [0, 1]
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
show: false,
|
|
107
|
+
realtime: true,
|
|
108
|
+
// start: 30,
|
|
109
|
+
// end: 70,
|
|
110
|
+
yAxisIndex: [0, 1]
|
|
111
|
+
}
|
|
112
|
+
],
|
|
113
|
+
xAxis: {
|
|
114
|
+
type: 'value', // value, time, log, category
|
|
115
|
+
nameLocation: 'middle',
|
|
116
|
+
axisLine: {
|
|
117
|
+
lineStyle: {
|
|
118
|
+
width: undefined
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
axisLabel: {
|
|
122
|
+
fontSize: 14
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
yAxis: {
|
|
126
|
+
type: 'value',
|
|
127
|
+
nameLocation: 'middle',
|
|
128
|
+
axisLabel: {
|
|
129
|
+
fontSize: 14
|
|
130
|
+
},
|
|
131
|
+
axisLine: {
|
|
132
|
+
lineStyle: {
|
|
133
|
+
width: undefined
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
scale: false
|
|
137
|
+
},
|
|
138
|
+
series: [
|
|
139
|
+
{
|
|
140
|
+
name: 'Highest',
|
|
141
|
+
type: 'line',
|
|
142
|
+
symbolSize: 8,
|
|
143
|
+
lineStyle: {
|
|
144
|
+
width: 2,
|
|
145
|
+
type: 'solid'
|
|
146
|
+
},
|
|
147
|
+
data: [10, 11, 13, 11, 12, 12, 9]
|
|
148
|
+
} as SeriesOption,
|
|
149
|
+
{
|
|
150
|
+
name: 'Lowest',
|
|
151
|
+
type: 'line',
|
|
152
|
+
symbolSize: 8,
|
|
153
|
+
lineStyle: {
|
|
154
|
+
width: 2,
|
|
155
|
+
type: 'solid'
|
|
156
|
+
},
|
|
157
|
+
data: [1, -2, 2, 5, 3, 2, 0]
|
|
158
|
+
} as SeriesOption
|
|
159
|
+
]
|
|
160
|
+
} as EChartsOption
|
|
161
|
+
}
|
|
25
162
|
|
|
26
|
-
update(changedProperties: Map<
|
|
163
|
+
update(changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): void {
|
|
27
164
|
if (changedProperties.has('inputData') && this.chartContainer) {
|
|
28
|
-
this.
|
|
29
|
-
this.
|
|
165
|
+
this.transformData()
|
|
166
|
+
this.applyData()
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (changedProperties.has('themeObject')) {
|
|
170
|
+
this.registerTheme(this.themeName, this.themeObject)
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (changedProperties.has('themeName')) {
|
|
174
|
+
this.registerTheme(this.themeName, this.themeObject)
|
|
175
|
+
this.deleteCharts()
|
|
176
|
+
this.transformData()
|
|
177
|
+
this.applyData()
|
|
30
178
|
}
|
|
31
179
|
super.update(changedProperties)
|
|
32
180
|
}
|
|
33
181
|
|
|
34
|
-
protected firstUpdated(): void {
|
|
35
|
-
this.chartContainer = this.shadowRoot?.querySelector('.chart-container')
|
|
36
|
-
this.
|
|
37
|
-
this.
|
|
182
|
+
protected firstUpdated(_changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): void {
|
|
183
|
+
this.chartContainer = this.shadowRoot?.querySelector('.chart-container')
|
|
184
|
+
this.transformData()
|
|
185
|
+
this.applyData()
|
|
186
|
+
// Add ResizeObserver for chart container
|
|
187
|
+
if (this.chartContainer) {
|
|
188
|
+
this.resizeObserver = new ResizeObserver(() => {
|
|
189
|
+
this.canvasList.forEach((chart) => {
|
|
190
|
+
chart.echart?.resize()
|
|
191
|
+
})
|
|
192
|
+
})
|
|
193
|
+
this.resizeObserver.observe(this.chartContainer)
|
|
194
|
+
}
|
|
38
195
|
}
|
|
39
196
|
|
|
40
|
-
|
|
197
|
+
registerTheme(themeName?: string, themeObject?: any) {
|
|
198
|
+
if (!themeObject || !themeName) return
|
|
199
|
+
|
|
200
|
+
echarts.registerTheme(themeName, this.themeObject)
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
transformData() {
|
|
41
204
|
if (!this?.inputData?.dataseries?.length) return
|
|
42
205
|
|
|
43
206
|
// reset all existing chart dataseries
|
|
44
|
-
this.canvasList.forEach((chartM) =>
|
|
207
|
+
this.canvasList.forEach((chartM) => {
|
|
208
|
+
chartM.series = []
|
|
209
|
+
chartM.doomed = true
|
|
210
|
+
})
|
|
45
211
|
this.inputData.dataseries.sort((a, b) => (a.advanced?.drawOrder ?? 0) - (b.advanced?.drawOrder ?? 0))
|
|
46
212
|
this.inputData.dataseries.forEach((ds) => {
|
|
47
213
|
ds.advanced ??= {}
|
|
48
214
|
ds.advanced.chartName ??= ''
|
|
49
|
-
|
|
50
|
-
ds.borderDash = JSON.parse(ds.borderDash)
|
|
51
|
-
} else {
|
|
52
|
-
ds.borderDash = undefined
|
|
53
|
-
}
|
|
215
|
+
|
|
54
216
|
ds.data ??= []
|
|
55
217
|
|
|
56
218
|
// pivot data
|
|
57
|
-
const distincts = [...new Set(ds.data.map((d
|
|
219
|
+
const distincts = [...new Set(ds.data.map((d) => d.pivot))].sort()
|
|
58
220
|
const derivedBgColors = tinycolor(ds.backgroundColor as ColorInput | undefined)
|
|
59
221
|
.monochromatic(distincts.length)
|
|
60
222
|
.map((c: any) => c.toHexString())
|
|
@@ -63,150 +225,150 @@ export class WidgetLinechart extends LitElement {
|
|
|
63
225
|
.map((c: any) => c.toHexString())
|
|
64
226
|
//sd
|
|
65
227
|
distincts.forEach((piv, i) => {
|
|
66
|
-
const prefix = piv
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
228
|
+
const prefix = piv ?? ''
|
|
229
|
+
const label = ds.label ?? ''
|
|
230
|
+
const name = prefix + (!!prefix && !!label ? ' - ' : '') + label
|
|
231
|
+
const lineColor = ds.advanced?.chartName?.includes('#split#')
|
|
232
|
+
? ds.borderColor
|
|
233
|
+
: derivedBdColors[i]
|
|
234
|
+
const fillColor = ds.advanced?.chartName?.includes('#split#')
|
|
235
|
+
? ds.backgroundColor
|
|
236
|
+
: derivedBgColors[i]
|
|
237
|
+
const data = distincts.length === 1 ? ds.data : ds.data?.filter((d) => d.pivot === piv)
|
|
238
|
+
const data2 = this.inputData?.axis?.timeseries
|
|
239
|
+
? data?.map((d) =>
|
|
240
|
+
d?.r !== undefined ? [new Date(d.x ?? ''), d.y, d.r] : [new Date(d.x ?? ''), d.y]
|
|
241
|
+
)
|
|
242
|
+
: data?.map((d) => (d?.r !== undefined ? [d.x, d.y, d.r] : [d.x, d.y]))
|
|
243
|
+
|
|
244
|
+
const pds: SeriesOption = {
|
|
245
|
+
name: name,
|
|
246
|
+
type: ds.type ?? 'line',
|
|
247
|
+
lineStyle: {
|
|
248
|
+
color: lineColor,
|
|
249
|
+
width: ds.styling?.borderWidth ?? 2,
|
|
250
|
+
// @ts-ignore
|
|
251
|
+
type: ds.styling?.borderDash ?? 'solid'
|
|
252
|
+
},
|
|
253
|
+
areaStyle: { color: ds.styling?.fill ? fillColor : 'transparent' },
|
|
254
|
+
symbol: ds.styling?.pointStyle ?? 'circle',
|
|
255
|
+
symbolSize: (data) => data[2] ?? 4,
|
|
256
|
+
showSymbol: ds.styling?.pointStyle === 'none' ? false : true,
|
|
257
|
+
data: data2 ?? []
|
|
85
258
|
}
|
|
259
|
+
// if (ds.type === 'scatter') (pds as ScatterSeriesOption).symbolSize = (data) => data[2]
|
|
260
|
+
|
|
86
261
|
let chartName = ds.advanced?.chartName ?? ''
|
|
87
262
|
if (chartName.includes('#split#')) {
|
|
88
|
-
chartName = prefix + chartName
|
|
263
|
+
chartName = prefix + '-' + chartName
|
|
89
264
|
}
|
|
90
|
-
// If the chartName ends with :pivot: then create a seperate chart for each pivoted dataseries
|
|
91
265
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
this.canvasList.set(chartName, {
|
|
95
|
-
chartJsInstance: undefined,
|
|
96
|
-
// @ts-ignore
|
|
97
|
-
dataSets: [] as Dataseries[]
|
|
98
|
-
})
|
|
99
|
-
}
|
|
100
|
-
this.canvasList.get(chartName)?.dataSets.push(pds)
|
|
266
|
+
const chart = this.setupChart(chartName)
|
|
267
|
+
chart?.series.push(pds)
|
|
101
268
|
})
|
|
102
269
|
})
|
|
103
|
-
// prevent duplicate transformation
|
|
104
|
-
// this.inputData.dataseries = []
|
|
105
|
-
// console.log('new linechart datasets', this.canvasList)
|
|
106
|
-
}
|
|
107
270
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
chartJsInstance.data.datasets = dataSets
|
|
116
|
-
chartJsInstance.options ??= {}
|
|
117
|
-
chartJsInstance.options.scales ??= {}
|
|
118
|
-
chartJsInstance.options.scales.x ??= {}
|
|
119
|
-
chartJsInstance.options.scales.y ??= {}
|
|
120
|
-
chartJsInstance.options.scales.x.type = this.xAxisType()
|
|
121
|
-
// @ts-ignore
|
|
122
|
-
chartJsInstance.options.scales.x.title.display = !!this.inputData?.axis?.xAxisLabel
|
|
123
|
-
// @ts-ignore
|
|
124
|
-
chartJsInstance.options.scales.x.title.text = this.inputData?.axis?.xAxisLabel
|
|
125
|
-
// @ts-ignore
|
|
126
|
-
chartJsInstance.options.scales.y.title.display = !!this.inputData?.axis?.yAxisLabel
|
|
127
|
-
// @ts-ignore
|
|
128
|
-
chartJsInstance.options.scales.y.title.text = this.inputData?.axis?.yAxisLabel
|
|
129
|
-
chartJsInstance?.update('resize')
|
|
130
|
-
}
|
|
131
|
-
})
|
|
271
|
+
Array.from(this.canvasList.entries())
|
|
272
|
+
.filter(([l, c]) => c.doomed)
|
|
273
|
+
.forEach(([label, chart]) => {
|
|
274
|
+
chart.echart?.dispose()
|
|
275
|
+
chart.element?.remove()
|
|
276
|
+
this.canvasList.delete(label)
|
|
277
|
+
})
|
|
132
278
|
}
|
|
133
279
|
|
|
134
|
-
xAxisType(): '
|
|
280
|
+
xAxisType(): 'value' | 'log' | 'category' | 'time' | undefined {
|
|
135
281
|
if (this.inputData?.axis?.timeseries) return 'time'
|
|
136
282
|
const onePoint = this.inputData?.dataseries?.[0]?.data?.[0]
|
|
137
|
-
if (!isNaN(Number(onePoint?.x))) return '
|
|
283
|
+
if (!isNaN(Number(onePoint?.x))) return 'value'
|
|
138
284
|
return 'category'
|
|
139
285
|
}
|
|
140
286
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
287
|
+
applyData() {
|
|
288
|
+
const modifier = 1
|
|
289
|
+
|
|
290
|
+
this.canvasList.forEach((chart, label) => {
|
|
291
|
+
chart.series.sort((a, b) => ((a.name as string) > (b.name as string) ? 1 : -1))
|
|
292
|
+
this.requestUpdate()
|
|
293
|
+
|
|
294
|
+
const option: any = window.structuredClone(this.template)
|
|
295
|
+
// Title
|
|
296
|
+
option.title.text = label
|
|
297
|
+
// option.title.textStyle.fontSize = 25 * modifier
|
|
298
|
+
|
|
299
|
+
// Axis
|
|
300
|
+
option.xAxis.name = this.inputData?.axis?.xAxisLabel ?? ''
|
|
301
|
+
option.xAxis.nameGap = 30 * modifier
|
|
302
|
+
option.dataZoom[0].show = this.inputData?.axis?.xAxisZoom ?? false
|
|
303
|
+
option.toolbox.show = this.inputData?.axis?.xAxisZoom ?? false
|
|
304
|
+
// option.xAxis.axisLine.lineStyle.width = 2 * modifier
|
|
305
|
+
// option.xAxis.axisLabel.fontSize = 20 * modifier
|
|
306
|
+
option.xAxis.type = this.xAxisType()
|
|
307
|
+
|
|
308
|
+
option.yAxis.name = this.inputData?.axis?.yAxisLabel ?? ''
|
|
309
|
+
option.yAxis.nameGap = 30 * modifier
|
|
310
|
+
// option.yAxis.axisLine.lineStyle.width = 2 * modifier
|
|
311
|
+
// option.yAxis.axisLabel.fontSize = 20 * modifier
|
|
312
|
+
option.yAxis.scale = this.inputData?.axis?.yAxisScaling ?? false
|
|
313
|
+
|
|
314
|
+
option.series = []
|
|
315
|
+
for (const ds of chart.series) {
|
|
316
|
+
option.series.push(ds)
|
|
147
317
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
if (!this.chartContainer) throw new Error('chartContainer not found')
|
|
151
|
-
|
|
152
|
-
const newContainer = document.createElement('div')
|
|
153
|
-
newContainer.setAttribute('name', chartName)
|
|
154
|
-
newContainer.setAttribute('class', 'sizer')
|
|
155
|
-
const canvas = document.createElement('canvas')
|
|
156
|
-
canvas.setAttribute('name', chartName)
|
|
157
|
-
newContainer.appendChild(canvas)
|
|
158
|
-
this.chartContainer.appendChild(newContainer)
|
|
159
|
-
|
|
160
|
-
if (!canvas) throw new Error('canvas not found')
|
|
161
|
-
// console.log('chartM', canvas, chartM.chart)
|
|
162
|
-
chartM.chartJsInstance = new Chart(canvas, {
|
|
163
|
-
type: 'line',
|
|
164
|
-
data: {
|
|
165
|
-
// @ts-ignore
|
|
166
|
-
datasets: chartM.dataSets
|
|
167
|
-
},
|
|
168
|
-
options: {
|
|
169
|
-
responsive: true,
|
|
170
|
-
maintainAspectRatio: false,
|
|
171
|
-
animations: {
|
|
172
|
-
colors: false,
|
|
173
|
-
x: false
|
|
174
|
-
},
|
|
175
|
-
transitions: {
|
|
176
|
-
active: {
|
|
177
|
-
animation: {
|
|
178
|
-
duration: 100
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
},
|
|
182
|
-
scales: {
|
|
183
|
-
x: {
|
|
184
|
-
type: this.xAxisType(),
|
|
185
|
-
title: {
|
|
186
|
-
display: !!this.inputData?.axis?.xAxisLabel,
|
|
187
|
-
text: this.inputData?.axis?.xAxisLabel
|
|
188
|
-
}
|
|
189
|
-
},
|
|
190
|
-
y: {
|
|
191
|
-
title: {
|
|
192
|
-
display: !!this.inputData?.axis?.yAxisLabel,
|
|
193
|
-
text: this.inputData?.axis?.yAxisLabel
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
})
|
|
318
|
+
chart.echart?.setOption(option)
|
|
199
319
|
})
|
|
200
320
|
}
|
|
201
321
|
|
|
322
|
+
deleteCharts() {
|
|
323
|
+
this.canvasList.forEach((chart, label) => {
|
|
324
|
+
chart.echart?.dispose()
|
|
325
|
+
chart.element?.remove()
|
|
326
|
+
this.canvasList.delete(label)
|
|
327
|
+
})
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
setupChart(label: string) {
|
|
331
|
+
const existingChart = this.canvasList.get(label)
|
|
332
|
+
|
|
333
|
+
if (existingChart) {
|
|
334
|
+
delete existingChart.doomed
|
|
335
|
+
return existingChart
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
if (!this.chartContainer) {
|
|
339
|
+
console.warn('Chart container not found')
|
|
340
|
+
return
|
|
341
|
+
}
|
|
342
|
+
const newContainer = document.createElement('div')
|
|
343
|
+
newContainer.setAttribute('name', label)
|
|
344
|
+
newContainer.setAttribute('class', 'sizer')
|
|
345
|
+
this.chartContainer.appendChild(newContainer)
|
|
346
|
+
|
|
347
|
+
const newChart = echarts.init(newContainer, this.themeName)
|
|
348
|
+
const chart = { echart: newChart, series: [] as SeriesOption[], element: newContainer }
|
|
349
|
+
this.canvasList.set(label, chart)
|
|
350
|
+
//@ts-ignore
|
|
351
|
+
this.themeBgColor = newChart._theme?.backgroundColor
|
|
352
|
+
//@ts-ignore
|
|
353
|
+
this.themeColor = newChart._theme?.title?.textStyle?.color
|
|
354
|
+
return chart
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
disconnectedCallback() {
|
|
358
|
+
if (this.resizeObserver && this.chartContainer) {
|
|
359
|
+
this.resizeObserver.unobserve(this.chartContainer)
|
|
360
|
+
this.resizeObserver.disconnect()
|
|
361
|
+
}
|
|
362
|
+
super.disconnectedCallback()
|
|
363
|
+
}
|
|
364
|
+
|
|
202
365
|
static styles = css`
|
|
203
366
|
:host {
|
|
204
367
|
display: block;
|
|
205
368
|
color: var(--re-text-color, #000);
|
|
206
|
-
|
|
207
369
|
font-family: sans-serif;
|
|
208
|
-
padding: 16px;
|
|
209
370
|
box-sizing: border-box;
|
|
371
|
+
position: relative;
|
|
210
372
|
margin: auto;
|
|
211
373
|
}
|
|
212
374
|
|
|
@@ -214,25 +376,25 @@ export class WidgetLinechart extends LitElement {
|
|
|
214
376
|
display: none !important;
|
|
215
377
|
}
|
|
216
378
|
|
|
217
|
-
.columnLayout {
|
|
218
|
-
flex-direction: column;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
379
|
.wrapper {
|
|
222
380
|
display: flex;
|
|
223
381
|
flex-direction: column;
|
|
224
382
|
height: 100%;
|
|
225
383
|
width: 100%;
|
|
384
|
+
padding: 16px;
|
|
385
|
+
box-sizing: border-box;
|
|
386
|
+
color: var(--re-text-color, #000);
|
|
387
|
+
gap: 12px;
|
|
226
388
|
}
|
|
227
389
|
|
|
228
|
-
.
|
|
229
|
-
display: flex;
|
|
390
|
+
.sizer {
|
|
230
391
|
flex: 1;
|
|
231
392
|
overflow: hidden;
|
|
232
393
|
position: relative;
|
|
233
394
|
}
|
|
234
395
|
|
|
235
|
-
.
|
|
396
|
+
.chart-container {
|
|
397
|
+
display: flex;
|
|
236
398
|
flex: 1;
|
|
237
399
|
overflow: hidden;
|
|
238
400
|
position: relative;
|
|
@@ -241,7 +403,6 @@ export class WidgetLinechart extends LitElement {
|
|
|
241
403
|
header {
|
|
242
404
|
display: flex;
|
|
243
405
|
flex-direction: column;
|
|
244
|
-
margin: 0 0 16px 0;
|
|
245
406
|
}
|
|
246
407
|
h3 {
|
|
247
408
|
margin: 0;
|
|
@@ -255,6 +416,18 @@ export class WidgetLinechart extends LitElement {
|
|
|
255
416
|
max-width: 300px;
|
|
256
417
|
font-size: 14px;
|
|
257
418
|
line-height: 17px;
|
|
419
|
+
overflow: hidden;
|
|
420
|
+
text-overflow: ellipsis;
|
|
421
|
+
white-space: nowrap;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
.chart {
|
|
425
|
+
width: 600px; /* will be overriden by adjustSizes */
|
|
426
|
+
height: 230px;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
.columnLayout {
|
|
430
|
+
flex-direction: column;
|
|
258
431
|
}
|
|
259
432
|
|
|
260
433
|
.no-data {
|
|
@@ -271,13 +444,12 @@ export class WidgetLinechart extends LitElement {
|
|
|
271
444
|
|
|
272
445
|
render() {
|
|
273
446
|
return html`
|
|
274
|
-
<div class="wrapper">
|
|
275
|
-
<header>
|
|
447
|
+
<div class="wrapper" style="background-color: ${this.themeBgColor}; color: ${this.themeColor}">
|
|
448
|
+
<header class="paging" ?active=${this.inputData?.title || this.inputData?.subTitle}>
|
|
276
449
|
<h3 class="paging" ?active=${this.inputData?.title}>${this.inputData?.title}</h3>
|
|
277
450
|
<p class="paging" ?active=${this.inputData?.subTitle}>${this.inputData?.subTitle}</p>
|
|
278
451
|
</header>
|
|
279
|
-
|
|
280
|
-
<div class="paging no-data" ?active=${!this.canvasList.size}>No Data</div>
|
|
452
|
+
<div class="paging no-data" ?active=${this.canvasList.size === 0}>No Data</div>
|
|
281
453
|
<div
|
|
282
454
|
class="chart-container ${this?.inputData?.axis?.columnLayout ? 'columnLayout' : ''}"
|
|
283
455
|
></div>
|
|
@@ -285,202 +457,3 @@ export class WidgetLinechart extends LitElement {
|
|
|
285
457
|
`
|
|
286
458
|
}
|
|
287
459
|
}
|
|
288
|
-
window.customElements.define('widget-linechart-versionplaceholder', WidgetLinechart)
|
|
289
|
-
|
|
290
|
-
// ############################################### WORKAROUND #######################################################################
|
|
291
|
-
//
|
|
292
|
-
// For some reason the import of that adapter is messed up. I suspect that rollup does things in the wrong order.
|
|
293
|
-
// Because this is an import that has side effects. i.e. it overrides the adapters of the previously imported Chart.js
|
|
294
|
-
// So the current solution is to execute the source code here in-line. (moving this to a local file and importing that does not work!)
|
|
295
|
-
// This is the source code of https://github.com/chartjs/chartjs-adapter-date-fns/blob/master/src/index.js
|
|
296
|
-
|
|
297
|
-
import { _adapters } from 'chart.js'
|
|
298
|
-
|
|
299
|
-
import {
|
|
300
|
-
parse,
|
|
301
|
-
parseISO,
|
|
302
|
-
toDate,
|
|
303
|
-
isValid,
|
|
304
|
-
format,
|
|
305
|
-
startOfSecond,
|
|
306
|
-
startOfMinute,
|
|
307
|
-
startOfHour,
|
|
308
|
-
startOfDay,
|
|
309
|
-
startOfWeek,
|
|
310
|
-
startOfMonth,
|
|
311
|
-
startOfQuarter,
|
|
312
|
-
startOfYear,
|
|
313
|
-
addMilliseconds,
|
|
314
|
-
addSeconds,
|
|
315
|
-
addMinutes,
|
|
316
|
-
addHours,
|
|
317
|
-
addDays,
|
|
318
|
-
addWeeks,
|
|
319
|
-
addMonths,
|
|
320
|
-
addQuarters,
|
|
321
|
-
addYears,
|
|
322
|
-
differenceInMilliseconds,
|
|
323
|
-
differenceInSeconds,
|
|
324
|
-
differenceInMinutes,
|
|
325
|
-
differenceInHours,
|
|
326
|
-
differenceInDays,
|
|
327
|
-
differenceInWeeks,
|
|
328
|
-
differenceInMonths,
|
|
329
|
-
differenceInQuarters,
|
|
330
|
-
differenceInYears,
|
|
331
|
-
endOfSecond,
|
|
332
|
-
endOfMinute,
|
|
333
|
-
endOfHour,
|
|
334
|
-
endOfDay,
|
|
335
|
-
endOfWeek,
|
|
336
|
-
endOfMonth,
|
|
337
|
-
endOfQuarter,
|
|
338
|
-
endOfYear
|
|
339
|
-
} from 'date-fns'
|
|
340
|
-
|
|
341
|
-
const FORMATS = {
|
|
342
|
-
datetime: 'MMM d, yyyy, h:mm:ss aaaa',
|
|
343
|
-
millisecond: 'h:mm:ss.SSS aaaa',
|
|
344
|
-
second: 'h:mm:ss aaaa',
|
|
345
|
-
minute: 'h:mm aaaa',
|
|
346
|
-
hour: 'ha',
|
|
347
|
-
day: 'MMM d',
|
|
348
|
-
week: 'PP',
|
|
349
|
-
month: 'MMM yyyy',
|
|
350
|
-
quarter: 'qqq - yyyy',
|
|
351
|
-
year: 'yyyy'
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
_adapters._date.override({
|
|
355
|
-
_id: 'date-fns', // DEBUG
|
|
356
|
-
formats: function () {
|
|
357
|
-
return FORMATS
|
|
358
|
-
},
|
|
359
|
-
|
|
360
|
-
parse: function (value, fmt) {
|
|
361
|
-
if (value === null || typeof value === 'undefined') {
|
|
362
|
-
return null
|
|
363
|
-
}
|
|
364
|
-
const type = typeof value
|
|
365
|
-
if (type === 'number' || value instanceof Date) {
|
|
366
|
-
// @ts-ignore
|
|
367
|
-
value = toDate(value)
|
|
368
|
-
} else if (type === 'string') {
|
|
369
|
-
if (typeof fmt === 'string') {
|
|
370
|
-
// @ts-ignore
|
|
371
|
-
value = parse(value, fmt, new Date(), this.options)
|
|
372
|
-
} else {
|
|
373
|
-
// @ts-ignore
|
|
374
|
-
value = parseISO(value, this.options)
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
// @ts-ignore
|
|
378
|
-
return isValid(value) ? value.getTime() : null
|
|
379
|
-
},
|
|
380
|
-
|
|
381
|
-
format: function (time, fmt) {
|
|
382
|
-
return format(time, fmt, this.options)
|
|
383
|
-
},
|
|
384
|
-
|
|
385
|
-
// @ts-ignore
|
|
386
|
-
add: function (time, amount, unit) {
|
|
387
|
-
switch (unit) {
|
|
388
|
-
case 'millisecond':
|
|
389
|
-
return addMilliseconds(time, amount)
|
|
390
|
-
case 'second':
|
|
391
|
-
return addSeconds(time, amount)
|
|
392
|
-
case 'minute':
|
|
393
|
-
return addMinutes(time, amount)
|
|
394
|
-
case 'hour':
|
|
395
|
-
return addHours(time, amount)
|
|
396
|
-
case 'day':
|
|
397
|
-
return addDays(time, amount)
|
|
398
|
-
case 'week':
|
|
399
|
-
return addWeeks(time, amount)
|
|
400
|
-
case 'month':
|
|
401
|
-
return addMonths(time, amount)
|
|
402
|
-
case 'quarter':
|
|
403
|
-
return addQuarters(time, amount)
|
|
404
|
-
case 'year':
|
|
405
|
-
return addYears(time, amount)
|
|
406
|
-
default:
|
|
407
|
-
return time
|
|
408
|
-
}
|
|
409
|
-
},
|
|
410
|
-
|
|
411
|
-
diff: function (max, min, unit) {
|
|
412
|
-
switch (unit) {
|
|
413
|
-
case 'millisecond':
|
|
414
|
-
return differenceInMilliseconds(max, min)
|
|
415
|
-
case 'second':
|
|
416
|
-
return differenceInSeconds(max, min)
|
|
417
|
-
case 'minute':
|
|
418
|
-
return differenceInMinutes(max, min)
|
|
419
|
-
case 'hour':
|
|
420
|
-
return differenceInHours(max, min)
|
|
421
|
-
case 'day':
|
|
422
|
-
return differenceInDays(max, min)
|
|
423
|
-
case 'week':
|
|
424
|
-
return differenceInWeeks(max, min)
|
|
425
|
-
case 'month':
|
|
426
|
-
return differenceInMonths(max, min)
|
|
427
|
-
case 'quarter':
|
|
428
|
-
return differenceInQuarters(max, min)
|
|
429
|
-
case 'year':
|
|
430
|
-
return differenceInYears(max, min)
|
|
431
|
-
default:
|
|
432
|
-
return 0
|
|
433
|
-
}
|
|
434
|
-
},
|
|
435
|
-
|
|
436
|
-
// @ts-ignore
|
|
437
|
-
startOf: function (time, unit, weekday) {
|
|
438
|
-
switch (unit) {
|
|
439
|
-
case 'second':
|
|
440
|
-
return startOfSecond(time)
|
|
441
|
-
case 'minute':
|
|
442
|
-
return startOfMinute(time)
|
|
443
|
-
case 'hour':
|
|
444
|
-
return startOfHour(time)
|
|
445
|
-
case 'day':
|
|
446
|
-
return startOfDay(time)
|
|
447
|
-
case 'week':
|
|
448
|
-
return startOfWeek(time)
|
|
449
|
-
case 'isoWeek':
|
|
450
|
-
// @ts-ignore
|
|
451
|
-
return startOfWeek(time, { weekStartsOn: +weekday })
|
|
452
|
-
case 'month':
|
|
453
|
-
return startOfMonth(time)
|
|
454
|
-
case 'quarter':
|
|
455
|
-
return startOfQuarter(time)
|
|
456
|
-
case 'year':
|
|
457
|
-
return startOfYear(time)
|
|
458
|
-
default:
|
|
459
|
-
return time
|
|
460
|
-
}
|
|
461
|
-
},
|
|
462
|
-
|
|
463
|
-
// @ts-ignore
|
|
464
|
-
endOf: function (time, unit) {
|
|
465
|
-
switch (unit) {
|
|
466
|
-
case 'second':
|
|
467
|
-
return endOfSecond(time)
|
|
468
|
-
case 'minute':
|
|
469
|
-
return endOfMinute(time)
|
|
470
|
-
case 'hour':
|
|
471
|
-
return endOfHour(time)
|
|
472
|
-
case 'day':
|
|
473
|
-
return endOfDay(time)
|
|
474
|
-
case 'week':
|
|
475
|
-
return endOfWeek(time)
|
|
476
|
-
case 'month':
|
|
477
|
-
return endOfMonth(time)
|
|
478
|
-
case 'quarter':
|
|
479
|
-
return endOfQuarter(time)
|
|
480
|
-
case 'year':
|
|
481
|
-
return endOfYear(time)
|
|
482
|
-
default:
|
|
483
|
-
return time
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
})
|