@operato/chart 7.0.12 → 7.0.14

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 (50) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/src/editors/configurer.d.ts +10 -1
  3. package/dist/src/editors/configurer.js +62 -2
  4. package/dist/src/editors/configurer.js.map +1 -1
  5. package/dist/src/editors/input-chart-abstract.d.ts +18 -0
  6. package/dist/src/editors/input-chart-abstract.js +438 -1
  7. package/dist/src/editors/input-chart-abstract.js.map +1 -1
  8. package/dist/src/editors/input-chart-styles.js +18 -9
  9. package/dist/src/editors/input-chart-styles.js.map +1 -1
  10. package/dist/src/editors/ox-input-chart-hbar.d.ts +2 -2
  11. package/dist/src/editors/ox-input-chart-hbar.js +10 -10
  12. package/dist/src/editors/ox-input-chart-hbar.js.map +1 -1
  13. package/dist/src/editors/ox-input-chart-mixed.d.ts +2 -2
  14. package/dist/src/editors/ox-input-chart-mixed.js +3 -3
  15. package/dist/src/editors/ox-input-chart-mixed.js.map +1 -1
  16. package/dist/src/editors/ox-input-chart-radar.d.ts +2 -2
  17. package/dist/src/editors/ox-input-chart-radar.js +3 -3
  18. package/dist/src/editors/ox-input-chart-radar.js.map +1 -1
  19. package/dist/src/editors/ox-input-chart-timeseries.d.ts +2 -2
  20. package/dist/src/editors/ox-input-chart-timeseries.js +6 -4
  21. package/dist/src/editors/ox-input-chart-timeseries.js.map +1 -1
  22. package/dist/src/editors/ox-property-editor-chart.d.ts +1 -0
  23. package/dist/src/editors/ox-property-editor-chart.js +1 -0
  24. package/dist/src/editors/ox-property-editor-chart.js.map +1 -1
  25. package/dist/src/scichart/scichart-builder.js +75 -5
  26. package/dist/src/scichart/scichart-builder.js.map +1 -1
  27. package/dist/stories/ox-input-chart-timeseries.stories.js +0 -4
  28. package/dist/stories/ox-input-chart-timeseries.stories.js.map +1 -1
  29. package/dist/tsconfig.tsbuildinfo +1 -1
  30. package/package.json +2 -2
  31. package/src/editors/configurer.ts +73 -2
  32. package/src/editors/input-chart-abstract.ts +459 -2
  33. package/src/editors/input-chart-styles.ts +18 -9
  34. package/src/editors/ox-input-chart-hbar.ts +10 -10
  35. package/src/editors/ox-input-chart-mixed.ts +3 -3
  36. package/src/editors/ox-input-chart-radar.ts +3 -3
  37. package/src/editors/ox-input-chart-timeseries.ts +6 -4
  38. package/src/editors/ox-property-editor-chart.ts +1 -0
  39. package/src/scichart/scichart-builder.ts +89 -4
  40. package/src/types.d.ts +19 -0
  41. package/stories/ox-input-chart-timeseries.stories.ts +0 -4
  42. package/translations/en.json +24 -17
  43. package/translations/ja.json +25 -18
  44. package/translations/ko.json +11 -4
  45. package/translations/ms.json +25 -18
  46. package/translations/zh.json +30 -23
  47. package/dist/src/editors/input-chart-multi-series-abstract.d.ts +0 -17
  48. package/dist/src/editors/input-chart-multi-series-abstract.js +0 -419
  49. package/dist/src/editors/input-chart-multi-series-abstract.js.map +0 -1
  50. package/src/editors/input-chart-multi-series-abstract.ts +0 -430
@@ -1,8 +1,9 @@
1
1
  import '@operato/i18n/ox-i18n.js'
2
2
 
3
- import { html } from 'lit'
4
- import { property } from 'lit/decorators.js'
3
+ import { html, PropertyValues } from 'lit'
4
+ import { property, query } from 'lit/decorators.js'
5
5
  import { random as randomColor, TinyColor } from '@ctrl/tinycolor'
6
+ import { MdIcon } from '@material/web/icon/icon.js'
6
7
 
