@spike-rabbit/charts-ng 49.0.0 → 49.13.0

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.
Files changed (51) hide show
  1. package/LICENSE.md +1 -1
  2. package/README.md +17 -3
  3. package/cartesian/package.json +4 -0
  4. package/chart/package.json +4 -0
  5. package/circle/package.json +4 -0
  6. package/common/package.json +4 -0
  7. package/custom-legend/package.json +4 -0
  8. package/fesm2022/spike-rabbit-charts-ng-cartesian.mjs +383 -0
  9. package/fesm2022/spike-rabbit-charts-ng-cartesian.mjs.map +1 -0
  10. package/fesm2022/spike-rabbit-charts-ng-chart.mjs +59 -0
  11. package/fesm2022/spike-rabbit-charts-ng-chart.mjs.map +1 -0
  12. package/fesm2022/spike-rabbit-charts-ng-circle.mjs +91 -0
  13. package/fesm2022/spike-rabbit-charts-ng-circle.mjs.map +1 -0
  14. package/fesm2022/spike-rabbit-charts-ng-common.mjs +2383 -0
  15. package/fesm2022/spike-rabbit-charts-ng-common.mjs.map +1 -0
  16. package/fesm2022/spike-rabbit-charts-ng-custom-legend.mjs +62 -0
  17. package/fesm2022/spike-rabbit-charts-ng-custom-legend.mjs.map +1 -0
  18. package/fesm2022/spike-rabbit-charts-ng-gauge.mjs +371 -0
  19. package/fesm2022/spike-rabbit-charts-ng-gauge.mjs.map +1 -0
  20. package/fesm2022/spike-rabbit-charts-ng-loading-spinner.mjs +27 -0
  21. package/fesm2022/spike-rabbit-charts-ng-loading-spinner.mjs.map +1 -0
  22. package/fesm2022/spike-rabbit-charts-ng-progress-bar.mjs +170 -0
  23. package/fesm2022/spike-rabbit-charts-ng-progress-bar.mjs.map +1 -0
  24. package/fesm2022/spike-rabbit-charts-ng-progress.mjs +220 -0
  25. package/fesm2022/spike-rabbit-charts-ng-progress.mjs.map +1 -0
  26. package/fesm2022/spike-rabbit-charts-ng-sankey.mjs +52 -0
  27. package/fesm2022/spike-rabbit-charts-ng-sankey.mjs.map +1 -0
  28. package/fesm2022/spike-rabbit-charts-ng-sunburst.mjs +52 -0
  29. package/fesm2022/spike-rabbit-charts-ng-sunburst.mjs.map +1 -0
  30. package/fesm2022/spike-rabbit-charts-ng.mjs +40 -3527
  31. package/fesm2022/spike-rabbit-charts-ng.mjs.map +1 -1
  32. package/gauge/package.json +4 -0
  33. package/loading-spinner/package.json +4 -0
  34. package/package.json +58 -12
  35. package/progress/package.json +4 -0
  36. package/progress-bar/package.json +4 -0
  37. package/projects/charts-ng/README.md +17 -3
  38. package/sankey/package.json +4 -0
  39. package/sunburst/package.json +4 -0
  40. package/types/spike-rabbit-charts-ng-cartesian.d.ts +91 -0
  41. package/types/spike-rabbit-charts-ng-chart.d.ts +9 -0
  42. package/types/spike-rabbit-charts-ng-circle.d.ts +74 -0
  43. package/{index.d.ts → types/spike-rabbit-charts-ng-common.d.ts} +102 -431
  44. package/types/spike-rabbit-charts-ng-custom-legend.d.ts +68 -0
  45. package/types/spike-rabbit-charts-ng-gauge.d.ts +96 -0
  46. package/types/spike-rabbit-charts-ng-loading-spinner.d.ts +8 -0
  47. package/types/spike-rabbit-charts-ng-progress-bar.d.ts +46 -0
  48. package/types/spike-rabbit-charts-ng-progress.d.ts +57 -0
  49. package/types/spike-rabbit-charts-ng-sankey.d.ts +19 -0
  50. package/types/spike-rabbit-charts-ng-sunburst.d.ts +19 -0
  51. package/types/spike-rabbit-charts-ng.d.ts +35 -0
