@tetacom/ng-components 1.0.27 → 1.0.28

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 (110) hide show
  1. package/component/filter/filter.module.d.ts +2 -1
  2. package/component/public-api.d.ts +0 -1
  3. package/directive/hint/hint.directive.d.ts +1 -0
  4. package/esm2020/component/filter/filter.module.mjs +6 -2
  5. package/esm2020/component/filter/numeric-filter/numeric-filter.component.mjs +4 -3
  6. package/esm2020/component/message/message.service.mjs +3 -3
  7. package/esm2020/component/public-api.mjs +1 -3
  8. package/esm2020/directive/click-outside/click-outside.directive.mjs +1 -3
  9. package/esm2020/directive/hint/hint.directive.mjs +4 -1
  10. package/esm2020/directive/only-number/only-number.directive.mjs +3 -2
  11. package/esm2020/pipe/public-api.mjs +2 -1
  12. package/esm2020/util/date-util.mjs +8 -5
  13. package/fesm2015/tetacom-ng-components.mjs +45 -2309
  14. package/fesm2015/tetacom-ng-components.mjs.map +1 -1
  15. package/fesm2020/tetacom-ng-components.mjs +45 -2303
  16. package/fesm2020/tetacom-ng-components.mjs.map +1 -1
  17. package/package.json +1 -1
  18. package/pipe/public-api.d.ts +1 -0
  19. package/component/chart/chart/chart.component.d.ts +0 -39
  20. package/component/chart/chart.module.d.ts +0 -8
  21. package/component/chart/core/axis-creator.d.ts +0 -29
  22. package/component/chart/core/chart.d.ts +0 -70
  23. package/component/chart/core/public-api.d.ts +0 -2
  24. package/component/chart/drawer/area-drawer.d.ts +0 -7
  25. package/component/chart/drawer/bar-drawer.d.ts +0 -8
  26. package/component/chart/drawer/contour-drawer.d.ts +0 -7
  27. package/component/chart/drawer/default-drawer-mapping.d.ts +0 -4
  28. package/component/chart/drawer/line-drawer.d.ts +0 -11
  29. package/component/chart/drawer/pie-drawer.d.ts +0 -7
  30. package/component/chart/drawer/public-api.d.ts +0 -6
  31. package/component/chart/drawer/scatter-drawer.d.ts +0 -15
  32. package/component/chart/drawer/spline-drawer.d.ts +0 -7
  33. package/component/chart/legend-drawer/default-drawer-legend-mapping.d.ts +0 -3
  34. package/component/chart/legend-drawer/gradient-drawer.d.ts +0 -5
  35. package/component/chart/legend-drawer/swatch-drawer.d.ts +0 -6
  36. package/component/chart/model/annotation.d.ts +0 -59
  37. package/component/chart/model/axis-options.d.ts +0 -43
  38. package/component/chart/model/chart-bounds.d.ts +0 -12
  39. package/component/chart/model/chart-options.d.ts +0 -51
  40. package/component/chart/model/enum/axis-type.d.ts +0 -4
  41. package/component/chart/model/enum/dispatch-type.d.ts +0 -4
  42. package/component/chart/model/enum/drag-point-type.d.ts +0 -5
  43. package/component/chart/model/enum/legend-type.d.ts +0 -4
  44. package/component/chart/model/enum/public-api.d.ts +0 -7
  45. package/component/chart/model/enum/scale-type.d.ts +0 -7
  46. package/component/chart/model/enum/scale.d.ts +0 -5
  47. package/component/chart/model/enum/series-type.d.ts +0 -10
  48. package/component/chart/model/enum/zoom-type.d.ts +0 -5
  49. package/component/chart/model/i-drag-event.d.ts +0 -5
  50. package/component/chart/model/i-drawer-legend.d.ts +0 -12
  51. package/component/chart/model/i-drawer.d.ts +0 -9
  52. package/component/chart/model/i-zoom-event.d.ts +0 -8
  53. package/component/chart/model/plot-band.d.ts +0 -28
  54. package/component/chart/model/plot-line.d.ts +0 -20
  55. package/component/chart/model/point/bar-point.d.ts +0 -6
  56. package/component/chart/model/point/base-point.d.ts +0 -9
  57. package/component/chart/model/point/contour-point.d.ts +0 -4
  58. package/component/chart/model/point/marker-options.d.ts +0 -11
  59. package/component/chart/model/point/public-api.d.ts +0 -3
  60. package/component/chart/model/point/scatter-point.d.ts +0 -5
  61. package/component/chart/model/public-api.d.ts +0 -15
  62. package/component/chart/model/series.d.ts +0 -62
  63. package/component/chart/model/tooltip-options.d.ts +0 -14
  64. package/component/chart/public-api.d.ts +0 -5
  65. package/esm2020/component/chart/chart/chart.component.mjs +0 -164
  66. package/esm2020/component/chart/chart.module.mjs +0 -18
  67. package/esm2020/component/chart/core/axis-creator.mjs +0 -82
  68. package/esm2020/component/chart/core/chart.mjs +0 -1339
  69. package/esm2020/component/chart/core/public-api.mjs +0 -3
  70. package/esm2020/component/chart/drawer/area-drawer.mjs +0 -20
  71. package/esm2020/component/chart/drawer/bar-drawer.mjs +0 -23
  72. package/esm2020/component/chart/drawer/contour-drawer.mjs +0 -29
  73. package/esm2020/component/chart/drawer/default-drawer-mapping.mjs +0 -17
  74. package/esm2020/component/chart/drawer/line-drawer.mjs +0 -152
  75. package/esm2020/component/chart/drawer/pie-drawer.mjs +0 -4
  76. package/esm2020/component/chart/drawer/public-api.mjs +0 -7
  77. package/esm2020/component/chart/drawer/scatter-drawer.mjs +0 -93
  78. package/esm2020/component/chart/drawer/spline-drawer.mjs +0 -23
  79. package/esm2020/component/chart/legend-drawer/default-drawer-legend-mapping.mjs +0 -7
  80. package/esm2020/component/chart/legend-drawer/gradient-drawer.mjs +0 -45
  81. package/esm2020/component/chart/legend-drawer/swatch-drawer.mjs +0 -62
  82. package/esm2020/component/chart/model/annotation.mjs +0 -30
  83. package/esm2020/component/chart/model/axis-options.mjs +0 -26
  84. package/esm2020/component/chart/model/chart-bounds.mjs +0 -13
  85. package/esm2020/component/chart/model/chart-options.mjs +0 -37
  86. package/esm2020/component/chart/model/enum/axis-type.mjs +0 -6
  87. package/esm2020/component/chart/model/enum/dispatch-type.mjs +0 -6
  88. package/esm2020/component/chart/model/enum/drag-point-type.mjs +0 -7
  89. package/esm2020/component/chart/model/enum/legend-type.mjs +0 -6
  90. package/esm2020/component/chart/model/enum/public-api.mjs +0 -8
  91. package/esm2020/component/chart/model/enum/scale-type.mjs +0 -9
  92. package/esm2020/component/chart/model/enum/scale.mjs +0 -7
  93. package/esm2020/component/chart/model/enum/series-type.mjs +0 -12
  94. package/esm2020/component/chart/model/enum/zoom-type.mjs +0 -7
  95. package/esm2020/component/chart/model/i-drag-event.mjs +0 -2
  96. package/esm2020/component/chart/model/i-drawer-legend.mjs +0 -2
  97. package/esm2020/component/chart/model/i-drawer.mjs +0 -2
  98. package/esm2020/component/chart/model/i-zoom-event.mjs +0 -2
  99. package/esm2020/component/chart/model/plot-band.mjs +0 -18
  100. package/esm2020/component/chart/model/plot-line.mjs +0 -13
  101. package/esm2020/component/chart/model/point/bar-point.mjs +0 -2
  102. package/esm2020/component/chart/model/point/base-point.mjs +0 -2
  103. package/esm2020/component/chart/model/point/contour-point.mjs +0 -2
  104. package/esm2020/component/chart/model/point/marker-options.mjs +0 -2
  105. package/esm2020/component/chart/model/point/public-api.mjs +0 -4
  106. package/esm2020/component/chart/model/point/scatter-point.mjs +0 -2
  107. package/esm2020/component/chart/model/public-api.mjs +0 -16
  108. package/esm2020/component/chart/model/series.mjs +0 -27
  109. package/esm2020/component/chart/model/tooltip-options.mjs +0 -19
  110. package/esm2020/component/chart/public-api.mjs +0 -6
@@ -16,13 +16,9 @@ import { TranslocoModule, TRANSLOCO_SCOPE } from '@ngneat/transloco';
16
16
  import * as hash from 'object-hash';
17
17
  import hash__default from 'object-hash';
18
18
  import { SizeStrategy, Datasource, UiScrollModule } from 'ngx-ui-scroll';
19
- import * as d3 from 'd3';
20
- import { zoomIdentity } from 'd3';
21
- import * as d3annotation from 'd3-svg-annotation';
22
- import { annotationBadge, annotationLabel, annotationCallout, annotationCalloutCircle, annotationCalloutCurve, annotationCalloutElbow, annotationCalloutRect, annotationCustomType, annotationXYThreshold } from 'd3-svg-annotation';
23
- import { tricontour } from 'd3-tricontour';
24
19
  import * as THREE from 'three';
25
20
  import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
21
+ import * as d3 from 'd3';
26
22
  import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
27
23
 
28
24
  class AccordionComponent {
@@ -530,6 +526,31 @@ var DatePickerMode;
530
526
  DatePickerMode[DatePickerMode["year"] = 2] = "year";
531
527
  })(DatePickerMode || (DatePickerMode = {}));
532
528
 