7
8
  import { InputChartStyles } from './input-chart-styles'
8
9
  import { Configurer } from './configurer'
@@ -14,6 +15,14 @@ export class InputChartAbstract extends OxFormField {
14
15
  @property({ type: Object }) value: OperatoChart.ChartConfig | null = null
15
16
  @property({ type: String, attribute: 'chart-type' }) chartType: OperatoChart.ChartType
16
17
 
18
+ @query('#annotations-tabs') annotationsTabs!: HTMLElement
19
+ @query('#annotations-tab-nav-left-button') annotationsTabNavLeftButton!: MdIcon
20
+ @query('#annotations-tab-nav-right-button') annotationsTabNavRightButton!: MdIcon
21
+
22
+ @query('#series-tabs') seriesTabs!: HTMLElement
23
+ @query('#series-tab-nav-left-button') seriesTabNavLeftButton!: MdIcon
24
+ @query('#series-tab-nav-right-button') seriesTabNavRightButton!: MdIcon
25
+
17
26
  private _configurer?: Configurer
18
27
 
19
28
  get configurer() {
@@ -71,6 +80,24 @@ export class InputChartAbstract extends OxFormField {
71
80
  this.renderRoot.addEventListener('change', this.onValuesChanged.bind(this))
72
81
  }
73
82
 
83
+ protected firstUpdated(_changedProperties: PropertyValues): void {
84
+ this.seriesTabContainer?.addEventListener('scroll', e => {
85
+ this._onTabScroll(e, 'series')
86
+ })
87
+
88
+ this.annotationsTabContainer?.addEventListener('scroll', e => {
89
+ this._onTabScroll(e, 'annotations')
90
+ })
91
+ }
92
+
93
+ get seriesTabContainer(): HTMLElement | null | undefined {
94
+ return this.seriesTabs
95
+ }
96
+
97
+ get annotationsTabContainer(): HTMLElement | null | undefined {
98
+ return this.annotationsTabs
99
+ }
100
+
74
101
  displayValueTemplate() {
75
102
  const configurer = this.configurer
76
103
 
@@ -290,6 +317,33 @@ export class InputChartAbstract extends OxFormField {
290
317
  this.requestUpdate()
291
318
  }
292
319
 
320
+ onTapAddAnnotation(e: Event) {
321
+ const configurer = this.configurer
322
+
323
+ const lastAnnotationIndex = configurer.annotations.length
324
+ configurer.annotations.push({ type: 'line', x1: 0, y1: 0 })
325
+
326
+ this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))
327
+ configurer.currentAnnotationIndex = lastAnnotationIndex
328
+
329
+ this.value = { ...this.configurer.value }
330
+ }
331
+
332
+ onTapRemoveCurrentAnnotation(index: number) {
333
+ const configurer = this.configurer
334
+
335
+ if (!configurer.config.data.datasets) {
336
+ return
337
+ }
338
+
339
+ this.configurer.data.datasets.splice(index, 1)
340
+
341
+ this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))
342
+ configurer.currentSeriesIndex = Math.max(0, configurer.currentSeriesIndex - 1)
343
+
344
+ this.requestUpdate()
345
+ }
346
+
293
347
  _getSeriesModel({
294
348
  chartType,
295
349
  datasetsLength,
@@ -330,4 +384,407 @@ export class InputChartAbstract extends OxFormField {
330
384
  return (element as any).value
331
385
  }
332
386
  }
387
+
388
+ annotationsTabTemplate() {
389
+ const configurer = this.configurer
390
+ const currentAnnotation = configurer.annotations[configurer.currentAnnotationIndex] || {}
391
+
392
+ return html`
393
+ <div id="annotations-properties-container" fullwidth>
394
+ <div id="annotations-tab-header">
395
+ <md-icon
396
+ id="annotations-tab-nav-left-button"
397
+ @tap=${(e: Event) => {
398
+ this._onTabScrollNavLeft(e, 'annotations')
399
+ }}
400
+ disabled
401
+ >chevron_left</md-icon
402
+ >
403
+ <div
404
+ id="annotations-tabs"
405
+ @change=${(e: Event) => {
406
+ configurer.currentAnnotationIndex = (e.target as any).activeTabIndex
407
+ }}
408
+ active-tab-index=${configurer.currentAnnotationIndex}
409
+ fit-container
410
+ >
411
+ ${configurer.annotations!.map(
412
+ (annotation: any, index: number) => html`
413
+ <div
414
+ data-annotation=${index + 1}
415
+ data-tab-index=${index}
416
+ tab
417
+ ?selected=${index == configurer.currentAnnotationIndex}
418
+ @click=${(e: Event) => {
419
+ const target = e.target as HTMLDivElement
420
+ this.configurer.setCurrentAnnotationIndex(Number(target.getAttribute('data-tab-index')))
421
+ this.value = { ...this.configurer.value }
422
+ }}
423
+ >
424
+ ${index + 1}
425
+ ${!configurer.annotations ||
426
+ (configurer.annotations.length != 1 && configurer.currentAnnotationIndex == index)
427
+ ? html` <md-icon @tap=${(e: Event) => this.onTapRemoveCurrentAnnotation(index)}> close </md-icon> `
428
+ : html``}
429
+ </div>
430
+ `
431
+ )}
432
+ </div>
433
+ <md-icon
434
+ id="annotations-tab-nav-right-button"
435
+ @click=${(e: Event) => {
436
+ this._onTabScrollNavRight(e, 'annotations')
437
+ }}
438
+ disabled
439
+ >chevron_right</md-icon
440
+ >
441
+ </div>
442
+ <div id="add-annotation-button-container">
443
+ <md-icon id="add-annotation-button" @tap=${(e: Event) => this.onTapAddAnnotation(e)}>add</md-icon>
444
+ </div>
445
+
446
+ <div class="tab-content">
447
+ <label for="annotation-type"> <ox-i18n msgid="label.chart-annotation-type">Type</ox-i18n> </label>
448
+ <select
449
+ id="annotation-type"
450
+ class="select-content"
451
+ value-key="annotation.type"
452
+ .value=${currentAnnotation.type || ''}
453
+ >
454
+ <option value="line">Line</option>
455
+ <option value="text">Text</option>
456
+ <option value="box">Box</option>
457
+ <option value="horizontalLine">Horizontal Line</option>
458
+ <option value="verticalLine">Vertical Line</option>
459
+ <option value="custom">Custom</option>
460
+ </select>
461
+
462
+ <label for="annotation-x1">X1</label>
463
+ <input
464
+ id="annotation-x1"
465
+ type="number"
466
+ value-key="annotation.x1"
467
+ .value=${String(currentAnnotation.x1 || 0)}
468
+ />
469
+
470
+ <label for="annotation-y1">Y1</label>
471
+ <input
472
+ id="annotation-y1"
473
+ type="number"
474
+ value-key="annotation.y1"
475
+ .value=${String(currentAnnotation.y1 || 0)}
476
+ />
477
+
478
+ <label for="annotation-x2">X2</label>
479
+ <input
480
+ id="annotation-x2"
481
+ type="number"
482
+ value-key="annotation.x2"
483
+ .value=${String(currentAnnotation.x2 || 0)}
484
+ />
485
+
486
+ <label for="annotation-y2">Y2</label>
487
+ <input
488
+ id="annotation-y2"
489
+ type="number"
490
+ value-key="annotation.y2"
491
+ .value=${String(currentAnnotation.y2 || 0)}
492
+ />
493
+
494
+ <label for="annotation-stroke"> <ox-i18n msgid="label.stroke-style">Stroke Style</ox-i18n> </label>
495
+ <ox-input-color
496
+ id="annotation-stroke"
497
+ value-key="annotation.stroke"
498
+ .value=${currentAnnotation.stroke}
499
+ ></ox-input-color>
500
+
501
+ <label for="annotation-stroke-thickness">
502
+ <ox-i18n msgid="label.stroke-thickness">Stroke Thickness</ox-i18n>
503
+ </label>
504
+ <input
505
+ id="annotation-stroke-thickness"
506
+ type="number"
507
+ value-key="annotation.strokeThickness"
508
+ .value=${String(currentAnnotation.strokeThickness || 1)}
509
+ />
510
+
511
+ <label for="annotation-fill"> <ox-i18n msgid="label.fill">Fill</ox-i18n> </label>
512
+ <ox-input-color
513
+ id="annotation-fill"
514
+ value-key="annotation.fill"
515
+ .value=${currentAnnotation.fill}
516
+ ></ox-input-color>
517
+
518
+ <label for="annotation-text"> <ox-i18n msgid="label.annotation-text">Text</ox-i18n> </label>
519
+ <input id="annotation-text" type="text" value-key="annotation.text" .value=${currentAnnotation.text || ''} />
520
+
521
+ <label for="annotation-horizontal-anchor">
522
+ <ox-i18n msgid="label.horizontal-anchor">Horizontal Anchor</ox-i18n>
523
+ </label>
524
+ <select
525
+ id="annotation-horizontal-anchor"
526
+ class="select-content"
527
+ value-key="annotation.horizontalAnchorPoint"
528
+ .value=${currentAnnotation.horizontalAnchorPoint || ''}
529
+ >
530
+ <option value="Left">Left</option>
531
+ <option value="Center">Center</option>
532
+ <option value="Right">Right</option>
533
+ </select>
534
+
535
+ <label for="annotation-vertical-anchor">
536
+ <ox-i18n msgid="label.vertical-anchor">Vertical Anchor</ox-i18n>
537
+ </label>
538
+ <select
539
+ id="annotation-vertical-anchor"
540
+ class="select-content"
541
+ value-key="annotation.verticalAnchorPoint"
542
+ .value=${currentAnnotation.verticalAnchorPoint || ''}
543
+ >
544
+ <option value="Top">Top</option>
545
+ <option value="Center">Center</option>
546
+ <option value="Bottom">Bottom</option>
547
+ </select>
548
+ </div>
549
+ </div>
550
+ `
551
+ }
552
+
553
+ multiSeriesTabTemplate() {
554
+ const configurer = this.configurer
555
+
556
+ return html`
557
+ <div id="series-properties-container" fullwidth>
558
+ <div id="series-tab-header">
559
+ <md-icon
560
+ id="series-tab-nav-left-button"
561
+ @tap=${(e: Event) => {
562
+ this._onTabScrollNavLeft(e, 'series')
563
+ }}
564
+ disabled
565
+ >chevron_left</md-icon
566
+ >
567
+ <div
568
+ id="series-tabs"
569
+ @change=${(e: Event) => {
570
+ configurer.currentSeriesIndex = (e.target as any).activeTabIndex
571
+ }}
572
+ active-tab-index=${configurer.currentSeriesIndex}
573
+ fit-container
574
+ >
575
+ ${configurer.datasets.map(
576
+ (dataset: any, index: number) => html`
577
+ <div
578
+ data-series=${index + 1}
579
+ data-tab-index=${index}
580
+ tab
581
+ ?selected=${index == configurer.currentSeriesIndex}
582
+ @click=${(e: Event) => {
583
+ const target = e.target as HTMLDivElement
584
+ this.configurer.setCurrentSeriesIndex(Number(target.getAttribute('data-tab-index')))
585
+ this.value = { ...this.configurer.value }
586
+ }}
587
+ >
588
+ ${index + 1}
589
+ ${!configurer.datasets || (configurer.datasets.length != 1 && configurer.currentSeriesIndex == index)
590
+ ? html` <md-icon @tap=${(e: Event) => this.onTapRemoveCurrentTab(index)}> close </md-icon> `
591
+ : html``}
592
+ </div>
593
+ `
594
+ )}
595
+ </div>
596
+ <md-icon
597
+ id="series-tab-nav-right-button"
598
+ @click=${(e: Event) => {
599
+ this._onTabScrollNavRight(e, 'series')
600
+ }}
601
+ disabled
602
+ >chevron_right</md-icon
603
+ >
604
+ </div>
605
+ <div id="add-series-button-container">
606
+ <md-icon id="add-series-button" @tap=${(e: Event) => this.onTapAddTab(e)}>add</md-icon>
607
+ </div>
608
+
609
+ <div class="tab-content">
610
+ <label for="data-key"> <ox-i18n msgid="label.data-key">Data Key</ox-i18n> </label>
611
+ <input id="data-key" type="text" value-key="dataKey" .value=${configurer.dataKey || ''} />
612
+
613
+ ${this.chartType == 'line' || this.chartType == 'bar'
614
+ ? html`
615
+ <label for="series-type"> <ox-i18n msgid="label.series-type">Type</ox-i18n> </label>
616
+ <select
617
+ id="series-type"
618
+ class="select-content"
619
+ value-key="series.type"
620
+ .value=${configurer.series.type || ''}
621
+ >
622
+ <option value="bar" selected>Bar</option>
623
+ <option value="line">Line</option>
624
+ </select>
625
+ `
626
+ : html``}
627
+
628
+ <label for="series-label"> <ox-i18n msgid="label.label">Label</ox-i18n> </label>
629
+ <input id="series-label" type="text" value-key="series.label" .value=${configurer.series.label || ''} />
630
+
631
+ ${configurer.series.type == 'line'
632
+ ? html`
633
+ <label for="series-line-tension"> <ox-i18n msgid="label.line-tension">Line Tension</ox-i18n> </label>
634
+ <select
635
+ id="series-line-tension"
636
+ class="select-content"
637
+ value-key="series.lineTension"
638
+ .value=${String(configurer.series.lineTension || 0)}
639
+ >
640
+ <option value="0.4">Smooth</option>
641
+ <option value="0">Angled</option>
642
+ </select>
643
+ `
644
+ : html``}
645
+ ${configurer.series.type == 'line'
646
+ ? html`
647
+ <label for="series-border-width"> <ox-i18n msgid="label.border-width">Border Width</ox-i18n> </label>
648
+ <input
649
+ id="series-border-width"
650
+ type="number"
651
+ value-key="series.borderWidth"
652
+ .value=${String(configurer.series.borderWidth || 0)}
653
+ />
654
+ `
655
+ : html``}
656
+
657
+ <label for="series-color"> <ox-i18n msgid="label.color">Color</ox-i18n> </label>
658
+ <ox-input-color id="series-color" value-key="color" .value=${configurer.color}></ox-input-color>
659
+
660
+ ${configurer.series.type == 'line'
661
+ ? html`
662
+ <label for="series-point-style"> <ox-i18n msgid="label.point-shape">Point Shape</ox-i18n> </label>
663
+ <select
664
+ id="series-point-style"
665
+ class="select-content"
666
+ value-key="series.pointStyle"
667
+ .value=${configurer.series.pointStyle || ''}
668
+ >
669
+ <option value="">&nbsp;</option>
670
+ <option value="circle">⚬</option>
671
+ <option value="triangle">▵</option>
672
+ <option value="rect">□</option>
673
+ <option value="rectRot">◇</option>
674
+ <option value="cross">+</option>
675
+ <option value="crossRot">⨉</option>
676
+ <option value="star">✱</option>
677
+ <option value="line">―</option>
678
+ <option value="dash">┄</option>
679
+ </select>
680
+
681
+ <label for="series-point-radius"> <ox-i18n msgid="label.point-size">Point Size</ox-i18n> </label>
682
+ <input
683
+ id="series-point-radius"
684
+ type="number"
685
+ value-key="series.pointRadius"
686
+ .value=${String(configurer.series.pointRadius || 0)}
687
+ />
688
+ `
689
+ : html``} <label for="series-stack"> <ox-i18n msgid="label.stack-group">Stack group</ox-i18n> </label>
690
+ <input id="series-stack" type="text" value-key="series.stack" .value=${configurer.series.stack || ''} />
691
+ ${configurer.series.type == 'line'
692
+ ? html`
693
+ <input id="seires-fill" type="checkbox" value-key="series.fill" ?checked=${configurer.series.fill} />
694
+ <label for="seires-fill"> <ox-i18n msgid="label.fill">Fill</ox-i18n> </label>
695
+ `
696
+ : html``}
697
+ ${configurer.multiAxis
698
+ ? html`
699
+ <label for="series-y-axis-id"> <ox-i18n msgid="label.target-axis">Target Axis</ox-i18n> </label>
700
+ <select
701
+ id="series-y-axis-id"
702
+ class="select-content"
703
+ value-key="series.yAxisID"
704
+ .value=${configurer.series.yAxisID || ''}
705
+ >
706
+ <option value="left">Left</option>
707
+ <option value="right">Right</option>
708
+ </select>
709
+ `
710
+ : html``}
711
+ ${this.displayValueTemplate()}
712
+ </div>
713
+ </div>
714
+ `
715
+ }
716
+
717
+ _onTabScroll(e: Event, type: 'series' | 'annotations') {
718
+ let tabContainer: HTMLElement | null | undefined
719
+ let tabNavLeftButton: MdIcon
720
+ let tabNavRightButton: MdIcon
721
+
722
+ if (type === 'series') {
723
+ tabContainer = this.seriesTabContainer
724
+ tabNavLeftButton = this.seriesTabNavLeftButton
725
+ tabNavRightButton = this.seriesTabNavRightButton
726
+ } else {
727
+ tabContainer = this.annotationsTabContainer
728
+ tabNavLeftButton = this.annotationsTabNavLeftButton
729
+ tabNavRightButton = this.annotationsTabNavRightButton
730
+ }
731
+
732
+ if (!tabContainer) {
733
+ return
734
+ }
735
+
736
+ if (tabContainer.clientWidth == tabContainer.scrollWidth) {
737
+ tabNavLeftButton.setAttribute('disabled', '')
738
+ tabNavRightButton.setAttribute('disabled', '')
739
+ }
740
+ // left-end
741
+ else if (tabContainer.scrollLeft == 0) {
742
+ tabNavLeftButton.setAttribute('disabled', '')
743
+ tabNavRightButton.removeAttribute('disabled')
744
+ }
745
+ // right-end
746
+ else if (tabContainer.scrollLeft + tabContainer.clientWidth >= tabContainer.scrollWidth) {
747
+ tabNavLeftButton.removeAttribute('disabled')
748
+ tabNavRightButton.setAttribute('disabled', '')
749
+ } else {
750
+ tabNavLeftButton.removeAttribute('disabled')
751
+ tabNavRightButton.removeAttribute('disabled')
752
+ }
753
+ }
754
+
755
+ _onTabScrollNavLeft(e: Event, type: 'series' | 'annotations') {
756
+ let tabContainer: HTMLElement | null | undefined
757
+
758
+ if (type === 'series') {
759
+ tabContainer = this.seriesTabContainer
760
+ } else {
761
+ tabContainer = this.annotationsTabContainer
762
+ }
763
+
764
+ if (!tabContainer) {
765
+ return
766
+ }
767
+
768
+ tabContainer.style.scrollBehavior = 'smooth'
769
+ tabContainer.scrollLeft -= tabContainer.clientWidth
770
+ tabContainer.style.scrollBehavior = 'auto'
771
+ }
772
+
773
+ _onTabScrollNavRight(e: Event, type: 'series' | 'annotations') {
774
+ let tabContainer: HTMLElement | null | undefined
775
+
776
+ if (type === 'series') {
777
+ tabContainer = this.seriesTabContainer
778
+ } else {
779
+ tabContainer = this.annotationsTabContainer
780
+ }
781
+
782
+ if (!tabContainer) {
783
+ return
784
+ }
785
+
786
+ tabContainer.style.scrollBehavior = 'smooth'
787
+ tabContainer.scrollLeft += tabContainer.clientWidth
788
+ tabContainer.style.scrollBehavior = 'auto'
789
+ }
333
790
  }