@@ -0,0 +1,2383 @@
1
+ import { TitleComponent, TooltipComponent } from 'echarts/components';
2
+ import * as echarts from 'echarts/core';
3
+ export { echarts };
4
+ import { CanvasRenderer, SVGRenderer } from 'echarts/renderers';
5
+ import * as i0 from '@angular/core';
6
+ import { viewChild, viewChildren, input, model, output, signal, inject, ChangeDetectorRef, NgZone, ChangeDetectionStrategy, Component } from '@angular/core';
7
+ import { SiCustomLegendComponent } from '@spike-rabbit/charts-ng/custom-legend';
8
+ import { SiChartLoadingSpinnerComponent } from '@spike-rabbit/charts-ng/loading-spinner';
9
+
10
+ /**
11
+ * Copyright (c) Siemens 2016 - 2026
12
+ * SPDX-License-Identifier: MIT
13
+ */
14
+ echarts.use([
15
+ // renderers
16
+ CanvasRenderer,
17
+ SVGRenderer,
18
+ // core components used by all charts
19
+ TitleComponent,
20
+ TooltipComponent
21
+ ]);
22
+
23
+ /**
24
+ * Copyright (c) Siemens 2016 - 2026
25
+ * SPDX-License-Identifier: MIT
26
+ */
27
+ const getProp = (style, prop) => {
28
+ return style.getPropertyValue(prop);
29
+ };
30
+ const candleStickValues = ['open', 'close', 'lowest', 'highest'];
31
+ const tooltipFormatter = (p) => {
32
+ const params = Array.isArray(p) ? p : [p];
33
+ const label = params[0]?.axisValueLabel ?? '';
34
+ let html = label;
35
+ for (const series of params) {
36
+ const isCandle = series.componentSubType === 'candlestick';
37
+ const isPie = series.componentSubType === 'pie';
38
+ const useName = series.name != series.axisValue;
39
+ const name = isPie
40
+ ? series.data.name
41
+ : useName
42
+ ? // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
43
+ series.name || series.seriesName
44
+ : series.seriesName;
45
+ const valIndex = (series.encode.value ?? series.encode.y)[0];
46
+ const value = isCandle
47
+ ? ''
48
+ : isPie
49
+ ? series.percent + '%'
50
+ : Array.isArray(series.value)
51
+ ? series.value[valIndex]
52
+ : series.value;
53
+ html += '<div style="display: flex; align-items: center;">';
54
+ html += series.marker?.replace('margin-right', 'margin-inline-end');
55
+ html += `<span style="margin-inline: 4px 8px">${name}</span>`;
56
+ html += `<span style="margin-inline-start: auto">${value}</span>`;
57
+ html += '</div>';
58
+ if (isCandle) {
59
+ const miniMarker = `<span style="display:inline-block;vertical-align:middle;margin-inline:3px 8px;border-radius:4px;width:4px;height:4px;background:${series.color};"></span>`;
60
+ for (let i = 0; i < candleStickValues.length; i++) {
61
+ const v = candleStickValues[i];
62
+ const idx = series.encode.y[i];
63
+ html += '<div style="display: flex; align-items: center;">';
64
+ html += miniMarker;
65
+ html += `<span style="margin-inline-end: 8px">${v}</span>`;
66
+ html += `<span style="margin-inline-start: auto">${series.value[idx]}</span>`;
67
+ html += '</div>';
68
+ }
69
+ }
70
+ }
71
+ return html;
72
+ };
73
+ const themeElement = {
74
+ name: 'element',
75
+ style: () => {
76
+ const style = window.getComputedStyle(document.documentElement);
77
+ const elementUi0 = getProp(style, '--element-ui-0');
78
+ const elementUi0Hover = getProp(style, '--element-ui-0-hover');
79
+ const elementUi1 = getProp(style, '--element-ui-1');
80
+ const elementUi2 = getProp(style, '--element-ui-2');
81
+ const elementUi3 = getProp(style, '--element-ui-3');
82
+ const elementUi4 = getProp(style, '--element-ui-4');
83
+ const elementBase1 = getProp(style, '--element-base-1');
84
+ const elementTextPrimary = getProp(style, '--element-text-primary');
85
+ const elementTextSecondary = getProp(style, '--element-text-secondary');
86
+ const elementTextInverse = getProp(style, '--element-text-inverse');
87
+ // The order of colors is provided by ux.
88
+ const colorPalettes = {
89
+ default: [
90
+ getProp(style, '--element-data-1'), // $siemens-data-petrol,
91
+ getProp(style, '--element-data-2'), // $siemens-data-turquoise-900,
92
+ getProp(style, '--element-data-4'), // $siemens-data-turquoise-700,
93
+ getProp(style, '--element-data-6'), // $siemens-data-interactive-coral-900,
94
+ getProp(style, '--element-data-5'), // $siemens-data-royal-blue-500,
95
+ getProp(style, '--element-data-7'), // $siemens-data-purple-700,
96
+ getProp(style, '--element-data-8'), // $siemens-data-purple-900,
97
+ getProp(style, '--element-data-9'), // $siemens-data-orchid-700,
98
+ getProp(style, '--element-data-11'), // $siemens-data-plum-900,
99
+ getProp(style, '--element-data-12'), // $siemens-data-plum-500
100
+ getProp(style, '--element-data-13'), // $siemens-data-royal-blue-700,
101
+ getProp(style, '--element-data-16'), // $siemens-data-sand-700,
102
+ getProp(style, '--element-data-17'), // $siemens-data-deep-blue-700
103
+ getProp(style, '--element-data-3'), // $siemens-data-green-700,
104
+ getProp(style, '--element-data-10'), // $siemens-data-red-700,
105
+ getProp(style, '--element-data-14'), // $siemens-data-orange-900,
106
+ getProp(style, '--element-data-15') // $siemens-data-yellow-900,
107
+ ]
108
+ };
109
+ const gradientColors = {
110
+ default: [
111
+ getProp(style, '--element-data-1'), // $siemens-data-petrol,
112
+ getProp(style, '--element-data-2') // $siemens-data-turquoise-900,
113
+ ]
114
+ };
115
+ const axisFontSize = 12;
116
+ const axisLineHeight = 12;
117
+ const axisLineColor = elementUi4;
118
+ const rootFontSizeRaw = getProp(style, 'font-size');
119
+ const rootFontSize = rootFontSizeRaw.endsWith('px') ? parseInt(rootFontSizeRaw) : 16;
120
+ // value based on body-2
121
+ const fontSize = rootFontSize * 0.875;
122
+ // diverging here by intention
123
+ const lineHeight = fontSize;
124
+ const textColor = elementTextPrimary;
125
+ const candlestickBull = colorPalettes.default[4];
126
+ const candlestickBear = colorPalettes.default[12];
127
+ const dataZoomFillerColor = echarts.color.modifyAlpha(elementUi4, 0.4);
128
+ const dataZoomBrushColor = elementUi0;
129
+ const dataZoomAreaColor = elementUi4;
130
+ const dataZoomLineColor = elementUi2;
131
+ const dataZoomHandleIcon = 'path://M-9.35,34.56V42m0-40V9.5m-2,0h4a2,2,0,0,1,2,2v21a2,2,0,0,1-2,2h-4a2,2,0,0,1-2-2v-21A2,2,0,0,1-11.35,9.5Z';
132
+ const dataZoomHandleColor = elementUi0;
133
+ const tooltipBackground = echarts.color.modifyAlpha(elementUi1, 0.8);
134
+ const rtl = style.direction === 'rtl';
135
+ // For E2E testing to get rid of font-loading instability.
136
+ const fontFamily = navigator.webdriver ? 'sans-serif' : undefined;
137
+ return {
138
+ textStyle: {
139
+ fontFamily
140
+ },
141
+ richInheritPlainLabel: false,
142
+ color: colorPalettes.default,
143
+ gradientColor: gradientColors.default,
144
+ backgroundColor: 'transparent',
145
+ animationDuration: 700,
146
+ title: {
147
+ left: 0,
148
+ top: 0,
149
+ padding: [10, 0, 0, 10],
150
+ textStyle: {
151
+ fontFamily,
152
+ lineHeight,
153
+ fontSize,
154
+ color: textColor
155
+ },
156
+ subtextStyle: {
157
+ fontFamily,
158
+ lineHeight,
159
+ fontSize,
160
+ color: elementTextSecondary
161
+ }
162
+ },
163
+ legend: {
164
+ backgroundColor: 'transparent',
165
+ inactiveColor: elementUi3,
166
+ left: 'auto',
167
+ right: 20,
168
+ top: 35,
169
+ itemGap: 10,
170
+ textStyle: {
171
+ fontFamily,
172
+ color: textColor,
173
+ lineHeight,
174
+ fontSize
175
+ },
176
+ icon: 'circle',
177
+ pageTextStyle: {
178
+ color: textColor
179
+ },
180
+ itemStyle: {
181
+ borderWidth: 0,
182
+ itemGap: 12
183
+ }
184
+ },
185
+ tooltip: {
186
+ borderWidth: 0,
187
+ backgroundColor: tooltipBackground,
188
+ textStyle: {
189
+ fontFamily,
190
+ color: 'var(--element-text-inverse)',
191
+ fontWeight: 400
192
+ },
193
+ padding: [8, 12, 8, 12],
194
+ axisPointer: {
195
+ crossStyle: {
196
+ color: elementUi3,
197
+ width: 1
198
+ }
199
+ },
200
+ formatter: tooltipFormatter
201
+ },
202
+ axisPointer: {
203
+ label: {
204
+ fontFamily,
205
+ color: elementTextInverse,
206
+ backgroundColor: elementUi1,
207
+ lineHeight: axisLineHeight,
208
+ fontSize: axisFontSize
209
+ },
210
+ lineStyle: {
211
+ color: elementUi3,
212
+ width: 2
213
+ },
214
+ handle: {
215
+ color: 'rgba(0,0,0,0)',
216
+ margin: 0
217
+ }
218
+ },
219
+ grid: {
220
+ top: 85,
221
+ left: 32,
222
+ right: 32,
223
+ bottom: 30,
224
+ containLabel: true
225
+ },
226
+ valueAxis: {
227
+ nameTextStyle: {
228
+ fontFamily,
229
+ color: elementTextSecondary
230
+ },
231
+ axisLine: {
232
+ show: true,
233
+ lineStyle: {
234
+ color: axisLineColor
235
+ }
236
+ },
237
+ axisLabel: {
238
+ fontFamily,
239
+ color: textColor,
240
+ lineHeight: axisLineHeight,
241
+ fontSize: axisFontSize,
242
+ hideOverlap: true
243
+ },
244
+ axisTick: {
245
+ alignWithLabel: true
246
+ },
247
+ splitLine: {
248
+ lineStyle: {
249
+ color: axisLineColor
250
+ }
251
+ }
252
+ },
253
+ timeAxis: {
254
+ inverse: rtl,
255
+ nameTextStyle: {
256
+ fontFamily,
257
+ color: elementTextSecondary
258
+ },
259
+ axisLine: {
260
+ show: true,
261
+ lineStyle: {
262
+ color: axisLineColor
263
+ }
264
+ },
265
+ axisLabel: {
266
+ fontFamily,
267
+ color: textColor,
268
+ lineHeight: axisLineHeight,
269
+ fontSize: axisFontSize,
270
+ hideOverlap: true
271
+ },
272
+ axisTick: {
273
+ show: true,
274
+ alignWithLabel: true
275
+ },
276
+ splitLine: {
277
+ lineStyle: {
278
+ color: axisLineColor
279
+ }
280
+ }
281
+ },
282
+ categoryAxis: {
283
+ inverse: rtl,
284
+ nameTextStyle: {
285
+ fontFamily,
286
+ color: elementTextSecondary
287
+ },
288
+ axisLine: {
289
+ show: true,
290
+ lineStyle: {
291
+ color: axisLineColor
292
+ }
293
+ },
294
+ axisLabel: {
295
+ fontFamily,
296
+ color: textColor,
297
+ lineHeight: axisLineHeight,
298
+ fontSize: axisFontSize,
299
+ hideOverlap: true
300
+ },
301
+ axisTick: {
302
+ show: true,
303
+ alignWithLabel: true
304
+ },
305
+ splitLine: {
306
+ lineStyle: {
307
+ color: axisLineColor
308
+ }
309
+ }
310
+ },
311
+ dataZoom: {
312
+ textStyle: {
313
+ fontFamily,
314
+ color: textColor,
315
+ lineHeight: axisLineHeight,
316
+ fontSize: axisFontSize
317
+ },
318
+ borderColor: elementUi4,
319
+ fillerColor: dataZoomFillerColor,
320
+ handleIcon: dataZoomHandleIcon,
321
+ handleStyle: {
322
+ color: dataZoomHandleColor,
323
+ borderColor: elementUi4
324
+ },
325
+ moveHandleStyle: {
326
+ color: elementUi4,
327
+ opacity: 1
328
+ },
329
+ brushStyle: {
330
+ color: dataZoomBrushColor
331
+ },
332
+ dataBackground: {
333
+ areaStyle: {
334
+ color: dataZoomAreaColor
335
+ },
336
+ lineStyle: {
337
+ color: dataZoomLineColor
338
+ }
339
+ },
340
+ selectedDataBackground: {
341
+ areaStyle: {
342
+ color: dataZoomLineColor,
343
+ opacity: 0.2
344
+ },
345
+ lineStyle: {
346
+ color: dataZoomLineColor
347
+ }
348
+ },
349
+ emphasis: {
350
+ moveHandleStyle: {
351
+ color: elementUi0Hover,
352
+ opacity: 1
353
+ },
354
+ handleStyle: {
355
+ color: elementUi0Hover,
356
+ borderColor: elementUi4
357
+ }
358
+ }
359
+ },
360
+ toolbox: {
361
+ feature: {
362
+ dataZoom: {
363
+ brushStyle: {
364
+ color: dataZoomFillerColor
365
+ }
366
+ }
367
+ }
368
+ },
369
+ // different chart types
370
+ graph: {
371
+ color: colorPalettes.default
372
+ },
373
+ bar: {
374
+ barGap: 0,
375
+ label: {
376
+ fontFamily,
377
+ color: elementTextSecondary,
378
+ fontSize
379
+ }
380
+ },
381
+ line: {
382
+ areaStyle: {
383
+ opacity: 0.3
384
+ },
385
+ symbol: 'circle',
386
+ symbolSize: 4
387
+ },
388
+ pie: {
389
+ radius: [0, '75%'],
390
+ label: {
391
+ distanceToLabelLine: 2,
392
+ fontFamily,
393
+ formatter: '{d}%',
394
+ color: elementTextSecondary,
395
+ lineHeight,
396
+ fontSize
397
+ },
398
+ labelLine: {
399
+ length: 15,
400
+ length2: 8,
401
+ lineStyle: {
402
+ color: elementTextSecondary
403
+ }
404
+ },
405
+ itemStyle: {
406
+ borderWidth: 2,
407
+ borderColor: elementBase1
408
+ }
409
+ },
410
+ candlestick: {
411
+ itemStyle: {
412
+ color: candlestickBull,
413
+ color0: candlestickBear,
414
+ borderColor: candlestickBull,
415
+ borderColor0: candlestickBear
416
+ }
417
+ },
418
+ gauge: {
419
+ detail: {
420
+ color: elementTextPrimary,
421
+ rich: {
422
+ value: {
423
+ color: elementTextPrimary
424
+ },
425
+ unit: {
426
+ color: elementTextPrimary
427
+ }
428
+ }
429
+ },
430
+ axisLabel: {
431
+ fontFamily,
432
+ color: elementTextPrimary
433
+ },
434
+ axisTick: {
435
+ lineStyle: {
436
+ color: axisLineColor
437
+ }
438
+ },
439
+ splitLine: {
440
+ lineStyle: {
441
+ color: axisLineColor
442
+ }
443
+ }
444
+ },
445
+ sankey: {
446
+ label: {
447
+ fontFamily,
448
+ textBorderColor: 'transparent',
449
+ color: textColor
450
+ }
451
+ },
452
+ sunburst: {
453
+ label: {
454
+ fontFamily,
455
+ textBorderColor: 'transparent',
456
+ color: textColor
457
+ }
458
+ },
459
+ simpl: {
460
+ colorPalettes,
461
+ dataZoom: {
462
+ options: {
463
+ height: 36,
464
+ bottom: 20
465
+ },
466
+ grid: {
467
+ bottom: 80
468
+ }
469
+ },
470
+ timeRangeBar: {
471
+ height: 32
472
+ },
473
+ externalZoomSlider: {
474
+ grid: {
475
+ bottom: 10
476
+ }
477
+ },
478
+ legendLeft: {
479
+ left: 10,
480
+ width: '45%'
481
+ },
482
+ legendRight: {
483
+ right: 20,
484
+ width: '45%'
485
+ },
486
+ noTitle: {
487
+ grid: {
488
+ top: 60
489
+ },
490
+ legend: {
491
+ top: 15
492
+ }
493
+ },
494
+ subTitle: {
495
+ grid: {
496
+ top: 110
497
+ },
498
+ legend: {
499
+ top: 65
500
+ }
501
+ },
502
+ customLegend: {
503
+ grid: {
504
+ top: 64
505
+ }
506
+ },
507
+ progress: {
508
+ itemWidth: 6,
509
+ itemGap: 6,
510
+ grey: elementUi4
511
+ },
512
+ progressBar: {
513
+ labelColor: textColor,
514
+ itemWidth: 20,
515
+ grid: {
516
+ left: 16,
517
+ right: 52,
518
+ containLabel: true
519
+ }
520
+ },
521
+ gauge: {
522
+ grey: elementUi4,
523
+ value: elementTextPrimary,
524
+ unit: elementTextSecondary,
525
+ defaultColor: elementUi0
526
+ }
527
+ }
528
+ };
529
+ }
530
+ };
531
+
532
+ /**
533
+ * Copyright (c) Siemens 2016 - 2026
534
+ * SPDX-License-Identifier: MIT
535
+ */
536
+ const themeSupport = {
537
+ _defaultTheme: themeElement,
538
+ _themes: {},
539
+ registerTheme(theme) {
540
+ if (theme.name) {
541
+ this._themes[theme.name] = theme;
542
+ }
543
+ },
544
+ getThemeNames() {
545
+ return Object.keys(this._themes);
546
+ },
547
+ getThemeByName(name) {
548
+ return this._themes[name];
549
+ },
550
+ setDefault(theme) {
551
+ this._defaultTheme = theme;
552
+ },
553
+ getDefault() {
554
+ return this._defaultTheme;
555
+ }
556
+ };
557
+
558
+ /**
559
+ * Copyright (c) Siemens 2016 - 2026
560
+ * SPDX-License-Identifier: MIT
561
+ */
562
+ class SiChartBaseComponent {
563
+ /**
564
+ * reference to the wrapper container. Used for setting scroll position, etc.
565
+ *
566
+ * @defaultValue
567
+ * ```
568
+ * viewChild.required<ElementRef>('chartContainerWrapper')
569
+ * ```
570
+ */
571
+ chartContainerWrapper = viewChild.required('chartContainerWrapper');
572
+ chartContainer = viewChild('chart', /* @ts-ignore */
573
+ ...(ngDevMode ? [{ debugName: "chartContainer" }] : /* istanbul ignore next */ []));
574
+ externalZoomSliderContainer = viewChild('externalZoomSlider', /* @ts-ignore */
575
+ ...(ngDevMode ? [{ debugName: "externalZoomSliderContainer" }] : /* istanbul ignore next */ []));
576
+ siCustomLegend = viewChildren('siCustomLegend', { ...(ngDevMode ? { debugName: "siCustomLegend" } : /* istanbul ignore next */ {}), read: SiCustomLegendComponent });
577
+ /**
578
+ * See [ECharts 5.x Documentation]{@link https://echarts.apache.org/en/option.html}
579
+ * for all available options.
580
+ */
581
+ options = input(/* @ts-ignore */
582
+ ...(ngDevMode ? [undefined, { debugName: "options" }] : /* istanbul ignore next */ []));
583
+ /** Used to override specific properties set in `options`. */
584
+ additionalOptions = input(/* @ts-ignore */
585
+ ...(ngDevMode ? [undefined, { debugName: "additionalOptions" }] : /* istanbul ignore next */ []));
586
+ /** The title of the chart. */
587
+ title = input(/* @ts-ignore */
588
+ ...(ngDevMode ? [undefined, { debugName: "title" }] : /* istanbul ignore next */ []));
589
+ /** The subtitle of the chart. */
590
+ subTitle = input(/* @ts-ignore */
591
+ ...(ngDevMode ? [undefined, { debugName: "subTitle" }] : /* istanbul ignore next */ []));
592
+ /**
593
+ * Show Echarts legend
594
+ *
595
+ * @defaultValue true
596
+ */
597
+ showLegend = model(true, /* @ts-ignore */
598
+ ...(ngDevMode ? [{ debugName: "showLegend" }] : /* istanbul ignore next */ []));
599
+ /**
600
+ * Enable to show a custom legend.
601
+ * The custom legend offers additional features such as, scroll bar to avoid legend and chart overlapping,
602
+ * Left and right alignment of legends based on y-axis, etc and many more.
603
+ * @defaultValue false
604
+ */
605
+ showCustomLegend = input(false, /* @ts-ignore */
606
+ ...(ngDevMode ? [{ debugName: "showCustomLegend" }] : /* istanbul ignore next */ []));
607
+ /**
608
+ * the renderer to use: canvas or svg
609
+ *
610
+ * @defaultValue 'canvas'
611
+ */
612
+ renderer = input('canvas', /* @ts-ignore */
613
+ ...(ngDevMode ? [{ debugName: "renderer" }] : /* istanbul ignore next */ []));
614
+ /**
615
+ * Enables the zoom slider below the chart.
616
+ *
617
+ * @defaultValue false
618
+ */
619
+ zoomSlider = input(false, /* @ts-ignore */
620
+ ...(ngDevMode ? [{ debugName: "zoomSlider" }] : /* istanbul ignore next */ []));
621
+ /**
622
+ * Shows data shadow in dataZoom slider, use together with `zoomSlider`.
623
+ *
624
+ * @defaultValue true
625
+ */
626
+ zoomSliderShadow = input(true, /* @ts-ignore */
627
+ ...(ngDevMode ? [{ debugName: "zoomSliderShadow" }] : /* istanbul ignore next */ []));
628
+ /**
629
+ * realtime update mode for zoom slider
630
+ *
631
+ * @defaultValue true
632
+ */
633
+ zoomSliderRealtime = input(true, /* @ts-ignore */
634
+ ...(ngDevMode ? [{ debugName: "zoomSliderRealtime" }] : /* istanbul ignore next */ []));
635
+ /**
636
+ * enable brush mode for zoom slider
637
+ *
638
+ * @defaultValue true
639
+ */
640
+ zoomSliderBrush = input(true, /* @ts-ignore */
641
+ ...(ngDevMode ? [{ debugName: "zoomSliderBrush" }] : /* istanbul ignore next */ []));
642
+ /**
643
+ * Enables zooming inside the chart with the mouse wheel/touch.
644
+ *
645
+ * Whether zooming inside the chart is possible with mouse.
646
+ *
647
+ * @defaultValue false
648
+ */
649
+ zoomInside = input(false, /* @ts-ignore */
650
+ ...(ngDevMode ? [{ debugName: "zoomInside" }] : /* istanbul ignore next */ []));
651
+ /**
652
+ * Maximum number of series data points shown in the chart.
653
+ *
654
+ * @defaultValue 1000
655
+ */
656
+ maxEntries = input(1000, /* @ts-ignore */
657
+ ...(ngDevMode ? [{ debugName: "maxEntries" }] : /* istanbul ignore next */ []));
658
+ /**
659
+ * No auto dataZoom update) by default. Use together with `autoZoomSeriesIndex`.
660
+ *
661
+ * @defaultValue -1
662
+ */
663
+ visibleEntries = model(-1, /* @ts-ignore */
664
+ ...(ngDevMode ? [{ debugName: "visibleEntries" }] : /* istanbul ignore next */ []));
665
+ /**
666
+ * No auto dataZoom update) by default. Use together with `autoZoomSeriesIndex`.
667
+ *
668
+ * @defaultValue -1
669
+ */
670
+ visibleRange = model(-1, /* @ts-ignore */
671
+ ...(ngDevMode ? [{ debugName: "visibleRange" }] : /* istanbul ignore next */ []));
672
+ /**
673
+ * No auto dataZoom update) by default. Use together with `visibleEntries`.
674
+ *
675
+ * @defaultValue -1
676
+ */
677
+ autoZoomSeriesIndex = input(-1, /* @ts-ignore */
678
+ ...(ngDevMode ? [{ debugName: "autoZoomSeriesIndex" }] : /* istanbul ignore next */ []));
679
+ /** The desired theme to load. */
680
+ theme = input(/* @ts-ignore */
681
+ ...(ngDevMode ? [undefined, { debugName: "theme" }] : /* istanbul ignore next */ []));
682
+ /** Used to override specific options of loaded `theme`. */
683
+ themeCustomization = input(/* @ts-ignore */
684
+ ...(ngDevMode ? [undefined, { debugName: "themeCustomization" }] : /* istanbul ignore next */ []));
685
+ /**
686
+ * The name of the color palette (if any) of the loaded `theme`.
687
+ *
688
+ * @defaultValue undefined
689
+ */
690
+ palette = input(/* @ts-ignore */
691
+ ...(ngDevMode ? [undefined, { debugName: "palette" }] : /* istanbul ignore next */ []));
692
+ /**
693
+ * Used to display `axisPointer` line either by click or mouse-move.
694
+ *
695
+ * @defaultValue false
696
+ */
697
+ axisPointer = input(false, /* @ts-ignore */
698
+ ...(ngDevMode ? [{ debugName: "axisPointer" }] : /* istanbul ignore next */ []));
699
+ /**
700
+ * Apply a specific zoom range (see {@link https://echarts.apache.org/en/option.html#dataZoom-inside}).
701
+ */
702
+ dataZoomRange = input(/* @ts-ignore */
703
+ ...(ngDevMode ? [undefined, { debugName: "dataZoomRange" }] : /* istanbul ignore next */ []));
704
+ /**
705
+ * The lower limit of the data zoom slider (see {@link https://echarts.apache.org/en/option.html#dataZoom-slider.minValueSpan}).
706
+ */
707
+ dataZoomMinValueSpan = input(/* @ts-ignore */
708
+ ...(ngDevMode ? [undefined, { debugName: "dataZoomMinValueSpan" }] : /* istanbul ignore next */ []));
709
+ /**
710
+ * The upper limit of the data zoom slider (see {@link https://echarts.apache.org/en/option.html#dataZoom-slider.maxValueSpan}).
711
+ */
712
+ dataZoomMaxValueSpan = input(/* @ts-ignore */
713
+ ...(ngDevMode ? [undefined, { debugName: "dataZoomMaxValueSpan" }] : /* istanbul ignore next */ []));
714
+ /**
715
+ * The data zoom filter mode. (see {@link https://echarts.apache.org/en/option.html#dataZoom-inside.filterMode})
716
+ *
717
+ * The value 'filter' will cause the lines to be disconnected to the outside of the chart.
718
+ *
719
+ * @defaultValue 'none'
720
+ */
721
+ dataZoomFilterMode = input('none', /* @ts-ignore */
722
+ ...(ngDevMode ? [{ debugName: "dataZoomFilterMode" }] : /* istanbul ignore next */ []));
723
+ /**
724
+ * Enable custom legend click actions exposed by the `selectionChanged` event.
725
+ */
726
+ customLegendAction = input(/* @ts-ignore */
727
+ ...(ngDevMode ? [undefined, { debugName: "customLegendAction" }] : /* istanbul ignore next */ []));
728
+ /**
729
+ * Specify selected legend item.
730
+ *
731
+ * @defaultValue
732
+ * ```
733
+ * { legendItemName: '' }
734
+ * ```
735
+ */
736
+ selectedItem = input({ legendItemName: '' }, /* @ts-ignore */
737
+ ...(ngDevMode ? [{ debugName: "selectedItem" }] : /* istanbul ignore next */ []));
738
+ /**
739
+ * The height of the ECharts container as decimal.
740
+ */
741
+ eChartContainerHeight = input(/* @ts-ignore */
742
+ ...(ngDevMode ? [undefined, { debugName: "eChartContainerHeight" }] : /* istanbul ignore next */ []));
743
+ /**
744
+ * Flag to use external zoom slider
745
+ *
746
+ * @defaultValue false
747
+ */
748
+ externalZoomSlider = input(false, /* @ts-ignore */
749
+ ...(ngDevMode ? [{ debugName: "externalZoomSlider" }] : /* istanbul ignore next */ []));
750
+ /** External XAxis Formatter from consumer */
751
+ externalXAxisFormatter = input(/* @ts-ignore */
752
+ ...(ngDevMode ? [undefined, { debugName: "externalXAxisFormatter" }] : /* istanbul ignore next */ []));
753
+ /**
754
+ * If true, add consumer-provided time range bar. Use together with `zoomSlider`.
755
+ * @deprecated The input will be removed in future versions as the time range bar slot is deprecated.
756
+ *
757
+ * @defaultValue false
758
+ */
759
+ showTimeRangeBar = input(false, /* @ts-ignore */
760
+ ...(ngDevMode ? [{ debugName: "showTimeRangeBar" }] : /* istanbul ignore next */ []));
761
+ /** Event emitted when data zoom changes. */
762
+ dataZoom = output();
763
+ /** Event emitted when axis pointer moves. */
764
+ pointer = output();
765
+ /** Event emitted when selection changes e.g. clicking on a legend item. */
766
+ selectionChanged = output();
767
+ /** Event emitted when a chart series is clicked. */
768
+ chartSeriesClick = output();
769
+ /** Event emitted when chart grid is resized. */
770
+ chartGridResized = output();
771
+ /** Event emitted when custom legend multi-line info changes. */
772
+ customLegendMultiLineInfoEvent = output();
773
+ /** Emitted when data zoom changes, indicating the time range in milliseconds, 0 for full range */
774
+ timeRangeChange = output();
775
+ /** Allow to override options specific for a chart type. */
776
+ actualOptions = {};
777
+ customLegend = [
778
+ {
779
+ customLegends: [
780
+ { list: [], unit: '' },
781
+ { list: [], unit: '' }
782
+ ],
783
+ legendAxis: 'both'
784
+ }
785
+ ];
786
+ /** @internal */
787
+ chart;
788
+ extZoomSliderChart;
789
+ echartElement;
790
+ eChartExtSliderElement;
791
+ inProgress = signal(false, /* @ts-ignore */
792
+ ...(ngDevMode ? [{ debugName: "inProgress" }] : /* istanbul ignore next */ []));
793
+ backgroundColor = signal('', /* @ts-ignore */
794
+ ...(ngDevMode ? [{ debugName: "backgroundColor" }] : /* istanbul ignore next */ []));
795
+ textColor = signal('', /* @ts-ignore */
796
+ ...(ngDevMode ? [{ debugName: "textColor" }] : /* istanbul ignore next */ []));
797
+ titleColor = signal('', /* @ts-ignore */
798
+ ...(ngDevMode ? [{ debugName: "titleColor" }] : /* istanbul ignore next */ []));
799
+ subTitleColor = signal('', /* @ts-ignore */
800
+ ...(ngDevMode ? [{ debugName: "subTitleColor" }] : /* istanbul ignore next */ []));
801
+ selectedSeriesColors = {};
802
+ unselectedSeriesColors = {};
803
+ seriesSelectionState = {};
804
+ containerHeight = signal(null, /* @ts-ignore */
805
+ ...(ngDevMode ? [{ debugName: "containerHeight" }] : /* istanbul ignore next */ []));
806
+ activeTheme;
807
+ autoZoomUpdate = true;
808
+ prevAxisPointer = {};
809
+ lastValidDataZoom = {};
810
+ presetDataZoomRange;
811
+ dataZoomSetupDone = false;
812
+ requestedDataZoom;
813
+ measureCanvas;
814
+ cdRef = inject(ChangeDetectorRef);
815
+ ngZone = inject(NgZone);
816
+ curWidth = 0;
817
+ curHeight = 0;
818
+ timeBarBottom = signal(50, /* @ts-ignore */
819
+ ...(ngDevMode ? [{ debugName: "timeBarBottom" }] : /* istanbul ignore next */ []));
820
+ timeBarLeft = signal(32, /* @ts-ignore */
821
+ ...(ngDevMode ? [{ debugName: "timeBarLeft" }] : /* istanbul ignore next */ []));
822
+ timeBarRight = signal(32, /* @ts-ignore */
823
+ ...(ngDevMode ? [{ debugName: "timeBarRight" }] : /* istanbul ignore next */ []));
824
+ timeBarHeight = signal(32, /* @ts-ignore */
825
+ ...(ngDevMode ? [{ debugName: "timeBarHeight" }] : /* istanbul ignore next */ []));
826
+ gridCoordinates = {
827
+ x: 0,
828
+ y: 0,
829
+ width: 0,
830
+ height: 0,
831
+ containerWidth: 0,
832
+ containerHeight: 0
833
+ };
834
+ customLegendsMultiLineInfo = [];
835
+ extZoomSliderOptions = {
836
+ animation: false,
837
+ dataZoom: [
838
+ { type: 'slider', showDataShadow: false },
839
+ { type: 'inside', showDataShadow: false }
840
+ ],
841
+ grid: [{ left: 32, right: 32, top: 0, height: 0, containLabel: false }],
842
+ xAxis: [{ type: 'time', axisLine: { onZero: true }, zlevel: 1 }],
843
+ yAxis: [{ type: 'value', boundaryGap: [0, '100%'], splitLine: { show: false }, show: false }],
844
+ series: [{ type: 'line', showSymbol: false, lineStyle: { opacity: 0 }, data: [] }]
845
+ };
846
+ echartMouseDown = () => this.handleChartMouseDown();
847
+ echartMouseUp = (event) => this.handleChartMouseUp(event);
848
+ echartExtSliderMouseDown = () => this.handleExtChartMouseDown();
849
+ echartExtSliderMouseUp = (event) => this.handleExtChartMouseUp(event);
850
+ shapePaths = {
851
+ circle: 'M6 0A6 6 0 1 1 6 12A6 6 0 1 1 6 0Z',
852
+ rect: 'M0 0H12V12H0Z',
853
+ roundRect: 'M2 0H10A2 2 0 0 1 12 2V10A2 2 0 0 1 10 12H2A2 2 0 0 1 0 10V2A2 2 0 0 1 2 0Z',
854
+ triangle: 'M6 0L12 12H0L6 0Z',
855
+ diamond: 'M6 0L12 6L6 12L0 6L6 0Z',
856
+ pin: 'M6.00049 0C8.48577 0 10.5005 2.01472 10.5005 4.5C10.5005 5.51817 10.0175 6.461 9.46826 7.31836C8.42358 8.94924 7.16317 10.4497 6.00049 12C4.83781 10.4497 3.57642 8.94924 2.53174 7.31836C1.98255 6.461 1.49951 5.51817 1.49951 4.5C1.49951 2.01472 3.51521 0 6.00049 0Z'
857
+ };
858
+ /**
859
+ * Allow consuming applications to re-draw chart on window resizes.
860
+ */
861
+ resize() {
862
+ if (!this.chart) {
863
+ return;
864
+ }
865
+ const rect = this.chartContainer()?.nativeElement.getBoundingClientRect();
866
+ const width = Math.floor(rect.width);
867
+ const height = Math.floor(rect.height);
868
+ if (width && height && (width !== this.curWidth || height !== this.curHeight)) {
869
+ this.curWidth = width;
870
+ this.curHeight = height;
871
+ this.ngZone.runOutsideAngular(() => {
872
+ this.chart.resize({ width, height: this.containerHeight() ?? height });
873
+ if (this.externalZoomSlider()) {
874
+ this.extZoomSliderChart.resize();
875
+ }
876
+ setTimeout(() => this.checkGridSizeChange());
877
+ });
878
+ this.afterChartResize();
879
+ }
880
+ this.updateCustomLegendMultiLineInfo();
881
+ }
882
+ ngOnChanges(changes) {
883
+ if (changes.options?.currentValue) {
884
+ this.actualOptions = this.options();
885
+ }
886
+ if (!this.chart) {
887
+ return;
888
+ }
889
+ if (changes.eChartContainerHeight) {
890
+ this.setContainerHeight();
891
+ }
892
+ const selectedLegendItem = changes.selectedItem;
893
+ if (selectedLegendItem &&
894
+ !selectedLegendItem.isFirstChange() &&
895
+ selectedLegendItem.currentValue) {
896
+ const event = {
897
+ name: selectedLegendItem.currentValue.legendItemName,
898
+ type: 'legendToggleSelect'
899
+ };
900
+ this.dispatchEChartAction(event);
901
+ }
902
+ if (this.customLegendAction() &&
903
+ changes.options &&
904
+ !changes.options.isFirstChange() &&
905
+ !changes.options.currentValue.color.length) {
906
+ this.actualOptions.color = changes.options.previousValue.color;
907
+ }
908
+ if (changes.theme || changes.renderer) {
909
+ // need to completely redo the chart for the theme change to take effect
910
+ return this.resetChart();
911
+ }
912
+ let updates = 0;
913
+ let applyAll = false;
914
+ let skipMerge = false;
915
+ if (changes.forceAll ||
916
+ changes.yAxis ||
917
+ changes.xAxis ||
918
+ changes.options ||
919
+ changes.series ||
920
+ changes.value) {
921
+ // this is to clean the legend item list
922
+ if (this.showCustomLegend() && this.customLegend && this.customLegend.length > 0) {
923
+ this.customLegend.forEach(cl => {
924
+ cl.customLegends = [
925
+ { list: [], unit: '' },
926
+ { list: [], unit: '' }
927
+ ];
928
+ });
929
+ }
930
+ this.applyOptions();
931
+ applyAll = true;
932
+ skipMerge =
933
+ changes.series?.previousValue &&
934
+ changes.series.currentValue &&
935
+ changes.series.currentValue.length < changes.series.previousValue.length;
936
+ updates++;
937
+ }
938
+ if (!applyAll && (changes.title || changes.subTitle)) {
939
+ // already called when `applyOptions()` has been called
940
+ this.applyTitles();
941
+ updates++;
942
+ }
943
+ if (applyAll ||
944
+ changes.forceAll ||
945
+ changes.zoomSlider ||
946
+ changes.zoomSliderShadow ||
947
+ changes.zoomSliderRealtime ||
948
+ changes.zoomSliderBrush ||
949
+ changes.zoomInside ||
950
+ changes.axisPointer ||
951
+ changes.autoZoomSeriesIndex ||
952
+ changes.visibleEntries ||
953
+ changes.visibleRange) {
954
+ this.applyDataZoom();
955
+ updates++;
956
+ }
957
+ if (applyAll || changes.forceAll || changes.palette || changes.additionalOptions) {
958
+ this.applyAdditionalOptions();
959
+ updates++;
960
+ }
961
+ if (applyAll) {
962
+ this.applyStyles();
963
+ setTimeout(() => this.updateCustomLegendMultiLineInfo());
964
+ }
965
+ let skipDz = false;
966
+ if (updates) {
967
+ if (changes.dataZoomRange) {
968
+ this.setDataZoomRange(true);
969
+ skipDz = true;
970
+ }
971
+ const dz = this.actualOptions.dataZoom;
972
+ let currentDataZoom;
973
+ if (skipMerge && this.hasDataZoom() && this.hasData() && !skipDz) {
974
+ // forced updated is required when adding/removing series, see:
975
+ // https://github.com/apache/incubator-echarts/issues/6202
976
+ // in order not to mess up current datazoom, save the current value and add it to options
977
+ this.saveCurrentDataZoom();
978
+ if (this.lastValidDataZoom) {
979
+ currentDataZoom = dz[0];
980
+ const newDataZoom = {};
981
+ echarts.util.merge(newDataZoom, dz[0], true);
982
+ echarts.util.merge(newDataZoom, this.lastValidDataZoom, true);
983
+ dz[0] = newDataZoom;
984
+ }
985
+ }
986
+ this.updateEChart(skipMerge);
987
+ if (currentDataZoom) {
988
+ dz[0] = currentDataZoom;
989
+ this.updateEChart(false, { dataZoom: this.actualOptions.dataZoom });
990
+ }
991
+ this.applyColorsToCustomLegends();
992
+ }
993
+ if (!skipDz && changes.dataZoomRange) {
994
+ // this is done after a possible setOptions call to ensure echarts has all the desired states
995
+ this.setDataZoomRange();
996
+ }
997
+ this.cdRef.markForCheck();
998
+ }
999
+ ngOnInit() {
1000
+ const canvas = document.createElement('canvas');
1001
+ this.measureCanvas = canvas.getContext('2d');
1002
+ this.measureCanvas.font = '12px "SiemensSans Pro"';
1003
+ const externalXAxisFormatter = this.externalXAxisFormatter();
1004
+ if (this.externalZoomSlider() && externalXAxisFormatter) {
1005
+ const consumerFormatter = externalXAxisFormatter;
1006
+ this.extZoomSliderOptions.xAxis[0].axisLabel = {
1007
+ formatter: (value) => consumerFormatter(value, this.visibleRange())
1008
+ };
1009
+ }
1010
+ this.applyTheme();
1011
+ // this is to clean the legend item list
1012
+ if (this.showCustomLegend() && this.customLegend && this.customLegend.length > 0) {
1013
+ this.customLegend.forEach(cl => {
1014
+ cl.customLegends = [
1015
+ { list: [], unit: '' },
1016
+ { list: [], unit: '' }
1017
+ ];
1018
+ });
1019
+ }
1020
+ this.applyOptions();
1021
+ this.applyAdditionalOptions();
1022
+ this.applyDataZoom();
1023
+ this.applyStyles();
1024
+ if (this.customLegendAction()) {
1025
+ this.fetchSeriesColors();
1026
+ }
1027
+ }
1028
+ ngAfterViewInit(skipZoom) {
1029
+ this.ngZone.runOutsideAngular(() => {
1030
+ const chartContainerEl = this.chartContainer().nativeElement;
1031
+ // set current dimension to avoid initial resize() call on chart
1032
+ const rect = chartContainerEl.getBoundingClientRect();
1033
+ this.curWidth = Math.floor(rect.width);
1034
+ this.curHeight = Math.floor(rect.height);
1035
+ const opts = { renderer: this.renderer() };
1036
+ this.chart = echarts.init(chartContainerEl, this.activeTheme, opts);
1037
+ this.echartElement = chartContainerEl;
1038
+ this.getEChartInner()?.addEventListener('mousedown', this.echartMouseDown);
1039
+ this.chart.setOption(this.actualOptions);
1040
+ setTimeout(() => this.checkGridSizeChange());
1041
+ if (this.externalZoomSlider()) {
1042
+ this.extZoomSliderChart = echarts.init(this.externalZoomSliderContainer().nativeElement, this.activeTheme, opts);
1043
+ this.eChartExtSliderElement = this.externalZoomSliderContainer()
1044
+ .nativeElement;
1045
+ this.getEChartExternalSliderInner()?.addEventListener('mousedown', this.echartExtSliderMouseDown);
1046
+ this.extZoomSliderChart.setOption(this.extZoomSliderOptions);
1047
+ this.extZoomSliderChart.on('datazoom', (event) => this.handleExtDataZoom(event));
1048
+ }
1049
+ this.afterChartInit(skipZoom);
1050
+ });
1051
+ setTimeout(() => {
1052
+ this.resize();
1053
+ this.applyColorsToCustomLegends();
1054
+ });
1055
+ }
1056
+ calculateTextWidth(text) {
1057
+ if (!this.measureCanvas) {
1058
+ return 150;
1059
+ }
1060
+ return Math.ceil(this.measureCanvas.measureText(text).width);
1061
+ }
1062
+ disposeChart() {
1063
+ if (this.chart && !this.chart.isDisposed()) {
1064
+ this.chart.dispose();
1065
+ }
1066
+ if (this.extZoomSliderChart && !this.extZoomSliderChart.isDisposed()) {
1067
+ this.extZoomSliderChart.dispose();
1068
+ }
1069
+ }
1070
+ ngOnDestroy() {
1071
+ this.disposeChart();
1072
+ }
1073
+ /**
1074
+ * Switch theme using echarts api, which does not need reloading the whole chart.
1075
+ */
1076
+ themeSwitch() {
1077
+ if (!this.chart) {
1078
+ return;
1079
+ }
1080
+ this.applyTheme();
1081
+ this.chart.setTheme(this.activeTheme);
1082
+ // Since color palette is set thorugh options, it needs to be set again.
1083
+ this.themeChanged();
1084
+ this.applyPalette();
1085
+ this.applyStyles();
1086
+ this.applyTitles();
1087
+ setTimeout(() => {
1088
+ this.applyColorsToCustomLegends();
1089
+ });
1090
+ this.chart.setOption(this.actualOptions);
1091
+ if (this.externalZoomSlider()) {
1092
+ this.extZoomSliderChart.setTheme(this.activeTheme);
1093
+ this.extZoomSliderChart.setOption(this.extZoomSliderOptions);
1094
+ }
1095
+ this.cdRef.markForCheck();
1096
+ }
1097
+ /**
1098
+ * Re-render the whole chart.
1099
+ * @deprecated The method is deprecated and should not be used directly by the consumer.
1100
+ */
1101
+ resetChart() {
1102
+ this.applyTheme();
1103
+ if (!this.actualOptions) {
1104
+ // this can happen if the SiThemeService fires the theme switch when the chart is not
1105
+ // yet completely initialized
1106
+ return;
1107
+ }
1108
+ this.disposeChart();
1109
+ this.applyPalette();
1110
+ const addOpts = this.additionalOptions();
1111
+ if (addOpts?.palette) {
1112
+ echarts.util.merge(this.actualOptions.palette, addOpts.palette, true);
1113
+ }
1114
+ this.themeChanged();
1115
+ this.applyStyles();
1116
+ this.applyTitles();
1117
+ this.ngAfterViewInit(true); // eslint-disable-line @angular-eslint/no-lifecycle-call
1118
+ this.cdRef.markForCheck();
1119
+ }
1120
+ handleLegendClick(legend) {
1121
+ this.doToggleSeriesVisibility(legend.name, legend.selected, legend);
1122
+ this.cdRef.markForCheck();
1123
+ }
1124
+ handleLegendHover(legend, start) {
1125
+ this.dispatchEChartAction({
1126
+ type: start ? 'highlight' : 'downplay',
1127
+ [legend.alternativeNaming ? 'name' : 'seriesName']: legend.name
1128
+ });
1129
+ }
1130
+ /**
1131
+ * Toggle visibility of a series.
1132
+ */
1133
+ toggleSeriesVisibility(name, visible) {
1134
+ const legendItem = this.findCustomLegendItem(name);
1135
+ this.doToggleSeriesVisibility(name, visible, legendItem);
1136
+ this.cdRef.markForCheck();
1137
+ }
1138
+ doToggleSeriesVisibility(name, visible, legendItem) {
1139
+ if (legendItem) {
1140
+ legendItem.selected = visible;
1141
+ }
1142
+ this.dispatchEChartAction({ type: visible ? 'legendSelect' : 'legendUnSelect', name });
1143
+ if (this.externalZoomSlider()) {
1144
+ this.ngZone.runOutsideAngular(() => {
1145
+ this.extZoomSliderChart.dispatchAction({
1146
+ type: visible ? 'legendSelect' : 'legendUnSelect',
1147
+ name
1148
+ });
1149
+ });
1150
+ }
1151
+ const opt = this.getOptionNoClone();
1152
+ if (Array.isArray(opt.legend)) {
1153
+ const selection = {};
1154
+ opt.legend.forEach((l) => Object.assign(selection, l.selected));
1155
+ this.handleSelectionChanged({ selected: selection });
1156
+ }
1157
+ }
1158
+ findCustomLegendItem(name) {
1159
+ if (this.showCustomLegend()) {
1160
+ for (const cl of this.customLegend) {
1161
+ for (const l of cl.customLegends) {
1162
+ for (const item of l.list) {
1163
+ if (item.name === name) {
1164
+ return item;
1165
+ }
1166
+ }
1167
+ }
1168
+ }
1169
+ }
1170
+ return undefined;
1171
+ }
1172
+ getValidXAxis() {
1173
+ return undefined;
1174
+ }
1175
+ setZoomMode() { }
1176
+ applyTheme() {
1177
+ // Set default theme if no theme provided
1178
+ const theme = this.theme();
1179
+ if (theme?.style) {
1180
+ this.activeTheme = theme.style();
1181
+ }
1182
+ else if (themeSupport._defaultTheme?.style) {
1183
+ this.activeTheme = themeSupport._defaultTheme.style();
1184
+ }
1185
+ const themeCustomization = this.themeCustomization();
1186
+ if (themeCustomization) {
1187
+ const custom = echarts.util.merge({}, themeCustomization);
1188
+ this.activeTheme = echarts.util.merge(custom, this.activeTheme);
1189
+ }
1190
+ }
1191
+ themeChanged() { }
1192
+ applyOptions() { }
1193
+ applyCustomLegendPosition() {
1194
+ if (this.showLegend() && this.showCustomLegend()) {
1195
+ this.customLegend.forEach(cl => {
1196
+ if (cl.customLegends?.[0].list && cl.customLegends?.[1].list) {
1197
+ const leftLegend = cl.customLegends[0];
1198
+ const rightLegend = cl.customLegends[1];
1199
+ // if we have left and right axis
1200
+ if (leftLegend.list.length > 0 && rightLegend.list.length > 0) {
1201
+ cl.legendAxis = 'both';
1202
+ }
1203
+ else if (leftLegend.list.length > 0 && rightLegend.list.length === 0) {
1204
+ // if we have only left axis data
1205
+ cl.legendAxis = 'left';
1206
+ }
1207
+ else if (leftLegend.list.length === 0 && rightLegend.list.length > 0) {
1208
+ // if we have only right axis data
1209
+ cl.legendAxis = 'right';
1210
+ }
1211
+ else {
1212
+ cl.legendAxis = 'both';
1213
+ }
1214
+ }
1215
+ else {
1216
+ cl.legendAxis = 'both';
1217
+ }
1218
+ });
1219
+ this.cdRef.markForCheck();
1220
+ }
1221
+ }
1222
+ applyAdditionalOptions() {
1223
+ // need to merge palette before the additionalOptions so that overrides work as expected
1224
+ this.applyPalette();
1225
+ if (this.additionalOptions()) {
1226
+ echarts.util.merge(this.actualOptions, this.additionalOptions(), true);
1227
+ }
1228
+ }
1229
+ applyPalette() {
1230
+ const paletteValue = this.palette() ?? 'default';
1231
+ if (paletteValue) {
1232
+ const palette = this.getThemeCustomValue(['colorPalettes', paletteValue], null);
1233
+ if (palette) {
1234
+ this.actualOptions.color = palette;
1235
+ if (this.customLegendAction()) {
1236
+ this.fetchSeriesColors(palette);
1237
+ }
1238
+ }
1239
+ }
1240
+ }
1241
+ applyDataZoom() {
1242
+ if (!this.actualOptions.grid) {
1243
+ return;
1244
+ }
1245
+ this.actualOptions.dataZoom ??= [];
1246
+ const sliderOptions = {};
1247
+ const dataZoomMinValueSpan = this.dataZoomMinValueSpan();
1248
+ if (dataZoomMinValueSpan) {
1249
+ sliderOptions.minValueSpan = dataZoomMinValueSpan;
1250
+ }
1251
+ const dataZoomMaxValueSpan = this.dataZoomMaxValueSpan();
1252
+ if (dataZoomMaxValueSpan) {
1253
+ sliderOptions.maxValueSpan = dataZoomMaxValueSpan;
1254
+ }
1255
+ sliderOptions.realtime = this.zoomSliderRealtime();
1256
+ sliderOptions.brushSelect = this.zoomSliderBrush();
1257
+ sliderOptions.showDataShadow = this.zoomSliderShadow();
1258
+ sliderOptions.filterMode = this.dataZoomFilterMode();
1259
+ sliderOptions.showDetail = false;
1260
+ // keep external zoom slider in sync, always at index 0
1261
+ Object.assign(this.extZoomSliderOptions.dataZoom[0], sliderOptions);
1262
+ const dz = this.actualOptions.dataZoom;
1263
+ const sliderIdx = dz.findIndex(z => z.type === 'slider');
1264
+ const insideIdx = dz.findIndex(z => z.type === 'inside');
1265
+ const zoomSlider = this.zoomSlider();
1266
+ if (zoomSlider && sliderIdx === -1) {
1267
+ // for the non-external, merge with other options
1268
+ const customOptions = this.getThemeCustomValue(['dataZoom', 'options'], {});
1269
+ const dzSliderOptions = Object.assign({ type: 'slider' }, customOptions, sliderOptions);
1270
+ Object.assign(this.extZoomSliderOptions.dataZoom[0], customOptions);
1271
+ const externalZoomSlider = this.externalZoomSlider();
1272
+ if (externalZoomSlider) {
1273
+ dzSliderOptions.show = false;
1274
+ }
1275
+ dz.push(dzSliderOptions);
1276
+ const gridOptions = externalZoomSlider
1277
+ ? this.getThemeCustomValue(['externalZoomSlider', 'grid'], {})
1278
+ : this.getThemeCustomValue(['dataZoom', 'grid'], {});
1279
+ if (this.showTimeRangeBar()) {
1280
+ const timeBarOptions = this.getThemeCustomValue(['timeRangeBar'], {});
1281
+ if (customOptions.height && customOptions.bottom) {
1282
+ this.timeBarBottom.set(customOptions.height + customOptions.bottom);
1283
+ }
1284
+ this.timeBarHeight.set(timeBarOptions?.height ?? 32);
1285
+ if (!externalZoomSlider) {
1286
+ gridOptions.bottom = (gridOptions?.bottom ?? 0) + this.timeBarHeight();
1287
+ }
1288
+ }
1289
+ echarts.util.merge(this.actualOptions.grid, gridOptions, true);
1290
+ }
1291
+ else if (zoomSlider && sliderIdx >= 0) {
1292
+ // update existing
1293
+ const dzSliderOptions = dz[sliderIdx];
1294
+ Object.assign(dzSliderOptions, sliderOptions);
1295
+ }
1296
+ else if (!zoomSlider && sliderIdx >= 0) {
1297
+ dz.splice(sliderIdx, 1);
1298
+ }
1299
+ const zoomInside = this.zoomInside();
1300
+ if (zoomInside && insideIdx === -1) {
1301
+ dz.push({ type: 'inside', filterMode: this.dataZoomFilterMode() });
1302
+ }
1303
+ else if (!zoomInside && insideIdx >= 0) {
1304
+ dz.splice(insideIdx, 1);
1305
+ }
1306
+ if (this.actualOptions.xAxis) {
1307
+ this.handleAxisPointer(this.actualOptions);
1308
+ }
1309
+ this.cdRef.markForCheck();
1310
+ }
1311
+ handleAxisPointer(options) {
1312
+ const axisPointer = this.axisPointer();
1313
+ if (axisPointer !== undefined) {
1314
+ options.axisPointer ??= {};
1315
+ }
1316
+ if (axisPointer === true) {
1317
+ options.axisPointer.triggerOn = 'click';
1318
+ }
1319
+ else if (axisPointer === false) {
1320
+ options.axisPointer.triggerOn = 'mousemove|click';
1321
+ }
1322
+ else if (typeof axisPointer === 'string') {
1323
+ options.axisPointer.triggerOn = axisPointer;
1324
+ }
1325
+ if (Array.isArray(options.xAxis)) {
1326
+ const xAxisArray = options.xAxis;
1327
+ xAxisArray.forEach(axis => this.handleAxisPointerSingleAxis(axis));
1328
+ }
1329
+ else {
1330
+ this.handleAxisPointerSingleAxis(options.xAxis);
1331
+ }
1332
+ }
1333
+ handleAxisPointerSingleAxis(xAxis) {
1334
+ if (this.axisPointer()) {
1335
+ echarts.util.merge(xAxis, { axisPointer: { handle: { show: true } } }, true);
1336
+ }
1337
+ else {
1338
+ echarts.util.merge(xAxis, { axisPointer: { handle: { show: false } } }, true);
1339
+ }
1340
+ }
1341
+ hasDataZoom() {
1342
+ return !!this.actualOptions.dataZoom?.length;
1343
+ }
1344
+ getThemeValue(props, defaultValue, ns) {
1345
+ if (!this.activeTheme) {
1346
+ return defaultValue;
1347
+ }
1348
+ let currentValue = this.activeTheme;
1349
+ if (ns) {
1350
+ currentValue = currentValue[ns];
1351
+ }
1352
+ for (let i = 0; currentValue && i < props.length; i++) {
1353
+ currentValue = currentValue[props[i]];
1354
+ }
1355
+ return currentValue ?? defaultValue;
1356
+ }
1357
+ getThemeCustomValue(props, defaultValue) {
1358
+ return this.getThemeValue(props, defaultValue, 'simpl');
1359
+ }
1360
+ applyTitles() {
1361
+ const title = this.title();
1362
+ const subTitle = this.subTitle();
1363
+ const options = this.actualOptions;
1364
+ if (this.showLegend() && this.showCustomLegend()) {
1365
+ if (options.title) {
1366
+ options.title.show = false;
1367
+ }
1368
+ options.legend?.forEach(legend => {
1369
+ legend.show = false;
1370
+ legend.height = 0;
1371
+ });
1372
+ if (options.grid) {
1373
+ const gridOptions = this.getThemeCustomValue(['customLegend', 'grid'], {});
1374
+ echarts.util.merge(options.grid, gridOptions, true);
1375
+ }
1376
+ this.titleColor.set(this.getThemeValue(['title', 'textStyle', 'color'], null));
1377
+ this.subTitleColor.set(this.getThemeValue(['title', 'subtextStyle', 'color'], this.titleColor));
1378
+ this.textColor.set(this.getThemeValue(['legend', 'textStyle', 'color'], null));
1379
+ this.backgroundColor.set(this.getThemeValue(['backgroundColor'], null));
1380
+ }
1381
+ else if (title || subTitle) {
1382
+ options.title = {
1383
+ text: title,
1384
+ subtext: subTitle
1385
+ };
1386
+ if (subTitle) {
1387
+ this.modifyTopAlignment('subTitle');
1388
+ }
1389
+ }
1390
+ else if (!title && !subTitle && !options.title) {
1391
+ this.modifyTopAlignment('noTitle');
1392
+ }
1393
+ }
1394
+ modifyTopAlignment(key) {
1395
+ const options = this.actualOptions;
1396
+ if (options.grid && !this.options()?.grid) {
1397
+ const gridOptions = this.getThemeCustomValue([key, 'grid'], {});
1398
+ echarts.util.merge(options.grid, gridOptions, true);
1399
+ }
1400
+ if (!this.options()?.legend) {
1401
+ const legendOptions = this.getThemeCustomValue([key, 'legend'], {});
1402
+ options.legend?.forEach(legend => echarts.util.merge(legend, legendOptions, true));
1403
+ }
1404
+ }
1405
+ afterChartInit(skipZoom) {
1406
+ this.chart.on('datazoom', (event) => this.handleDataZoom(event, 'echart'));
1407
+ if (!this.customLegendAction()) {
1408
+ // default generic si-chart behavior
1409
+ this.chart.on('legendselectchanged', (event) => this.handleSelectionChanged(event));
1410
+ this.chart.on('click', (event) => this.handleClickOnChart(event, false));
1411
+ }
1412
+ else {
1413
+ // custom chart behaviour
1414
+ this.chart.on('legendselectchanged', (event) => this.handleSelectionChangedCustom(event));
1415
+ this.chart.on('click', (event) => this.handleClickOnChart(event, true));
1416
+ }
1417
+ this.chart.on('updateaxispointer', (event) => this.handleUpdateAxisPointer(event));
1418
+ if (!skipZoom) {
1419
+ this.setDataZoomRange();
1420
+ }
1421
+ this.cdRef.markForCheck();
1422
+ }
1423
+ afterChartResize() { }
1424
+ getEChartInner() {
1425
+ return this.echartElement.querySelector(':scope > div:first-child');
1426
+ }
1427
+ getEChartExternalSliderInner() {
1428
+ return this.eChartExtSliderElement.querySelector(':scope > div:first-child');
1429
+ }
1430
+ handleExtChartMouseDown() {
1431
+ window.addEventListener('mouseup', this.echartExtSliderMouseUp);
1432
+ }
1433
+ handleExtChartMouseUp(event) {
1434
+ window.removeEventListener('mouseup', this.echartExtSliderMouseUp);
1435
+ const newEvent = new MouseEvent('mouseup', event);
1436
+ setTimeout(() => {
1437
+ this.getEChartExternalSliderInner()?.dispatchEvent(newEvent);
1438
+ this.cdRef.markForCheck();
1439
+ }, 1);
1440
+ }
1441
+ handleChartMouseDown() {
1442
+ window.addEventListener('mouseup', this.echartMouseUp);
1443
+ }
1444
+ handleChartMouseUp(event) {
1445
+ window.removeEventListener('mouseup', this.echartMouseUp);
1446
+ const newEvent = new MouseEvent('mouseup', event);
1447
+ setTimeout(() => {
1448
+ this.getEChartInner()?.dispatchEvent(newEvent);
1449
+ this.cdRef.markForCheck();
1450
+ }, 1);
1451
+ }
1452
+ setDataZoomRange(skipUpdate) {
1453
+ // Checking if we received a valid dataZoomRange Object
1454
+ const dataZoomRange = this.dataZoomRange();
1455
+ if (dataZoomRange && Object.keys(dataZoomRange).length > 0) {
1456
+ // If series has data, then directly dispatch action for the dataZoom event
1457
+ // Else, Store the dataZoomRange values in presetDataZoomRange variable for applying zoom
1458
+ // after data is received in chart
1459
+ // No need to reassign presetDataZoomRange if earlier value is not consumed
1460
+ if (this.hasData()) {
1461
+ const dz = this.getPresetDataZoom(dataZoomRange);
1462
+ if (dz) {
1463
+ const requested = { ...dataZoomRange };
1464
+ this.presetDataZoomRange = undefined;
1465
+ this.updateDataZoom(dz);
1466
+ if (!skipUpdate) {
1467
+ this.updateEChart(false, { dataZoom: [dz] });
1468
+ }
1469
+ // update user with proper data
1470
+ setTimeout(() => {
1471
+ this.ngZone.runOutsideAngular(() => {
1472
+ this.requestedDataZoom = requested;
1473
+ this.handleDataZoom(dz, 'setDataZoomRange');
1474
+ });
1475
+ });
1476
+ return;
1477
+ }
1478
+ }
1479
+ this.presetDataZoomRange = dataZoomRange;
1480
+ }
1481
+ }
1482
+ handleDataZoom(event, source) {
1483
+ // events can be batched
1484
+ if (event.batch?.length) {
1485
+ event = event.batch[0];
1486
+ }
1487
+ if (Number.isNaN(event.start) || Number.isNaN(event.end)) {
1488
+ // need to fix to the last valid dataZoom setting, see below
1489
+ this.chart.dispatchAction({ type: 'dataZoom', ...this.lastValidDataZoom });
1490
+ return;
1491
+ }
1492
+ const effectiveOpts = this.getOptionNoClone();
1493
+ // in case of pane by chart area, event.start and event.end are always undefined.
1494
+ // and in case of slider move, they has values in percentage(0-100)
1495
+ // so, to handle in case of pane, we need to get start and end values from datazoom property
1496
+ // following condition will be executed only if autozoom is false; and start and end are undefined(undefined means call is from pane)
1497
+ const dz = effectiveOpts.dataZoom[0];
1498
+ this.autoZoomUpdate = !!dz && dz.end === 100;
1499
+ // Due to chart updates outside Angular, we need to emit events back
1500
+ // inside Angular to activate Angular's change detection.
1501
+ const range = this.getVisibleRange();
1502
+ if (range) {
1503
+ range.source = source ?? event.source;
1504
+ this.calculateVisibleRange(range);
1505
+ if (this.requestedDataZoom) {
1506
+ range.requested = this.requestedDataZoom;
1507
+ this.requestedDataZoom = undefined;
1508
+ }
1509
+ this.ngZone.run(() => {
1510
+ this.dataZoom.emit(range);
1511
+ this.timeRangeChange.emit(dz.start === 0 && dz.end === 100 ? 0 : range.rangeEnd - range.rangeStart);
1512
+ });
1513
+ setTimeout(() => this.checkGridSizeChange());
1514
+ this.presetDataZoomRange = undefined;
1515
+ this.dataZoomSetupDone = true;
1516
+ // sync/store values
1517
+ this.updateDataZoom({ startValue: range.rangeStart, endValue: range.rangeEnd });
1518
+ if (event.source !== 'extSlider') {
1519
+ this.extZoomSliderChart?.dispatchAction({
1520
+ type: 'dataZoom',
1521
+ source: 'mainChart',
1522
+ startValue: range.rangeStart,
1523
+ endValue: range.rangeEnd
1524
+ });
1525
+ }
1526
+ }
1527
+ this.cdRef.markForCheck();
1528
+ }
1529
+ handleExtDataZoom(event) {
1530
+ if (event.batch?.length) {
1531
+ event = event.batch[0];
1532
+ }
1533
+ if (event.source === 'mainChart') {
1534
+ return;
1535
+ }
1536
+ const zoomModel = this.extZoomSliderChart._model;
1537
+ const range = this.doGetVisibleRange(zoomModel);
1538
+ if (range) {
1539
+ this.calculateVisibleRange(range);
1540
+ this.chart?.dispatchAction({
1541
+ type: 'dataZoom',
1542
+ source: 'extSlider',
1543
+ startValue: range.rangeStart,
1544
+ endValue: range.rangeEnd
1545
+ });
1546
+ }
1547
+ }
1548
+ handleSelectionChanged(event) {
1549
+ this.selectionChanged.emit(event);
1550
+ for (const a in event.selected) {
1551
+ if (event.selected[a] !== false) {
1552
+ return;
1553
+ }
1554
+ }
1555
+ this.saveCurrentDataZoom();
1556
+ }
1557
+ /**
1558
+ * Creates two objects that stores the colors for selected and unselected series. Used only for custom legend actions.
1559
+ */
1560
+ fetchSeriesColors(colorsToBeUSed) {
1561
+ const options = this.actualOptions;
1562
+ if (!options.color?.length && this.activeTheme) {
1563
+ options.color = [...this.activeTheme.color];
1564
+ }
1565
+ if (!colorsToBeUSed && !this.activeTheme) {
1566
+ return;
1567
+ }
1568
+ options.series?.forEach((element, index) => {
1569
+ this.unselectedSeriesColors[element.name] = {
1570
+ color: this.getThemeValue(['legend', 'unselected', 'color'], '#ccc'),
1571
+ index
1572
+ };
1573
+ const colors = colorsToBeUSed ?? this.activeTheme.color;
1574
+ this.selectedSeriesColors[element.name] = { color: colors[index], index };
1575
+ });
1576
+ }
1577
+ /**
1578
+ * Handles legend select event in non echart native way.
1579
+ * @param event - legend select
1580
+ */
1581
+ handleSelectionChangedCustom(event) {
1582
+ const optionsToChange = this.styleSelectedSeries(event.name, false, event.dataIndex);
1583
+ this.ngZone.runOutsideAngular(() => {
1584
+ this.chart.setOption(optionsToChange);
1585
+ this.chart.dispatchAction({ type: 'legendSelect', name: event.name });
1586
+ });
1587
+ }
1588
+ /**
1589
+ * Handles click on series in non echart native way.
1590
+ * @param event - click
1591
+ */
1592
+ handleClickOnChart(event, toggleVisibility) {
1593
+ if (event.componentType !== 'series') {
1594
+ return;
1595
+ }
1596
+ if (toggleVisibility) {
1597
+ const optionsToChange = this.styleSelectedSeries(event.seriesName, true, event.dataIndex);
1598
+ this.chart.setOption(optionsToChange);
1599
+ }
1600
+ else {
1601
+ this.ngZone.run(() => this.chartSeriesClick.emit({
1602
+ itemName: event.seriesName,
1603
+ dataIndex: event.dataIndex
1604
+ }));
1605
+ }
1606
+ }
1607
+ /**
1608
+ * Selects or unselects the series based on series state object
1609
+ * @param seriesName - series to be selected/unselected
1610
+ * @param emit - if true event is emitted otherwise no event is emitted
1611
+ */
1612
+ styleSelectedSeries(seriesName, emit, seriesDataIndex) {
1613
+ if (this.seriesSelectionState?.[seriesName]) {
1614
+ const elementToStyle = this.actualOptions.series?.find(element => element.name === seriesName);
1615
+ this.seriesSelectionState[seriesName] = false;
1616
+ return this.selectSeries(elementToStyle, emit, seriesDataIndex);
1617
+ }
1618
+ else {
1619
+ const elementToStyle = this.actualOptions.series?.find(element => element.name === seriesName);
1620
+ this.seriesSelectionState[seriesName] = true;
1621
+ return this.unselectSeries(elementToStyle, emit, seriesDataIndex);
1622
+ }
1623
+ }
1624
+ /**
1625
+ * Selects the series
1626
+ * @param element - to be styled as selected
1627
+ * @param emit - if true event is emitted otherwise no event is emitted
1628
+ */
1629
+ selectSeries(element, emit, seriesDataIndex) {
1630
+ const options = this.actualOptions;
1631
+ const optionsToChange = { color: options.color, series: [options.series] };
1632
+ const optionsColorIndex = this.selectedSeriesColors[element.name].index;
1633
+ optionsToChange.color[optionsColorIndex] = this.selectedSeriesColors[element.name].color;
1634
+ if (element.areaStyle) {
1635
+ element.areaStyle.opacity = 0.4;
1636
+ optionsToChange.series[this.selectedSeriesColors[element.name].index] = element;
1637
+ }
1638
+ if (emit) {
1639
+ this.chartSeriesClick.emit({
1640
+ itemName: element.name,
1641
+ dataIndex: seriesDataIndex,
1642
+ selected: false,
1643
+ color: this.selectedSeriesColors[element.name].color
1644
+ });
1645
+ }
1646
+ return optionsToChange;
1647
+ }
1648
+ /**
1649
+ * Unselects the series
1650
+ * @param element - to be styled as unselected
1651
+ * @param emit - if true event is emitted otherwise no event is emitted
1652
+ */
1653
+ unselectSeries(element, emit, seriesDataIndex) {
1654
+ const options = this.actualOptions;
1655
+ const optionsToChange = { color: options.color, series: [options.series] };
1656
+ const optionsColorIndex = this.selectedSeriesColors[element.name].index;
1657
+ optionsToChange.color[optionsColorIndex] = this.unselectedSeriesColors[element.name].color;
1658
+ if (element.areaStyle) {
1659
+ element.areaStyle.opacity = 0;
1660
+ optionsToChange.series[this.unselectedSeriesColors[element.name].index] = element;
1661
+ }
1662
+ if (emit) {
1663
+ this.chartSeriesClick.emit({
1664
+ itemName: element.name,
1665
+ dataIndex: seriesDataIndex,
1666
+ selected: true,
1667
+ color: this.selectedSeriesColors[element.name].color
1668
+ });
1669
+ }
1670
+ return optionsToChange;
1671
+ }
1672
+ isValidDataZoomValue(val) {
1673
+ return val !== null && val !== undefined && !Number.isNaN(val);
1674
+ }
1675
+ saveCurrentDataZoom() {
1676
+ const options = this.actualOptions;
1677
+ if (!options.grid || !options.dataZoom) {
1678
+ return;
1679
+ }
1680
+ // When the last item on the legend is disabled, remember the current valid
1681
+ // dataZoom setting. Due to a bug in ECharts it happens
1682
+ // that the zoom slider disappears not to ever reappear again. To work around
1683
+ // the problem, we simply inject the last valid dataZoom settings saved here
1684
+ // once the invalid values (NaN) are detected
1685
+ const currentOpts = this.getOptionNoClone();
1686
+ if (!currentOpts?.dataZoom?.[0]) {
1687
+ return;
1688
+ }
1689
+ const dz = currentOpts.dataZoom[0];
1690
+ if (dz) {
1691
+ this.lastValidDataZoom = {};
1692
+ if (this.isValidDataZoomValue(dz.startValue)) {
1693
+ this.lastValidDataZoom.startValue = dz.startValue;
1694
+ }
1695
+ else if (this.isValidDataZoomValue(dz.start)) {
1696
+ this.lastValidDataZoom.start = dz.start;
1697
+ }
1698
+ if (this.isValidDataZoomValue(dz.endValue)) {
1699
+ this.lastValidDataZoom.endValue = dz.endValue;
1700
+ }
1701
+ else if (this.isValidDataZoomValue(dz.end)) {
1702
+ this.lastValidDataZoom.end = dz.end;
1703
+ }
1704
+ }
1705
+ }
1706
+ /**
1707
+ * Get color by series name.
1708
+ */
1709
+ getSeriesColorBySeriesName(seriesName) {
1710
+ return this.doGetSeriesColorBySeriesName(seriesName).color;
1711
+ }
1712
+ doGetSeriesColorBySeriesName(seriesName) {
1713
+ const ecModel = this.internalGetModel();
1714
+ const ecSeries = ecModel.getSeriesByName(seriesName);
1715
+ if (ecSeries && ecSeries.length > 0) {
1716
+ return { color: ecSeries[0].getData().getVisual('style')?.fill, altName: false };
1717
+ }
1718
+ let ret = { color: undefined, altName: false };
1719
+ ecModel.eachRawSeries((seriesModel) => {
1720
+ const idx = seriesModel.legendVisualProvider?.indexOfName(seriesName) ?? -1;
1721
+ if (idx >= 0) {
1722
+ ret = {
1723
+ color: seriesModel.legendVisualProvider.getItemVisual(idx, 'style')?.fill,
1724
+ altName: true
1725
+ };
1726
+ }
1727
+ });
1728
+ return ret;
1729
+ }
1730
+ applyColorsToCustomLegends() {
1731
+ if (!this.showLegend() || !this.showCustomLegend()) {
1732
+ return;
1733
+ }
1734
+ this.customLegend.forEach(cl => {
1735
+ cl.customLegends.forEach(legendAxis => {
1736
+ legendAxis?.list.forEach(legend => {
1737
+ const color = this.doGetSeriesColorBySeriesName(legend.name);
1738
+ legend.color = color.color;
1739
+ legend.alternativeNaming = color.altName;
1740
+ });
1741
+ });
1742
+ });
1743
+ this.cdRef.markForCheck();
1744
+ }
1745
+ handleUpdateAxisPointer(event) {
1746
+ if (event.seriesIndex !== this.prevAxisPointer.seriesIndex ||
1747
+ event.dataIndex !== this.prevAxisPointer.dataIndex) {
1748
+ this.prevAxisPointer.seriesIndex = event.seriesIndex;
1749
+ this.prevAxisPointer.dataIndex = event.dataIndex;
1750
+ if (this.axisPointer() && event.seriesIndex === undefined) {
1751
+ return;
1752
+ }
1753
+ // Due to chart updates outside Angular, we need to emit events back
1754
+ // inside Angular to activate Angular's change detection.
1755
+ this.ngZone.run(() => {
1756
+ this.pointer.emit({
1757
+ seriesIndex: event.seriesIndex,
1758
+ dataIndex: event.dataIndex
1759
+ });
1760
+ });
1761
+ }
1762
+ }
1763
+ /**
1764
+ * Get current data zoom range.
1765
+ */
1766
+ getVisibleRange() {
1767
+ return this.doGetVisibleRange(this.internalGetModel());
1768
+ }
1769
+ internalGetModel() {
1770
+ return this.chart._model;
1771
+ }
1772
+ /**
1773
+ * returns the current EChart options, w/o cloning anything. Be very careful
1774
+ * not to change anything in the data structure in it.
1775
+ */
1776
+ getOptionNoClone() {
1777
+ return this.internalGetModel().option;
1778
+ }
1779
+ parsePercent(percent, all) {
1780
+ if (typeof percent === 'string') {
1781
+ if (percent.match(/\d+%/)) {
1782
+ return (parseFloat(percent) / 100) * all;
1783
+ }
1784
+ return parseFloat(percent);
1785
+ }
1786
+ return percent;
1787
+ }
1788
+ doGetVisibleRange(zoomModel) {
1789
+ const effectiveOpts = zoomModel.option;
1790
+ const xAxis = effectiveOpts.xAxis?.[0];
1791
+ const dz = effectiveOpts.dataZoom[0];
1792
+ const rangeStartArray = [];
1793
+ const rangeEndArray = [];
1794
+ for (let i = 0; i < effectiveOpts.xAxis?.length; i++) {
1795
+ const axis = zoomModel.getComponent('xAxis', i);
1796
+ const extent = axis?.axis?.scale?.getExtent();
1797
+ if (extent?.length) {
1798
+ if (this.isValidDataZoomValue(extent[0])) {
1799
+ rangeStartArray.push(extent[0]);
1800
+ }
1801
+ if (this.isValidDataZoomValue(extent[1])) {
1802
+ rangeEndArray.push(extent[1]);
1803
+ }
1804
+ }
1805
+ }
1806
+ const rangeStart = rangeStartArray.length ? Math.min(...rangeStartArray) : dz?.startValue;
1807
+ const rangeEnd = rangeEndArray.length ? Math.max(...rangeEndArray) : dz?.endValue;
1808
+ if (!this.isValidDataZoomValue(rangeEnd)) {
1809
+ return;
1810
+ }
1811
+ let gridWidth;
1812
+ if (effectiveOpts.grid && effectiveOpts.grid.length > 0) {
1813
+ const width = this.chart.getWidth();
1814
+ const grid = effectiveOpts.grid[0];
1815
+ gridWidth =
1816
+ width - this.parsePercent(grid.left, width) - this.parsePercent(grid.right, width);
1817
+ }
1818
+ return {
1819
+ rangeType: xAxis.type,
1820
+ rangeStart,
1821
+ rangeEnd,
1822
+ width: gridWidth,
1823
+ autoZoomUpdate: this.autoZoomUpdate
1824
+ };
1825
+ }
1826
+ updateEChart(force = false, options) {
1827
+ if (!this.chart) {
1828
+ return;
1829
+ }
1830
+ let axisDZUpdated = this.updateAxisAndDataZoom(options);
1831
+ options ??= this.actualOptions;
1832
+ const isFilledArray = (v) => Array.isArray(v) && v.length > 0;
1833
+ if (isFilledArray(options.grid) &&
1834
+ isFilledArray(options.xAxis) &&
1835
+ isFilledArray(options.dataZoom)) {
1836
+ // adjust grid for axis labels
1837
+ let max = 0;
1838
+ options.yAxis.forEach((axis) => {
1839
+ if (axis.position !== 'right' && isFilledArray(axis.data)) {
1840
+ axis.data.forEach((label) => {
1841
+ const width = this.calculateTextWidth(label);
1842
+ max = Math.max(max, width);
1843
+ });
1844
+ }
1845
+ });
1846
+ max += 16; // long text getting truncated, so add some padding
1847
+ const grids = options.grid;
1848
+ grids.forEach(g => (g.left = Math.max(g.left, max)));
1849
+ // update dataZoom if not already set
1850
+ const zoom = options.dataZoom[0];
1851
+ if (!this.isValidDataZoomValue(zoom?.startValue) &&
1852
+ !this.isValidDataZoomValue(zoom?.endValue) &&
1853
+ !this.isValidDataZoomValue(zoom?.end)) {
1854
+ const range = this.getVisibleRange();
1855
+ if (range) {
1856
+ this.updateDataZoom({ startValue: range.rangeStart, endValue: range.rangeEnd });
1857
+ }
1858
+ }
1859
+ // change in grid/axis requires a full update
1860
+ force = true;
1861
+ axisDZUpdated = true;
1862
+ }
1863
+ this.ngZone.runOutsideAngular(() => {
1864
+ this.chart.setOption(options, force);
1865
+ this.setZoomMode();
1866
+ if (axisDZUpdated && this.externalZoomSlider()) {
1867
+ this.extZoomSliderChart.setOption(this.extZoomSliderOptions, false);
1868
+ }
1869
+ });
1870
+ setTimeout(() => this.checkGridSizeChange());
1871
+ }
1872
+ updateAxisAndDataZoom(inOptions) {
1873
+ const options = this.actualOptions;
1874
+ if (!options.xAxis) {
1875
+ return false;
1876
+ }
1877
+ const isFull = !inOptions || inOptions === options;
1878
+ inOptions = inOptions ?? {};
1879
+ if (!isFull && !inOptions.series && !options.dataZoom) {
1880
+ return false;
1881
+ }
1882
+ const xAxis = Array.isArray(options.xAxis) ? options.xAxis : [options.xAxis];
1883
+ if (!isFull && !inOptions.xAxis) {
1884
+ // for delta update, make sure we have same-sized axis array
1885
+ inOptions.xAxis = xAxis.map(() => ({}));
1886
+ }
1887
+ const minMax = this.getSeriesMinMax();
1888
+ // extend range if DZ is bigger than actual data
1889
+ const dz = inOptions?.dataZoom?.[0];
1890
+ if (dz?.startValue != null &&
1891
+ (minMax.min === undefined || dz.startValue < minMax.min)) {
1892
+ minMax.min = dz.startValue;
1893
+ }
1894
+ if (dz?.endValue != null &&
1895
+ (minMax.max === undefined || dz.endValue > minMax.max)) {
1896
+ minMax.max = dz.endValue;
1897
+ }
1898
+ // Update all sub chart index to be controlled by the dataZoom
1899
+ let xAxisIndexes = [];
1900
+ xAxis.forEach((axis, index) => {
1901
+ if (axis.gridIndex >= 0) {
1902
+ // set min/max the same on all axis so that datazoom can work
1903
+ axis.min = minMax.min;
1904
+ axis.max = minMax.max;
1905
+ if (!isFull) {
1906
+ inOptions.xAxis[index].min = minMax.min;
1907
+ inOptions.xAxis[index].max = minMax.max;
1908
+ }
1909
+ xAxisIndexes.push(index);
1910
+ }
1911
+ });
1912
+ // update dataZoom
1913
+ const effectiveOpts = this.getOptionNoClone();
1914
+ const effectiveXAxis = effectiveOpts.xAxis;
1915
+ if (effectiveXAxis.length > 1) {
1916
+ // 1. find out all visible series
1917
+ // 2. find out valid x index
1918
+ // 3. remove invalid x axis from the xAxisIndex array
1919
+ const validXAxis = this.getValidXAxis();
1920
+ if (validXAxis) {
1921
+ xAxisIndexes = xAxisIndexes.filter(index => validXAxis.has(index));
1922
+ }
1923
+ }
1924
+ if (xAxisIndexes.length) {
1925
+ const allDataZoom = options.dataZoom;
1926
+ allDataZoom.forEach(zoom => (zoom.xAxisIndex = xAxisIndexes));
1927
+ if (!isFull && inOptions.dataZoom) {
1928
+ inOptions.dataZoom.forEach(zoom => (zoom.xAxisIndex = xAxisIndexes));
1929
+ }
1930
+ }
1931
+ // update external slider if required
1932
+ if (this.externalZoomSlider()) {
1933
+ const extSliderAxis = this.extZoomSliderOptions.xAxis[0];
1934
+ if (extSliderAxis.min !== minMax.min || extSliderAxis.max !== minMax.max) {
1935
+ extSliderAxis.min = minMax.min;
1936
+ extSliderAxis.max = minMax.max;
1937
+ this.extZoomSliderOptions.series[0].data = [
1938
+ [minMax.min, null],
1939
+ [minMax.max, null]
1940
+ ];
1941
+ }
1942
+ }
1943
+ return true;
1944
+ }
1945
+ /**
1946
+ * Send action to echart.
1947
+ * @see https://echarts.apache.org/en/api.html#action
1948
+ */
1949
+ dispatchEChartAction(action) {
1950
+ if (!this.chart) {
1951
+ return;
1952
+ }
1953
+ this.ngZone.runOutsideAngular(() => {
1954
+ this.chart.dispatchAction(action);
1955
+ });
1956
+ this.cdRef.markForCheck();
1957
+ }
1958
+ getSeriesMinMax(visibleOnly = false) {
1959
+ const legend = visibleOnly ? this.internalGetModel().getComponent('legend') : undefined;
1960
+ let min;
1961
+ let max;
1962
+ this.actualOptions.series?.forEach(s => {
1963
+ const seriesData = s.data;
1964
+ if (seriesData?.length > 1 && (!legend || legend.isSelected(s.name))) {
1965
+ const start = seriesData[0][0]?.valueOf();
1966
+ const last = seriesData[seriesData.length - 1];
1967
+ // end value is can be undefined sometimes, if we don't have milliseconds as a value, instead
1968
+ // we have value[] array of Date, so to handle that scenario we are taking value[0].valueOf() to
1969
+ // calculate the millisecond value i.e from Date(value[0])
1970
+ const end = last[0]?.valueOf() ?? last.value?.[0]?.valueOf();
1971
+ if (this.isValidDataZoomValue(start) && this.isValidDataZoomValue(end)) {
1972
+ if (min === undefined || start < min) {
1973
+ min = start;
1974
+ }
1975
+ if (max === undefined || end > max) {
1976
+ max = end;
1977
+ }
1978
+ }
1979
+ }
1980
+ });
1981
+ return { min, max };
1982
+ }
1983
+ calculateVisibleRange(range) {
1984
+ const options = this.actualOptions;
1985
+ if (!options.xAxis || !this.hasDataZoom() || !range) {
1986
+ return;
1987
+ }
1988
+ if (!Array.isArray(options.xAxis) && options.xAxis.type === 'category') {
1989
+ this.visibleRange.set(Math.ceil(range.rangeEnd) - Math.floor(range.rangeStart));
1990
+ }
1991
+ else {
1992
+ this.visibleRange.set(Math.round(range.rangeEnd - range.rangeStart));
1993
+ }
1994
+ // once in range mode, disable the entries mode to prevent overriding the user
1995
+ this.visibleEntries.set(-1);
1996
+ }
1997
+ getValueFromSeriesPoint(point) {
1998
+ return Array.isArray(point) ? point : point.value;
1999
+ }
2000
+ calculateZoomStartValue() {
2001
+ const options = this.actualOptions;
2002
+ if (!options.series) {
2003
+ return null;
2004
+ }
2005
+ const seriesData = options.series[this.autoZoomSeriesIndex()]?.data;
2006
+ if (!seriesData) {
2007
+ return null;
2008
+ }
2009
+ if (this.visibleEntries() > -1) {
2010
+ const offset = Math.min(seriesData.length, this.visibleEntries());
2011
+ const data = seriesData[seriesData.length - offset];
2012
+ return data ? this.getValueFromSeriesPoint(data)[0] : null;
2013
+ }
2014
+ else if (this.visibleRange() > -1) {
2015
+ const minMax = this.getSeriesMinMax(true);
2016
+ if (minMax.min && minMax.max) {
2017
+ // make sure startValue is >= the min data value
2018
+ return Math.max(minMax.min, minMax.max - this.visibleRange());
2019
+ }
2020
+ const data = seriesData[seriesData.length - 1];
2021
+ return data ? this.getValueFromSeriesPoint(data)[0] - this.visibleRange() : null;
2022
+ }
2023
+ return null;
2024
+ }
2025
+ hasData() {
2026
+ return this.actualOptions.series?.some(s => s.data?.length > 0) ?? false;
2027
+ }
2028
+ /**
2029
+ * Re-render the chart series data. This method should be called on series data changes.
2030
+ */
2031
+ refreshSeries(isLive = true, dzToSet) {
2032
+ dzToSet ??= this.presetDataZoomRange;
2033
+ const optionsToUpdate = {
2034
+ series: this.actualOptions.series
2035
+ };
2036
+ if (!isLive) {
2037
+ this.updateEChart(false, optionsToUpdate);
2038
+ return;
2039
+ }
2040
+ if (this.hasDataZoom() && this.hasData()) {
2041
+ if (dzToSet) {
2042
+ this.dataZoomSetupDone = true;
2043
+ const dz = this.getPresetDataZoom(dzToSet);
2044
+ if (dz) {
2045
+ const requested = { ...dzToSet };
2046
+ this.presetDataZoomRange = undefined;
2047
+ this.updateDataZoom(dz, optionsToUpdate);
2048
+ // dispatch the same async. reasoning: the sync here is needed to prevent
2049
+ // flickering, the async dispatch to ensure a DataZoomEvent is fired so
2050
+ // that any consumer of this event work as expected
2051
+ setTimeout(() => {
2052
+ this.ngZone.runOutsideAngular(() => {
2053
+ this.requestedDataZoom = requested;
2054
+ this.handleDataZoom(dz, 'refreshSeries');
2055
+ });
2056
+ });
2057
+ }
2058
+ }
2059
+ else if (!this.dataZoomSetupDone) {
2060
+ // need to do this async to have the data in ECharts
2061
+ setTimeout(() => {
2062
+ if (!this.dataZoomSetupDone && !this.dataZoomRange() && this.chart) {
2063
+ this.calculateVisibleRange(this.getVisibleRange());
2064
+ }
2065
+ this.dataZoomSetupDone = true;
2066
+ });
2067
+ }
2068
+ else if (this.zoomSlider() && this.autoZoomUpdate && this.autoZoomSeriesIndex() !== -1) {
2069
+ // this ensures the slider is at the end and the window size remains stable, showing new data
2070
+ const startValue = this.calculateZoomStartValue();
2071
+ if (this.isValidDataZoomValue(startValue)) {
2072
+ this.updateDataZoom({ startValue, end: 100 }, optionsToUpdate);
2073
+ }
2074
+ if (isLive) {
2075
+ this.dispatchEChartAction({ type: 'hideTip' });
2076
+ }
2077
+ }
2078
+ else {
2079
+ // this ensures the current displayed window stays stable as new data arrives
2080
+ const dz = this.getOptionNoClone().dataZoom[0];
2081
+ if (this.isValidDataZoomValue(dz.startValue) &&
2082
+ this.isValidDataZoomValue(dz.endValue) &&
2083
+ dz.end !== 100) {
2084
+ this.updateDataZoom({ startValue: dz.startValue, endValue: dz.endValue }, optionsToUpdate);
2085
+ }
2086
+ }
2087
+ }
2088
+ this.updateEChart(false, optionsToUpdate);
2089
+ }
2090
+ // this ensures DZ is in sync everywhere
2091
+ updateDataZoom(dz, optionsToUpdate) {
2092
+ const options = this.actualOptions;
2093
+ if (options.dataZoom?.[0]) {
2094
+ this.doUpdateDZ(dz, options.dataZoom[0]);
2095
+ }
2096
+ if (optionsToUpdate && optionsToUpdate !== options) {
2097
+ if (Array.isArray(optionsToUpdate.dataZoom)) {
2098
+ this.doUpdateDZ(dz, optionsToUpdate.dataZoom[0]);
2099
+ }
2100
+ else if (optionsToUpdate.dataZoom) {
2101
+ this.doUpdateDZ(dz, optionsToUpdate.dataZoom);
2102
+ }
2103
+ else {
2104
+ optionsToUpdate.dataZoom = [{ ...dz }];
2105
+ }
2106
+ }
2107
+ if (this.externalZoomSlider()) {
2108
+ this.doUpdateDZ(dz, this.extZoomSliderOptions.dataZoom[0]);
2109
+ }
2110
+ }
2111
+ doUpdateDZ(dz, dzOptions) {
2112
+ // make sure only to have value or percent
2113
+ if (this.isValidDataZoomValue(dz.startValue)) {
2114
+ dzOptions.startValue = dz.startValue;
2115
+ dzOptions.start = undefined;
2116
+ }
2117
+ else if (this.isValidDataZoomValue(dz.start)) {
2118
+ dzOptions.start = dz.start;
2119
+ dzOptions.startValue = undefined;
2120
+ }
2121
+ if (this.isValidDataZoomValue(dz.endValue)) {
2122
+ dzOptions.endValue = dz.endValue;
2123
+ dzOptions.end = undefined;
2124
+ }
2125
+ else if (this.isValidDataZoomValue(dz.end)) {
2126
+ dzOptions.end = dz.end;
2127
+ dzOptions.endValue = undefined;
2128
+ }
2129
+ }
2130
+ applyStyles() {
2131
+ const bodyStyle = window.getComputedStyle(document.body);
2132
+ const options = this.actualOptions;
2133
+ options.textStyle = {
2134
+ fontFamily: navigator.webdriver ? 'sans-serif' : bodyStyle.fontFamily,
2135
+ fontSize: bodyStyle.fontSize
2136
+ };
2137
+ this.extZoomSliderOptions.textStyle = options.textStyle;
2138
+ }
2139
+ addLegendItem(name, visible, index = 0, gridIndex = 0, customLegendProp, seriesSymbol) {
2140
+ const options = this.actualOptions;
2141
+ if (!options.legend?.length) {
2142
+ return;
2143
+ }
2144
+ const legend = options.legend[options.legend.length > index ? index : 0];
2145
+ const unitText = customLegendProp ? customLegendProp.unit : undefined;
2146
+ const customLegendItem = {
2147
+ name: '',
2148
+ displayName: '',
2149
+ color: '',
2150
+ selected: false,
2151
+ tooltip: customLegendProp ? customLegendProp.tooltip : '',
2152
+ symbol: this.getPath(seriesSymbol, false)
2153
+ };
2154
+ legend.data?.push({
2155
+ name,
2156
+ icon: this.getPath(seriesSymbol, true)
2157
+ });
2158
+ legend.selected ??= {};
2159
+ if (visible !== null && visible !== undefined) {
2160
+ legend.selected[name] = visible;
2161
+ customLegendItem.selected = visible;
2162
+ }
2163
+ const showCustomLegend = this.showCustomLegend();
2164
+ if (this.showLegend() && showCustomLegend) {
2165
+ if (visible !== false) {
2166
+ customLegendItem.selected = true;
2167
+ }
2168
+ customLegendItem.name = name;
2169
+ customLegendItem.displayName = customLegendProp?.displayName ?? name;
2170
+ if (showCustomLegend) {
2171
+ this.addCustomLegend(customLegendItem, unitText, index, gridIndex);
2172
+ }
2173
+ }
2174
+ this.cdRef.markForCheck();
2175
+ }
2176
+ getPath(seriesSymbol, prefix) {
2177
+ const path = seriesSymbol ? this.shapePaths[seriesSymbol] : this.shapePaths.circle;
2178
+ return prefix ? 'path://' + path : path;
2179
+ }
2180
+ addCustomLegend(customLegendItem, unitText, index, gridIndex = 0) {
2181
+ if (this.actualOptions.legend) {
2182
+ if (!this.customLegend[gridIndex].customLegends) {
2183
+ this.customLegend[gridIndex].customLegends = [
2184
+ { list: [], unit: '' },
2185
+ { list: [], unit: '' }
2186
+ ];
2187
+ }
2188
+ // index = 0 means left legend
2189
+ if (index === 0) {
2190
+ if (!this.customLegend[gridIndex]?.customLegends[0]?.list) {
2191
+ this.customLegend[gridIndex].customLegends[0] = { list: [customLegendItem] };
2192
+ }
2193
+ else {
2194
+ // legend with same id and name not found
2195
+ this.customLegend[gridIndex].customLegends[0].list.push(customLegendItem);
2196
+ }
2197
+ this.customLegend[gridIndex].customLegends[0].unit = unitText;
2198
+ }
2199
+ else {
2200
+ // index = 1 means right legend
2201
+ if (!this.customLegend[gridIndex]?.customLegends[1]?.list) {
2202
+ this.customLegend[gridIndex].customLegends[1] = { list: [customLegendItem] };
2203
+ }
2204
+ else {
2205
+ this.customLegend[gridIndex].customLegends[1].list.push(customLegendItem);
2206
+ }
2207
+ this.customLegend[gridIndex].customLegends[1].unit = unitText;
2208
+ }
2209
+ this.applyCustomLegendPosition();
2210
+ }
2211
+ }
2212
+ /**
2213
+ * Show loading indicator.
2214
+ */
2215
+ startProgressIndication() {
2216
+ this.inProgress.set(true);
2217
+ }
2218
+ /**
2219
+ * Hide loading indicator.
2220
+ */
2221
+ stopProgressIndication() {
2222
+ this.inProgress.set(false);
2223
+ }
2224
+ /**
2225
+ * Set the data zoom range for the chart in milliseconds.
2226
+ * As an example one hour is the value 3600000.
2227
+ */
2228
+ setTimeRange(range) {
2229
+ const currentDZ = this.getVisibleRange();
2230
+ const minMax = this.getSeriesMinMax(true);
2231
+ if (!currentDZ || minMax.min == null || minMax.max == null) {
2232
+ return;
2233
+ }
2234
+ const mid = (currentDZ.rangeStart + currentDZ.rangeEnd) / 2;
2235
+ const halfRange = range / 2;
2236
+ let start;
2237
+ let end;
2238
+ if (range === 0 || range > minMax.max - minMax.min) {
2239
+ start = minMax.min;
2240
+ end = minMax.max;
2241
+ }
2242
+ else {
2243
+ start = mid - halfRange;
2244
+ end = mid + halfRange;
2245
+ // at start
2246
+ if (start < minMax.min) {
2247
+ start = minMax.min;
2248
+ end = start + range;
2249
+ }
2250
+ // at end. Special case: if already at end, keep end
2251
+ if (end > minMax.max || currentDZ.rangeEnd === minMax.max) {
2252
+ start = minMax.max - range;
2253
+ end = minMax.max;
2254
+ }
2255
+ }
2256
+ this.dispatchEChartAction({ type: 'dataZoom', startValue: start, endValue: end });
2257
+ }
2258
+ addDataInternal(series) {
2259
+ const options = this.actualOptions;
2260
+ series.forEach(update => {
2261
+ const currentSeries = options.series[update.index];
2262
+ if (!currentSeries) {
2263
+ return;
2264
+ }
2265
+ const seriesData = currentSeries.data;
2266
+ seriesData.push(update.data);
2267
+ if (this.maxEntries() > 0 && seriesData.length > this.maxEntries()) {
2268
+ seriesData.splice(0, seriesData.length - this.maxEntries());
2269
+ }
2270
+ });
2271
+ this.refreshSeries();
2272
+ }
2273
+ getPresetDataZoom(range) {
2274
+ let ret;
2275
+ if (range.visibleWidth && this.autoZoomSeriesIndex() !== -1) {
2276
+ this.visibleRange.set(range.visibleWidth);
2277
+ const startValue = this.calculateZoomStartValue();
2278
+ if (this.isValidDataZoomValue(startValue)) {
2279
+ this.autoZoomUpdate = true;
2280
+ ret = { startValue, end: 100 };
2281
+ }
2282
+ }
2283
+ else if (this.isValidDataZoomValue(range.startValue) &&
2284
+ this.isValidDataZoomValue(range.endValue)) {
2285
+ // handling the case when startValue and endValue is given as a fixed time interval
2286
+ ret = {
2287
+ startValue: range.startValue,
2288
+ endValue: range.endValue
2289
+ };
2290
+ this.autoZoomUpdate = false;
2291
+ }
2292
+ else {
2293
+ ret = { ...range };
2294
+ }
2295
+ return ret;
2296
+ }
2297
+ checkGridSizeChange() {
2298
+ if (!this.chart) {
2299
+ return;
2300
+ }
2301
+ const gridRectNew = this.internalGetModel()?.getComponent('grid')?.coordinateSystem?._rect;
2302
+ if (gridRectNew) {
2303
+ const nativeWrapper = this.chartContainerWrapper().nativeElement;
2304
+ gridRectNew.containerWidth = nativeWrapper.offsetWidth;
2305
+ gridRectNew.containerHeight = nativeWrapper.offsetHeight;
2306
+ let isGridResized = false;
2307
+ for (const objKey of Object.keys(this.gridCoordinates)) {
2308
+ if (this.gridSizeItemChanged(gridRectNew[objKey], this.gridCoordinates[objKey])) {
2309
+ isGridResized = true;
2310
+ break;
2311
+ }
2312
+ }
2313
+ if (isGridResized) {
2314
+ // update new coordinates and emit event
2315
+ this.gridCoordinates = gridRectNew;
2316
+ this.timeBarLeft.set(this.gridCoordinates.x);
2317
+ this.timeBarRight.set(this.gridCoordinates.containerWidth - this.gridCoordinates.x - this.gridCoordinates.width);
2318
+ if (this.externalZoomSlider() && Array.isArray(this.extZoomSliderOptions?.grid)) {
2319
+ this.extZoomSliderOptions.grid[0].left = this.timeBarLeft();
2320
+ this.extZoomSliderOptions.grid[0].right = this.timeBarRight();
2321
+ this.extZoomSliderChart.setOption({ grid: this.extZoomSliderOptions.grid }, false);
2322
+ }
2323
+ this.ngZone.run(() => this.chartGridResized.emit(this.gridCoordinates));
2324
+ }
2325
+ }
2326
+ this.cdRef.markForCheck();
2327
+ }
2328
+ gridSizeItemChanged(a, b) {
2329
+ return Array.isArray(a)
2330
+ ? a.length !== b.length || a.some((item, index) => item !== b[index])
2331
+ : a !== b;
2332
+ }
2333
+ setContainerHeight() {
2334
+ const newHeight = parseInt(this.eChartContainerHeight(), 10) || null;
2335
+ if (newHeight !== this.containerHeight()) {
2336
+ this.containerHeight.set(newHeight);
2337
+ this.ngZone.runOutsideAngular(() => {
2338
+ this.chart?.resize({ width: this.curWidth, height: newHeight ?? this.curHeight });
2339
+ if (this.externalZoomSlider()) {
2340
+ this.extZoomSliderChart.resize();
2341
+ }
2342
+ });
2343
+ }
2344
+ }
2345
+ updateCustomLegendMultiLineInfo() {
2346
+ const event = [];
2347
+ this.siCustomLegend().forEach((legend, index) => {
2348
+ event.push({
2349
+ customLegendId: index,
2350
+ isCustomLegendMultilined: legend.customLegendContainer().nativeElement.offsetHeight > 20
2351
+ });
2352
+ });
2353
+ if (event.length !== this.customLegendsMultiLineInfo.length ||
2354
+ event.some((e, index) => e.isCustomLegendMultilined !==
2355
+ this.customLegendsMultiLineInfo[index].isCustomLegendMultilined)) {
2356
+ this.customLegendsMultiLineInfo = event;
2357
+ this.customLegendMultiLineInfoEvent.emit(event);
2358
+ }
2359
+ this.cdRef.markForCheck();
2360
+ }
2361
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: SiChartBaseComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2362
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: SiChartBaseComponent, isStandalone: true, selector: "si-chart-base", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, additionalOptions: { classPropertyName: "additionalOptions", publicName: "additionalOptions", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, subTitle: { classPropertyName: "subTitle", publicName: "subTitle", isSignal: true, isRequired: false, transformFunction: null }, showLegend: { classPropertyName: "showLegend", publicName: "showLegend", isSignal: true, isRequired: false, transformFunction: null }, showCustomLegend: { classPropertyName: "showCustomLegend", publicName: "showCustomLegend", isSignal: true, isRequired: false, transformFunction: null }, renderer: { classPropertyName: "renderer", publicName: "renderer", isSignal: true, isRequired: false, transformFunction: null }, zoomSlider: { classPropertyName: "zoomSlider", publicName: "zoomSlider", isSignal: true, isRequired: false, transformFunction: null }, zoomSliderShadow: { classPropertyName: "zoomSliderShadow", publicName: "zoomSliderShadow", isSignal: true, isRequired: false, transformFunction: null }, zoomSliderRealtime: { classPropertyName: "zoomSliderRealtime", publicName: "zoomSliderRealtime", isSignal: true, isRequired: false, transformFunction: null }, zoomSliderBrush: { classPropertyName: "zoomSliderBrush", publicName: "zoomSliderBrush", isSignal: true, isRequired: false, transformFunction: null }, zoomInside: { classPropertyName: "zoomInside", publicName: "zoomInside", isSignal: true, isRequired: false, transformFunction: null }, maxEntries: { classPropertyName: "maxEntries", publicName: "maxEntries", isSignal: true, isRequired: false, transformFunction: null }, visibleEntries: { classPropertyName: "visibleEntries", publicName: "visibleEntries", isSignal: true, isRequired: false, transformFunction: null }, visibleRange: { classPropertyName: "visibleRange", publicName: "visibleRange", isSignal: true, isRequired: false, transformFunction: null }, autoZoomSeriesIndex: { classPropertyName: "autoZoomSeriesIndex", publicName: "autoZoomSeriesIndex", isSignal: true, isRequired: false, transformFunction: null }, theme: { classPropertyName: "theme", publicName: "theme", isSignal: true, isRequired: false, transformFunction: null }, themeCustomization: { classPropertyName: "themeCustomization", publicName: "themeCustomization", isSignal: true, isRequired: false, transformFunction: null }, palette: { classPropertyName: "palette", publicName: "palette", isSignal: true, isRequired: false, transformFunction: null }, axisPointer: { classPropertyName: "axisPointer", publicName: "axisPointer", isSignal: true, isRequired: false, transformFunction: null }, dataZoomRange: { classPropertyName: "dataZoomRange", publicName: "dataZoomRange", isSignal: true, isRequired: false, transformFunction: null }, dataZoomMinValueSpan: { classPropertyName: "dataZoomMinValueSpan", publicName: "dataZoomMinValueSpan", isSignal: true, isRequired: false, transformFunction: null }, dataZoomMaxValueSpan: { classPropertyName: "dataZoomMaxValueSpan", publicName: "dataZoomMaxValueSpan", isSignal: true, isRequired: false, transformFunction: null }, dataZoomFilterMode: { classPropertyName: "dataZoomFilterMode", publicName: "dataZoomFilterMode", isSignal: true, isRequired: false, transformFunction: null }, customLegendAction: { classPropertyName: "customLegendAction", publicName: "customLegendAction", isSignal: true, isRequired: false, transformFunction: null }, selectedItem: { classPropertyName: "selectedItem", publicName: "selectedItem", isSignal: true, isRequired: false, transformFunction: null }, eChartContainerHeight: { classPropertyName: "eChartContainerHeight", publicName: "eChartContainerHeight", isSignal: true, isRequired: false, transformFunction: null }, externalZoomSlider: { classPropertyName: "externalZoomSlider", publicName: "externalZoomSlider", isSignal: true, isRequired: false, transformFunction: null }, externalXAxisFormatter: { classPropertyName: "externalXAxisFormatter", publicName: "externalXAxisFormatter", isSignal: true, isRequired: false, transformFunction: null }, showTimeRangeBar: { classPropertyName: "showTimeRangeBar", publicName: "showTimeRangeBar", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { showLegend: "showLegendChange", visibleEntries: "visibleEntriesChange", visibleRange: "visibleRangeChange", dataZoom: "dataZoom", pointer: "pointer", selectionChanged: "selectionChanged", chartSeriesClick: "chartSeriesClick", chartGridResized: "chartGridResized", customLegendMultiLineInfoEvent: "customLegendMultiLineInfoEvent", timeRangeChange: "timeRangeChange" }, host: { listeners: { "window:theme-switch": "themeSwitch()" } }, viewQueries: [{ propertyName: "chartContainerWrapper", first: true, predicate: ["chartContainerWrapper"], descendants: true, isSignal: true }, { propertyName: "chartContainer", first: true, predicate: ["chart"], descendants: true, isSignal: true }, { propertyName: "externalZoomSliderContainer", first: true, predicate: ["externalZoomSlider"], descendants: true, isSignal: true }, { propertyName: "siCustomLegend", predicate: ["siCustomLegend"], descendants: true, read: SiCustomLegendComponent, isSignal: true }], usesOnChanges: true, ngImport: i0, template: "@if (showCustomLegend() && (title() || subTitle())) {\n <div class=\"si-h5 chart-title chart-title-width\" [style.background-color]=\"backgroundColor()\">\n <div class=\"chart-title-text\" [style.color]=\"titleColor()\">{{ title() }}</div>\n @if (subTitle()) {\n <div class=\"si-body\" [style.color]=\"subTitleColor()\">{{ subTitle() }}</div>\n }\n </div>\n}\n\n<div\n #chartContainerWrapper\n class=\"chart-container-wrapper\"\n [class.chart-scroll]=\"containerHeight()\"\n [attr.tabindex]=\"containerHeight() ? '0' : null\"\n>\n <div class=\"chart-container\" [style.height.px]=\"containerHeight()\">\n @if (showCustomLegend()) {\n @for (cl of customLegend; track $index) {\n <si-custom-legend\n #siCustomLegend\n class=\"custom-legend\"\n [style.top.px]=\"cl.top\"\n [title]=\"title()\"\n [subTitle]=\"subTitle()\"\n [customLegend]=\"cl\"\n [style.background-color]=\"backgroundColor()\"\n [titleColor]=\"titleColor()\"\n [subTitleColor]=\"subTitleColor()\"\n [textColor]=\"textColor()\"\n (legendIconClickEvent)=\"handleLegendClick($event)\"\n (legendClickEvent)=\"handleLegendClick($event)\"\n (legendHoverStartEvent)=\"handleLegendHover($event, true)\"\n (legendHoverEndEvent)=\"handleLegendHover($event, false)\"\n />\n }\n }\n <div #chart class=\"echart-container\" [style.height.px]=\"containerHeight()\"></div>\n </div>\n</div>\n@if (externalZoomSlider()) {\n <div\n #externalZoomSlider\n class=\"external-zoom-container\"\n [class.has-time-range-bar]=\"showTimeRangeBar()\"\n [style.--time-bar-height.px]=\"timeBarHeight()\"\n ></div>\n}\n\n@if (showTimeRangeBar() && zoomSlider()) {\n <div\n class=\"time-range-bar\"\n [style.bottom.px]=\"timeBarBottom()\"\n [style.padding-left.px]=\"timeBarLeft()\"\n [style.padding-right.px]=\"timeBarRight()\"\n >\n <ng-content select=\"[slot=timeRangeBar]\" />\n </div>\n}\n\n@if (inProgress()) {\n <div class=\"progress-container\">\n <si-chart-loading-spinner />\n </div>\n}\n", styles: [":host{block-size:100%;position:relative;display:flex!important;flex-direction:column;inline-size:100%}.chart-container-wrapper{display:flex;flex:1 0 0;inline-size:inherit;overflow:hidden}.chart-scroll{overflow-y:auto}.chart-container{position:relative;display:flex;flex:1 0 0;overflow:hidden}.echart-container{flex:1 0 0;inline-size:100%;min-block-size:var(--si-chart-min-height, 200px);overflow:hidden}.custom-legend{position:absolute;z-index:2;inline-size:100%}.chart-title{padding-block:12px 8px;padding-inline-start:24px}.external-zoom-container{display:flex;flex:1 0 0;inline-size:inherit;max-block-size:112px}.external-zoom-container.has-time-range-bar{max-block-size:calc(112px + var(--time-bar-height))}.tooltip-inner{max-inline-size:375px;min-inline-size:375px;color:#162938;font-size:18px;background-color:#162938}.time-range-bar{position:absolute;inset-inline:0;z-index:2}.progress-container{position:absolute;inset:0;pointer-events:none;z-index:100;display:flex;justify-content:center;align-items:center}\n"], dependencies: [{ kind: "component", type: SiCustomLegendComponent, selector: "si-custom-legend", inputs: ["customLegend", "title", "subTitle", "titleColor", "subTitleColor", "textColor"], outputs: ["legendIconClickEvent", "legendClickEvent", "legendHoverStartEvent", "legendHoverEndEvent"] }, { kind: "component", type: SiChartLoadingSpinnerComponent, selector: "si-chart-loading-spinner" }], changeDetection: i0.ChangeDetectionStrategy.Eager });
2363
+ }
2364
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: SiChartBaseComponent, decorators: [{
2365
+ type: Component,
2366
+ args: [{ selector: 'si-chart-base', imports: [SiCustomLegendComponent, SiChartLoadingSpinnerComponent], changeDetection: ChangeDetectionStrategy.Eager, host: {
2367
+ '(window:theme-switch)': 'themeSwitch()'
2368
+ }, template: "@if (showCustomLegend() && (title() || subTitle())) {\n <div class=\"si-h5 chart-title chart-title-width\" [style.background-color]=\"backgroundColor()\">\n <div class=\"chart-title-text\" [style.color]=\"titleColor()\">{{ title() }}</div>\n @if (subTitle()) {\n <div class=\"si-body\" [style.color]=\"subTitleColor()\">{{ subTitle() }}</div>\n }\n </div>\n}\n\n<div\n #chartContainerWrapper\n class=\"chart-container-wrapper\"\n [class.chart-scroll]=\"containerHeight()\"\n [attr.tabindex]=\"containerHeight() ? '0' : null\"\n>\n <div class=\"chart-container\" [style.height.px]=\"containerHeight()\">\n @if (showCustomLegend()) {\n @for (cl of customLegend; track $index) {\n <si-custom-legend\n #siCustomLegend\n class=\"custom-legend\"\n [style.top.px]=\"cl.top\"\n [title]=\"title()\"\n [subTitle]=\"subTitle()\"\n [customLegend]=\"cl\"\n [style.background-color]=\"backgroundColor()\"\n [titleColor]=\"titleColor()\"\n [subTitleColor]=\"subTitleColor()\"\n [textColor]=\"textColor()\"\n (legendIconClickEvent)=\"handleLegendClick($event)\"\n (legendClickEvent)=\"handleLegendClick($event)\"\n (legendHoverStartEvent)=\"handleLegendHover($event, true)\"\n (legendHoverEndEvent)=\"handleLegendHover($event, false)\"\n />\n }\n }\n <div #chart class=\"echart-container\" [style.height.px]=\"containerHeight()\"></div>\n </div>\n</div>\n@if (externalZoomSlider()) {\n <div\n #externalZoomSlider\n class=\"external-zoom-container\"\n [class.has-time-range-bar]=\"showTimeRangeBar()\"\n [style.--time-bar-height.px]=\"timeBarHeight()\"\n ></div>\n}\n\n@if (showTimeRangeBar() && zoomSlider()) {\n <div\n class=\"time-range-bar\"\n [style.bottom.px]=\"timeBarBottom()\"\n [style.padding-left.px]=\"timeBarLeft()\"\n [style.padding-right.px]=\"timeBarRight()\"\n >\n <ng-content select=\"[slot=timeRangeBar]\" />\n </div>\n}\n\n@if (inProgress()) {\n <div class=\"progress-container\">\n <si-chart-loading-spinner />\n </div>\n}\n", styles: [":host{block-size:100%;position:relative;display:flex!important;flex-direction:column;inline-size:100%}.chart-container-wrapper{display:flex;flex:1 0 0;inline-size:inherit;overflow:hidden}.chart-scroll{overflow-y:auto}.chart-container{position:relative;display:flex;flex:1 0 0;overflow:hidden}.echart-container{flex:1 0 0;inline-size:100%;min-block-size:var(--si-chart-min-height, 200px);overflow:hidden}.custom-legend{position:absolute;z-index:2;inline-size:100%}.chart-title{padding-block:12px 8px;padding-inline-start:24px}.external-zoom-container{display:flex;flex:1 0 0;inline-size:inherit;max-block-size:112px}.external-zoom-container.has-time-range-bar{max-block-size:calc(112px + var(--time-bar-height))}.tooltip-inner{max-inline-size:375px;min-inline-size:375px;color:#162938;font-size:18px;background-color:#162938}.time-range-bar{position:absolute;inset-inline:0;z-index:2}.progress-container{position:absolute;inset:0;pointer-events:none;z-index:100;display:flex;justify-content:center;align-items:center}\n"] }]
2369
+ }], propDecorators: { chartContainerWrapper: [{ type: i0.ViewChild, args: ['chartContainerWrapper', { isSignal: true }] }], chartContainer: [{ type: i0.ViewChild, args: ['chart', { isSignal: true }] }], externalZoomSliderContainer: [{ type: i0.ViewChild, args: ['externalZoomSlider', { isSignal: true }] }], siCustomLegend: [{ type: i0.ViewChildren, args: ['siCustomLegend', { ...{
2370
+ read: SiCustomLegendComponent
2371
+ }, isSignal: true }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], additionalOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "additionalOptions", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], subTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "subTitle", required: false }] }], showLegend: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLegend", required: false }] }, { type: i0.Output, args: ["showLegendChange"] }], showCustomLegend: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCustomLegend", required: false }] }], renderer: [{ type: i0.Input, args: [{ isSignal: true, alias: "renderer", required: false }] }], zoomSlider: [{ type: i0.Input, args: [{ isSignal: true, alias: "zoomSlider", required: false }] }], zoomSliderShadow: [{ type: i0.Input, args: [{ isSignal: true, alias: "zoomSliderShadow", required: false }] }], zoomSliderRealtime: [{ type: i0.Input, args: [{ isSignal: true, alias: "zoomSliderRealtime", required: false }] }], zoomSliderBrush: [{ type: i0.Input, args: [{ isSignal: true, alias: "zoomSliderBrush", required: false }] }], zoomInside: [{ type: i0.Input, args: [{ isSignal: true, alias: "zoomInside", required: false }] }], maxEntries: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxEntries", required: false }] }], visibleEntries: [{ type: i0.Input, args: [{ isSignal: true, alias: "visibleEntries", required: false }] }, { type: i0.Output, args: ["visibleEntriesChange"] }], visibleRange: [{ type: i0.Input, args: [{ isSignal: true, alias: "visibleRange", required: false }] }, { type: i0.Output, args: ["visibleRangeChange"] }], autoZoomSeriesIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoZoomSeriesIndex", required: false }] }], theme: [{ type: i0.Input, args: [{ isSignal: true, alias: "theme", required: false }] }], themeCustomization: [{ type: i0.Input, args: [{ isSignal: true, alias: "themeCustomization", required: false }] }], palette: [{ type: i0.Input, args: [{ isSignal: true, alias: "palette", required: false }] }], axisPointer: [{ type: i0.Input, args: [{ isSignal: true, alias: "axisPointer", required: false }] }], dataZoomRange: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataZoomRange", required: false }] }], dataZoomMinValueSpan: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataZoomMinValueSpan", required: false }] }], dataZoomMaxValueSpan: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataZoomMaxValueSpan", required: false }] }], dataZoomFilterMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataZoomFilterMode", required: false }] }], customLegendAction: [{ type: i0.Input, args: [{ isSignal: true, alias: "customLegendAction", required: false }] }], selectedItem: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedItem", required: false }] }], eChartContainerHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "eChartContainerHeight", required: false }] }], externalZoomSlider: [{ type: i0.Input, args: [{ isSignal: true, alias: "externalZoomSlider", required: false }] }], externalXAxisFormatter: [{ type: i0.Input, args: [{ isSignal: true, alias: "externalXAxisFormatter", required: false }] }], showTimeRangeBar: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTimeRangeBar", required: false }] }], dataZoom: [{ type: i0.Output, args: ["dataZoom"] }], pointer: [{ type: i0.Output, args: ["pointer"] }], selectionChanged: [{ type: i0.Output, args: ["selectionChanged"] }], chartSeriesClick: [{ type: i0.Output, args: ["chartSeriesClick"] }], chartGridResized: [{ type: i0.Output, args: ["chartGridResized"] }], customLegendMultiLineInfoEvent: [{ type: i0.Output, args: ["customLegendMultiLineInfoEvent"] }], timeRangeChange: [{ type: i0.Output, args: ["timeRangeChange"] }] } });
2372
+
2373
+ /**
2374
+ * Copyright (c) Siemens 2016 - 2026
2375
+ * SPDX-License-Identifier: MIT
2376
+ */
2377
+
2378
+ /**
2379
+ * Generated bundle index. Do not edit.
2380
+ */
2381
+
2382
+ export { SiChartBaseComponent, themeElement, themeSupport };
2383
+ //# sourceMappingURL=spike-rabbit-charts-ng-common.mjs.map