529
+ const getPrecision = (a) => {
530
+ if (!isFinite(a)) {
531
+ return 0;
532
+ }
533
+ let e = 1;
534
+ let p = 0;
535
+ while (Math.round(a * e) / e !== a) {
536
+ e *= 10;
537
+ p++;
538
+ }
539
+ return p;
540
+ };
541
+ const formatNumber = (value, decimalLength, chunkDelimiter, decimalDelimiter, chunkLength) => {
542
+ const abs = Math.abs(value);
543
+ if (0 < abs && 1 > abs) {
544
+ const firstDigitIndex = Math.floor(Math.abs(Math.log10(abs)));
545
+ decimalLength += firstDigitIndex;
546
+ }
547
+ const precision = Math.min(getPrecision(value), Math.floor(decimalLength));
548
+ const result = '\\d(?=(\\d{' + chunkLength + '})+' + (precision > 0 ? '\\D' : '$') + ')';
549
+ const num = value.toFixed(precision);
550
+ return (decimalDelimiter ? num.replace('.', decimalDelimiter) : num).replace(new RegExp(result, 'g'), '$&' + chunkDelimiter);
551
+ };
552
+ const prependZero = (input, length) => ('0'.repeat(length) + input).slice(-length);
553
+
533
554
  class DateUtil {
534
555
  /**
535
556
  * Вычесть n-дней
@@ -577,10 +598,12 @@ class DateUtil {
577
598
  return '';
578
599
  }
579
600
  const month = dat.getMonth() + 1;
580
- const monthString = month < 10 ? '0' + month.toString() : month.toString();
581
- return `${dat.getDate().toString()}.${monthString}.${dat
582
- .getFullYear()
583
- .toString()} ${dat.getHours()}:${dat.getMinutes()}:${dat.getSeconds()}`;
601
+ return `${prependZero(dat.getDate(), 2)}.
602
+ ${prependZero(month, 2)}.
603
+ ${dat.getFullYear()}
604
+ ${prependZero(dat.getHours(), 2)}:
605
+ ${prependZero(dat.getMinutes(), 2)}:
606
+ ${prependZero(dat.getSeconds(), 2)}`;
584
607
  }
585
608
  /**
586
609
  * Подготовка даты к отправке на сервер, чтобы небыло смещения часов
@@ -1510,31 +1533,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.1", ngImpor
1510
1533
  type: Output
1511
1534
  }] } });
1512
1535
 
1513
- const getPrecision = (a) => {
1514
- if (!isFinite(a)) {
1515
- return 0;
1516
- }
1517
- let e = 1;
1518
- let p = 0;
1519
- while (Math.round(a * e) / e !== a) {
1520
- e *= 10;
1521
- p++;
1522
- }
1523
- return p;
1524
- };
1525
- const formatNumber = (value, decimalLength, chunkDelimiter, decimalDelimiter, chunkLength) => {
1526
- const abs = Math.abs(value);
1527
- if (0 < abs && 1 > abs) {
1528
- const firstDigitIndex = Math.floor(Math.abs(Math.log10(abs)));
1529
- decimalLength += firstDigitIndex;
1530
- }
1531
- const precision = Math.min(getPrecision(value), Math.floor(decimalLength));
1532
- const result = '\\d(?=(\\d{' + chunkLength + '})+' + (precision > 0 ? '\\D' : '$') + ')';
1533
- const num = value.toFixed(precision);
1534
- return (decimalDelimiter ? num.replace('.', decimalDelimiter) : num).replace(new RegExp(result, 'g'), '$&' + chunkDelimiter);
1535
- };
1536
- const prependZero = (input, length) => ('0'.repeat(length) + input).slice(-length);
1537
-
1538
1536
  class PrependZeroPipe {
1539
1537
  transform(value, length) {
1540
1538
  if (value === null || value === undefined) {
@@ -2491,7 +2489,6 @@ class ClickOutsideDirective {
2491
2489
  }
2492
2490
  const clickedInside = DomUtil.clickedInside(this._elementRef.nativeElement, click);
2493
2491
  if (!clickedInside) {
2494
- console.log('clickedInside', clickedInside);
2495
2492
  this.clickOutside.emit(click);
2496
2493
  }
2497
2494
  };
@@ -2517,7 +2514,6 @@ class ClickOutsideDirective {
2517
2514
  }
2518
2515
  addListener(handleRightClick) {
2519
2516
  window.addEventListener('click', this.listener);
2520
- console.log('handleRightClick', handleRightClick);
2521
2517
  if (handleRightClick) {
2522
2518
  window.addEventListener('contextmenu', this.listener);
2523
2519
  }
@@ -2653,7 +2649,8 @@ class OnlyNumberDirective {
2653
2649
  }
2654
2650
  else {
2655
2651
  if (e.key === ',' && originalValue.indexOf('.') < 0) {
2656
- this._elementRef.nativeElement.value = originalValue + '.';
2652
+ this._elementRef.nativeElement.value =
2653
+ `${originalValue.slice(0, cursorPosition)}.${originalValue.slice(cursorPosition)}`;
2657
2654
  }
2658
2655
  e.preventDefault();
2659
2656
  }
@@ -3459,10 +3456,10 @@ class NumericFilterComponent extends FilterComponentBase {
3459
3456
  }
3460
3457
  }
3461
3458
  NumericFilterComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: NumericFilterComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3462
- NumericFilterComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.0.1", type: NumericFilterComponent, selector: "teta-numeric-filter", inputs: { column: "column", filterOptions: "filterOptions", state: "state" }, outputs: { filterChanged: "filterChanged" }, usesInheritance: true, ngImport: i0, template: "<div class=\"form-row padding-3\">\n <teta-input [label]=\"'\u041E\u0442'\">\n <input class=\"input\" type=\"text\"\n style=\"width: 110px\"\n [ngModel]=\"filter.value?.greaterThan\"\n (ngModelChange)=\"filter.value.greaterThan=$event\"/>\n </teta-input>\n <teta-input [label]=\"'\u0414\u043E'\">\n <input class=\"input\" type=\"text\"\n style=\"width: 110px\"\n [ngModel]=\"filter.value?.lessThan\"\n (ngModelChange)=\"filter.value.lessThan=$event\"/>\n </teta-input>\n</div>\n", styles: [""], components: [{ type: InputComponent, selector: "teta-input", inputs: ["label", "horizontal", "required"] }], directives: [{ type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3459
+ NumericFilterComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.0.1", type: NumericFilterComponent, selector: "teta-numeric-filter", inputs: { column: "column", filterOptions: "filterOptions", state: "state" }, outputs: { filterChanged: "filterChanged" }, usesInheritance: true, ngImport: i0, template: "<div class=\"form-row padding-3\">\n <teta-input [label]=\"'\u041E\u0442'\">\n <input class=\"input\" type=\"text\"\n style=\"width: 110px\"\n [tetaOnlyNumber]=\"true\"\n [ngModel]=\"filter.value?.greaterThan\"\n (ngModelChange)=\"filter.value.greaterThan=$event\"/>\n </teta-input>\n <teta-input [label]=\"'\u0414\u043E'\">\n <input class=\"input\" type=\"text\"\n style=\"width: 110px\"\n [tetaOnlyNumber]=\"true\"\n [ngModel]=\"filter.value?.lessThan\"\n (ngModelChange)=\"filter.value.lessThan=$event\"/>\n </teta-input>\n</div>\n", styles: [""], components: [{ type: InputComponent, selector: "teta-input", inputs: ["label", "horizontal", "required"] }], directives: [{ type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: OnlyNumberDirective, selector: "[tetaOnlyNumber]", inputs: ["tetaOnlyNumber", "allowDecimals", "allowSign", "decimalSeparator", "commaSeparator"] }, { type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3463
3460
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: NumericFilterComponent, decorators: [{
3464
3461
  type: Component,
3465
- args: [{ selector: 'teta-numeric-filter', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"form-row padding-3\">\n <teta-input [label]=\"'\u041E\u0442'\">\n <input class=\"input\" type=\"text\"\n style=\"width: 110px\"\n [ngModel]=\"filter.value?.greaterThan\"\n (ngModelChange)=\"filter.value.greaterThan=$event\"/>\n </teta-input>\n <teta-input [label]=\"'\u0414\u043E'\">\n <input class=\"input\" type=\"text\"\n style=\"width: 110px\"\n [ngModel]=\"filter.value?.lessThan\"\n (ngModelChange)=\"filter.value.lessThan=$event\"/>\n </teta-input>\n</div>\n", styles: [""] }]
3462
+ args: [{ selector: 'teta-numeric-filter', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"form-row padding-3\">\n <teta-input [label]=\"'\u041E\u0442'\">\n <input class=\"input\" type=\"text\"\n style=\"width: 110px\"\n [tetaOnlyNumber]=\"true\"\n [ngModel]=\"filter.value?.greaterThan\"\n (ngModelChange)=\"filter.value.greaterThan=$event\"/>\n </teta-input>\n <teta-input [label]=\"'\u0414\u043E'\">\n <input class=\"input\" type=\"text\"\n style=\"width: 110px\"\n [tetaOnlyNumber]=\"true\"\n [ngModel]=\"filter.value?.lessThan\"\n (ngModelChange)=\"filter.value.lessThan=$event\"/>\n </teta-input>\n</div>\n", styles: [""] }]
3466
3463
  }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { column: [{
3467
3464
  type: Input
3468
3465
  }], filterOptions: [{
@@ -4669,7 +4666,8 @@ FilterModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "
4669
4666
  DatePickerModule,
4670
4667
  RadioModule,
4671
4668
  InputModule,
4672
- CheckboxModule], exports: [FilterPanelComponent,
4669
+ CheckboxModule,
4670
+ OnlyNumberModule], exports: [FilterPanelComponent,
4673
4671
  NumericFilterComponent,
4674
4672
  StringFilterComponent,
4675
4673
  ListFilterComponent,
@@ -4684,6 +4682,7 @@ FilterModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "
4684
4682
  RadioModule,
4685
4683
  InputModule,
4686
4684
  CheckboxModule,
4685
+ OnlyNumberModule,
4687
4686
  ]] });
4688
4687
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: FilterModule, decorators: [{
4689
4688
  type: NgModule,
@@ -4714,6 +4713,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.1", ngImpor
4714
4713
  RadioModule,
4715
4714
  InputModule,
4716
4715
  CheckboxModule,
4716
+ OnlyNumberModule,
4717
4717
  ],
4718
4718
  }]
4719
4719
  }] });
@@ -4900,7 +4900,7 @@ class FilterState {
4900
4900
 
4901
4901
  class MessageService {
4902
4902
  constructor() {
4903
- this._message = new Subject();
4903
+ this._message = new ReplaySubject(1);
4904
4904
  this._clear = new Subject();
4905
4905
  this.message = this._message.asObservable();
4906
4906
  this.clear = this._clear.asObservable();
@@ -6138,6 +6138,9 @@ class HintDirective extends DynamicContentBaseDirective {
6138
6138
  'hint',
6139
6139
  ];
6140
6140
  }
6141
+ ngOnDestroy() {
6142
+ super.ngOnDestroy();
6143
+ }
6141
6144
  }
6142
6145
  HintDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: HintDirective, deps: [{ token: DOCUMENT }, { token: i0.ElementRef }, { token: DynamicComponentService }, { token: i0.Injector }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
6143
6146
  HintDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.0.1", type: HintDirective, selector: "[tetaHint]", inputs: { tetaHint: "tetaHint", align: "align", verticalAlign: "verticalAlign", delay: "delay" }, host: { listeners: { "mouseenter": "mouseenter($event)", "mouseleave": "mouseleave($event)", "click": "click($event)" } }, usesInheritance: true, ngImport: i0 });
@@ -9956,2267 +9959,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.1", ngImpor
9956
9959
  }]
9957
9960
  }] });
9958
9961
 
9959
- var Scale;
9960
- (function (Scale) {
9961
- Scale["time"] = "time";
9962
- Scale["number"] = "number";
9963
- Scale["category"] = "category";
9964
- })(Scale || (Scale = {}));
9965
-
9966
- var SeriesType;
9967
- (function (SeriesType) {
9968
- SeriesType[SeriesType["area"] = 0] = "area";
9969
- SeriesType[SeriesType["bar"] = 1] = "bar";
9970
- SeriesType[SeriesType["line"] = 2] = "line";
9971
- SeriesType[SeriesType["pie"] = 3] = "pie";
9972
- SeriesType[SeriesType["scatter"] = 4] = "scatter";
9973
- SeriesType[SeriesType["spline"] = 5] = "spline";
9974
- SeriesType[SeriesType["contour"] = 6] = "contour";
9975
- SeriesType[SeriesType["custom"] = 7] = "custom";
9976
- })(SeriesType || (SeriesType = {}));
9977
-
9978
- class AreaDrawer {
9979
- draw(series, context, scaleX, scaleY) {
9980
- const points = series.data;
9981
- const path = d3
9982
- .area()
9983
- .x1((d) => (d.x1 != null ? scaleX(d.x1) : scaleX(0)))
9984
- .x0((d) => scaleX(d.x))
9985
- .y((d) => scaleY(d.y));
9986
- context
9987
- .append('path')
9988
- .attr('transform', `translate(${0}, 0)`)
9989
- .attr('fill', series.color)
9990
- .attr('stroke', series.color)
9991
- .attr('stroke-width', series.strokeWidth ? series.strokeWidth : 1)
9992
- .datum(points)
9993
- .attr('d', path);
9994
- }
9995
- }
9996
-
9997
- class BarDrawer {
9998
- draw(series, context, scaleX, scaleY) {
9999
- const points = series.data.filter((_) => _.visible);
10000
- const barScale = d3
10001
- .scaleBand()
10002
- .domain(d3.range(points.length))
10003
- .range(scaleX.range())
10004
- .paddingInner(0.2)
10005
- .paddingOuter(0.2);
10006
- const u = context.selectAll('rect').data(points);
10007
- u.enter()
10008
- .append('rect')
10009
- .merge(u)
10010
- .attr('x', (d, i) => barScale(i))
10011
- .attr('y', (d) => scaleY(d.y))
10012
- .attr('width', barScale.bandwidth())
10013
- .attr('height', (d) => Math.abs(scaleY(0) - scaleY(d.y)))
10014
- .attr('fill', (d) => d.color);
10015
- u.exit().remove();
10016
- }
10017
- }
10018
-
10019
- var DispatchType;
10020
- (function (DispatchType) {
10021
- DispatchType["moveLine"] = "moveLine";
10022
- DispatchType["movePoint"] = "movePoint";
10023
- })(DispatchType || (DispatchType = {}));
10024
-
10025
- var DragPointType;
10026
- (function (DragPointType) {
10027
- DragPointType[DragPointType["x"] = 0] = "x";
10028
- DragPointType[DragPointType["y"] = 1] = "y";
10029
- DragPointType[DragPointType["xy"] = 2] = "xy";
10030
- })(DragPointType || (DragPointType = {}));
10031
-
10032
- class LineDrawer {
10033
- constructor() {
10034
- this.dispatch = d3.dispatch(DispatchType.moveLine, DispatchType.movePoint);
10035
- }
10036
- draw(series, context, scaleX, scaleY, options) {
10037
- const points = series.data;
10038
- const markerPoints = points.filter((_) => _.marker);
10039
- const path = d3
10040
- .line()
10041
- .curve(series.curveType)
10042
- .defined((d) => d.x != null && d.y != null)
10043
- .x((d) => scaleX(d.x))
10044
- .y((d) => scaleY(d.y));
10045
- const seriesIndex = options.series.findIndex((_) => _.id === series.id);
10046
- context
10047
- .append('path')
10048
- .attr('class', (d) => series?.drag.enable ? 'draggable' : `series-${seriesIndex}`)
10049
- .attr('data-draggable-id', seriesIndex)
10050
- .attr('fill', 'none')
10051
- .attr('stroke', series.color)
10052
- .attr('stroke-dasharray', series?.strokeDasharray)
10053
- .attr('stroke-width', series.strokeWidth ? series.strokeWidth : 1)
10054
- .style('cursor', series?.drag?.enable ? 'move' : 'default')
10055
- .datum(points)
10056
- .attr('d', path);
10057
- const u = context.append('g').attr('class', 'grabbers');
10058
- const emit = (event, target) => {
10059
- this.dispatch.apply(DispatchType.moveLine, {
10060
- target,
10061
- event,
10062
- });
10063
- };
10064
- if (series.drag.enable) {
10065
- u.selectAll('circle')
10066
- .data(points)
10067
- .enter()
10068
- .append('circle')
10069
- .attr('data-grabber-id', seriesIndex)
10070
- .attr('stroke', series?.drag?.grabbers?.stroke ?? series?.color)
10071
- .attr('stroke-width', series?.drag?.grabbers?.strokeWidth ?? 1)
10072
- .attr('fill', series?.drag?.grabbers?.fill ?? series?.color)
10073
- .attr('r', series?.drag?.grabbers?.radius ?? 4)
10074
- .attr('cx', function (d) {
10075
- return scaleX(d.x);
10076
- })
10077
- .attr('cy', function (d) {
10078
- return scaleY(d.y);
10079
- })
10080
- .style('cursor', 'move')
10081
- .call(d3.drag().on('start drag end', function (event, d) {
10082
- d.x = scaleX.invert(event.sourceEvent?.offsetX);
10083
- d.y = scaleY.invert(event.sourceEvent?.offsetY);
10084
- d3.select(this).attr('cx', scaleX(d.x)).attr('cy', scaleY(d.y));
10085
- context
10086
- .select(`[data-draggable-id='${seriesIndex}']`)
10087
- .attr('d', path);
10088
- emit(event, series);
10089
- if (series?.drag?.extendLine) {
10090
- drawExtendedLine();
10091
- }
10092
- }));
10093
- u.exit().remove();
10094
- }
10095
- const drawExtendedLine = () => {
10096
- context.selectAll(`[data-extended-id='${seriesIndex}']`).remove();
10097
- const p1 = points[0];
10098
- const p2 = points[points.length - 1];
10099
- const distance = Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p2.y, 2));
10100
- if (distance <= 0) {
10101
- return;
10102
- }
10103
- const extendLength = 50;
10104
- const extendedEndX = p2.x + ((p2.x - p1.x) / distance) * extendLength;
10105
- const extendedEndY = p2.y + ((p2.y - p1.y) / distance) * extendLength;
10106
- const extendedStartX = p1.x - ((p2.x - p1.x) / distance) * extendLength;
10107
- const extendedStartY = p1.y - ((p2.y - p1.y) / distance) * extendLength;
10108
- context
10109
- .append('line')
10110
- .attr('class', 'extendedLine')
10111
- .attr('data-extended-id', seriesIndex)
10112
- .attr('stroke', series?.color)
10113
- .attr('stroke-width', series?.strokeWidth)
10114
- .attr('stroke-dasharray', series?.strokeDasharray)
10115
- .attr('x1', scaleX(p1.x))
10116
- .attr('y1', scaleY(p1.y))
10117
- .attr('x2', scaleX(extendedStartX))
10118
- .attr('y2', scaleY(extendedStartY));
10119
- context
10120
- .append('line')
10121
- .attr('class', 'extendedLine')
10122
- .attr('data-extended-id', seriesIndex)
10123
- .attr('stroke', series?.color)
10124
- .attr('stroke-width', series?.strokeWidth)
10125
- .attr('stroke-dasharray', series?.strokeDasharray)
10126
- .attr('x1', scaleX(p2.x))
10127
- .attr('y1', scaleY(p2.y))
10128
- .attr('x2', scaleX(extendedEndX))
10129
- .attr('y2', scaleY(extendedEndY));
10130
- };
10131
- if (series?.drag?.extendLine && points?.length) {
10132
- drawExtendedLine();
10133
- }
10134
- if (markerPoints?.length) {
10135
- const emit = (event, target) => {
10136
- this.dispatch.apply(DispatchType.movePoint, {
10137
- target: series,
10138
- point: {
10139
- ...target,
10140
- },
10141
- event,
10142
- });
10143
- };
10144
- context
10145
- .selectAll(`draggable-marker-${seriesIndex}`)
10146
- .data(markerPoints)
10147
- .enter()
10148
- .append('circle')
10149
- .attr('class', `draggable-marker-${seriesIndex}`)
10150
- .attr('r', (d) => d.marker?.style?.radius || 5)
10151
- .attr('cx', function (d) {
10152
- return scaleX(d.x);
10153
- })
10154
- .attr('cy', function (d) {
10155
- return scaleY(d.y);
10156
- })
10157
- .style('cursor', 'pointer')
10158
- .style('fill', (d) => d.marker?.style?.color || 'none')
10159
- .attr('stroke', (d) => d.marker?.style?.stroke || 'none')
10160
- .attr('stroke-width', (d) => d.marker?.style?.strokeWidth || 0);
10161
- context.selectAll(`.draggable-marker-${seriesIndex}`).call(d3.drag().on('drag start end', function dragged(event, d) {
10162
- const node = d3.select(this);
10163
- if (event.type === 'start') {
10164
- node.raise().classed('active', true);
10165
- }
10166
- if (d.marker?.dragType === DragPointType.x) {
10167
- d.x = scaleX.invert(event.sourceEvent?.offsetX);
10168
- node.attr('cx', scaleX(d.x));
10169
- }
10170
- if (d.marker?.dragType === DragPointType.y) {
10171
- d.y = scaleY.invert(event.sourceEvent?.offsetY);
10172
- node.attr('cy', scaleY(d.y));
10173
- }
10174
- context.select(`.series-${seriesIndex}`).attr('d', path);
10175
- emit(event, d);
10176
- }));
10177
- }
10178
- }
10179
- }
10180
-
10181
- class PieDrawer {
10182
- draw(series, context, scaleX, scaleY) { }
10183
- }
10184
-
10185
- class SplineDrawer {
10186
- draw(series, context, scaleX, scaleY) {
10187
- const points = series.data;
10188
- const path = d3
10189
- .line()
10190
- .curve(d3.curveCatmullRom)
10191
- .defined((d) => d.x != null && d.y != null)
10192
- .x((d) => scaleX(d.x))
10193
- .y((d) => scaleY(d.y));
10194
- context
10195
- .append('path')
10196
- .attr('transform', `translate(${0}, 0)`)
10197
- .attr('fill', 'none')
10198
- .attr('stroke', series.color)
10199
- .attr('stroke-width', series.strokeWidth ? series.strokeWidth : 1)
10200
- .datum(points)
10201
- .attr('d', path)
10202
- .transition()
10203
- .duration(750);
10204
- }
10205
- }
10206
-
10207
- class ScatterDrawer {
10208
- constructor() {
10209
- this._colorToData = {};
10210
- }
10211
- draw(series, context, scaleX, scaleY, options) {
10212
- this._options = options;
10213
- d3.select(context.node().parentNode).select('.virtual-canvas').remove();
10214
- if (series.renderTo === 'canvas') {
10215
- this._context = context;
10216
- const height = context.node().clientHeight;
10217
- const width = context.node().clientWidth;
10218
- const points = series.data;
10219
- const context2D = context.node().getContext('2d');
10220
- this._virtualCanvas = d3
10221
- .select(context.node().parentNode)
10222
- .append('canvas')
10223
- .attr('class', 'virtual-canvas')
10224
- .style('display', 'none');
10225
- this._virtualCanvas.attr('width', width).attr('height', height);
10226
- const virtualContext = this._virtualCanvas.node().getContext('2d');
10227
- context.on('mouseout', () => {
10228
- d3.select(this._context.node().parentNode)
10229
- .select('.tooltip-chart')
10230
- .style('display', 'none');
10231
- context.on('mousemove', null);
10232
- });
10233
- context.on('mouseenter', () => {
10234
- d3.select(this._context.node().parentNode)
10235
- .select('.tooltip-chart')
10236
- .style('display', null);
10237
- context.on('mousemove', (e) => this.handleMouseMove(e));
10238
- });
10239
- points.forEach((d, idx) => {
10240
- const color = this.getColor(idx);
10241
- this._colorToData[color] = d;
10242
- virtualContext.fillStyle = color;
10243
- context2D.fillStyle = d.color;
10244
- const cx = scaleX(d.x);
10245
- const cy = scaleY(d.y);
10246
- context2D.beginPath();
10247
- context2D.arc(cx, cy, d.radius, 0, 2 * Math.PI);
10248
- context2D.closePath();
10249
- context2D.fill();
10250
- virtualContext.beginPath();
10251
- virtualContext.arc(cx, cy, d.radius, 0, 2 * Math.PI);
10252
- virtualContext.closePath();
10253
- virtualContext.fill();
10254
- });
10255
- }
10256
- }
10257
- getColor(index) {
10258
- return d3
10259
- .rgb(Math.floor(index / 256 / 256) % 256, Math.floor(index / 256) % 256, index % 256)
10260
- .toString();
10261
- }
10262
- tooltipPosition(event) {
10263
- const centerX = this._context.node().clientWidth / 2;
10264
- const centerY = this._context.node().clientHeight / 2;
10265
- const padding = { x: 10, y: 10 };
10266
- const scene = {
10267
- left: event.pageX > centerX ? 'initial' : `${event.pageX + padding.x}px`,
10268
- top: event.pageY > centerY ? 'initial' : `${event.pageY + padding.y}px`,
10269
- bottom: event.pageY > centerY
10270
- ? `${window.innerHeight - event.pageY}px`
10271
- : 'initial',
10272
- right: event.pageX > centerX
10273
- ? `${window.innerWidth - event.pageX + padding.x}px`
10274
- : 'initial',
10275
- };
10276
- return scene;
10277
- }
10278
- handleMouseMove(event) {
10279
- const mouse = d3.pointer(event);
10280
- const virtualContext = this._virtualCanvas.node().getContext('2d');
10281
- const image = virtualContext.getImageData(mouse[0], mouse[1], 1, 1);
10282
- const color = d3.rgb.apply(null, image.data).toString();
10283
- const possibleDatum = this._colorToData[color];
10284
- const { top, right, bottom, left } = this.tooltipPosition(event);
10285
- if (possibleDatum) {
10286
- const formatted = this._options.tooltip?.format([possibleDatum]);
10287
- d3.select(this._context.node().parentNode)
10288
- .select('.tooltip-chart')
10289
- .style('z-index', 3)
10290
- .style('top', top)
10291
- .style('right', right)
10292
- .style('bottom', bottom)
10293
- .style('left', left)
10294
- .html(formatted);
10295
- }
10296
- }
10297
- }
10298
-
10299
- class ContourDrawer {
10300
- draw(series, context, scaleX, scaleY) {
10301
- const points = series.data;
10302
- const tricontourFn = tricontour()
10303
- .x((d) => scaleX(d.x))
10304
- .y((d) => scaleY(d.y))
10305
- .value((d) => d.value)
10306
- .thresholds(30);
10307
- let contours = tricontourFn(points);
10308
- const geoFn = d3.geoPath();
10309
- const color = series?.colorScale.domain(d3.extent(contours, (d) => d.value));
10310
- contours = contours.map((_) => ({
10311
- ..._,
10312
- color: color(_.value),
10313
- }));
10314
- const u = context.selectAll('path').data(contours);
10315
- u.enter()
10316
- .append('path')
10317
- .merge(u)
10318
- .attr('d', (_) => geoFn(_))
10319
- .attr('stroke', 'rgba(255, 255,255,0.5)')
10320
- .attr('stroke-width', 0.5)
10321
- .attr('fill', (_) => _.color);
10322
- u.exit().remove();
10323
- }
10324
- }
10325
-
10326
- const defaultDrawerMapping = new Map()
10327
- .set(SeriesType.area, new AreaDrawer())
10328
- .set(SeriesType.bar, new BarDrawer())
10329
- .set(SeriesType.line, new LineDrawer())
10330
- .set(SeriesType.pie, new PieDrawer())
10331
- .set(SeriesType.scatter, new ScatterDrawer())
10332
- .set(SeriesType.spline, new SplineDrawer())
10333
- .set(SeriesType.contour, new ContourDrawer());
10334
-
10335
- var LegendType;
10336
- (function (LegendType) {
10337
- LegendType[LegendType["swatches"] = 0] = "swatches";
10338
- LegendType[LegendType["gradient"] = 1] = "gradient";
10339
- })(LegendType || (LegendType = {}));
10340
-
10341
- const classTypeLegendMapping = new Map()
10342
- .set(SeriesType.line, 'line')
10343
- .set(SeriesType.spline, 'line');
10344
- class SwatchDrawer {
10345
- draw(options) {
10346
- d3.select(options.context.parentElement)
10347
- .select('.legend-container')
10348
- .selectAll('.legend')
10349
- .remove();
10350
- const defaultData = options.series?.filter((serie) => serie.type !== SeriesType.bar);
10351
- const barData = options?.series
10352
- ?.filter((serie) => serie.type === SeriesType.bar)
10353
- .reduce((acc, serie) => {
10354
- const data = serie.data.map((_) => ({
10355
- ..._,
10356
- serieType: serie.type,
10357
- serieIndex: serie.id,
10358
- }));
10359
- return acc.concat(data);
10360
- }, []);
10361
- const legendContainer = d3
10362
- .select(options.context.parentElement)
10363
- .select('.legend-container')
10364
- .append('div')
10365
- .attr('class', 'legend padding-bottom-4');
10366
- const defaultLegend = legendContainer
10367
- .selectAll('div')
10368
- .data(defaultData)
10369
- .enter()
10370
- .append('div')
10371
- .attr('class', 'item')
10372
- .style('user-select', 'none');
10373
- const barLegend = legendContainer
10374
- .selectAll('.bar')
10375
- .data(barData)
10376
- .enter()
10377
- .append('div')
10378
- .attr('class', 'item bar')
10379
- .style('user-select', 'none');
10380
- defaultLegend
10381
- .append('div')
10382
- .attr('class', (_) => classTypeLegendMapping.get(_.type) || 'swatch')
10383
- .style('background', (_) => _.visible ? _.color ?? 'black' : 'var(--color-text-10)');
10384
- defaultLegend
10385
- .append('div')
10386
- .attr('class', 'label')
10387
- .text((_) => _.name ?? 'Без названия')
10388
- .style('text-decoration', (_) => (_.visible ? 'unset' : 'line-through'));
10389
- barLegend
10390
- .append('div')
10391
- .attr('class', 'swatch')
10392
- .style('background', (_) => _.visible ? _.color ?? 'black' : 'var(--color-text-10)');
10393
- barLegend
10394
- .append('div')
10395
- .attr('class', 'label')
10396
- .text((_) => _.label ?? 'Без названия')
10397
- .style('text-decoration', (_) => (_.visible ? 'unset' : 'line-through'));
10398
- }
10399
- }
10400
-
10401
- class GradientDrawer {
10402
- draw(options) {
10403
- const container = d3
10404
- .select(options.context.parentElement)
10405
- .select('.legend-container');
10406
- container.selectAll('.gradient-legend').remove();
10407
- const svg = container
10408
- .append('svg')
10409
- .attr('class', 'gradient-legend')
10410
- .attr('width', options.width)
10411
- .attr('height', 32);
10412
- svg.selectAll('.legend-defs').remove();
10413
- const extent = d3.extent(options.series[0]?.data, (d) => d.value);
10414
- const defs = svg.append('defs').attr('class', 'legend-defs');
10415
- const linearGradient = defs
10416
- .append('linearGradient')
10417
- .attr('id', 'legend-gradient');
10418
- linearGradient
10419
- .selectAll('stop')
10420
- .data([...options.series[0]?.data].reverse())
10421
- .enter()
10422
- .append('stop')
10423
- .attr('offset', (d) => ((d.value - extent[0]) / (extent[1] - extent[0])) * 100 + '%')
10424
- .attr('stop-color', (d) => d.color);
10425
- const g = svg.append('g').attr('class', 'gradient-legend');
10426
- g.append('rect')
10427
- .attr('width', options.width - 80)
10428
- .attr('transform', 'translate(40, 0)')
10429
- .attr('height', 4)
10430
- .style('fill', 'url(#legend-gradient)');
10431
- const xScale = d3
10432
- .scaleLinear()
10433
- .range([80, options.width - 80])
10434
- .domain(extent)
10435
- .nice();
10436
- const tickCount = options.width / 80;
10437
- const xAxis = d3.axisBottom(xScale).tickSize(8).ticks(tickCount);
10438
- g.call(xAxis).call((node) => {
10439
- node.select('.domain').remove();
10440
- node.selectAll('line').remove();
10441
- });
10442
- }
10443
- }
10444
-
10445
- const defaultLegendDrawerMapping = new Map()
10446
- .set(LegendType.swatches, new SwatchDrawer())
10447
- .set(LegendType.gradient, new GradientDrawer());
10448
-
10449
- var AxisType;
10450
- (function (AxisType) {
10451
- AxisType[AxisType["abscissa"] = 0] = "abscissa";
10452
- AxisType[AxisType["ordinatus"] = 1] = "ordinatus";
10453
- })(AxisType || (AxisType = {}));
10454
-
10455
- class Axis {
10456
- constructor(options) {
10457
- this._extents = [0, 0];
10458
- this._type = options?.type;
10459
- this._index = options?.index || 0;
10460
- this._chartOptions = options?.chartOptions;
10461
- this._height = options?.height;
10462
- if (this._chartOptions == null) {
10463
- throw new Error(`No chartOptions for axis ${AxisType[this._type]}`);
10464
- }
10465
- this.createExtents();
10466
- this.width = this.calculateAxisWidth();
10467
- }
10468
- get index() {
10469
- return this._index;
10470
- }
10471
- get options() {
10472
- return this._type === AxisType.abscissa
10473
- ? this._chartOptions.xAxis[this.index]
10474
- : this._chartOptions.yAxis[this.index];
10475
- }
10476
- get extent() {
10477
- return this._extents;
10478
- }
10479
- get type() {
10480
- return this._type;
10481
- }
10482
- get offset() {
10483
- return this._offset;
10484
- }
10485
- get ticks() {
10486
- return this._ticks;
10487
- }
10488
- setOffset(offset) {
10489
- this._offset = offset;
10490
- }
10491
- calculateAxisWidth() {
10492
- if (this.type === AxisType.abscissa) {
10493
- return 0;
10494
- }
10495
- const y = d3
10496
- .scaleLinear()
10497
- .domain([this.extent[0], this.extent[1]])
10498
- .range([0, this._height])
10499
- .nice();
10500
- const body = d3
10501
- .select('body')
10502
- .append('svg')
10503
- .attr('class', 'calculate-offset')
10504
- .style('position', 'absolute')
10505
- .style('left', '-9999px');
10506
- const axis = d3.axisRight(y).tickValues(this.ticks);
10507
- const element = body.append('g').attr('class', 'font-caption').call(axis);
10508
- const bBox = element.node().getBBox();
10509
- d3.selectAll('.calculate-offset').remove();
10510
- return bBox.width;
10511
- }
10512
- createExtents() {
10513
- const hasMin = this.options?.min != null;
10514
- const hasMax = this.options?.max != null;
10515
- if (!hasMin || !hasMax) {
10516
- const filtered = this._chartOptions?.series?.filter((serie) => this._index ===
10517
- serie[this._type === AxisType.abscissa ? 'xAxisIndex' : 'yAxisIndex']);
10518
- const raw = filtered.map((series) => d3.extent(series?.data, (point) => this._type === AxisType.abscissa ? point.x : point.y));
10519
- const merged = [].concat(...(raw ?? []));
10520
- const abs = (num) => Math.abs(num);
10521
- this._extents = this.options.negative
10522
- ? [-Math.abs(d3.max(merged.map(abs))), d3.max(merged.map(abs))]
10523
- : [d3.min(merged), d3.max(merged)];
10524
- }
10525
- if (hasMin) {
10526
- this._extents[0] = this.options?.min;
10527
- }
10528
- if (hasMax) {
10529
- this._extents[1] = this.options?.max;
10530
- }
10531
- }
10532
- }
10533
- Axis.offsetFactor = 22;
10534
-
10535
- var ScaleType;
10536
- (function (ScaleType) {
10537
- ScaleType[ScaleType["linear"] = 0] = "linear";
10538
- ScaleType[ScaleType["log"] = 1] = "log";
10539
- ScaleType[ScaleType["pow"] = 2] = "pow";
10540
- ScaleType[ScaleType["sqrt"] = 3] = "sqrt";
10541
- ScaleType[ScaleType["time"] = 4] = "time";
10542
- })(ScaleType || (ScaleType = {}));
10543
-
10544
- var ZoomType;
10545
- (function (ZoomType) {
10546
- ZoomType[ZoomType["x"] = 0] = "x";
10547
- ZoomType[ZoomType["y"] = 1] = "y";
10548
- ZoomType[ZoomType["xy"] = 2] = "xy";
10549
- })(ZoomType || (ZoomType = {}));
10550
-
10551
- class TetaChart {
10552
- constructor(options, element) {
10553
- this.plotLinesMove$ = new Subject();
10554
- this.plotBandsMove$ = new Subject();
10555
- this.seriesMove$ = new Subject();
10556
- this.pointMove$ = new Subject();
10557
- this.zoom$ = new Subject();
10558
- this._container = null;
10559
- this._width = 0;
10560
- this._height = 0;
10561
- this._zoomYCache = new Map();
10562
- this._zoomXCache = new Map();
10563
- this._zoom = d3.zoom();
10564
- this.visibleChartWindowWidth = 0;
10565
- this._xScales = new Map();
10566
- this._yScales = new Map();
10567
- this._clonedX = new Map();
10568
- this._clonedY = new Map();
10569
- this.offsetOpposite = 0;
10570
- this.offsetNonOpposite = 0;
10571
- this._zoomAdded = false;
10572
- this._options = options;
10573
- this.selectNode(element);
10574
- this.createTooltip();
10575
- this.plotLinesMove = this.plotLinesMove$.asObservable();
10576
- this.plotBandsMove = this.plotBandsMove$.asObservable();
10577
- this.seriesMove = this.seriesMove$.asObservable();
10578
- this.pointMove = this.pointMove$.asObservable();
10579
- this.zoom = this.zoom$.asObservable();
10580
- }
10581
- redraw(options) {
10582
- if (options) {
10583
- this._options = options;
10584
- }
10585
- this.createAxis();
10586
- this.createScales();
10587
- this.createMarkers();
10588
- this.createVisibleWindow();
10589
- this._redraw();
10590
- this.drawLegend();
10591
- if (this._commonZoomTransform) {
10592
- this._chart.call(this._zoom.transform, this._commonZoomTransform);
10593
- }
10594
- if (!this._zoomAdded) {
10595
- this.addZoom();
10596
- this._zoomAdded = true;
10597
- }
10598
- this.addAxesZoom();
10599
- }
10600
- setZoom(zoom) {
10601
- if (!this._zoom) {
10602
- return;
10603
- }
10604
- this._chart.call(this._zoom.transform, zoom?.zoomTransform ?? zoomIdentity);
10605
- }
10606
- setSize(size = { width: 0, height: 0 }) {
10607
- this._height = size.height;
10608
- this._width = size.width;
10609
- this._chart.attr('width', this._width).attr('height', this._height);
10610
- this._canvas.attr('width', this._width).attr('height', this._height);
10611
- const extent = [
10612
- [
10613
- this.offsetNonOpposite
10614
- ? this.offsetNonOpposite
10615
- : this._options.bounds.left,
10616
- this._options.bounds.top,
10617
- ],
10618
- [
10619
- this._width -
10620
- (this.offsetOpposite
10621
- ? this.offsetOpposite
10622
- : this._options.bounds.right),
10623
- this._height - this._options.bounds.bottom,
10624
- ],
10625
- ];
10626
- this._zoom
10627
- .scaleExtent([1, Infinity])
10628
- .translateExtent(extent)
10629
- .extent(extent);
10630
- }
10631
- createVisibleWindow() {
10632
- this.uniqId = (Date.now() + Math.random()).toString(36);
10633
- this._chart.selectAll('defs').remove();
10634
- this._chart
10635
- .append('defs')
10636
- .append('clipPath')
10637
- .attr('id', `draw-window-${this.uniqId}`)
10638
- .append('rect')
10639
- .attr('x', this.offsetNonOpposite === 0
10640
- ? this._options.bounds.left
10641
- : this.offsetNonOpposite)
10642
- .attr('y', this._options.bounds.top)
10643
- .attr('width', this.visibleChartWindowWidth + 1)
10644
- .attr('height', this._height -
10645
- this._options.bounds.bottom -
10646
- this._options.bounds.top +
10647
- 1 >
10648
- 0
10649
- ? this._height -
10650
- this._options.bounds.bottom -
10651
- this._options.bounds.top +
10652
- 1
10653
- : 0);
10654
- }
10655
- createAxis() {
10656
- this._xAxisList = this._options.xAxis.map((_, index) => new Axis({
10657
- type: AxisType.abscissa,
10658
- index,
10659
- chartOptions: this._options,
10660
- }));
10661
- this._yAxisList = this._options.yAxis.map((_, index) => {
10662
- const axis = new Axis({
10663
- type: AxisType.ordinatus,
10664
- index,
10665
- chartOptions: this._options,
10666
- height: this._height,
10667
- });
10668
- return axis;
10669
- });
10670
- const nonTitleOffset = 6;
10671
- this.offsetNonOpposite = d3.reduce(this._yAxisList.filter((_) => _.options?.opposite !== true && _.options?.visible), (sum, axis) => {
10672
- const offset = sum +
10673
- axis.width +
10674
- (axis?.options?.title ? Axis.offsetFactor : nonTitleOffset);
10675
- axis.setOffset(offset);
10676
- return offset;
10677
- }, 0);
10678
- this.offsetOpposite = d3.reduce(this._yAxisList.filter((_) => _.options?.opposite === true && _.options?.visible), (sum, axis) => {
10679
- const offset = sum +
10680
- axis.width +
10681
- (axis?.options?.title ? Axis.offsetFactor : nonTitleOffset);
10682
- axis.setOffset(offset);
10683
- return offset;
10684
- }, 0);
10685
- this.visibleChartWindowWidth = this.caluclateChartWidth();
10686
- }
10687
- _redraw() {
10688
- this.drawPlotBands();
10689
- this.drawPlotLines();
10690
- this.drawChart();
10691
- this.drawAxis();
10692
- this.drawGridLines();
10693
- this.drawAnnotations();
10694
- }
10695
- addZoom() {
10696
- if (this._options?.zoom?.enable) {
10697
- const hasXZoom = [ZoomType.x, ZoomType.xy].includes(this._options.zoom.zoomType);
10698
- const hasYZoom = [ZoomType.y, ZoomType.xy].includes(this._options.zoom.zoomType);
10699
- this._chart.call(this._zoom.on('start end zoom', (event) => {
10700
- if (hasXZoom) {
10701
- for (const [key, value] of this._clonedX.entries()) {
10702
- const rescaled = event.transform.rescaleX(value);
10703
- this._xScales.set(key, rescaled);
10704
- if (event.sourceEvent) {
10705
- this.zoom$.next({
10706
- domain: rescaled.domain(),
10707
- zoomTransform: event.transform,
10708
- zoomType: ZoomType.x,
10709
- event,
10710
- });
10711
- }
10712
- }
10713
- }
10714
- if (hasYZoom) {
10715
- for (const [key, value] of this._clonedY.entries()) {
10716
- const rescaled = event.transform.rescaleY(value);
10717
- this._yScales.set(key, rescaled);
10718
- if (event.type === 'zoom') {
10719
- if (event.sourceEvent) {
10720
- this.zoom$.next({
10721
- domain: rescaled.domain(),
10722
- zoomTransform: event.transform,
10723
- zoomType: ZoomType.y,
10724
- event,
10725
- });
10726
- }
10727
- }
10728
- }
10729
- }
10730
- if (event.type === 'end') {
10731
- this._commonZoomTransform = event.transform;
10732
- }
10733
- this._redraw();
10734
- }));
10735
- }
10736
- }
10737
- addAxesZoom() {
10738
- this._chart.selectAll('.zoom-behavior').remove();
10739
- [...this._yAxisList, ...this._xAxisList]
10740
- .filter((axis) => axis.options.visible && axis.options.zoom)
10741
- .forEach((axis) => {
10742
- const foundNode = this._chart
10743
- .select(`[data-${axis.type === AxisType.abscissa ? 'x' : 'y'}-scale-id='${axis.index}']`)
10744
- .node();
10745
- if (!foundNode) {
10746
- return;
10747
- }
10748
- const bBox = foundNode.getBBox();
10749
- const translateX = axis.type === AxisType.abscissa
10750
- ? this.offsetNonOpposite
10751
- ? this.offsetNonOpposite
10752
- : this._options.bounds.left + this.offsetNonOpposite
10753
- : axis.options.opposite
10754
- ? this._width - axis.offset
10755
- : axis.offset - bBox.width;
10756
- const zoom = d3
10757
- .zoom()
10758
- .scaleExtent([1, Infinity])
10759
- .on('zoom end', (event) => {
10760
- if (axis.type === AxisType.abscissa) {
10761
- const scale = this._clonedX.get(axis.index);
10762
- this._xScales.set(axis.index, event.transform.rescaleX(scale));
10763
- }
10764
- else {
10765
- const scale = this._clonedY.get(axis.index);
10766
- this._yScales.set(axis.index, event.transform.rescaleY(scale));
10767
- }
10768
- if (event.type === 'end') {
10769
- if (axis.type === AxisType.ordinatus) {
10770
- this._zoomYCache.set(axis.index, event.transform);
10771
- }
10772
- if (axis.type === AxisType.abscissa) {
10773
- this._zoomXCache.set(axis.index, event.transform);
10774
- this._chart.call(this._zoom.transform, event.transform);
10775
- }
10776
- }
10777
- this._redraw();
10778
- });
10779
- const restoredTransform = axis.type === AxisType.ordinatus
10780
- ? this._zoomYCache.get(axis.index)
10781
- : this._zoomXCache.get(axis.index);
10782
- this._chart
10783
- .append('rect')
10784
- .attr('class', 'zoom-behavior')
10785
- .attr('height', bBox.height)
10786
- .attr('width', bBox.width)
10787
- .attr('transform', `translate(${translateX}, ${axis.type === AxisType.abscissa
10788
- ? this._height - this._options.bounds.bottom
10789
- : this._options.bounds.top})`)
10790
- .style('opacity', '0')
10791
- .style('pointer-events', 'all')
10792
- .call(zoom.transform, restoredTransform ?? d3.zoomIdentity)
10793
- .call(zoom);
10794
- });
10795
- }
10796
- selectNode(element) {
10797
- this._container = element;
10798
- d3.select(element.nativeElement).selectAll('.tooltip-chart').remove();
10799
- d3.select(element.nativeElement).selectAll('svg').remove();
10800
- d3.select(element.nativeElement).selectAll('canvas').remove();
10801
- this._chart = d3
10802
- .select(element.nativeElement)
10803
- .append('svg')
10804
- .attr('position', 'relative')
10805
- .style('z-index', 0);
10806
- this._canvas = d3
10807
- .select(element.nativeElement)
10808
- .append('canvas')
10809
- .attr('class', 'main-canvas')
10810
- .style('transform', 'translate(35, 0)')
10811
- .style('position', 'absolute')
10812
- .style('z-index', 1);
10813
- }
10814
- drawAnnotations() {
10815
- this._chart.selectAll('.annotations').remove();
10816
- const annotations = this._options.annotations?.map((annotation) => {
10817
- const x = this._xScales.get(annotation.xAxisIndex);
10818
- const y = this._yScales.get(annotation.yAxisIndex);
10819
- return {
10820
- note: annotation.note,
10821
- connector: annotation.connector,
10822
- x: x(annotation.point?.x),
10823
- y: y(annotation.point?.y),
10824
- dx: annotation.dx,
10825
- dy: annotation.dy,
10826
- type: annotation.type,
10827
- className: annotation.className,
10828
- };
10829
- });
10830
- const makeAnnotations = d3annotation
10831
- .annotation()
10832
- .annotations(annotations ?? []);
10833
- this._chart
10834
- .append('g')
10835
- .attr('class', 'annotations')
10836
- .attr('clip-path', `url(#draw-window-${this.uniqId})`)
10837
- .call(makeAnnotations)
10838
- .lower();
10839
- }
10840
- drawPlotLines() {
10841
- this._chart.selectAll('.plotlines').remove();
10842
- const plotlineGroup = this._chart
10843
- .append('g')
10844
- .attr('class', 'plotlines')
10845
- .style('shape-rendering', 'crispEdges')
10846
- .attr('clip-path', `url(#draw-window-${this.uniqId})`);
10847
- this._xAxisList
10848
- .filter((_) => _.options.plotLines.length > 0)
10849
- .forEach((axis) => {
10850
- const [min, max] = axis.extent;
10851
- const x = this._xScales.get(axis.index);
10852
- const plotlinesPoints = axis.options.plotLines;
10853
- const getTextCenterPointPx = (d, idx) => x((d?.value +
10854
- (plotlinesPoints[idx - 1]
10855
- ? plotlinesPoints[idx - 1]?.value
10856
- : 0)) /
10857
- 2);
10858
- const opacity = (d, idx) => {
10859
- const displayWidth = 20;
10860
- const width = x(d?.value) -
10861
- x(plotlinesPoints[idx - 1] ? plotlinesPoints[idx - 1]?.value : 0);
10862
- return width <= displayWidth ? 0 : 1;
10863
- };
10864
- plotlineGroup
10865
- .selectAll('.label')
10866
- .data(plotlinesPoints)
10867
- .join('text')
10868
- .attr('class', 'label font-body-3 fill-text-70')
10869
- .attr('x', getTextCenterPointPx)
10870
- .attr('y', (d) => this._height / 2)
10871
- .attr('text-anchor', 'middle')
10872
- .attr('dominant-baseline', 'central')
10873
- .attr('transform', (d, idx) => `rotate(-90, ${getTextCenterPointPx(d, idx)}, ${this._height / 2})`)
10874
- .text((d) => d?.label ?? '')
10875
- .style('opacity', opacity);
10876
- plotlineGroup
10877
- .selectAll('.plotline')
10878
- .data(plotlinesPoints)
10879
- .join('line')
10880
- .attr('class', 'plotline')
10881
- .attr('data-plotline-id', (d) => d.id)
10882
- .attr('x1', (d) => x(d.value))
10883
- .attr('x2', (d) => x(d.value))
10884
- .attr('y1', 0)
10885
- .attr('y2', this._height -
10886
- this._options.bounds.top -
10887
- this._options.bounds.bottom)
10888
- .attr('transform', `translate(0, ${this._options.bounds.top})`)
10889
- .style('stroke-width', (d) => d.width)
10890
- .style('stroke', (d) => d.color)
10891
- .style('stroke-dasharray', (d) => (d.dashed ? '8, 8' : '0, 0'));
10892
- const emit = (event, plotLine) => {
10893
- this.plotLinesMove$.next({ event, target: plotLine });
10894
- };
10895
- plotlineGroup
10896
- .selectAll('.drag-plotline')
10897
- .data(plotlinesPoints)
10898
- .join('line')
10899
- .attr('class', 'drag-plotline')
10900
- .attr('x1', (d) => x(d.value))
10901
- .attr('x2', (d) => x(d.value))
10902
- .attr('y1', 0)
10903
- .attr('y2', this._height -
10904
- this._options.bounds.top -
10905
- this._options.bounds.bottom)
10906
- .attr('transform', `translate(0, ${this._options.bounds.top})`)
10907
- .style('stroke-width', 8)
10908
- .style('stroke', 'rgba(0, 0, 0, 0)')
10909
- .style('cursor', 'col-resize')
10910
- .call(d3
10911
- .drag()
10912
- .on('drag', function (event, d) {
10913
- const group = d3.select(this).node().parentElement;
10914
- const draggedPlotLine = d3
10915
- .select(group)
10916
- .select(`[data-plotline-id='${d.id}']`);
10917
- d.value = x.invert(event.x);
10918
- const minValue = d.min ?? min;
10919
- const maxValue = d.max ?? max;
10920
- const borderLeftReached = d.value <= minValue;
10921
- const borderRightReached = d.value >= maxValue;
10922
- if (borderLeftReached) {
10923
- d.value = minValue;
10924
- }
10925
- if (borderRightReached) {
10926
- d.value = maxValue;
10927
- }
10928
- d3.select(this).attr('x1', x(d.value)).attr('x2', x(d.value));
10929
- draggedPlotLine.attr('x1', x(d.value)).attr('x2', x(d.value));
10930
- emit(event, d);
10931
- })
10932
- .on('end', (event, d) => {
10933
- emit(event, d);
10934
- }));
10935
- });
10936
- this._yAxisList
10937
- .filter((_) => _.options.plotLines.length > 0)
10938
- .forEach((axis) => {
10939
- const [min, max] = axis.extent;
10940
- const y = this._yScales.get(axis.index);
10941
- const plotlinesPoints = axis.options.plotLines;
10942
- plotlineGroup
10943
- .selectAll('.plotline')
10944
- .data(plotlinesPoints)
10945
- .join('line')
10946
- .attr('class', 'plotline')
10947
- .attr('data-plotline-id', (d) => d.id)
10948
- .attr('y1', (d) => y(d.value))
10949
- .attr('y2', (d) => y(d.value))
10950
- .attr('x1', 0)
10951
- .attr('x2', this._width - this._options.bounds.left - this._options.bounds.right)
10952
- .attr('transform', `translate(${this._options.bounds.left}, 0)`)
10953
- .style('stroke-width', (d) => d.width)
10954
- .style('stroke', (d) => d.color)
10955
- .style('stroke-dasharray', (d) => (d.dashed ? '8, 8' : '0, 0'));
10956
- const emit = (event, plotLine) => {
10957
- this.plotLinesMove$.next({ event, target: plotLine });
10958
- };
10959
- plotlineGroup
10960
- .selectAll('.drag-plotline')
10961
- .data(plotlinesPoints)
10962
- .join('line')
10963
- .attr('class', 'drag-plotline')
10964
- .attr('y1', (d) => y(d.value))
10965
- .attr('y2', (d) => y(d.value))
10966
- .attr('x1', 0)
10967
- .attr('x2', this._width - this._options.bounds.left - this._options.bounds.right)
10968
- .attr('transform', `translate(${this._options.bounds.left}, 0)`)
10969
- .style('stroke-width', 8)
10970
- .style('stroke', 'rgba(0, 0, 0, 0)')
10971
- .style('cursor', 'row-resize')
10972
- .call(d3
10973
- .drag()
10974
- .on('drag', function (event, d) {
10975
- const group = d3.select(this).node().parentElement;
10976
- const draggedPlotLine = d3
10977
- .select(group)
10978
- .select(`[data-plotline-id='${d.id}']`);
10979
- d.value = y.invert(event.y);
10980
- const minValue = d.min ?? min;
10981
- const maxValue = d.max ?? max;
10982
- const borderTopReached = d.value <= minValue;
10983
- const borderBottomReached = d.value >= maxValue;
10984
- if (borderTopReached) {
10985
- d.value = minValue;
10986
- }
10987
- if (borderBottomReached) {
10988
- d.value = maxValue;
10989
- }
10990
- d3.select(this).attr('y1', y(d.value)).attr('y2', y(d.value));
10991
- draggedPlotLine.attr('y1', y(d.value)).attr('y2', y(d.value));
10992
- emit(event, d);
10993
- })
10994
- .on('end', (event, d) => {
10995
- emit(event, d);
10996
- }));
10997
- });
10998
- }
10999
- drawPlotBands() {
11000
- this._chart.selectAll('.plotbands').remove();
11001
- const plotBandGroup = this._chart
11002
- .append('g')
11003
- .attr('class', 'plotbands')
11004
- .attr('clip-path', `url(#draw-window-${this.uniqId})`);
11005
- this._xAxisList
11006
- .filter((_) => _.options.plotBands.length > 0)
11007
- .forEach((axis) => {
11008
- const x = this._xScales.get(axis.index);
11009
- const [min, max] = axis.extent;
11010
- const plotband = plotBandGroup
11011
- .append('g')
11012
- .style('shape-rendering', 'crispEdges');
11013
- const plotBandHeight = this._height - this._options.bounds.top - this._options.bounds.bottom;
11014
- const emit = (event, plotBand) => {
11015
- this.plotBandsMove$.next({
11016
- event,
11017
- target: plotBand,
11018
- });
11019
- };
11020
- plotband
11021
- .selectAll('rect')
11022
- .data(axis.options.plotBands)
11023
- .on('start', (_) => {
11024
- this._chart.selectAll('.marker').style('display', 'none');
11025
- d3.select(this._container.nativeElement)
11026
- .select('.tooltip-chart')
11027
- .style('display', 'none');
11028
- })
11029
- .join('rect')
11030
- .attr('data-plotband-id', (d) => d.id)
11031
- .attr('x', (d) => x(d.from))
11032
- .attr('y', 0)
11033
- .attr('width', (d) => Math.abs(x(d.to) - x(d.from)))
11034
- .attr('fill', (d) => {
11035
- if (d.image) {
11036
- return `url(#${d.image})`;
11037
- }
11038
- return d.color;
11039
- })
11040
- .style('opacity', (d) => d.opacity ?? 1)
11041
- .attr('height', plotBandHeight > 0 ? plotBandHeight : 0)
11042
- .attr('transform', `translate(0, ${this._options.bounds.top})`);
11043
- plotband
11044
- .selectAll('.line-left')
11045
- .data(axis.options.plotBands)
11046
- .join('line')
11047
- .attr('data-line-left-id', (d) => d.id)
11048
- .attr('class', 'line-left')
11049
- .attr('x1', (d) => x(d.from))
11050
- .attr('x2', (d) => x(d.from))
11051
- .attr('y1', 0)
11052
- .attr('y2', this._height -
11053
- this._options.bounds.top -
11054
- this._options.bounds.bottom)
11055
- .attr('transform', `translate(0, ${this._options.bounds.top})`)
11056
- .style('stroke-width', 1)
11057
- .style('stroke-dasharray', '8, 8')
11058
- .style('stroke', 'var(--color-text-90)')
11059
- .style('opacity', (d) => (d.showGrabbers ? 1 : 0));
11060
- plotband
11061
- .selectAll('.drag-left')
11062
- .data(axis.options.plotBands)
11063
- .join('line')
11064
- .attr('x1', (d) => x(d.from))
11065
- .attr('x2', (d) => x(d.from))
11066
- .attr('y1', 0)
11067
- .attr('y2', this._height -
11068
- this._options.bounds.top -
11069
- this._options.bounds.bottom)
11070
- .style('display', (d) => (d?.resizable ? 'unset' : 'none'))
11071
- .attr('transform', `translate(0, ${this._options.bounds.top})`)
11072
- .style('stroke-width', 8)
11073
- .style('stroke', 'rgba(0, 0, 0, 0)')
11074
- .style('cursor', 'col-resize')
11075
- .call(d3
11076
- .drag()
11077
- .on('drag', function (event, d) {
11078
- const group = d3.select(this).node().parentElement;
11079
- const draggedBand = d3
11080
- .select(group)
11081
- .select(`[data-plotband-id='${d.id}']`);
11082
- const draggedLine = d3
11083
- .select(group)
11084
- .select(`[data-line-left-id='${d.id}']`);
11085
- d.from = x.invert(event.x);
11086
- const minValue = d.min ?? min;
11087
- const borderReached = d.from <= minValue;
11088
- if (borderReached) {
11089
- d.from = minValue;
11090
- }
11091
- if (d.from >= d.to) {
11092
- d.from = d.to;
11093
- }
11094
- d3.select(this).attr('x1', x(d.from)).attr('x2', x(d.from));
11095
- draggedBand
11096
- .attr('x', x(d.from))
11097
- .attr('width', x(d.to) - x(d.from));
11098
- draggedLine.attr('x1', x(d.from)).attr('x2', x(d.from));
11099
- emit(event, d);
11100
- })
11101
- .on('end', (event, d) => emit(event, d)));
11102
- plotband
11103
- .selectAll('.line-right')
11104
- .data(axis.options.plotBands)
11105
- .join('line')
11106
- .attr('data-line-right-id', (d) => d.id)
11107
- .attr('class', 'line-right')
11108
- .attr('x1', (d) => x(d.to))
11109
- .attr('x2', (d) => x(d.to))
11110
- .attr('y1', 0)
11111
- .attr('y2', this._height -
11112
- this._options.bounds.top -
11113
- this._options.bounds.bottom)
11114
- .attr('transform', `translate(0, ${this._options.bounds.top})`)
11115
- .style('stroke-width', 1)
11116
- .style('stroke-dasharray', '8, 8')
11117
- .style('stroke', 'var(--color-text-90)')
11118
- .style('opacity', (d) => (d.showGrabbers ? 1 : 0));
11119
- plotband
11120
- .selectAll('.drag-right')
11121
- .data(axis.options.plotBands)
11122
- .join('line')
11123
- .attr('class', 'drag-right')
11124
- .style('display', (d) => (d?.resizable ? 'unset' : 'none'))
11125
- .attr('x1', (d) => x(d.to))
11126
- .attr('x2', (d) => x(d.to))
11127
- .attr('y1', 0)
11128
- .attr('y2', this._height -
11129
- this._options.bounds.top -
11130
- this._options.bounds.bottom)
11131
- .attr('transform', `translate(0, ${this._options.bounds.top})`)
11132
- .style('stroke-width', 8)
11133
- .style('stroke', 'rgba(0, 0, 0, 0)')
11134
- .style('cursor', 'col-resize')
11135
- .call(d3
11136
- .drag()
11137
- .on('drag', function (event, d) {
11138
- const group = d3.select(this).node().parentElement;
11139
- const draggedBand = d3
11140
- .select(group)
11141
- .select(`[data-plotband-id='${d.id}']`);
11142
- const draggedLine = d3
11143
- .select(group)
11144
- .select(`[data-line-right-id='${d.id}']`);
11145
- d.to = x.invert(event.x);
11146
- const maxValue = d.max ?? max;
11147
- const borderReached = d.to >= maxValue;
11148
- if (borderReached) {
11149
- d.to = maxValue;
11150
- }
11151
- if (d.to <= d.from) {
11152
- d.to = d.from;
11153
- }
11154
- d3.select(this).attr('x1', x(d.to)).attr('x2', x(d.to));
11155
- draggedBand.attr('width', x(d.to) - x(d.from));
11156
- draggedLine.attr('x1', x(d.to)).attr('x2', x(d.to));
11157
- emit(event, d);
11158
- })
11159
- .on('end', (event, d) => emit(event, d)));
11160
- });
11161
- this._yAxisList
11162
- .filter((_) => _.options.plotBands.length > 0)
11163
- .forEach((axis) => {
11164
- const y = this._yScales.get(axis.index);
11165
- const [min, max] = axis.extent;
11166
- const plotband = plotBandGroup
11167
- .append('g')
11168
- .style('shape-rendering', 'crispEdges');
11169
- const plotBandWidth = this._width - this._options.bounds.left - this._options.bounds.right; // TODO add multiaxis support width
11170
- const emit = (event, plotBand) => {
11171
- this.plotBandsMove$.next({
11172
- event,
11173
- target: plotBand,
11174
- });
11175
- };
11176
- const dragPlotband = d3
11177
- .drag()
11178
- .subject(function () {
11179
- const element = d3.select(this);
11180
- return { y: element.attr('y') };
11181
- })
11182
- .on('start drag end', function (event, d) {
11183
- const element = d3.select(this);
11184
- const height = parseFloat(element.attr('height'));
11185
- d.to = y.invert(event.y + height);
11186
- d.from = y.invert(event.y);
11187
- const minValue = d.min ?? min;
11188
- const maxValue = d.max ?? max;
11189
- const borderReachedMin = d.from <= minValue;
11190
- const borderReachedMax = d.to >= maxValue;
11191
- if (borderReachedMin) {
11192
- d.to = y.invert(y(minValue) + height);
11193
- d.from = minValue;
11194
- }
11195
- if (borderReachedMax) {
11196
- d.to = maxValue;
11197
- d.from = y.invert(y(maxValue) - height);
11198
- }
11199
- element.attr('y', y(d.from));
11200
- const group = element.node().parentElement;
11201
- d3.select(group)
11202
- .select(`[data-line-left-id='${d.id}']`)
11203
- .attr('y1', y(d.from))
11204
- .attr('y2', y(d.from));
11205
- d3.select(group)
11206
- .select(`[data-grab-left-id='${d.id}']`)
11207
- .attr('y1', y(d.from))
11208
- .attr('y2', y(d.from));
11209
- d3.select(group)
11210
- .select(`[data-line-right-id='${d.id}']`)
11211
- .attr('y1', y(d.to))
11212
- .attr('y2', y(d.to));
11213
- d3.select(group)
11214
- .select(`[data-grab-right-id='${d.id}']`)
11215
- .attr('y1', y(d.to))
11216
- .attr('y2', y(d.to));
11217
- emit(event, d);
11218
- });
11219
- const leftGrabDrag = d3
11220
- .drag()
11221
- .on('drag', function (event, d) {
11222
- const group = d3.select(this).node().parentElement;
11223
- const draggedBand = d3
11224
- .select(group)
11225
- .select(`[data-plotband-id='${d.id}']`);
11226
- const draggedLine = d3
11227
- .select(group)
11228
- .select(`[data-line-left-id='${d.id}']`);
11229
- d.from = y.invert(event.y);
11230
- const minValue = d.min ?? min;
11231
- const borderReached = d.from <= minValue;
11232
- if (borderReached) {
11233
- d.from = minValue;
11234
- }
11235
- if (d.from >= d.to) {
11236
- d.from = d.to;
11237
- }
11238
- d3.select(this).attr('y1', y(d.from)).attr('y2', y(d.from));
11239
- draggedBand
11240
- .attr('y', y(d.from))
11241
- .attr('height', Math.abs(y(d.to) - y(d.from)));
11242
- draggedLine.attr('y1', y(d.from)).attr('y2', y(d.from));
11243
- emit(event, d);
11244
- })
11245
- .on('end', (event, d) => emit(event, d));
11246
- const rightGrabDrag = d3
11247
- .drag()
11248
- .on('drag', function (event, d) {
11249
- const group = d3.select(this).node().parentElement;
11250
- const draggedBand = d3
11251
- .select(group)
11252
- .select(`[data-plotband-id='${d.id}']`);
11253
- const draggedLine = d3
11254
- .select(group)
11255
- .select(`[data-line-right-id='${d.id}']`);
11256
- d.to = y.invert(event.y);
11257
- const maxValue = d.max ?? max;
11258
- const borderReached = d.to >= maxValue;
11259
- if (borderReached) {
11260
- d.to = maxValue;
11261
- }
11262
- if (d.to <= d.from) {
11263
- d.to = d.from;
11264
- }
11265
- d3.select(this).attr('y1', y(d.to)).attr('y2', y(d.to));
11266
- draggedBand
11267
- .attr('y', y(d.from))
11268
- .attr('height', Math.abs(y(d.to) - y(d.from)));
11269
- draggedLine.attr('y1', y(d.to)).attr('y2', y(d.to));
11270
- emit(event, d);
11271
- })
11272
- .on('end', (event, d) => emit(event, d));
11273
- plotband
11274
- .selectAll('rect')
11275
- .data(axis.options.plotBands)
11276
- .join('rect')
11277
- .attr('data-plotband-id', (d) => d.id)
11278
- .attr('x', 0)
11279
- .attr('y', (d) => y(d.from))
11280
- .attr('width', (d) => plotBandWidth)
11281
- .attr('fill', (d) => {
11282
- if (d.image) {
11283
- return `url(#${d.image})`;
11284
- }
11285
- return d.color;
11286
- })
11287
- .style('opacity', (d) => d.opacity ?? 1)
11288
- .attr('height', (d) => Math.abs(y(d.to) - y(d.from)))
11289
- .attr('cursor', (d) => (d.draggable ? 'move' : 'default'));
11290
- plotband
11291
- .selectAll('.line-left')
11292
- .data(axis.options.plotBands.filter((d) => d.resizable))
11293
- .join('line')
11294
- .attr('data-line-left-id', (d) => d.id)
11295
- .attr('class', 'line-left')
11296
- .attr('y1', (d) => y(d.from))
11297
- .attr('y2', (d) => y(d.from))
11298
- .attr('x1', 0)
11299
- .attr('x2', plotBandWidth)
11300
- .style('stroke-width', 1)
11301
- .style('stroke-dasharray', '8, 8')
11302
- .style('stroke', 'var(--color-text-90)')
11303
- .style('opacity', (d) => (d.showGrabbers ? 1 : 0));
11304
- plotband
11305
- .selectAll('.drag-left')
11306
- .data(axis.options.plotBands.filter((d) => d.resizable))
11307
- .join('line')
11308
- .attr('data-grab-left-id', (d) => d.id)
11309
- .attr('y1', (d) => y(d.from))
11310
- .attr('y2', (d) => y(d.from))
11311
- .attr('x1', 0)
11312
- .attr('x2', plotBandWidth)
11313
- .style('stroke-width', 8)
11314
- .style('stroke', 'rgba(0, 0, 0, 0)')
11315
- .style('cursor', (d) => (d.resizable ? 'row-resize' : 'default'));
11316
- plotband
11317
- .selectAll('.line-right')
11318
- .data(axis.options.plotBands.filter((d) => d.resizable))
11319
- .join('line')
11320
- .attr('data-line-right-id', (d) => d.id)
11321
- .attr('class', 'line-right')
11322
- .attr('y1', (d) => y(d.to))
11323
- .attr('y2', (d) => y(d.to))
11324
- .attr('x1', 0)
11325
- .attr('x2', plotBandWidth)
11326
- .style('stroke-width', 1)
11327
- .style('stroke-dasharray', '8, 8')
11328
- .style('stroke', 'var(--color-text-90)')
11329
- .style('opacity', (d) => (d.showGrabbers ? 1 : 0));
11330
- plotband
11331
- .selectAll('.drag-right')
11332
- .data(axis.options.plotBands.filter((d) => d.resizable))
11333
- .join('line')
11334
- .attr('class', 'drag-right')
11335
- .attr('data-grab-right-id', (d) => d.id)
11336
- .attr('y1', (d) => y(d.to))
11337
- .attr('y2', (d) => y(d.to))
11338
- .attr('x1', 0)
11339
- .attr('x2', plotBandWidth)
11340
- .style('stroke-width', 8)
11341
- .style('stroke', 'rgba(0, 0, 0, 0)')
11342
- .style('cursor', (d) => (d.resizable ? 'row-resize' : 'default'));
11343
- axis.options.plotBands.forEach((_) => {
11344
- if (_.draggable) {
11345
- plotband.select(`[data-plotband-id='${_.id}']`).call(dragPlotband);
11346
- }
11347
- if (_.resizable) {
11348
- plotband.select(`[data-grab-left-id='${_.id}']`).call(leftGrabDrag);
11349
- plotband
11350
- .select(`[data-grab-right-id='${_.id}']`)
11351
- .call(rightGrabDrag);
11352
- }
11353
- });
11354
- });
11355
- }
11356
- drawChart() {
11357
- const series = this._options.series?.filter((_) => _.visible);
11358
- this._chart.selectAll('.series').remove();
11359
- if (!series || series.length < 1) {
11360
- d3.select(this._container.nativeElement)
11361
- .select('canvas')
11362
- .style('display', 'none');
11363
- }
11364
- const group = this._chart
11365
- .append('g')
11366
- .attr('class', 'series')
11367
- .attr('clip-path', `url(#draw-window-${this.uniqId})`);
11368
- series?.forEach((seriesItem, index) => {
11369
- if (seriesItem.renderTo === 'canvas') {
11370
- d3.select(this._container.nativeElement)
11371
- .select('canvas')
11372
- .style('display', null);
11373
- d3.select(this._container.nativeElement)
11374
- .select('svg')
11375
- .style('position', 'absolute');
11376
- }
11377
- else {
11378
- d3.select(this._container.nativeElement)
11379
- .select('canvas')
11380
- .style('display', 'none');
11381
- }
11382
- if (!this._xScales.has(seriesItem.xAxisIndex) ||
11383
- !this._yScales.has(seriesItem.yAxisIndex)) {
11384
- return;
11385
- }
11386
- const foundX = this._xScales.get(seriesItem.xAxisIndex);
11387
- const foundY = this._yScales.get(seriesItem.yAxisIndex);
11388
- const drawer = seriesItem.drawer != null
11389
- ? seriesItem.drawer
11390
- : defaultDrawerMapping.get(seriesItem.type);
11391
- if (!drawer) {
11392
- throw new Error(`No drawer for series ${seriesItem.name}, type ${SeriesType[seriesItem.type]}`);
11393
- }
11394
- if (seriesItem.renderTo === 'canvas') {
11395
- const context = this._canvas.node().getContext('2d');
11396
- context.clearRect(0, 0, this._width, this._height);
11397
- }
11398
- let [xMin, xMax] = foundX.domain();
11399
- let [yMin, yMax] = foundY.domain();
11400
- xMin = xMin instanceof Date ? xMin.getTime() : xMin;
11401
- xMax = xMax instanceof Date ? xMax.getTime() : xMax;
11402
- yMin = yMin instanceof Date ? yMin.getTime() : yMin;
11403
- yMax = yMax instanceof Date ? yMax.getTime() : yMax;
11404
- const visiblePoints = (point, idx, arr) => (point.x <= xMax ||
11405
- point.x1 <= xMax ||
11406
- (arr[idx - 1] && arr[idx - 1].x <= xMax) ||
11407
- (arr[idx - 1] && arr[idx - 1].x1 <= xMax)) &&
11408
- (point.x >= xMin ||
11409
- point.x1 >= xMin ||
11410
- (arr[idx + 1] && arr[idx + 1].x >= xMin) ||
11411
- (arr[idx + 1] && arr[idx + 1].x1 >= xMin)) &&
11412
- (point.y <= yMax ||
11413
- point.y1 <= yMax ||
11414
- (arr[idx - 1] && arr[idx - 1].y <= yMax) ||
11415
- (arr[idx - 1] && arr[idx - 1].y1 <= yMax)) &&
11416
- (point.y >= yMin ||
11417
- point.y1 >= yMin ||
11418
- (arr[idx + 1] && arr[idx + 1].y >= yMin) ||
11419
- (arr[idx + 1] && arr[idx + 1].y1 >= yMin));
11420
- const filteredData = seriesItem.data; //.filter(visiblePoints);
11421
- const serie = {
11422
- ...seriesItem,
11423
- data: filteredData,
11424
- };
11425
- drawer.draw(serie, seriesItem.renderTo === 'canvas' ? this._canvas : group, foundX, foundY, this._options);
11426
- const emit = (event) => {
11427
- this.seriesMove$.next(event);
11428
- };
11429
- const emitPoint = (event) => {
11430
- this.pointMove$.next(event);
11431
- };
11432
- drawer?.dispatch?.on(DispatchType.moveLine, function () {
11433
- emit(this);
11434
- });
11435
- drawer?.dispatch?.on(DispatchType.movePoint, function () {
11436
- emitPoint(this);
11437
- });
11438
- });
11439
- }
11440
- createTooltip() {
11441
- d3.select(this._container.nativeElement)
11442
- .append('div')
11443
- .attr('class', 'tooltip-chart color-text-90 bg-background-50 shadow-2')
11444
- .style('position', 'fixed')
11445
- .style('top', 'unset')
11446
- .style('right', 'unset')
11447
- .style('bottom', 'unset')
11448
- .style('left', 'unset')
11449
- .style('pointer-events', 'none')
11450
- .style('display', 'none');
11451
- }
11452
- handleMouseMove(options) {
11453
- const mouse = d3.pointer(options.event);
11454
- const { top, right, bottom, left } = this.tooltipPosition(options.event);
11455
- const tooltipsData = [];
11456
- this._chart
11457
- .select('.marker-line')
11458
- .attr('transform', `translate(${0}, ${mouse[1] - 2})`);
11459
- this._chart
11460
- .selectAll('.marker')
11461
- .attr('transform', (d) => {
11462
- if (!d.data.length) {
11463
- return;
11464
- }
11465
- if (!this._xScales.has(d.xAxisIndex) ||
11466
- !this._yScales.has(d.yAxisIndex)) {
11467
- return;
11468
- }
11469
- const foundX = this._xScales.get(d.xAxisIndex);
11470
- const foundY = this._yScales.get(d.yAxisIndex);
11471
- if (this._options.tooltip.tracking === 'x') {
11472
- const [min, max] = foundX.domain();
11473
- const filteredData = d.data.filter((point) => point.x <= max && point.x >= min);
11474
- const sorted = [...filteredData].sort((a, b) => d3.ascending(a.x, b.x));
11475
- const bisect = d3.bisector((dd) => dd.x).left;
11476
- const x0 = foundX.invert(mouse[0]);
11477
- const index = bisect(sorted, x0);
11478
- const data = sorted[index] ? sorted[index] : sorted[index - 1];
11479
- tooltipsData.push({
11480
- point: data,
11481
- color: d.color,
11482
- name: d.name,
11483
- });
11484
- return `translate(${!isNaN(data?.x) && data?.x != null ? foundX(data.x) : -10}, ${!isNaN(data?.y) && data?.y != null ? foundY(data.y) : -10})`;
11485
- }
11486
- if (this._options.tooltip.tracking === 'y') {
11487
- const sorted = [...d.data].sort((a, b) => d3.ascending(a.y, b.y));
11488
- const bisect = d3.bisector((dd) => dd.y).left;
11489
- const y0 = foundY.invert(mouse[1]);
11490
- const index = bisect(sorted, y0, 0);
11491
- const data = sorted[index] ? sorted[index] : sorted[index - 1];
11492
- tooltipsData.push({
11493
- point: data,
11494
- color: d.color,
11495
- name: d.name,
11496
- });
11497
- return `translate(${!isNaN(data?.x) && data?.x != null ? foundX(data.x) : -10}, ${!isNaN(data?.y) && data?.y != null ? foundY(data.y) : -10})`;
11498
- }
11499
- });
11500
- if (this._options.tooltip?.format) {
11501
- const formatted = this._options.tooltip?.format(tooltipsData);
11502
- d3.select(this._container.nativeElement)
11503
- .select('.tooltip-chart')
11504
- .style('top', top)
11505
- .style('right', right)
11506
- .style('bottom', bottom)
11507
- .style('left', left)
11508
- .html(formatted);
11509
- }
11510
- }
11511
- tooltipPosition(event) {
11512
- const centerX = this._width / 2;
11513
- const centerY = this._height / 2;
11514
- const padding = { x: 10, y: 10 };
11515
- const scene = {
11516
- left: event.pageX > centerX ? 'initial' : `${event.pageX + padding.x}px`,
11517
- top: event.pageY > centerY ? 'initial' : `${event.pageY + padding.y}px`,
11518
- bottom: event.pageY > centerY
11519
- ? `${window.innerHeight - event.pageY}px`
11520
- : 'initial',
11521
- right: event.pageX > centerX
11522
- ? `${window.innerWidth - event.pageX + padding.x}px`
11523
- : 'initial',
11524
- };
11525
- return scene;
11526
- }
11527
- createMarkers() {
11528
- if (this._options.tooltip === undefined) {
11529
- return;
11530
- }
11531
- if (!this._options.tooltip.enable) {
11532
- return;
11533
- }
11534
- this._chart.selectAll('.marker').remove();
11535
- this._chart.select('.marker-line').remove();
11536
- this._chart
11537
- .append('line')
11538
- .attr('class', 'marker-line')
11539
- .attr('x1', 35)
11540
- .attr('x2', this._width)
11541
- .style('stroke-width', 0.5)
11542
- .style('stroke', 'var(--color-text-40)')
11543
- .style('display', 'none');
11544
- const { series } = this._options;
11545
- if (!series) {
11546
- return;
11547
- }
11548
- const markers = this._chart
11549
- .selectAll()
11550
- .data(series.filter((_) => _.visible));
11551
- markers
11552
- .enter()
11553
- .append('circle')
11554
- .attr('class', 'marker')
11555
- .attr('pointer-events', 'none')
11556
- .attr('r', 3)
11557
- .attr('fill', (_, i) => _.color)
11558
- .style('display', 'none');
11559
- const mouseoutEvent = () => {
11560
- this._chart.selectAll('.marker').style('display', 'none');
11561
- this._chart.select('.marker-line').style('display', 'none');
11562
- d3.select(this._container.nativeElement)
11563
- .select('.tooltip-chart')
11564
- .style('display', 'none');
11565
- };
11566
- const mouseMoveEvent = (event) => {
11567
- const options = {
11568
- event,
11569
- series,
11570
- };
11571
- this.handleMouseMove(options);
11572
- };
11573
- const mouseOverEvent = () => {
11574
- if (this._options.tooltip.showMarkers) {
11575
- this._chart
11576
- .selectAll('.marker')
11577
- .style('display', (d) => {
11578
- if (d.data.length) {
11579
- return null;
11580
- }
11581
- return 'none';
11582
- });
11583
- }
11584
- if (this._options.tooltip.showLine) {
11585
- this._chart.select('.marker-line').style('display', null);
11586
- }
11587
- d3.select(this._container.nativeElement)
11588
- .select('.tooltip-chart')
11589
- .style('display', null);
11590
- };
11591
- this._chart
11592
- .on('mouseover', mouseOverEvent)
11593
- .on('mousemove', mouseMoveEvent)
11594
- .on('mouseleave', mouseoutEvent);
11595
- }
11596
- drawLegend() {
11597
- if (this._options.legend?.visible === false) {
11598
- return;
11599
- }
11600
- this._chart.selectAll('.legend').remove();
11601
- const drawer = this._options.legend?.type
11602
- ? defaultLegendDrawerMapping.get(this._options.legend.type)
11603
- : defaultLegendDrawerMapping.get(LegendType.swatches);
11604
- const context = this._container.nativeElement;
11605
- if (!drawer) {
11606
- throw new Error(`No drawer for legend
11607
- }`);
11608
- }
11609
- drawer.draw({
11610
- context,
11611
- series: this._options.series.filter((_) => _.showInLegend),
11612
- width: this._width,
11613
- height: this._height,
11614
- });
11615
- }
11616
- caluclateChartWidth() {
11617
- let width = -this._width;
11618
- if (this.offsetOpposite > 0) {
11619
- width = -this._width + this.offsetOpposite + this.offsetNonOpposite;
11620
- }
11621
- if (this.offsetNonOpposite > 0) {
11622
- width =
11623
- -this._width + this._options.bounds.right + this.offsetNonOpposite;
11624
- }
11625
- if (this.offsetOpposite >= Axis.offsetFactor &&
11626
- this.offsetNonOpposite === 0) {
11627
- width = -this._width + this.offsetOpposite + this._options.bounds.left;
11628
- }
11629
- if (this.offsetOpposite > 0 && this.offsetNonOpposite > 0) {
11630
- width = -this._width + this.offsetOpposite + this.offsetNonOpposite;
11631
- }
11632
- return Math.abs(width);
11633
- }
11634
- drawGridLines() {
11635
- if (this._options.gridLines === false) {
11636
- return;
11637
- }
11638
- const translateX = this.offsetNonOpposite > 0
11639
- ? this.offsetNonOpposite
11640
- : this._options.bounds.left + this.offsetNonOpposite;
11641
- this._chart.selectAll('.grid').remove();
11642
- const yList = this._yAxisList.filter((_) => _.options.visible && !_.options.opposite);
11643
- const y = yList?.length > 0
11644
- ? this._yScales.get(yList[yList.length - 1].index)
11645
- : this._yScales.get(0);
11646
- const x = this._xScales.get(0);
11647
- if (!y || !x) {
11648
- return;
11649
- }
11650
- const TICK_HEIGHT = 40;
11651
- const TICK_WIDTH = 60;
11652
- const tickCount = Math.round(this._height / TICK_HEIGHT);
11653
- const tickCountX = Math.round(this._width / TICK_WIDTH);
11654
- const gridY = this._chart
11655
- .append('g')
11656
- .attr('class', 'grid color-text-10')
11657
- .style('shape-rendering', 'crispEdges');
11658
- const gridlinesY = d3
11659
- .axisLeft(y)
11660
- .tickFormat('')
11661
- .tickSize(-this.visibleChartWindowWidth);
11662
- const hasBarSeriesType = this._options.series.some((_) => _.type === SeriesType.bar);
11663
- if (!hasBarSeriesType) {
11664
- const gridX = this._chart
11665
- .append('g')
11666
- .attr('class', 'grid color-text-10')
11667
- .style('shape-rendering', 'crispEdges');
11668
- const gridlinesX = d3
11669
- .axisBottom(x)
11670
- .ticks(tickCountX)
11671
- .tickFormat('')
11672
- .tickSize(this._height - this._options.bounds.bottom - this._options.bounds.top);
11673
- gridX
11674
- .call(gridlinesX)
11675
- .attr('transform', `translate(0, ${this._options.bounds.top})`)
11676
- .lower();
11677
- }
11678
- gridY
11679
- .call(gridlinesY)
11680
- .attr('transform', `translate(${translateX}, ${0})`)
11681
- .lower();
11682
- this._chart.selectAll('.grid path').remove();
11683
- }
11684
- createScales() {
11685
- this._xScales.clear();
11686
- this._yScales.clear();
11687
- const defaultScaleMapping = new Map()
11688
- .set(ScaleType.linear, d3.scaleLinear)
11689
- .set(ScaleType.log, d3.scaleLog)
11690
- .set(ScaleType.sqrt, d3.scaleSqrt)
11691
- .set(ScaleType.pow, d3.scalePow);
11692
- const xRange = [
11693
- this.offsetNonOpposite
11694
- ? this.offsetNonOpposite
11695
- : this._options.bounds.left,
11696
- this._width -
11697
- (this.offsetOpposite
11698
- ? this.offsetOpposite
11699
- : this._options.bounds.right),
11700
- ];
11701
- const yRange = [
11702
- this._height - this._options.bounds.bottom,
11703
- this._options.bounds.top,
11704
- ];
11705
- this._xAxisList.forEach((axis, index) => {
11706
- let scale = null;
11707
- if (axis.options.type === Scale.time) {
11708
- scale = d3
11709
- .scaleTime()
11710
- .domain(axis.extent)
11711
- .range(axis.options.inverted ? [...xRange].reverse() : xRange);
11712
- }
11713
- if (axis.options.type === Scale.number) {
11714
- scale = defaultScaleMapping
11715
- .get(axis.options.scaleOptions.type)()
11716
- .domain(axis.extent)
11717
- .range(axis.options.inverted ? [...xRange].reverse() : xRange);
11718
- }
11719
- if (axis.options.niceTicks) {
11720
- scale.nice();
11721
- }
11722
- if (axis.options.scaleOptions.type === ScaleType.log) {
11723
- scale.base(axis.options.scaleOptions.base);
11724
- }
11725
- if (axis.options.scaleOptions.type === ScaleType.pow) {
11726
- scale.exponent(axis.options.scaleOptions.base);
11727
- }
11728
- this._xScales.set(index, scale);
11729
- });
11730
- this._yAxisList.forEach((axis, index) => {
11731
- let scale = null;
11732
- if (axis.options.type === Scale.number) {
11733
- scale = defaultScaleMapping
11734
- .get(axis.options.scaleOptions.type)()
11735
- .domain(axis.extent)
11736
- .range(axis.options.inverted ? [...yRange].reverse() : yRange);
11737
- }
11738
- if (axis.options.type === Scale.time) {
11739
- scale = d3
11740
- .scaleTime()
11741
- .domain(axis.extent)
11742
- .range(axis.options.inverted ? [...yRange].reverse() : yRange);
11743
- }
11744
- if (axis.options.niceTicks) {
11745
- scale.nice();
11746
- }
11747
- if (axis.options.scaleOptions.type === ScaleType.log) {
11748
- scale.base(axis.options.scaleOptions.base);
11749
- }
11750
- if (axis.options.scaleOptions.type === ScaleType.pow) {
11751
- scale.exponent(axis.options.scaleOptions.base);
11752
- }
11753
- this._yScales.set(index, scale);
11754
- });
11755
- for (const [key, value] of this._yScales) {
11756
- this._clonedY.set(key, value.copy());
11757
- }
11758
- for (const [key, value] of this._xScales) {
11759
- this._clonedX.set(key, value.copy());
11760
- }
11761
- }
11762
- drawAxis() {
11763
- const hasVisibleAxis = [...this._xAxisList, ...this._yAxisList].filter((axis) => axis.options.visible);
11764
- if (!hasVisibleAxis) {
11765
- return;
11766
- }
11767
- const negative = false;
11768
- this._chart.selectAll('.axes').remove();
11769
- const axes = this._chart
11770
- .append('g')
11771
- .attr('class', 'axes')
11772
- .style('shape-rendering', 'crispEdges');
11773
- const TICK_HEIGHT = 40;
11774
- const TICK_WIDTH = 60;
11775
- const tickCount = Math.round(this._height / TICK_HEIGHT);
11776
- const tickCountX = Math.round(this._width / TICK_WIDTH);
11777
- this._xAxisList.forEach((axis) => {
11778
- const options = axis.options;
11779
- const translate = `translate(${0}, ${this._height - this._options.bounds.bottom})`;
11780
- const x = this._xScales.get(axis.index);
11781
- const xAxis = d3.axisBottom(x).ticks(tickCountX);
11782
- if (axis.options?.tickFormat) {
11783
- xAxis.tickFormat(axis.options.tickFormat);
11784
- }
11785
- if (options.visible !== false) {
11786
- const translateX = this.offsetNonOpposite
11787
- ? this.offsetNonOpposite
11788
- : this._options.bounds.left + this.offsetNonOpposite;
11789
- axes
11790
- .append('g')
11791
- .attr('class', 'x-axis-label')
11792
- .append('text')
11793
- .style('fill', 'var(--color-text-50)')
11794
- .attr('transform', 'translate(' +
11795
- this._width / 2 +
11796
- ' ,' +
11797
- (this._height - this._options.bounds.bottom) +
11798
- ')')
11799
- .style('text-anchor', 'middle')
11800
- .attr('dy', '3em')
11801
- .text(options.title ?? '');
11802
- axes
11803
- .append('g')
11804
- .attr('class', 'x-axis font-caption')
11805
- .attr('data-x-scale-id', axis.index)
11806
- .attr('transform', translate)
11807
- .style('pointer-events', 'none')
11808
- .call(xAxis)
11809
- .call((_) => {
11810
- _.select('.domain').remove();
11811
- _.selectAll('.tick').attr('class', 'color-text-50');
11812
- if (negative) {
11813
- _.append('line')
11814
- .attr('y1', 0)
11815
- .attr('y2', this._height)
11816
- .attr('transform', `translate(${x(0)}, -${this._height})`)
11817
- .style('stroke-width', 0.5)
11818
- .style('stroke', 'var(--color-text-50)');
11819
- }
11820
- _.append('line')
11821
- .attr('x1', 0)
11822
- .attr('x2', this.visibleChartWindowWidth)
11823
- .attr('transform', `translate(${translateX}, ${0})`)
11824
- .style('stroke-width', 0.5)
11825
- .style('stroke', 'var(--color-text-50)');
11826
- });
11827
- }
11828
- });
11829
- this._yAxisList.forEach((axis) => {
11830
- const translate = axis.options.opposite
11831
- ? `translate(${this._width - axis.offset}, ${0})`
11832
- : `translate(${axis.offset}, ${0})`;
11833
- const y = this._yScales.get(axis.index);
11834
- const yAxis = axis.options.opposite ? d3.axisRight(y) : d3.axisLeft(y);
11835
- if (axis.options.visible !== false) {
11836
- const labelOffset = axis.options.opposite
11837
- ? this._width - axis.offset + axis.width
11838
- : axis.offset - axis.width;
11839
- axes
11840
- .append('g')
11841
- .attr('class', 'y-axis-label')
11842
- .append('text')
11843
- .style('fill', 'var(--color-text-50)')
11844
- .attr('transform', 'rotate(-90)')
11845
- .attr('y', labelOffset)
11846
- .attr('x', 0 - this._height / 2)
11847
- .attr('dy', axis.options.opposite ? '12px' : '-3px')
11848
- .style('text-anchor', 'middle')
11849
- .text(axis.options.title ?? '');
11850
- axes
11851
- .append('g')
11852
- .attr('class', 'y-axis font-caption')
11853
- .attr('data-y-scale-id', axis.index)
11854
- .attr('transform', translate)
11855
- .call(yAxis)
11856
- .style('pointer-events', 'none')
11857
- .call((_) => {
11858
- _.select('.domain').remove();
11859
- _.selectAll('.tick').attr('class', 'color-text-50');
11860
- if (!negative) {
11861
- _.append('line')
11862
- .attr('y1', 0)
11863
- .attr('y2', this._height -
11864
- this._options.bounds.top -
11865
- this._options.bounds.bottom)
11866
- .attr('transform', `translate(${0}, ${this._options.bounds.top})`)
11867
- .style('stroke-width', 0.5)
11868
- .style('stroke', 'var(--color-text-50)');
11869
- }
11870
- });
11871
- }
11872
- });
11873
- }
11874
- }
11875
-
11876
- class ChartComponent {
11877
- constructor(_zone) {
11878
- this._zone = _zone;
11879
- this.plotLinesMove = new EventEmitter();
11880
- this.plotBandsMove = new EventEmitter();
11881
- this.seriesMove = new EventEmitter();
11882
- this.pointMove = new EventEmitter();
11883
- this.zoomChange = new EventEmitter();
11884
- this._alive = true;
11885
- this.size$ = new Subject();
11886
- }
11887
- click(event) {
11888
- const composedPath = event.composedPath();
11889
- const triggerToken = 'legend';
11890
- const isLegend = composedPath.some((_) => _.classList?.contains(triggerToken));
11891
- if (isLegend) {
11892
- const clickedElement = event.target?.__data__;
11893
- if (!clickedElement) {
11894
- return;
11895
- }
11896
- const serieIndex = this._config?.series?.indexOf(clickedElement);
11897
- if (clickedElement.serieType === SeriesType.bar) {
11898
- const foundSerie = this._config.series[clickedElement.serieIndex];
11899
- this._config.series[foundSerie.id].data = this._config.series[foundSerie.id].data.map((_) => {
11900
- if (clickedElement.id === _.id) {
11901
- return {
11902
- ..._,
11903
- visible: !_.visible,
11904
- };
11905
- }
11906
- return _;
11907
- });
11908
- this.redraw(this._config);
11909
- }
11910
- if (serieIndex !== -1) {
11911
- const foundSerie = this._config.series[serieIndex];
11912
- const yAxisIndex = foundSerie?.yAxisIndex;
11913
- this._config.series[serieIndex].visible = !foundSerie.visible;
11914
- const attachedYAxes = this._config.series
11915
- ?.filter((_) => _.visible)
11916
- .map((_) => _.yAxisIndex);
11917
- const shouldVisibleYAxis = attachedYAxes?.includes(yAxisIndex);
11918
- this._config.yAxis[yAxisIndex].visible = shouldVisibleYAxis;
11919
- this.redraw(this._config);
11920
- }
11921
- }
11922
- }
11923
- ngOnChanges(changes) {
11924
- if (this.config && changes.hasOwnProperty('config')) {
11925
- this.setConfig(this.config);
11926
- if (this.zoom) {
11927
- this._chart?.setZoom(this.zoom);
11928
- }
11929
- }
11930
- if (this.zoom && changes.hasOwnProperty('zoom')) {
11931
- this._chart?.setZoom(this.zoom);
11932
- }
11933
- }
11934
- ngOnInit() { }
11935
- ngAfterViewInit() {
11936
- this._observer = new ResizeObserver((entries) => {
11937
- const { contentRect } = entries[0];
11938
- this.size$.next(contentRect);
11939
- });
11940
- this._observer.observe(this.chart.nativeElement);
11941
- this.size$
11942
- .pipe(throttleTime(100, undefined, { trailing: true }))
11943
- .pipe(takeWhile((_) => this._alive), map((_) => {
11944
- this.resize(_);
11945
- this.redraw(this._config);
11946
- }))
11947
- .subscribe();
11948
- }
11949
- get showLegend() {
11950
- return this._config?.legend?.visible;
11951
- }
11952
- ngOnDestroy() {
11953
- this._alive = false;
11954
- this._observer?.unobserve(this.chart.nativeElement);
11955
- }
11956
- redraw(config) {
11957
- if (config) {
11958
- this._chart.redraw(config);
11959
- }
11960
- }
11961
- resize(contentRect) {
11962
- const { width, height } = contentRect;
11963
- this._chart.setSize({
11964
- width,
11965
- height,
11966
- });
11967
- }
11968
- setConfig(config) {
11969
- if (config) {
11970
- this._config = config;
11971
- this.hasSeriesData = !!this._config?.series?.some((_) => _.data.length);
11972
- if (!this._chart) {
11973
- this._chart = new TetaChart(this._config, this.chart);
11974
- this._chart.plotLinesMove
11975
- .pipe(takeWhile((_) => this._alive))
11976
- .subscribe((_) => this.plotLinesMove.emit(_));
11977
- this._chart.plotBandsMove
11978
- .pipe(takeWhile((_) => this._alive))
11979
- .subscribe((_) => this.plotBandsMove.emit(_));
11980
- this._chart.seriesMove
11981
- .pipe(takeWhile((_) => this._alive))
11982
- .subscribe((_) => this.seriesMove.emit(_));
11983
- this._chart.pointMove
11984
- .pipe(takeWhile((_) => this._alive))
11985
- .subscribe((_) => {
11986
- this.pointMove.emit(_);
11987
- });
11988
- this._chart.zoom
11989
- .pipe(takeWhile((_) => this._alive), map((_) => {
11990
- this.zoomChange.emit(_);
11991
- }))
11992
- .subscribe();
11993
- }
11994
- if (this.chart) {
11995
- if (this.hasSeriesData) {
11996
- if (!this._zoom || this._zoom?.event?.type === 'end') {
11997
- this.redraw(this._config);
11998
- }
11999
- }
12000
- }
12001
- }
12002
- }
12003
- }
12004
- ChartComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: ChartComponent, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
12005
- ChartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.0.1", type: ChartComponent, selector: "teta-chart", inputs: { zoom: "zoom", config: "config" }, outputs: { plotLinesMove: "plotLinesMove", plotBandsMove: "plotBandsMove", seriesMove: "seriesMove", pointMove: "pointMove", zoomChange: "zoomChange" }, host: { listeners: { "click": "click($event)" } }, viewQueries: [{ propertyName: "chart", first: true, predicate: ["chart"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div [style.display]=\"hasSeriesData ? 'contents' : 'none'\">\n <div #chart class=\"chart-container\"></div>\n <div *ngIf=\"showLegend\" class=\"legend-container\"></div>\n</div>\n<div [style.display]=\"!hasSeriesData ? 'block' : 'none'\" class=\"chart-placeholder text-align-center\">\n <span class=\"font-body-3 color-text-40\">\u0414\u0430\u043D\u043D\u044B\u0435 \u043E\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044E\u0442</span>\n</div>\n\n\n", styles: [":host{display:flex;width:100%;height:100%;flex-direction:column}.chart-container{position:relative;min-height:0;flex-grow:1;flex-basis:1px}.chart-placeholder{margin:auto;width:100%}.chart-placeholder span{text-overflow:ellipsis;overflow:hidden;display:block}.legend-container{flex-shrink:0;flex-basis:1px}::ng-deep .grid line{stroke-dasharray:1,4}::ng-deep .tooltip-chart{padding:8px 12px;border-radius:2px}::ng-deep .legend{grid-gap:8px;padding-bottom:5px;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-evenly}::ng-deep .legend .item{display:flex;align-items:center;cursor:pointer}::ng-deep .legend .item .swatch{width:10px;height:10px}::ng-deep .legend .item .line{width:12px;height:2px}::ng-deep .legend .item .label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-left:5px}\n"], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
12006
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: ChartComponent, decorators: [{
12007
- type: Component,
12008
- args: [{ selector: 'teta-chart', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [style.display]=\"hasSeriesData ? 'contents' : 'none'\">\n <div #chart class=\"chart-container\"></div>\n <div *ngIf=\"showLegend\" class=\"legend-container\"></div>\n</div>\n<div [style.display]=\"!hasSeriesData ? 'block' : 'none'\" class=\"chart-placeholder text-align-center\">\n <span class=\"font-body-3 color-text-40\">\u0414\u0430\u043D\u043D\u044B\u0435 \u043E\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044E\u0442</span>\n</div>\n\n\n", styles: [":host{display:flex;width:100%;height:100%;flex-direction:column}.chart-container{position:relative;min-height:0;flex-grow:1;flex-basis:1px}.chart-placeholder{margin:auto;width:100%}.chart-placeholder span{text-overflow:ellipsis;overflow:hidden;display:block}.legend-container{flex-shrink:0;flex-basis:1px}::ng-deep .grid line{stroke-dasharray:1,4}::ng-deep .tooltip-chart{padding:8px 12px;border-radius:2px}::ng-deep .legend{grid-gap:8px;padding-bottom:5px;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-evenly}::ng-deep .legend .item{display:flex;align-items:center;cursor:pointer}::ng-deep .legend .item .swatch{width:10px;height:10px}::ng-deep .legend .item .line{width:12px;height:2px}::ng-deep .legend .item .label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-left:5px}\n"] }]
12009
- }], ctorParameters: function () { return [{ type: i0.NgZone }]; }, propDecorators: { zoom: [{
12010
- type: Input
12011
- }], config: [{
12012
- type: Input
12013
- }], plotLinesMove: [{
12014
- type: Output
12015
- }], plotBandsMove: [{
12016
- type: Output
12017
- }], seriesMove: [{
12018
- type: Output
12019
- }], pointMove: [{
12020
- type: Output
12021
- }], zoomChange: [{
12022
- type: Output
12023
- }], chart: [{
12024
- type: ViewChild,
12025
- args: ['chart', {
12026
- static: true,
12027
- }]
12028
- }], click: [{
12029
- type: HostListener,
12030
- args: ['click', ['$event']]
12031
- }] } });
12032
-
12033
- class ChartModule {
12034
- }
12035
- ChartModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: ChartModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
12036
- ChartModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: ChartModule, declarations: [ChartComponent], imports: [CommonModule], exports: [ChartComponent] });
12037
- ChartModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: ChartModule, imports: [[CommonModule]] });
12038
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: ChartModule, decorators: [{
12039
- type: NgModule,
12040
- args: [{
12041
- declarations: [ChartComponent],
12042
- exports: [ChartComponent],
12043
- imports: [CommonModule],
12044
- }]
12045
- }] });
12046
-
12047
- class AxisOptions {
12048
- constructor(options) {
12049
- this.niceTicks = true;
12050
- this.title = options?.title;
12051
- this.min = options?.min;
12052
- this.max = options?.max;
12053
- this.visible = options?.visible ?? true;
12054
- this.tickFormat = options?.tickFormat;
12055
- this.transform = options?.transform;
12056
- this.zoom = options?.zoom;
12057
- this.type = options?.type ?? 'number';
12058
- this.scaleOptions = {
12059
- type: ScaleType.linear,
12060
- base: 10,
12061
- ...options?.scaleOptions,
12062
- };
12063
- this.inverted = options?.inverted;
12064
- this.negative = options?.negative;
12065
- this.opposite = options?.opposite;
12066
- this.niceTicks = options?.niceTicks == null ? true : options.niceTicks;
12067
- this.plotLines = options?.plotLines || [];
12068
- this.plotBands = options?.plotBands || [];
12069
- }
12070
- }
12071
-
12072
- class Series {
12073
- constructor(options) {
12074
- this.id = options?.id;
12075
- this.renderTo = options?.renderTo ?? 'svg';
12076
- this.type = options?.type != null ? options?.type : SeriesType.line;
12077
- this.curveType =
12078
- options?.curveType != null ? options?.curveType : d3.curveLinear;
12079
- this.data = options?.data?.filter((_) => !isNaN(_.x) && !isNaN(_.y));
12080
- this.axisFormat = options?.axisFormat;
12081
- this.name = options?.name;
12082
- this.xAxisIndex = options?.xAxisIndex != null ? options?.xAxisIndex : 0;
12083
- this.yAxisIndex = options?.yAxisIndex != null ? options?.yAxisIndex : 0;
12084
- this.drawer = options?.drawer;
12085
- this.strokeWidth = options?.strokeWidth;
12086
- this.strokeDasharray = options?.strokeDasharray ?? null;
12087
- this.visible = options?.visible || true;
12088
- this.color = options?.color ?? 'cyan';
12089
- this.colorScale = options?.colorScale;
12090
- this.drag = { enable: false, extendLine: false, ...options?.drag };
12091
- this.showInLegend =
12092
- options?.showInLegend != null ? options?.showInLegend : true;
12093
- this.extend = options?.extend != null ? options?.extend : false;
12094
- }
12095
- }
12096
-
12097
- class TooltipOptions {
12098
- constructor(options) {
12099
- const defaultFormatter = (tooltips) => {
12100
- let html = '';
12101
- tooltips
12102
- .filter((_) => _.point)
12103
- .forEach((_) => {
12104
- html += `<div>${_.name ?? 'Без названия'} x: ${_.point?.x?.toFixed(2)} y: ${_.point?.y?.toFixed(2)}</div>`;
12105
- });
12106
- return html;
12107
- };
12108
- this.enable = options?.enable ?? true;
12109
- this.showMarkers = options?.showMarkers ?? true;
12110
- this.showLine = options?.showLine ?? false;
12111
- this.tracking = options?.tracking ?? 'x';
12112
- this.format = options?.format ?? defaultFormatter;
12113
- }
12114
- }
12115
-
12116
- class ChartBounds {
12117
- constructor(options) {
12118
- this.top = 35;
12119
- this.right = 50;
12120
- this.bottom = 50;
12121
- this.left = 35;
12122
- this.top = options?.top || this.top;
12123
- this.right = options?.right || this.right;
12124
- this.bottom = options?.bottom || this.bottom;
12125
- this.left = options?.left || this.left;
12126
- }
12127
- }
12128
-
12129
- class ChartOptions {
12130
- constructor(options) {
12131
- this.bounds = new ChartBounds();
12132
- this.name = options?.name;
12133
- this.zoom = {
12134
- enable: false,
12135
- zoomType: ZoomType.x,
12136
- ...options?.zoom,
12137
- };
12138
- this.series = options?.series?.map((series, idx) => ({
12139
- ...series,
12140
- id: idx,
12141
- }));
12142
- this.zoom = { enable: false, zoomType: ZoomType.x, ...options?.zoom };
12143
- this.series = options?.series?.map((series, idx) => new Series(series));
12144
- this.tooltip = new TooltipOptions({ ...options?.tooltip });
12145
- this.xAxis = options?.xAxis?.map((_) => new AxisOptions(_));
12146
- this.yAxis = options?.yAxis?.map((_) => new AxisOptions(_));
12147
- this.gridLines = options?.gridLines == null ? true : options.gridLines;
12148
- this.width = options?.width;
12149
- this.height = options?.height;
12150
- this.legend = {
12151
- visible: true,
12152
- type: LegendType.swatches,
12153
- ...options?.legend,
12154
- };
12155
- this.bounds = { ...this.bounds, ...options?.bounds };
12156
- this.annotations = options?.annotations;
12157
- }
12158
- }
12159
-
12160
- const annotationMap = [
12161
- annotationBadge,
12162
- annotationLabel,
12163
- annotationCallout,
12164
- annotationCalloutCircle,
12165
- annotationCalloutCurve,
12166
- annotationCalloutElbow,
12167
- annotationCalloutRect,
12168
- annotationCustomType,
12169
- annotationXYThreshold,
12170
- ];
12171
- class Annotation {
12172
- constructor(options) {
12173
- this.point = options?.point;
12174
- this.yAxisIndex = options?.yAxisIndex;
12175
- this.xAxisIndex = options?.xAxisIndex;
12176
- this.type = options?.type || annotationLabel;
12177
- this.enabled = options?.enabled;
12178
- this.className = options?.className;
12179
- this.fillColor = options?.fillColor;
12180
- this.borderColor = options?.borderColor;
12181
- this.borderWidth = options?.borderWidth;
12182
- this.note = options?.note;
12183
- this.connector = options?.connector;
12184
- this.dx = options?.dx;
12185
- this.dy = options?.dy;
12186
- }
12187
- }
12188
-
12189
- class PlotLine {
12190
- constructor(options) {
12191
- this.id = options?.id;
12192
- this.width = options?.width || 1;
12193
- this.value = options?.value;
12194
- this.label = options?.label;
12195
- this.dashed = options?.dashed || false;
12196
- this.color = options?.color || 'var(--color-text-70)';
12197
- this.min = options?.min;
12198
- this.max = options?.max;
12199
- }
12200
- }
12201
-
12202
- class PlotBand {
12203
- constructor(options) {
12204
- this.id = options?.id;
12205
- this.from = options?.from;
12206
- this.to = options?.to;
12207
- this.label = options?.label;
12208
- this.color = options?.color || '#59AE501A';
12209
- this.image = options?.image;
12210
- this.showGrabbers =
12211
- options?.showGrabbers != null ? options.showGrabbers : true;
12212
- this.draggable = options?.draggable != null ? options?.draggable : false;
12213
- this.resizable = options?.resizable != null ? options?.resizable : true;
12214
- this.min = options?.min;
12215
- this.max = options?.max;
12216
- this.opacity = options?.opacity;
12217
- }
12218
- }
12219
-
12220
9962
  class Chart3dComponent {
12221
9963
  constructor(_elementRef, _themeService) {
12222
9964
  this._elementRef = _elementRef;
@@ -13239,5 +10981,5 @@ class StringUtil {
13239
10981
  * Generated bundle index. Do not edit.
13240
10982
  */
13241
10983
 
13242
- export { AccordionComponent, AccordionContentDirective, AccordionHeadComponent, AccordionItemComponent, AccordionModule, AggregationType, Align, Annotation, AreaDrawer, ArrayUtil, Axis, AxisOptions, AxisType, BarDrawer, BooleanCellComponent, BooleanFilter, BooleanFilterComponent, ButtonComponent, ButtonModule, CHECKBOX_CONTROL_VALUE_ACCESSOR, CellComponent, CellComponentBase, CellHostComponent, Chart3dComponent, Chart3dModule, Chart3dOptions, ChartBounds, ChartComponent, ChartModule, ChartOptions, CheckboxComponent, CheckboxModule, ClickOutsideDirective, ClickOutsideModule, ClickService, ColumnReorderEvent, ColumnResizeEvent, ContextMenuDirective, ContextMenuModule, CurrentModal, DATE_PICKER_CONTROL_VALUE_ACCESSOR, DAY_SELECT_CONTROL_VALUE_ACCESSOR, DateCellComponent, DateFilter, DateFilterComponent, DateFilterValue, DatePeriod, DatePickerComponent, DatePickerModule, DateTimeCellComponent, DateUtil, DaySelectComponent, DelimiterComponent, DelimiterModule, DetailComponentBase, DialogComponent, DialogService, DisableControlDirective, DisableControlModule, DomUtil, DragPointType, DragSortContainerDirective, DragSortItemDirective, DragSortModule, DropdownComponent, DropdownContentDirective, DropdownDirective, DropdownHeadDirective, DropdownModule, DynamicComponentModule, DynamicComponentService, DynamicContentBaseDirective, DynamicData, EditEvent, EditType, ExpandPanelComponent, ExpandPanelContentDirective, ExpandPanelHeadDirective, ExpandPanelModule, FileItemComponent, FileUploadAreaComponent, FileUploadModule, FilterBase, FilterComponentBase, FilterHostComponent, FilterItem, FilterModule, FilterPanelComponent, FilterState, FilterType, FormGroupTitleComponent, FormsUtil, GroupRowComponent, HeadCellComponentBase, HeadCellHostComponent, HighlightDirective, HighlightModule, HintDirective, HintModule, IconComponent, IconModule, IconService, IconSpriteDirective, InputComponent, InputModule, LegendType, LineDrawer, ListCellComponent, ListFilter, ListFilterComponent, ListFilterType, LoaderDirective, LoaderModule, MONTH_PICKER_CONTROL_VALUE_ACCESSOR, Message, MessageComponent, MessageHostComponent, MessageModule, MessageService, ModalCloseReason, ModalContainerComponent, ModalInstance, ModalModule, ModalService, MonthPickerComponent, NoAutofillDirective, NoAutofillModule, NumberPipe, NumberPipeModule, NumericCellComponent, NumericFilter, NumericFilterComponent, NumericFilterValue, OnlyNumberDirective, OnlyNumberModule, OverlayContainerService, PagerComponent, PagerModule, PagerState, PagerUtil, PanelComponent, PanelModule, PieDrawer, PlotBand, PlotLine, PopupContentComponent, PositionUtil, ProgressBarComponent, ProgressBarModule, PropertyGridComponent, PropertyGridModule, RadioButtonComponent, RadioComponent, RadioModule, ResizeDragDirective, ResizeDragModule, ResizePanelComponent, ResizePanelModule, SLIDER_CONTROL_VALUE_ACCESSOR, SWITCH_CONTROL_VALUE_ACCESSOR, Scale, ScaleType, ScatterDrawer, SelectComponent, SelectModule, SelectOptionDirective, SelectType, SelectValueDirective, Series, SeriesType, SidebarComponent, SidebarModule, SidebarPosition, SortEvent, SortParam, SplineDrawer, StateUtil, StringCellComponent, StringFilter, StringFilterComponent, StringFilterType, StringUtil, SwitchButtonComponent, SwitchComponent, SwitchModule, TOGGLE_CONTROL_VALUE_ACCESSOR, TabComponent, TabContentDirective, TabTitleDirective, TableBodyComponent, TableColumn, TableColumnStore, TableComponent, TableContextMenuConfig, TableHeadComponent, TableModule, TableRow, TableService, TableUtil, TabsComponent, TabsModule, TetaChart, TetaContentRef, TetaSize, TetaTemplateDirective, TetaTemplateModule, TextFieldComponent, ThemeSwitchComponent, ThemeSwitchModule, ThemeSwitchService, ToggleComponent, ToggleModule, ToolbarComponent, ToolbarModule, TooltipDirective, TooltipModule, TooltipOptions, TreeComponent, TreeItemToggleComponent, TreeModule, TreeService, VerticalAlign, ZoomType, getCellComponent };
10984
+ export { AccordionComponent, AccordionContentDirective, AccordionHeadComponent, AccordionItemComponent, AccordionModule, AggregationType, Align, ArrayUtil, BooleanCellComponent, BooleanFilter, BooleanFilterComponent, ButtonComponent, ButtonModule, CHECKBOX_CONTROL_VALUE_ACCESSOR, CellComponent, CellComponentBase, CellHostComponent, Chart3dComponent, Chart3dModule, Chart3dOptions, CheckboxComponent, CheckboxModule, ClickOutsideDirective, ClickOutsideModule, ClickService, ColumnReorderEvent, ColumnResizeEvent, ContextMenuDirective, ContextMenuModule, CurrentModal, DATE_PICKER_CONTROL_VALUE_ACCESSOR, DAY_SELECT_CONTROL_VALUE_ACCESSOR, DateCellComponent, DateFilter, DateFilterComponent, DateFilterValue, DatePeriod, DatePickerComponent, DatePickerModule, DateTimeCellComponent, DateUtil, DaySelectComponent, DelimiterComponent, DelimiterModule, DetailComponentBase, DialogComponent, DialogService, DisableControlDirective, DisableControlModule, DomUtil, DragSortContainerDirective, DragSortItemDirective, DragSortModule, DropdownComponent, DropdownContentDirective, DropdownDirective, DropdownHeadDirective, DropdownModule, DynamicComponentModule, DynamicComponentService, DynamicContentBaseDirective, DynamicData, EditEvent, EditType, ExpandPanelComponent, ExpandPanelContentDirective, ExpandPanelHeadDirective, ExpandPanelModule, FileItemComponent, FileUploadAreaComponent, FileUploadModule, FilterBase, FilterComponentBase, FilterHostComponent, FilterItem, FilterModule, FilterPanelComponent, FilterState, FilterType, FormGroupTitleComponent, FormsUtil, GroupRowComponent, HeadCellComponentBase, HeadCellHostComponent, HighlightDirective, HighlightModule, HintDirective, HintModule, IconComponent, IconModule, IconService, IconSpriteDirective, InputComponent, InputModule, ListCellComponent, ListFilter, ListFilterComponent, ListFilterType, LoaderDirective, LoaderModule, MONTH_PICKER_CONTROL_VALUE_ACCESSOR, Message, MessageComponent, MessageHostComponent, MessageModule, MessageService, ModalCloseReason, ModalContainerComponent, ModalInstance, ModalModule, ModalService, MonthPickerComponent, NoAutofillDirective, NoAutofillModule, NumberPipe, NumberPipeModule, NumericCellComponent, NumericFilter, NumericFilterComponent, NumericFilterValue, OnlyNumberDirective, OnlyNumberModule, OverlayContainerService, PagerComponent, PagerModule, PagerState, PagerUtil, PanelComponent, PanelModule, PopupContentComponent, PositionUtil, ProgressBarComponent, ProgressBarModule, PropertyGridComponent, PropertyGridModule, RadioButtonComponent, RadioComponent, RadioModule, ResizeDragDirective, ResizeDragModule, ResizePanelComponent, ResizePanelModule, SLIDER_CONTROL_VALUE_ACCESSOR, SWITCH_CONTROL_VALUE_ACCESSOR, SelectComponent, SelectModule, SelectOptionDirective, SelectType, SelectValueDirective, SidebarComponent, SidebarModule, SidebarPosition, SortEvent, SortParam, StateUtil, StringCellComponent, StringFilter, StringFilterComponent, StringFilterType, StringUtil, SwitchButtonComponent, SwitchComponent, SwitchModule, TOGGLE_CONTROL_VALUE_ACCESSOR, TabComponent, TabContentDirective, TabTitleDirective, TableBodyComponent, TableColumn, TableColumnStore, TableComponent, TableContextMenuConfig, TableHeadComponent, TableModule, TableRow, TableService, TableUtil, TabsComponent, TabsModule, TetaContentRef, TetaSize, TetaTemplateDirective, TetaTemplateModule, TextFieldComponent, ThemeSwitchComponent, ThemeSwitchModule, ThemeSwitchService, ToggleComponent, ToggleModule, ToolbarComponent, ToolbarModule, TooltipDirective, TooltipModule, TreeComponent, TreeItemToggleComponent, TreeModule, TreeService, VerticalAlign, formatNumber, getCellComponent, getPrecision, prependZero };
13243
10985
  //# sourceMappingURL=tetacom-ng-components.mjs.map