@@ -28,18 +28,21 @@ export const InputChartStyles = css`
28
28
  text-transform: capitalize;
29
29
  }
30
30
 
31
- #series-properties-container {
31
+ #series-properties-container,
32
+ #annotations-properties-container {
32
33
  display: grid;
33
34
  grid-template-columns: 1fr 25px;
34
35
  align-items: center;
35
36
  justify-content: center;
36
37
  }
37
38
 
38
- #series-properties-container > [tab-content] {
39
+ #series-properties-container > [tab-content],
40
+ #annotations-properties-container > [tab-content] {
39
41
  grid-column: span 2;
40
42
  }
41
43
 
42
- #tab-header {
44
+ #series-tab-header,
45
+ #annotations-tab-header {
43
46
  display: grid;
44
47
  grid-template-columns: 25px 1fr 25px;
45
48
  grid-gap: 5px;
@@ -53,20 +56,24 @@ export const InputChartStyles = css`
53
56
  align-items: center;
54
57
  }
55
58
 
56
- #tab-header > div {
59
+ #series-tab-header > div,
60
+ #annotations-tab-header > div {
57
61
  height: 25px;
58
62
  }
59
63
 
60
- #tab-header md-icon[disabled] {
64
+ #series-tab-header md-icon[disabled],
65
+ #annotations-tab-header md-icon[disabled] {
61
66
  opacity: 0.1;
