@record-evolution/widget-linechart 1.6.33 → 1.7.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/dist/widget-linechart.js +463 -397
- package/dist/widget-linechart.js.map +1 -1
- package/package.json +2 -2
- package/src/default-data.json +7 -4
- package/src/definition-schema.d.ts +15 -0
- package/src/definition-schema.json +23 -0
- package/src/widget-linechart.ts +137 -41
package/src/widget-linechart.ts
CHANGED
|
@@ -39,7 +39,12 @@ type Theme = {
|
|
|
39
39
|
theme_object: any
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
type SeriesOptionX = SeriesOption & {
|
|
42
|
+
type SeriesOptionX = SeriesOption & {
|
|
43
|
+
minDate?: number
|
|
44
|
+
maxDate?: number
|
|
45
|
+
drawOrder: number
|
|
46
|
+
yAxisIndex?: number
|
|
47
|
+
}
|
|
43
48
|
@customElement('widget-linechart-versionplaceholder')
|
|
44
49
|
export class WidgetLinechart extends LitElement {
|
|
45
50
|
@property({ type: Object })
|
|
@@ -143,21 +148,45 @@ export class WidgetLinechart extends LitElement {
|
|
|
143
148
|
fontSize: 14
|
|
144
149
|
}
|
|
145
150
|
},
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
}
|
|
151
|
+
// index 0 = left (primary) axis, index 1 = right (secondary) axis.
|
|
152
|
+
// Must stay function-free: the template is copied via structuredClone.
|
|
153
|
+
yAxis: [
|
|
154
|
+
{
|
|
155
|
+
type: 'value',
|
|
156
|
+
nameLocation: 'middle',
|
|
157
|
+
name: 'Temperature (°C)',
|
|
158
|
+
nameGap: 30,
|
|
159
|
+
position: 'left',
|
|
160
|
+
axisLabel: {
|
|
161
|
+
fontSize: 14
|
|
162
|
+
},
|
|
163
|
+
axisLine: {
|
|
164
|
+
lineStyle: {
|
|
165
|
+
width: undefined
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
scale: false
|
|
158
169
|
},
|
|
159
|
-
|
|
160
|
-
|
|
170
|
+
{
|
|
171
|
+
type: 'value',
|
|
172
|
+
position: 'right',
|
|
173
|
+
show: false,
|
|
174
|
+
name: '',
|
|
175
|
+
nameGap: 30,
|
|
176
|
+
axisLabel: {
|
|
177
|
+
fontSize: 14
|
|
178
|
+
},
|
|
179
|
+
axisLine: {
|
|
180
|
+
lineStyle: {
|
|
181
|
+
width: undefined
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
splitLine: {
|
|
185
|
+
show: false
|
|
186
|
+
},
|
|
187
|
+
scale: false
|
|
188
|
+
}
|
|
189
|
+
],
|
|
161
190
|
series: [
|
|
162
191
|
{
|
|
163
192
|
name: 'Highest',
|
|
@@ -185,6 +214,10 @@ export class WidgetLinechart extends LitElement {
|
|
|
185
214
|
}
|
|
186
215
|
|
|
187
216
|
update(changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): void {
|
|
217
|
+
if (changedProperties.has('inputData')) {
|
|
218
|
+
this.cachedXAxisType = undefined
|
|
219
|
+
this.cachedYAxisType = undefined
|
|
220
|
+
}
|
|
188
221
|
if (changedProperties.has('inputData') && this.chartContainer) {
|
|
189
222
|
// const drawingStates = Array.from(this.canvasList).map(([key, chart]) => chart.drawing)
|
|
190
223
|
// if (drawingStates.every((d) => !d)) {
|
|
@@ -314,7 +347,8 @@ export class WidgetLinechart extends LitElement {
|
|
|
314
347
|
symbolSize: (d: any[]) => d[2] ?? 0,
|
|
315
348
|
showSymbol: ds.styling?.pointStyle === 'none' ? false : true,
|
|
316
349
|
data: data2 ?? [],
|
|
317
|
-
drawOrder: ds.advanced?.drawOrder ?? 0
|
|
350
|
+
drawOrder: ds.advanced?.drawOrder ?? 0,
|
|
351
|
+
yAxisIndex: ds.yAxis === 'right' ? 1 : 0
|
|
318
352
|
}
|
|
319
353
|
let chartName = ds.advanced?.chartName ?? ''
|
|
320
354
|
chartName = chartName.replace('#split#', prefix)
|
|
@@ -363,17 +397,38 @@ export class WidgetLinechart extends LitElement {
|
|
|
363
397
|
}
|
|
364
398
|
}
|
|
365
399
|
|
|
400
|
+
// cached per inputData change — cleared in update(), see xAxisType()/yAxisType()
|
|
401
|
+
private cachedXAxisType?: 'value' | 'category' | 'time'
|
|
402
|
+
private cachedYAxisType?: 'value' | 'category'
|
|
403
|
+
|
|
366
404
|
xAxisType(): 'value' | 'log' | 'category' | 'time' | undefined {
|
|
367
|
-
if (this.
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
405
|
+
if (this.cachedXAxisType) return this.cachedXAxisType
|
|
406
|
+
if (this.inputData?.axis?.timeseries) {
|
|
407
|
+
this.cachedXAxisType = 'time'
|
|
408
|
+
return this.cachedXAxisType
|
|
409
|
+
}
|
|
410
|
+
this.cachedXAxisType = 'value'
|
|
411
|
+
for (const ds of this.inputData?.dataseries ?? []) {
|
|
412
|
+
const point = ds.data?.find((d) => d.x !== undefined && d.x !== null)
|
|
413
|
+
if (point) {
|
|
414
|
+
this.cachedXAxisType = !isNaN(Number(point.x)) ? 'value' : 'category'
|
|
415
|
+
break
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
return this.cachedXAxisType
|
|
371
419
|
}
|
|
372
420
|
|
|
373
421
|
yAxisType(): 'value' | 'log' | 'category' | undefined {
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
422
|
+
if (this.cachedYAxisType) return this.cachedYAxisType
|
|
423
|
+
this.cachedYAxisType = 'value'
|
|
424
|
+
for (const ds of this.inputData?.dataseries ?? []) {
|
|
425
|
+
const point = ds.data?.find((d) => d.y !== undefined && d.y !== null)
|
|
426
|
+
if (point) {
|
|
427
|
+
this.cachedYAxisType = !isNaN(Number(point.y)) ? 'value' : 'category'
|
|
428
|
+
break
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
return this.cachedYAxisType
|
|
377
432
|
}
|
|
378
433
|
|
|
379
434
|
calculateAnimationDuration(chart: any, label: string): number {
|
|
@@ -454,10 +509,13 @@ export class WidgetLinechart extends LitElement {
|
|
|
454
509
|
yAxisLabel: this.inputData?.axis?.yAxisLabel,
|
|
455
510
|
xAxisZoom: this.inputData?.axis?.xAxisZoom,
|
|
456
511
|
yAxisScaling: this.inputData?.axis?.yAxisScaling,
|
|
512
|
+
yAxisLabelRight: this.inputData?.axis?.yAxisLabelRight,
|
|
513
|
+
yAxisScalingRight: this.inputData?.axis?.yAxisScalingRight,
|
|
457
514
|
xAxisType: this.xAxisType(),
|
|
458
515
|
yAxisType: this.yAxisType(),
|
|
459
516
|
seriesCount: chart.series.length,
|
|
460
|
-
seriesNames: chart.series.map((s) => s.name).join(',')
|
|
517
|
+
seriesNames: chart.series.map((s) => s.name).join(','),
|
|
518
|
+
seriesAxes: chart.series.map((s) => s.yAxisIndex ?? 0).join(',')
|
|
461
519
|
})
|
|
462
520
|
const configChanged = chart.lastConfig !== currentConfig
|
|
463
521
|
chart.lastConfig = currentConfig
|
|
@@ -498,28 +556,66 @@ export class WidgetLinechart extends LitElement {
|
|
|
498
556
|
option.dataZoom[0].show = this.inputData?.axis?.xAxisZoom ?? false
|
|
499
557
|
option.toolbox.show = this.inputData?.axis?.xAxisZoom ?? false
|
|
500
558
|
|
|
559
|
+
// Y axes: index 0 = left (primary), index 1 = right (secondary).
|
|
560
|
+
// The template holds an array, but getOption() (merge path) also returns
|
|
561
|
+
// component options normalized to arrays — handle both shapes.
|
|
562
|
+
const yAxes: any[] = Array.isArray(option.yAxis) ? option.yAxis : [option.yAxis ?? {}]
|
|
563
|
+
while (yAxes.length < 2) yAxes.push({})
|
|
564
|
+
option.yAxis = yAxes
|
|
565
|
+
|
|
566
|
+
const rightAxisUsed = chart.series.some((s) => (s.yAxisIndex ?? 0) === 1)
|
|
567
|
+
const leftAxisUsed =
|
|
568
|
+
chart.series.length === 0 || chart.series.some((s) => (s.yAxisIndex ?? 0) === 0)
|
|
569
|
+
const showLeftAxis = showYAxis && leftAxisUsed
|
|
570
|
+
const showRightAxis = showYAxis && rightAxisUsed
|
|
571
|
+
|
|
501
572
|
const yAxisLabel = this.inputData?.axis?.yAxisLabel ?? ''
|
|
502
|
-
const
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
573
|
+
const yAxisLabelRight = this.inputData?.axis?.yAxisLabelRight ?? ''
|
|
574
|
+
const hasYAxisLabel = showLeftAxis && !!yAxisLabel
|
|
575
|
+
const hasYAxisLabelRight = showRightAxis && !!yAxisLabelRight
|
|
576
|
+
|
|
577
|
+
const yType = this.yAxisType()
|
|
578
|
+
const numericAxisLabel = ['value', 'log'].includes(yType ?? '')
|
|
579
|
+
? { fontSize: 14, formatter: (value: number) => Math.round(value * 100) / 100 }
|
|
580
|
+
: undefined
|
|
581
|
+
|
|
582
|
+
Object.assign(yAxes[0], {
|
|
583
|
+
type: yType,
|
|
584
|
+
name: yAxisLabel,
|
|
585
|
+
scale: this.inputData?.axis?.yAxisScaling ?? false,
|
|
586
|
+
show: showLeftAxis,
|
|
587
|
+
position: 'left',
|
|
588
|
+
nameLocation: 'end',
|
|
589
|
+
nameGap: 10,
|
|
590
|
+
nameTextStyle: { align: 'left' },
|
|
591
|
+
axisLine: { show: true }
|
|
592
|
+
})
|
|
593
|
+
if (numericAxisLabel) yAxes[0].axisLabel = numericAxisLabel
|
|
594
|
+
|
|
595
|
+
Object.assign(yAxes[1], {
|
|
596
|
+
type: yType,
|
|
597
|
+
name: showRightAxis ? yAxisLabelRight : '',
|
|
598
|
+
scale: this.inputData?.axis?.yAxisScalingRight ?? false,
|
|
599
|
+
show: showRightAxis,
|
|
600
|
+
position: 'right',
|
|
601
|
+
nameLocation: 'end',
|
|
602
|
+
nameGap: 10,
|
|
603
|
+
nameTextStyle: { align: 'right' },
|
|
604
|
+
axisLine: { show: true },
|
|
605
|
+
splitLine: { show: false }
|
|
606
|
+
})
|
|
607
|
+
if (numericAxisLabel) yAxes[1].axisLabel = numericAxisLabel
|
|
516
608
|
|
|
517
609
|
option.series = chart.series
|
|
518
610
|
option.legend.show = showLegend
|
|
519
611
|
|
|
520
612
|
// Dynamic grid padding based on visible elements
|
|
521
|
-
// Add extra top space when Y-axis label is shown at 'end' position
|
|
522
|
-
|
|
613
|
+
// Add extra top space when Y-axis label is shown at 'end' position.
|
|
614
|
+
// The right axis name and the legend both live in the top-right corner,
|
|
615
|
+
// so reserve an extra row when both are visible.
|
|
616
|
+
const topPadding =
|
|
617
|
+
(showTitle || hasYAxisLabel || hasYAxisLabelRight ? 30 : 0) +
|
|
618
|
+
(showLegend && hasYAxisLabelRight ? 25 : 0)
|
|
523
619
|
option.grid = {
|
|
524
620
|
...option.grid,
|
|
525
621
|
show: showBox,
|
|
@@ -528,7 +624,7 @@ export class WidgetLinechart extends LitElement {
|
|
|
528
624
|
borderColor: this.themeTitleColor ?? '#ccc',
|
|
529
625
|
top: topPadding,
|
|
530
626
|
bottom: showXAxis ? 20 : 0,
|
|
531
|
-
left:
|
|
627
|
+
left: showLeftAxis ? 20 : 0,
|
|
532
628
|
right: 0,
|
|
533
629
|
containLabel: showXAxis || showYAxis
|
|
534
630
|
}
|