62
67
  }
63
68
 
64
- #tabs {
69
+ #series-tabs,
70
+ #annotations-tabs {
65
71
  display: flex;
66
72
  overflow: hidden;
67
73
  }
68
74
 
69
- #tab-header #tabs [tab] md-icon {
75
+ #series-tab-header #series-tabs [tab] md-icon,
76
+ #annotations-tab-header #annotations-tabs [tab] md-icon {
70
77
  margin-left: auto;
71
78
  padding: 2px;
72
79
  color: var(--md-sys-color-on-surface);
@@ -74,7 +81,8 @@ export const InputChartStyles = css`
74
81
  --md-icon-size: 12px;
75
82
  }
76
83
 
77
- #add-series-button-container {
84
+ #add-series-button-container,
85
+ #add-annotation-button-container {
78
86
  height: 100%;
79
87
  box-sizing: border-box;
80
88
  align-items: center;
@@ -84,7 +92,8 @@ export const InputChartStyles = css`
84
92
  border-bottom: rgba(0, 0, 0, 0.2) 1px solid;
85
93
  }
86
94
 
87
- #add-series-button {
95
+ #add-series-button,
96
+ #add-annotation-button {
88
97
  width: 20px;
89
98
  height: 20px;
90
99
  padding: 0;
@@ -6,11 +6,11 @@ import { html } from 'lit'
6
6
  import { customElement } from 'lit/decorators.js'
7
7
  import { ifDefined } from 'lit/directives/if-defined.js'
8
8
 
9
- import { InputChartMultiSeriesAbstract } from './input-chart-multi-series-abstract'
9
+ import { InputChartAbstract } from './input-chart-abstract'
10
10
 
11
11
  @customElement('ox-input-chart-hbar')
12
- export class OxInputChartHBar extends InputChartMultiSeriesAbstract {
13
- static styles = [...InputChartMultiSeriesAbstract.styles]
12
+ export class OxInputChartHBar extends InputChartAbstract {
13
+ static styles = InputChartAbstract.styles
14
14
 
15
15
  subTemplate() {
16
16
  const configurer = this.configurer
@@ -149,17 +149,17 @@ export class OxInputChartHBar extends InputChartMultiSeriesAbstract {
149
149
 
150
150
  return html`
151
151
  <div id="series-properties-container" fullwidth>
152
- <div id="tab-header">
152
+ <div id="series-tab-header">
153
153
  <md-icon
154
- id="tab-nav-left-button"
154
+ id="series-tab-nav-left-button"
155
155
  @tap=${(e: Event) => {
156
- this._onTabScrollNavLeft(e)
156
+ this._onTabScrollNavLeft(e, 'series')
157
157
  }}
158
158
  disabled
159
159
  >chevron_left</md-icon
160
160
  >
161
161
  <div
162
- id="tabs"
162
+ id="series-tabs"
163
163
  @change=${(e: Event) => {
164
164
  configurer.currentSeriesIndex = (e.target as any).activeTabIndex
165
165
  }}
@@ -181,16 +181,16 @@ export class OxInputChartHBar extends InputChartMultiSeriesAbstract {
181
181
  >
182
182
  ${index + 1}
183
183
  ${!configurer.datasets || (configurer.datasets.length != 1 && configurer.currentSeriesIndex == index)
184
- ? html` <md-icon @tap="${(e: Event) => this.onTapRemoveCurrentTab(index)}"> close </md-icon> `
184
+ ? html` <md-icon @tap=${(e: Event) => this.onTapRemoveCurrentTab(index)}> close </md-icon> `
185
185
  : html``}
186
186
  </div>
187
187
  `
188
188
  )}
189
189
  </div>
190
190
  <md-icon
191
- id="tab-nav-right-button"
191
+ id="series-tab-nav-right-button"
192
192
  @click=${(e: Event) => {
193
- this._onTabScrollNavRight(e)
193
+ this._onTabScrollNavRight(e, 'series')
194
194
  }}
195
195
  disabled
196
196
  >chevron_right</md-icon
@@ -4,11 +4,11 @@ import { html } from 'lit'
4
4
  import { customElement } from 'lit/decorators.js'
5
5
  import { ifDefined } from 'lit/directives/if-defined.js'
6
6
 
7
- import { InputChartMultiSeriesAbstract } from './input-chart-multi-series-abstract'
7
+ import { InputChartAbstract } from './input-chart-abstract'
8
8
 
9
9
  @customElement('ox-input-chart-mixed')
10
- export class OxInputChartMixed extends InputChartMultiSeriesAbstract {
11
- static styles = InputChartMultiSeriesAbstract.styles
10
+ export class OxInputChartMixed extends InputChartAbstract {
11
+ static styles = InputChartAbstract.styles
12
12
 
13
13
  subTemplate() {
14
14
  const configurer = this.configurer
@@ -4,11 +4,11 @@ import { html } from 'lit'
4
4
  import { customElement } from 'lit/decorators.js'
5
5
  import { ifDefined } from 'lit/directives/if-defined.js'
6
6
 
7
- import { InputChartMultiSeriesAbstract } from './input-chart-multi-series-abstract'
7
+ import { InputChartAbstract } from './input-chart-abstract'
8
8
 
9
9
  @customElement('ox-input-chart-radar')
10
- export default class OxInputChartRadar extends InputChartMultiSeriesAbstract {
11
- static styles = InputChartMultiSeriesAbstract.styles
10
+ export default class OxInputChartRadar extends InputChartAbstract {
11
+ static styles = InputChartAbstract.styles
12
12
 
13
13
  subTemplate() {
14
14
  const configurer = this.configurer
@@ -4,11 +4,11 @@ import { html } from 'lit'
4
4
  import { customElement } from 'lit/decorators.js'
5
5
  import { ifDefined } from 'lit/directives/if-defined.js'
6
6
 
7
- import { InputChartMultiSeriesAbstract } from './input-chart-multi-series-abstract'
7
+ import { InputChartAbstract } from './input-chart-abstract'
8
8
 
9
9
  @customElement('ox-input-chart-timeseries')
10
- export class OxInputChartTimeseries extends InputChartMultiSeriesAbstract {
11
- static styles = InputChartMultiSeriesAbstract.styles
10
+ export class OxInputChartTimeseries extends InputChartAbstract {
11
+ static styles = InputChartAbstract.styles
12
12
 
13
13
  subTemplate() {
14
14
  const configurer = this.configurer
@@ -18,9 +18,11 @@ export class OxInputChartTimeseries extends InputChartMultiSeriesAbstract {
18
18
  <label for="multi-axis"> <ox-i18n msgid="label.multi-axis">Multi Axis</ox-i18n> </label>
19
19
 
20
20
  <legend><ox-i18n msgid="label.series">Series</ox-i18n></legend>
21
-
22
21
  <div fullwidth>${this.multiSeriesTabTemplate()}</div>
23
22
 
23
+ <legend><ox-i18n msgid="label.chart-annotation">Annotations</ox-i18n></legend>
24
+ <div fullwidth>${this.annotationsTabTemplate()}</div>
25
+
24
26
  <legend><ox-i18n msgid="label.x-axes">X Axes</ox-i18n></legend>
25
27
 
26
28
  <label for="series-data-key"> <ox-i18n msgid="label.data-key">Data Key</ox-i18n> </label>