@tetacom/svg-charts 1.2.3 → 1.2.4

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 (32) hide show
  1. package/chart/chart/chart.component.d.ts +2 -1
  2. package/chart/chart-container/chart-container.component.d.ts +3 -5
  3. package/chart/chart-container/series/linear-series-base.d.ts +1 -1
  4. package/chart/chart-container/series/scatter-series/scatter-series.component.d.ts +0 -1
  5. package/chart/chart-container/x-axis/x-axis.component.d.ts +2 -4
  6. package/chart/core/axis/axis.d.ts +3 -0
  7. package/chart/service/chart.service.d.ts +4 -0
  8. package/chart/service/scale.service.d.ts +2 -0
  9. package/esm2020/chart/chart/chart.component.mjs +10 -2
  10. package/esm2020/chart/chart-container/annotation/annotation.component.mjs +3 -3
  11. package/esm2020/chart/chart-container/chart-container.component.mjs +10 -12
  12. package/esm2020/chart/chart-container/gridlines/gridlines.component.mjs +7 -7
  13. package/esm2020/chart/chart-container/series/area-series/area-series.component.mjs +5 -5
  14. package/esm2020/chart/chart-container/series/bar/bar-series.component.mjs +5 -5
  15. package/esm2020/chart/chart-container/series/block-area-series/block-area-series.component.mjs +3 -3
  16. package/esm2020/chart/chart-container/series/block-series/block-series.component.mjs +3 -3
  17. package/esm2020/chart/chart-container/series/linear-series-base.mjs +19 -21
  18. package/esm2020/chart/chart-container/series/scatter-series/scatter-series.component.mjs +3 -3
  19. package/esm2020/chart/chart-container/x-axis/x-axis.component.mjs +3 -27
  20. package/esm2020/chart/chart-container/y-axis/y-axis.component.mjs +3 -3
  21. package/esm2020/chart/core/axis/axis.mjs +7 -1
  22. package/esm2020/chart/default/default-axis-config.mjs +2 -2
  23. package/esm2020/chart/directives/zoomable.directive.mjs +4 -3
  24. package/esm2020/chart/service/brush.service.mjs +16 -13
  25. package/esm2020/chart/service/chart.service.mjs +6 -1
  26. package/esm2020/chart/service/scale.service.mjs +134 -1
  27. package/esm2020/chart/service/zoom.service.mjs +2 -2
  28. package/fesm2015/tetacom-svg-charts.mjs +233 -99
  29. package/fesm2015/tetacom-svg-charts.mjs.map +1 -1
  30. package/fesm2020/tetacom-svg-charts.mjs +225 -98
  31. package/fesm2020/tetacom-svg-charts.mjs.map +1 -1
  32. package/package.json +1 -1
@@ -7,9 +7,9 @@ import * as d3 from 'd3';
7
7
  import { zoomIdentity } from 'd3';
8
8
  import objectHash from 'object-hash';
9
9
  import { maxIndex } from 'd3-array';
10
+ import { debounceTime, tap as tap$1 } from 'rxjs/operators';
10
11
  import { tetaZoneFull } from '@tetacom/ng-components';
11
12
  import * as i3 from '@angular/platform-browser';
12
- import { tap as tap$1, debounceTime } from 'rxjs/operators';
13
13
 
14
14
  var ZoomType;
15
15
  (function (ZoomType) {
@@ -94,7 +94,7 @@ const defaultAxisConfig = {
94
94
  scaleType: {
95
95
  type: ScaleType.linear,
96
96
  },
97
- niceTicks: true,
97
+ niceTicks: false,
98
98
  };
99
99
 
100
100
  var SeriesType;
@@ -148,6 +148,7 @@ class ChartService {
148
148
  this.chartContextMenu$ = new Subject();
149
149
  this.annotationEvent$ = new Subject();
150
150
  this.annotationMove$ = new Subject();
151
+ this.zoomInstance$ = new Subject();
151
152
  this.id = of((Date.now() + Math.random()).toString(36));
152
153
  this.config = this.config$.asObservable().pipe(withLatestFrom(this.id), map(this.setDefaults), map(this.setPreparationData), map(this.restoreLocalStorage), shareReplay({
153
154
  bufferSize: 1,
@@ -174,6 +175,7 @@ class ChartService {
174
175
  this.plotBandContextMenu = this.plotBandEvent$
175
176
  .asObservable()
176
177
  .pipe(filter((_) => _?.event?.type === 'contextmenu'));
178
+ this.zoomInstance = this.zoomInstance$.asObservable();
177
179
  }
178
180
  setConfig(config) {
179
181
  this.clearTooltips();
@@ -240,6 +242,9 @@ class ChartService {
240
242
  emitChartContextMenu(event) {
241
243
  this.chartContextMenu$.next(event);
242
244
  }
245
+ emitZoomInstance(event) {
246
+ this.zoomInstance$.next(event);
247
+ }
243
248
  saveCookie(config) {
244
249
  if (!config.name)
245
250
  return;
@@ -361,7 +366,7 @@ class ZoomService {
361
366
  this.scaleHashMap = new Map();
362
367
  this.elementHashMap = new Map();
363
368
  this.zoomHashMap = new Map();
364
- this.zoomed$ = new BehaviorSubject(null);
369
+ this.zoomed$ = new BehaviorSubject({});
365
370
  this.zoomed = this.zoomed$.asObservable().pipe(shareReplay({
366
371
  bufferSize: 1,
367
372
  refCount: true
@@ -567,6 +572,9 @@ class Axis {
567
572
  setOriginDomain(domain) {
568
573
  this._originDomain = domain;
569
574
  }
575
+ setScale(scale) {
576
+ this._scale = scale;
577
+ }
570
578
  setSelfSize() {
571
579
  this._selfSize = new AxisSizeBuilder().build(this);
572
580
  }
@@ -579,6 +587,9 @@ class Axis {
579
587
  : this.chartConfig.yAxis[this.index];
580
588
  this._options = options;
581
589
  }
590
+ get scale() {
591
+ return this._scale;
592
+ }
582
593
  get extremes() {
583
594
  return this._extremes;
584
595
  }
@@ -706,6 +717,139 @@ class ScaleService {
706
717
  bufferSize: 1,
707
718
  refCount: true,
708
719
  }));
720
+ this.xMap = combineLatest([
721
+ this.chartService.size,
722
+ this.chartService.config,
723
+ this.zoomService.zoomed,
724
+ ]).pipe(map((data) => {
725
+ const [size, config, zoom] = data;
726
+ const xAxisMap = new Map();
727
+ const yAxisMap = new Map();
728
+ config.yAxis.map((_, index) => {
729
+ yAxisMap.set(index, Axis.createAxis(AxisOrientation.y, config, index));
730
+ });
731
+ config.xAxis.map((_, index) => {
732
+ xAxisMap.set(index, Axis.createAxis(AxisOrientation.x, config, index));
733
+ });
734
+ const left = Array.from(yAxisMap.values())
735
+ .filter((_) => _.options?.visible && _.options?.opposite)
736
+ .reduce((acc, cur) => acc + cur.selfSize, 0);
737
+ const right = Array.from(yAxisMap.values())
738
+ .filter((_) => _.options?.visible && _.options?.opposite !== true)
739
+ .reduce((acc, cur) => acc + cur.selfSize, 0);
740
+ const finalWidth = (size.width || 0) - left - right;
741
+ xAxisMap.forEach((axis) => {
742
+ let domain = axis.extremes;
743
+ if (axis?.options.inverted) {
744
+ domain = [...axis.extremes].reverse();
745
+ }
746
+ let scale = this.scaleMapping
747
+ .get(axis.options.scaleType.type)()
748
+ .domain(domain)
749
+ .range([0, finalWidth - config.bounds.right]);
750
+ if (axis.options.niceTicks) {
751
+ scale.nice();
752
+ }
753
+ if (axis.options.scaleType.type === ScaleType.log) {
754
+ scale.base(axis.options.scaleType.base);
755
+ }
756
+ axis.setScale(scale);
757
+ axis.setOriginDomain(scale.domain());
758
+ const hasCache = this.transformCacheX.has(axis.index);
759
+ const shouldRestore = zoom?.target?.orientation !== AxisOrientation.x ||
760
+ zoom.target?.index !== axis.index;
761
+ if (hasCache && shouldRestore) {
762
+ const restoredTransform = this.transformCacheX.get(axis.index);
763
+ axis.setScale(restoredTransform.rescaleX(scale));
764
+ }
765
+ });
766
+ if (zoom) {
767
+ const event = zoom.event;
768
+ if (zoom.target?.orientation === AxisOrientation.x) {
769
+ if (xAxisMap.has(zoom.target.index)) {
770
+ const x = xAxisMap.get(zoom.target.index);
771
+ const rescaled = event.transform.rescaleX(x.scale);
772
+ x.setScale(rescaled);
773
+ const axis = xAxisMap.get(zoom.target.index);
774
+ this.transformCacheX.set(axis.index, event.transform);
775
+ }
776
+ }
777
+ }
778
+ return xAxisMap;
779
+ }), shareReplay({
780
+ bufferSize: 1,
781
+ refCount: true,
782
+ }));
783
+ this.yMap = combineLatest([
784
+ this.chartService.size,
785
+ this.chartService.config,
786
+ this.zoomService.zoomed,
787
+ ]).pipe(map((data) => {
788
+ const [size, config, zoom] = data;
789
+ const xAxisMap = new Map();
790
+ const yAxisMap = new Map();
791
+ config.yAxis.map((_, index) => {
792
+ yAxisMap.set(index, Axis.createAxis(AxisOrientation.y, config, index));
793
+ });
794
+ config.xAxis.map((_, index) => {
795
+ xAxisMap.set(index, Axis.createAxis(AxisOrientation.x, config, index));
796
+ });
797
+ const top = Array.from(xAxisMap.values())
798
+ .filter((_) => _.options?.visible && _.options?.opposite)
799
+ .reduce((acc, cur) => acc + cur.selfSize, 0);
800
+ const bottom = Array.from(xAxisMap.values())
801
+ .filter((_) => _.options?.visible && _.options?.opposite !== true)
802
+ .reduce((acc, cur) => acc + cur.selfSize, 0);
803
+ const finalHeight = (size.height || 0) -
804
+ top -
805
+ bottom -
806
+ config?.bounds?.top -
807
+ config.bounds?.bottom;
808
+ yAxisMap.forEach((axis) => {
809
+ let domain = axis.extremes;
810
+ if (axis.orientation === AxisOrientation.y) {
811
+ domain = [...axis.extremes].reverse();
812
+ }
813
+ if (axis?.options.inverted) {
814
+ domain = domain.reverse();
815
+ }
816
+ const scale = this.scaleMapping
817
+ .get(axis.options.scaleType.type)()
818
+ .domain(domain)
819
+ .range([config.bounds.top, finalHeight]);
820
+ if (axis.options.niceTicks) {
821
+ scale.nice();
822
+ }
823
+ if (axis.options.scaleType.type === ScaleType.log) {
824
+ scale.base(axis.options.scaleType.base);
825
+ }
826
+ axis.setScale(scale);
827
+ axis.setOriginDomain(scale.domain());
828
+ const hasCache = this.transformCacheY.has(axis.index);
829
+ const shouldRestore = zoom?.target?.orientation !== AxisOrientation.y ||
830
+ zoom.target?.index !== axis.index;
831
+ if (hasCache && shouldRestore) {
832
+ const restoredTransform = this.transformCacheY.get(axis.index);
833
+ axis.setScale(restoredTransform.rescaleY(scale));
834
+ }
835
+ });
836
+ if (zoom) {
837
+ const event = zoom.event;
838
+ if (zoom.target?.orientation === AxisOrientation.y) {
839
+ if (yAxisMap.has(zoom.target.index)) {
840
+ const y = yAxisMap.get(zoom.target.index);
841
+ const rescaled = event.transform.rescaleY(y.scale);
842
+ y.setScale(rescaled);
843
+ const axis = yAxisMap.get(zoom.target.index);
844
+ this.transformCacheY.set(axis.index, event.transform);
845
+ }
846
+ }
847
+ }
848
+ return yAxisMap;
849
+ }), shareReplay({
850
+ bufferSize: 1,
851
+ refCount: true,
852
+ }));
709
853
  this.yScaleMap = combineLatest([
710
854
  this.chartService.size,
711
855
  this.chartService.config,
@@ -956,20 +1100,22 @@ class BrushService {
956
1100
  brushScale(domain[0]),
957
1101
  brushScale(domain[1]),
958
1102
  ]);
959
- if (m.message.event.type === 'end') {
960
- const brushMessage = new BrushMessage({
961
- event: null,
962
- selection: domain,
963
- brushType: config?.brush?.type ?? BrushType.x,
964
- brushScale,
965
- });
966
- this.broadcastService.broadcastBrush({
967
- channel: config?.zoom?.syncChannel,
968
- message: brushMessage,
969
- });
970
- }
971
1103
  this.selection = domain;
972
1104
  }
1105
+ }), debounceTime(30), tap((m) => {
1106
+ const { message: { domain }, } = m;
1107
+ if (m.message.event.type === 'zoom') {
1108
+ const brushMessage = new BrushMessage({
1109
+ event: null,
1110
+ selection: domain,
1111
+ brushType: config?.brush?.type ?? BrushType.x,
1112
+ brushScale,
1113
+ });
1114
+ this.broadcastService.broadcastBrush({
1115
+ channel: config?.zoom?.syncChannel,
1116
+ message: brushMessage,
1117
+ });
1118
+ }
973
1119
  }))
974
1120
  .subscribe();
975
1121
  }
@@ -1067,17 +1213,17 @@ class LinearSeriesBase extends SeriesBaseComponent {
1067
1213
  };
1068
1214
  this.defaultClipPointsMapping.set(ClipPointsDirection.x, filterX);
1069
1215
  this.defaultClipPointsMapping.set(ClipPointsDirection.y, filterY);
1070
- this.transform = this.svc.pointerMove.pipe(withLatestFrom(this.scaleService.xScaleMap, this.scaleService.yScaleMap), map((data) => {
1216
+ this.transform = this.svc.pointerMove.pipe(withLatestFrom(this.scaleService.xMap, this.scaleService.yMap), map((data) => {
1071
1217
  const [event, x, y] = data;
1072
- return this.getTransform(event, x, y);
1218
+ return this.getTransform(event, x.get(this.series.xAxisIndex).scale, y.get(this.series.yAxisIndex).scale);
1073
1219
  }), tap(() => setTimeout(() => this.cdr.detectChanges())));
1074
1220
  this.path = combineLatest([
1075
- this.scaleService.xScaleMap,
1076
- this.scaleService.yScaleMap,
1221
+ this.scaleService.xMap,
1222
+ this.scaleService.yMap,
1077
1223
  ]).pipe(map((data) => {
1078
1224
  const [x, y] = data;
1079
- this.x = x.get(this.series.xAxisIndex);
1080
- this.y = y.get(this.series.yAxisIndex);
1225
+ this.x = x.get(this.series.xAxisIndex).scale;
1226
+ this.y = y.get(this.series.yAxisIndex).scale;
1081
1227
  const filter = this.defaultClipPointsMapping.get(this.series.clipPointsDirection);
1082
1228
  const line = d3
1083
1229
  .line()
@@ -1160,8 +1306,6 @@ class LinearSeriesBase extends SeriesBaseComponent {
1160
1306
  return null;
1161
1307
  }
1162
1308
  const mouse = [event?.offsetX, event?.offsetY];
1163
- const foundX = scaleX.get(this.series.xAxisIndex);
1164
- const foundY = scaleY.get(this.series.yAxisIndex);
1165
1309
  const tooltipTracking = this.config?.tooltip?.tracking;
1166
1310
  const lineIntersection = (p0_x, p0_y, p1_x, p1_y, p2_x, p2_y, p3_x, p3_y) => {
1167
1311
  const rV = {};
@@ -1187,18 +1331,18 @@ class LinearSeriesBase extends SeriesBaseComponent {
1187
1331
  if (tooltipTracking === TooltipTracking.x) {
1188
1332
  const bisect = d3.bisector((_) => _.x).right;
1189
1333
  const pointer = mouse[0];
1190
- let x0 = foundX.invert(pointer);
1334
+ let x0 = scaleX.invert(pointer);
1191
1335
  if (x0 instanceof Date) {
1192
1336
  x0 = x0.getTime();
1193
1337
  }
1194
1338
  const rightId = bisect(this.series.data, x0);
1195
- const range = foundY.range();
1196
- const intersect = lineIntersection(pointer, range[0], pointer, range[1], foundX(this.series.data[rightId - 1]?.x), foundY(this.series.data[rightId - 1]?.y), foundX(this.series.data[rightId]?.x), foundY(this.series.data[rightId]?.y));
1197
- const x = foundX.invert(intersect.x);
1198
- const y = foundY.invert(intersect.y);
1339
+ const range = scaleY.range();
1340
+ const intersect = lineIntersection(pointer, range[0], pointer, range[1], scaleX(this.series.data[rightId - 1]?.x), scaleY(this.series.data[rightId - 1]?.y), scaleX(this.series.data[rightId]?.x), scaleY(this.series.data[rightId]?.y));
1341
+ const x = scaleX.invert(intersect.x);
1342
+ const y = scaleY.invert(intersect.y);
1199
1343
  if (x !== null && x !== undefined && !isNaN(x) && y !== null && y !== undefined && !isNaN(y)) {
1200
1344
  this.svc.setTooltip({
1201
- point: { x: foundX.invert(intersect.x), y: foundY.invert(intersect.y) },
1345
+ point: { x: scaleX.invert(intersect.x), y: scaleY.invert(intersect.y) },
1202
1346
  series: this.series,
1203
1347
  });
1204
1348
  }
@@ -1215,18 +1359,18 @@ class LinearSeriesBase extends SeriesBaseComponent {
1215
1359
  }
1216
1360
  if (tooltipTracking === TooltipTracking.y) {
1217
1361
  const bisect = d3.bisector((_) => _.y).right;
1218
- let y0 = foundY.invert(mouse[1]);
1362
+ let y0 = scaleY.invert(mouse[1]);
1219
1363
  if (y0 instanceof Date) {
1220
1364
  y0 = y0.getTime();
1221
1365
  }
1222
1366
  const rightId = bisect(this.series.data, y0);
1223
- const range = foundX.range();
1224
- const intersect = lineIntersection(range[0], mouse[1], range[1], mouse[1], foundX(this.series.data[rightId - 1]?.x), foundY(this.series.data[rightId - 1]?.y), foundX(this.series.data[rightId]?.x), foundY(this.series.data[rightId]?.y));
1225
- const x = foundX.invert(intersect.x);
1226
- const y = foundY.invert(intersect.y);
1367
+ const range = scaleX.range();
1368
+ const intersect = lineIntersection(range[0], mouse[1], range[1], mouse[1], scaleX(this.series.data[rightId - 1]?.x), scaleY(this.series.data[rightId - 1]?.y), scaleX(this.series.data[rightId]?.x), scaleY(this.series.data[rightId]?.y));
1369
+ const x = scaleX.invert(intersect.x);
1370
+ const y = scaleY.invert(intersect.y);
1227
1371
  if (x !== null && x !== undefined && !isNaN(x) && y !== null && y !== undefined && !isNaN(y)) {
1228
1372
  this.svc.setTooltip({
1229
- point: { x: foundX.invert(intersect.x), y: foundY.invert(intersect.y) },
1373
+ point: { x: scaleX.invert(intersect.x), y: scaleY.invert(intersect.y) },
1230
1374
  series: this.series,
1231
1375
  });
1232
1376
  }
@@ -1284,8 +1428,8 @@ class BarSeriesComponent extends SeriesBaseComponent {
1284
1428
  const count = _.series.filter((_) => _.type === SeriesType.bar && _.xAxisIndex === this.series.xAxisIndex);
1285
1429
  return count.length;
1286
1430
  }));
1287
- this.x1 = this.scaleService.xScaleMap.pipe(map((_) => {
1288
- const x = _.get(this.series.xAxisIndex);
1431
+ this.x1 = this.scaleService.xMap.pipe(map((_) => {
1432
+ const x = _.get(this.series.xAxisIndex).scale;
1289
1433
  const range = x.range();
1290
1434
  const domain = this.series.data.map((_) => _.x);
1291
1435
  return d3
@@ -1294,8 +1438,8 @@ class BarSeriesComponent extends SeriesBaseComponent {
1294
1438
  .domain(domain)
1295
1439
  .padding(0.1);
1296
1440
  }));
1297
- this.x = this.scaleService.xScaleMap.pipe(map((_) => _.get(this.series.xAxisIndex)));
1298
- this.y = this.scaleService.yScaleMap.pipe(map((_) => _.get(this.series.yAxisIndex)));
1441
+ this.x = this.scaleService.xMap.pipe(map((_) => _.get(this.series.xAxisIndex).scale));
1442
+ this.y = this.scaleService.yMap.pipe(map((_) => _.get(this.series.yAxisIndex).scale));
1299
1443
  }
1300
1444
  mouseenter(point) {
1301
1445
  this.svc.setTooltip({
@@ -1328,8 +1472,8 @@ class ScatterSeriesComponent extends SeriesBaseComponent {
1328
1472
  this.element = element;
1329
1473
  }
1330
1474
  ngOnInit() {
1331
- this.x = this.scaleService.xScaleMap.pipe(map(_ => _.get(this.series.xAxisIndex)));
1332
- this.y = this.scaleService.yScaleMap.pipe(map(_ => _.get(this.series.yAxisIndex)));
1475
+ this.x = this.scaleService.xMap.pipe(map(_ => _.get(this.series.xAxisIndex).scale));
1476
+ this.y = this.scaleService.yMap.pipe(map(_ => _.get(this.series.yAxisIndex).scale));
1333
1477
  }
1334
1478
  ngAfterViewInit() {
1335
1479
  }
@@ -1367,8 +1511,8 @@ class BlockSeriesComponent extends SeriesBaseComponent {
1367
1511
  }
1368
1512
  ngOnInit() {
1369
1513
  const defaultVisiblePixels = 0;
1370
- this.x = this.scaleService.xScaleMap.pipe(map((_) => _.get(this.series.xAxisIndex)));
1371
- this.y = this.scaleService.yScaleMap.pipe(map((_) => _.get(this.series.yAxisIndex)));
1514
+ this.x = this.scaleService.xMap.pipe(map((_) => _.get(this.series.xAxisIndex).scale));
1515
+ this.y = this.scaleService.yMap.pipe(map((_) => _.get(this.series.yAxisIndex).scale));
1372
1516
  this.displayPoints = this.y.pipe(map((y) => {
1373
1517
  return this.series.data.filter((point, index, arr) => {
1374
1518
  const [min, max] = y.domain();
@@ -1419,8 +1563,8 @@ class BlockAreaSeriesComponent extends SeriesBaseComponent {
1419
1563
  }
1420
1564
  ngOnInit() {
1421
1565
  const defaultVisiblePixels = 0;
1422
- this.x = this.scaleService.xScaleMap.pipe(map((_) => _.get(this.series.xAxisIndex)));
1423
- this.y = this.scaleService.yScaleMap.pipe(map((_) => _.get(this.series.yAxisIndex)));
1566
+ this.x = this.scaleService.xMap.pipe(map((_) => _.get(this.series.xAxisIndex).scale));
1567
+ this.y = this.scaleService.yMap.pipe(map((_) => _.get(this.series.yAxisIndex).scale));
1424
1568
  this.displayPoints = this.y.pipe(map((y) => {
1425
1569
  return this.series.data.filter((point, index, arr) => {
1426
1570
  const [min, max] = y.domain();
@@ -1472,12 +1616,12 @@ class AreaSeriesComponent extends LinearSeriesBase {
1472
1616
  ngOnInit() {
1473
1617
  super.ngOnInit();
1474
1618
  this.areaPath = combineLatest([
1475
- this.scaleService.xScaleMap,
1476
- this.scaleService.yScaleMap,
1619
+ this.scaleService.xMap,
1620
+ this.scaleService.yMap,
1477
1621
  ]).pipe(map((data) => {
1478
1622
  const [x, y] = data;
1479
- this.x = x.get(this.series.xAxisIndex);
1480
- this.y = y.get(this.series.yAxisIndex);
1623
+ this.x = x.get(this.series.xAxisIndex).scale;
1624
+ this.y = y.get(this.series.yAxisIndex).scale;
1481
1625
  const area = d3
1482
1626
  .area()
1483
1627
  .defined((point) => point.x !== null &&
@@ -1567,16 +1711,16 @@ class GridlinesComponent {
1567
1711
  this.svc = svc;
1568
1712
  this.chartService = chartService;
1569
1713
  this.config = this.chartService.config;
1570
- this.tickYValues = this.svc.yScaleMap.pipe(map((_) => {
1714
+ this.tickYValues = this.svc.yMap.pipe(map((_) => {
1571
1715
  const ratio = this.size.height / 40;
1572
- return _.get(0).ticks(ratio);
1716
+ return _.get(0).scale.ticks(ratio);
1573
1717
  }));
1574
- this.tickXValues = this.svc.xScaleMap.pipe(map((_) => {
1718
+ this.tickXValues = this.svc.xMap.pipe(map((_) => {
1575
1719
  const ratio = this.size.width / 40;
1576
- return _.get(0).ticks(ratio);
1720
+ return _.get(0).scale.ticks(ratio);
1577
1721
  }));
1578
- this.y = this.svc.yScaleMap.pipe(map((_) => _.get(0)));
1579
- this.x = this.svc.xScaleMap.pipe(map((_) => _.get(0)));
1722
+ this.y = this.svc.yMap.pipe(map((_) => _.get(0).scale));
1723
+ this.x = this.svc.xMap.pipe(map((_) => _.get(0).scale));
1580
1724
  }
1581
1725
  ngAfterViewInit() {
1582
1726
  }
@@ -1594,8 +1738,8 @@ class XAxisComponent {
1594
1738
  constructor(scaleService) {
1595
1739
  this.scaleService = scaleService;
1596
1740
  this._alive = true;
1597
- this.x = this.scaleService.xScaleMap.pipe(map((_) => {
1598
- return _.get(this.axis.index);
1741
+ this.x = this.scaleService.xMap.pipe(map((_) => {
1742
+ return _.get(this.axis.index)?.scale;
1599
1743
  }));
1600
1744
  }
1601
1745
  getLabelTransform() {
@@ -1605,30 +1749,6 @@ class XAxisComponent {
1605
1749
  ngOnDestroy() {
1606
1750
  this._alive = false;
1607
1751
  }
1608
- ngAfterViewInit() {
1609
- // this.draw();
1610
- }
1611
- draw() {
1612
- // if (!this.node || !this.axis) {
1613
- // return;
1614
- // }
1615
- //
1616
- // const axis = this.axis.options.opposite
1617
- // ? d3
1618
- // .axisTop(this.scale)
1619
- // .tickFormat(
1620
- // this.axis.options.tickFormat ?? this.axis.defaultFormatter()
1621
- // )
1622
- // : d3
1623
- // .axisBottom(this.scale)
1624
- // .tickFormat(
1625
- // this.axis.options.tickFormat ?? this.axis.defaultFormatter()
1626
- // );
1627
- //
1628
- // d3.select(this.node.nativeElement)
1629
- // .call(axis)
1630
- // .call((_) => _.select('.domain').remove());
1631
- }
1632
1752
  }
1633
1753
  XAxisComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: XAxisComponent, deps: [{ token: ScaleService }], target: i0.ɵɵFactoryTarget.Component });
1634
1754
  XAxisComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.2", type: XAxisComponent, selector: "[teta-x-axis]", inputs: { axis: "axis", size: "size" }, ngImport: i0, template: "<ng-container *ngIf=\"x | async as scale\">\n <svg:g text-anchor=\"middle\" *ngFor=\"let tick of scale.ticks()\" [attr.transform]=\"'translate('+ scale(tick) +', 0)'\">\n <text fill=\"var(--color-text-70)\" [attr.dy]=\"axis.options.opposite ? '-0.71em' : '0.71em'\" [attr.y]=\"axis.options.opposite ? 0 : 9\">{{ this.axis.options.tickFormat ? this.axis.options.tickFormat(tick) : this.axis.defaultFormatter()(tick) }}</text>\n <line stroke=\"var(--color-text-30)\" [attr.y2]=\"axis.options.opposite ? -6 : 6\"></line>\n </svg:g>\n\n <svg:g class=\"label-axis font-caption\" [attr.transform]=\"getLabelTransform()\">\n <text fill=\"var(--color-text-70)\" text-anchor=\"middle\" dominant-baseline=\"middle\">{{ axis.options.title }}</text>\n </svg:g>\n</ng-container>\n\n", styles: [":host .tick{stroke:var(--color-text-20)}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
@@ -1645,8 +1765,8 @@ class YAxisComponent {
1645
1765
  constructor(scaleService) {
1646
1766
  this.scaleService = scaleService;
1647
1767
  this._alive = true;
1648
- this.y = this.scaleService.yScaleMap.pipe(map((_) => {
1649
- return _.get(this.axis.index);
1768
+ this.y = this.scaleService.yMap.pipe(map((_) => {
1769
+ return _.get(this.axis.index)?.scale;
1650
1770
  }));
1651
1771
  }
1652
1772
  ngOnInit() { }
@@ -2069,6 +2189,7 @@ class ZoomableDirective {
2069
2189
  this.zoom.scaleExtent([maxZoom, minZoom]);
2070
2190
  this.zoom.on('zoom end', this.zoomed);
2071
2191
  this._element.call(this.zoom).on('dblclick.zoom', null); // Disable dbclick zoom
2192
+ this.chartService.emitZoomInstance(this.zoomService);
2072
2193
  if (this.config?.zoom?.zoomBehavior === ZoomBehaviorType.wheel) {
2073
2194
  this.runWheelZoom();
2074
2195
  }
@@ -2121,7 +2242,7 @@ class ZoomableDirective {
2121
2242
  .pipe(combineLatestWith(this.chartService.size), takeWhile((_) => this.alive), filter((data) => {
2122
2243
  const [m] = data;
2123
2244
  return Boolean(m.message.selection);
2124
- }), debounceTime(150), tap$1((data) => {
2245
+ }), tap$1((data) => {
2125
2246
  const [m] = data;
2126
2247
  const currentTransform = d3.zoomTransform(this._element.node());
2127
2248
  if (!m.message.event &&
@@ -2300,8 +2421,8 @@ class AnnotationComponent {
2300
2421
  this.scaleService = scaleService;
2301
2422
  this.cdr = cdr;
2302
2423
  this.chartService = chartService;
2303
- this.x = this.scaleService.xScaleMap.pipe(map((_) => _.get(this.annotation.xAxisIndex ?? 0)));
2304
- this.y = this.scaleService.yScaleMap.pipe(map((_) => _.get(this.annotation.yAxisIndex ?? 0)));
2424
+ this.x = this.scaleService.xMap.pipe(map((_) => _.get(this.annotation.xAxisIndex ?? 0).scale));
2425
+ this.y = this.scaleService.yMap.pipe(map((_) => _.get(this.annotation.yAxisIndex ?? 0).scale));
2305
2426
  this.drag = d3.drag();
2306
2427
  }
2307
2428
  set annotation(annotation) {
@@ -2415,27 +2536,25 @@ class ChartContainerComponent {
2415
2536
  this.sumSize = (acc, curr) => acc + curr.selfSize;
2416
2537
  this.config = this._svc.config;
2417
2538
  this.size = this._svc.size;
2418
- this.yAxisMap = this._scaleService.yAxisMap;
2419
- this.xAxisMap = this._scaleService.xAxisMap;
2420
- this.yScaleMap = this._scaleService.yScaleMap.pipe(observeOn(animationFrameScheduler, 10), tetaZoneFull(this._zone), shareReplay({
2539
+ this.yMap = this._scaleService.yMap.pipe(observeOn(animationFrameScheduler), tetaZoneFull(this._zone), shareReplay({
2421
2540
  bufferSize: 1,
2422
2541
  refCount: true,
2423
2542
  }));
2424
- this.xScaleMap = this._scaleService.xScaleMap.pipe(observeOn(animationFrameScheduler, 10), tetaZoneFull(this._zone), shareReplay({
2543
+ this.xMap = this._scaleService.xMap.pipe(observeOn(animationFrameScheduler), tetaZoneFull(this._zone), shareReplay({
2425
2544
  bufferSize: 1,
2426
2545
  refCount: true,
2427
2546
  }));
2428
2547
  this.brushScale = combineLatest([
2429
- this._scaleService.xScaleMap,
2430
- this._scaleService.yScaleMap,
2548
+ this._scaleService.xMap,
2549
+ this._scaleService.yMap,
2431
2550
  ]).pipe(withLatestFrom(this.config), map((data) => {
2432
2551
  const [[x, y], config] = data;
2433
- return config.brush?.type === BrushType.x || config?.zoom?.type === ZoomType.x ? x.get(0) : y.get(0);
2552
+ return config.brush?.type === BrushType.x || config?.zoom?.type === ZoomType.x ? x.get(0).scale : y.get(0).scale;
2434
2553
  }), shareReplay({
2435
2554
  bufferSize: 1,
2436
2555
  refCount: true,
2437
2556
  }));
2438
- this.visibleRect = this.size.pipe(combineLatestWith(this.xAxisMap, this.yAxisMap)).pipe(withLatestFrom(this.config), map((data) => {
2557
+ this.visibleRect = this.size.pipe(combineLatestWith(this.xMap, this.yMap)).pipe(withLatestFrom(this.config), map((data) => {
2439
2558
  const [[size, x, y], config] = data;
2440
2559
  const yAxesArray = [...y.values()];
2441
2560
  const xAxesArray = [...x.values()];
@@ -2490,7 +2609,7 @@ class ChartContainerComponent {
2490
2609
  this._observer.disconnect();
2491
2610
  }
2492
2611
  getTranslate(axis, size) {
2493
- return combineLatest([this.xAxisMap, this.yAxisMap]).pipe(withLatestFrom(this.config), map((data) => {
2612
+ return combineLatest([this.xMap, this.yMap]).pipe(withLatestFrom(this.config), map((data) => {
2494
2613
  const [[x, y], config] = data;
2495
2614
  const xAxesArray = [...x.values()];
2496
2615
  const yAxesArray = [...y.values()];
@@ -2556,10 +2675,10 @@ class ChartContainerComponent {
2556
2675
  }
2557
2676
  }
2558
2677
  ChartContainerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: ChartContainerComponent, deps: [{ token: ChartService }, { token: i0.ChangeDetectorRef }, { token: ScaleService }, { token: ZoomService }, { token: i0.ElementRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
2559
- ChartContainerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.2", type: ChartContainerComponent, selector: "teta-chart-container", ngImport: i0, template: "<ng-container *ngIf=\"{\n size: size | async,\n config: config | async,\n xAxisMap: xAxisMap | async,\n yAxisMap: yAxisMap | async,\n xScaleMap: xScaleMap | async,\n yScaleMap: yScaleMap | async,\n visibleRect: visibleRect | async,\n brushScale: brushScale | async\n} as data\" xmlns:svg=\"http://www.w3.org/1999/html\">\n <teta-tooltip *ngIf=\"data.config?.tooltip?.enable\"\n [size]=\"data.size\"\n [config]=\"data.config\"></teta-tooltip>\n <ng-container *ngIf=\"data.visibleRect?.width > 0 && data.visibleRect?.height > 0 && data.xScaleMap && data.yScaleMap\">\n <svg height=\"100%\" width=\"100%\" class=\"position-absolute\">\n <g class=\"y-axis-container\">\n <ng-container *ngFor=\"let item of data.yAxisMap | keyvalue; trackBy: identify\">\n <ng-container *ngIf=\"item.value.options.visible\">\n <g\n teta-y-axis\n [axis]=\"item.value\"\n [size]=\"data.visibleRect\"\n [attr.transform]=\"getTranslate(item.value, data.size) | async\"></g>\n <rect\n tetaZoomable\n fill-opacity=\"0\"\n [brushScale]=\"data.brushScale\"\n [scale]=\"data.yScaleMap.get(item.key)\"\n [axis]=\"item.value\"\n [config]=\"data.config\"\n [size]=\"data.visibleRect\"\n [attr.x]=\"item.value.options.opposite ? 0 : -item.value.selfSize\"\n [attr.y]=\"0\"\n [attr.height]=\"data.visibleRect.height\"\n [attr.width]=\"item.value.selfSize\"\n [attr.transform]=\"getTranslate(item.value, data.size) | async\"></rect>\n </ng-container>\n\n </ng-container>\n </g>\n <g class=\"x-axis-container\">\n <ng-container *ngFor=\"let item of data.xAxisMap | keyvalue; trackBy: identify\">\n <ng-container *ngIf=\"item.value.options.visible && data.xScaleMap && data.yScaleMap\">\n <g\n teta-x-axis\n [axis]=\"item.value\"\n [size]=\"data.visibleRect\"\n [attr.transform]=\"getTranslate(item.value, data.size) | async\"></g>\n <rect\n tetaZoomable\n fill-opacity=\"0\"\n [brushScale]=\"data.brushScale\"\n [scale]=\"data.xScaleMap.get(item.key)\"\n [axis]=\"item.value\"\n [config]=\"data.config\"\n [size]=\"data.visibleRect\"\n [attr.x]=\"0\"\n [attr.y]=\"item.value.options.opposite ? -item.value.selfSize : 0\"\n [attr.width]=\"data.visibleRect.width\"\n [attr.height]=\"item.value.selfSize\"\n [attr.transform]=\"getTranslate(item.value, data.size) | async\"></rect>\n </ng-container>\n </ng-container>\n </g>\n </svg>\n </ng-container>\n <ng-container *ngIf=\"data.visibleRect?.width > 0 && data.visibleRect?.height > 0 && data.xScaleMap && data.yScaleMap\">\n <svg\n tetaBrushable\n tetaZoomable\n class=\"position-absolute\"\n [size]=\"data.visibleRect\"\n [brushScale]=\"data.brushScale\"\n [scale]=\"data.brushScale\"\n [config]=\"data.config\"\n [axis]=\"data.config?.zoom?.type === zoomType.x ? data.xAxisMap.get(0) : data.yAxisMap.get(0)\"\n [attr.width]=\"data.visibleRect.width\"\n [attr.height]=\"data.visibleRect.height\"\n [attr.viewBox]=\"'0 0 ' + data.visibleRect.width + ' ' + data.visibleRect.height\"\n [style.transform]=\"'translate('+ data.visibleRect.x +'px, '+ data.visibleRect.y +'px)'\"\n (contextmenu)=\"contextMenu($event, data.xScaleMap, data.yScaleMap)\"\n (click)=\"click($event, data.xScaleMap, data.yScaleMap)\"\n (mouseleave)=\"mouseLeave($event)\"\n (mousemove)=\"mouseMove($event)\">\n\n <g class=\"gridlines\"\n teta-gridlines\n *ngIf=\"data.config.gridLines?.enable !== false\"\n [size]=\"data.size\"></g>\n\n <g class=\"x-axis-plotband-container\">\n <ng-container *ngFor=\"let axis of data.config.xAxis; let i = index\">\n <g teta-plot-band *ngFor=\"let plotBand of axis.plotBands\"\n [plotBand]=\"plotBand\"\n [scale]=\"data.xScaleMap.get(i)\"\n [size]=\"data.size\"\n [axis]=\"data.xAxisMap.get(i)\"></g>\n </ng-container>\n </g>\n <g class=\"y-axis-plotband-container\">\n <ng-container *ngFor=\"let axis of data.config.yAxis; let i = index\">\n <g teta-plot-band *ngFor=\"let plotBand of axis.plotBands\"\n [plotBand]=\"plotBand\"\n [scale]=\"data.yScaleMap.get(i)\"\n [size]=\"data.size\"\n [axis]=\"data.yAxisMap.get(i)\"></g>\n </ng-container>\n </g>\n <g class=\"x-axis-plotline-container\">\n <ng-container *ngFor=\"let axis of data.config.xAxis; let i = index\">\n <g teta-plot-line *ngFor=\"let plotLine of axis.plotLines\"\n [plotLine]=\"plotLine\"\n [scale]=\"data.xScaleMap.get(i)\"\n [size]=\"data.size\"\n [axis]=\"data.xAxisMap.get(i)\"></g>\n </ng-container>\n </g>\n <g class=\"y-axis-plotline-container\">\n <ng-container *ngFor=\"let axis of data.config.yAxis; let i = index\">\n <g teta-plot-line *ngFor=\"let plotLine of axis.plotLines\"\n [plotLine]=\"plotLine\"\n [scale]=\"data.yScaleMap.get(i)\"\n [size]=\"data.size\"\n [axis]=\"data.yAxisMap.get(i)\"></g>\n </ng-container>\n </g>\n <g class=\"series-container\">\n <ng-container *ngFor=\"let series of data.config.series\">\n <g teta-series-host\n *ngIf=\"series.visible\"\n [config]=\"data.config\"\n [series]=\"series\"></g>\n </ng-container>\n </g>\n <g class=\"annotations\">\n <g teta-annotation\n *ngFor=\"let annotation of data.config.annotations\"\n [annotation]=\"annotation\"></g>\n </g>\n <g class=\"crosshair\" *ngIf=\"data.config.tooltip?.showCrosshair\">\n <g teta-crosshair [size]=\"data.visibleRect\"></g>\n </g>\n </svg>\n\n </ng-container>\n</ng-container>\n", styles: [":host{display:flex;flex-direction:column;flex-grow:1;min-width:0;min-height:0}:host .zoomable:hover{cursor:grab}:host .zoomable:active{cursor:grabbing}:host .crosshair{cursor:crosshair}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: SeriesHostComponent, selector: "[teta-series-host]", inputs: ["config", "series"] }, { kind: "component", type: GridlinesComponent, selector: "[teta-gridlines]", inputs: ["size"] }, { kind: "component", type: XAxisComponent, selector: "[teta-x-axis]", inputs: ["axis", "size"] }, { kind: "component", type: YAxisComponent, selector: "[teta-y-axis]", inputs: ["axis", "size"] }, { kind: "component", type: PlotlineComponent, selector: "[teta-plot-line]", inputs: ["plotLine", "size", "axis", "scale"] }, { kind: "component", type: PlotBandComponent, selector: "[teta-plot-band]", inputs: ["plotBand", "axis", "scale", "size"] }, { kind: "component", type: TooltipComponent, selector: "teta-tooltip", inputs: ["size", "config"] }, { kind: "directive", type: ZoomableDirective, selector: "[tetaZoomable]", inputs: ["config", "axis", "size", "brushScale", "scale"] }, { kind: "directive", type: BrushableDirective, selector: "[tetaBrushable]", inputs: ["config", "brushScale"] }, { kind: "component", type: AnnotationComponent, selector: "[teta-annotation]", inputs: ["annotation"] }, { kind: "component", type: CrosshairComponent, selector: "[teta-crosshair]", inputs: ["size"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i4.KeyValuePipe, name: "keyvalue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2678
+ ChartContainerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.2", type: ChartContainerComponent, selector: "teta-chart-container", ngImport: i0, template: "<ng-container *ngIf=\"{\n size: size | async,\n config: config | async,\n yMap: yMap | async,\n xMap: xMap | async,\n visibleRect: visibleRect | async,\n brushScale: brushScale | async\n} as data\" xmlns:svg=\"http://www.w3.org/1999/html\">\n <teta-tooltip *ngIf=\"data.config?.tooltip?.enable\"\n [size]=\"data.size\"\n [config]=\"data.config\"></teta-tooltip>\n <ng-container *ngIf=\"data.visibleRect?.width > 0 && data.visibleRect?.height > 0 && data.xMap.size === data.config?.xAxis?.length && data.yMap.size === data.config?.yAxis?.length\">\n <svg height=\"100%\" width=\"100%\" class=\"position-absolute\">\n <g class=\"y-axis-container\">\n <ng-container *ngFor=\"let item of data.yMap | keyvalue; trackBy: identify\">\n <ng-container *ngIf=\"item.value.options.visible\">\n <g\n teta-y-axis\n [axis]=\"item.value\"\n [size]=\"data.visibleRect\"\n [attr.transform]=\"getTranslate(item.value, data.size) | async\"></g>\n <rect\n tetaZoomable\n fill-opacity=\"0\"\n [brushScale]=\"data.brushScale\"\n [scale]=\"data.yMap.get(item.key).scale\"\n [axis]=\"item.value\"\n [config]=\"data.config\"\n [size]=\"data.visibleRect\"\n [attr.x]=\"item.value.options.opposite ? 0 : -item.value.selfSize\"\n [attr.y]=\"0\"\n [attr.height]=\"data.visibleRect.height\"\n [attr.width]=\"item.value.selfSize\"\n [attr.transform]=\"getTranslate(item.value, data.size) | async\"></rect>\n </ng-container>\n\n </ng-container>\n </g>\n <g class=\"x-axis-container\">\n <ng-container *ngFor=\"let item of data.xMap | keyvalue; trackBy: identify\">\n <ng-container *ngIf=\"item.value.options.visible && data.xMap.size === data.config?.xAxis?.length && data.yMap.size === data.config?.yAxis?.length\">\n <g\n teta-x-axis\n [axis]=\"item.value\"\n [size]=\"data.visibleRect\"\n [attr.transform]=\"getTranslate(item.value, data.size) | async\"></g>\n <rect\n tetaZoomable\n fill-opacity=\"0\"\n [brushScale]=\"data.brushScale\"\n [scale]=\"data.xMap.get(item.key).scale\"\n [axis]=\"item.value\"\n [config]=\"data.config\"\n [size]=\"data.visibleRect\"\n [attr.x]=\"0\"\n [attr.y]=\"item.value.options.opposite ? -item.value.selfSize : 0\"\n [attr.width]=\"data.visibleRect.width\"\n [attr.height]=\"item.value.selfSize\"\n [attr.transform]=\"getTranslate(item.value, data.size) | async\"></rect>\n </ng-container>\n </ng-container>\n </g>\n </svg>\n </ng-container>\n <ng-container *ngIf=\"data.visibleRect?.width > 0 && data.visibleRect?.height > 0 && data.xMap.size === data.config?.xAxis?.length && data.yMap.size === data.config?.yAxis?.length\">\n <svg\n tetaBrushable\n tetaZoomable\n class=\"position-absolute\"\n [size]=\"data.visibleRect\"\n [brushScale]=\"data.brushScale\"\n [scale]=\"data.brushScale\"\n [config]=\"data.config\"\n [axis]=\"data.config?.zoom?.type === zoomType.x ? data.xMap.get(0) : data.yMap.get(0)\"\n [attr.width]=\"data.visibleRect.width\"\n [attr.height]=\"data.visibleRect.height\"\n [attr.viewBox]=\"'0 0 ' + data.visibleRect.width + ' ' + data.visibleRect.height\"\n [style.transform]=\"'translate('+ data.visibleRect.x +'px, '+ data.visibleRect.y +'px)'\"\n (contextmenu)=\"contextMenu($event, data.xMap, data.yMap)\"\n (click)=\"click($event, data.xMap, data.yMap)\"\n (mouseleave)=\"mouseLeave($event)\"\n (mousemove)=\"mouseMove($event)\">\n\n <g class=\"gridlines\"\n teta-gridlines\n *ngIf=\"data.config.gridLines?.enable !== false\"\n [size]=\"data.size\"></g>\n\n <g class=\"x-axis-plotband-container\">\n <ng-container *ngFor=\"let axis of data.config.xAxis; let i = index\">\n <g teta-plot-band *ngFor=\"let plotBand of axis.plotBands\"\n [plotBand]=\"plotBand\"\n [scale]=\"data.xMap.get(i).scale\"\n [size]=\"data.size\"\n [axis]=\"data.xMap.get(i)\"></g>\n </ng-container>\n </g>\n <g class=\"y-axis-plotband-container\">\n <ng-container *ngFor=\"let axis of data.config.yAxis; let i = index\">\n <g teta-plot-band *ngFor=\"let plotBand of axis.plotBands\"\n [plotBand]=\"plotBand\"\n [scale]=\"data.yMap.get(i).scale\"\n [size]=\"data.size\"\n [axis]=\"data.yMap.get(i)\"></g>\n </ng-container>\n </g>\n <g class=\"x-axis-plotline-container\">\n <ng-container *ngFor=\"let axis of data.config.xAxis; let i = index\">\n <g teta-plot-line *ngFor=\"let plotLine of axis.plotLines\"\n [plotLine]=\"plotLine\"\n [scale]=\"data.xMap.get(i).scale\"\n [size]=\"data.size\"\n [axis]=\"data.xMap.get(i)\"></g>\n </ng-container>\n </g>\n <g class=\"y-axis-plotline-container\">\n <ng-container *ngFor=\"let axis of data.config.yAxis; let i = index\">\n <g teta-plot-line *ngFor=\"let plotLine of axis.plotLines\"\n [plotLine]=\"plotLine\"\n [scale]=\"data.yMap.get(i).scale\"\n [size]=\"data.size\"\n [axis]=\"data.yMap.get(i)\"></g>\n </ng-container>\n </g>\n <g class=\"series-container\">\n <ng-container *ngFor=\"let series of data.config.series\">\n <g teta-series-host\n *ngIf=\"series.visible\"\n [config]=\"data.config\"\n [series]=\"series\"></g>\n </ng-container>\n </g>\n <g class=\"annotations\">\n <g teta-annotation\n *ngFor=\"let annotation of data.config.annotations\"\n [annotation]=\"annotation\"></g>\n </g>\n <g class=\"crosshair\" *ngIf=\"data.config.tooltip?.showCrosshair\">\n <g teta-crosshair [size]=\"data.visibleRect\"></g>\n </g>\n </svg>\n\n </ng-container>\n</ng-container>\n", styles: [":host{display:flex;flex-direction:column;flex-grow:1;min-width:0;min-height:0}:host .zoomable:hover{cursor:grab}:host .zoomable:active{cursor:grabbing}:host .crosshair{cursor:crosshair}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: SeriesHostComponent, selector: "[teta-series-host]", inputs: ["config", "series"] }, { kind: "component", type: GridlinesComponent, selector: "[teta-gridlines]", inputs: ["size"] }, { kind: "component", type: XAxisComponent, selector: "[teta-x-axis]", inputs: ["axis", "size"] }, { kind: "component", type: YAxisComponent, selector: "[teta-y-axis]", inputs: ["axis", "size"] }, { kind: "component", type: PlotlineComponent, selector: "[teta-plot-line]", inputs: ["plotLine", "size", "axis", "scale"] }, { kind: "component", type: PlotBandComponent, selector: "[teta-plot-band]", inputs: ["plotBand", "axis", "scale", "size"] }, { kind: "component", type: TooltipComponent, selector: "teta-tooltip", inputs: ["size", "config"] }, { kind: "directive", type: ZoomableDirective, selector: "[tetaZoomable]", inputs: ["config", "axis", "size", "brushScale", "scale"] }, { kind: "directive", type: BrushableDirective, selector: "[tetaBrushable]", inputs: ["config", "brushScale"] }, { kind: "component", type: AnnotationComponent, selector: "[teta-annotation]", inputs: ["annotation"] }, { kind: "component", type: CrosshairComponent, selector: "[teta-crosshair]", inputs: ["size"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i4.KeyValuePipe, name: "keyvalue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2560
2679
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: ChartContainerComponent, decorators: [{
2561
2680
  type: Component,
2562
- args: [{ selector: 'teta-chart-container', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"{\n size: size | async,\n config: config | async,\n xAxisMap: xAxisMap | async,\n yAxisMap: yAxisMap | async,\n xScaleMap: xScaleMap | async,\n yScaleMap: yScaleMap | async,\n visibleRect: visibleRect | async,\n brushScale: brushScale | async\n} as data\" xmlns:svg=\"http://www.w3.org/1999/html\">\n <teta-tooltip *ngIf=\"data.config?.tooltip?.enable\"\n [size]=\"data.size\"\n [config]=\"data.config\"></teta-tooltip>\n <ng-container *ngIf=\"data.visibleRect?.width > 0 && data.visibleRect?.height > 0 && data.xScaleMap && data.yScaleMap\">\n <svg height=\"100%\" width=\"100%\" class=\"position-absolute\">\n <g class=\"y-axis-container\">\n <ng-container *ngFor=\"let item of data.yAxisMap | keyvalue; trackBy: identify\">\n <ng-container *ngIf=\"item.value.options.visible\">\n <g\n teta-y-axis\n [axis]=\"item.value\"\n [size]=\"data.visibleRect\"\n [attr.transform]=\"getTranslate(item.value, data.size) | async\"></g>\n <rect\n tetaZoomable\n fill-opacity=\"0\"\n [brushScale]=\"data.brushScale\"\n [scale]=\"data.yScaleMap.get(item.key)\"\n [axis]=\"item.value\"\n [config]=\"data.config\"\n [size]=\"data.visibleRect\"\n [attr.x]=\"item.value.options.opposite ? 0 : -item.value.selfSize\"\n [attr.y]=\"0\"\n [attr.height]=\"data.visibleRect.height\"\n [attr.width]=\"item.value.selfSize\"\n [attr.transform]=\"getTranslate(item.value, data.size) | async\"></rect>\n </ng-container>\n\n </ng-container>\n </g>\n <g class=\"x-axis-container\">\n <ng-container *ngFor=\"let item of data.xAxisMap | keyvalue; trackBy: identify\">\n <ng-container *ngIf=\"item.value.options.visible && data.xScaleMap && data.yScaleMap\">\n <g\n teta-x-axis\n [axis]=\"item.value\"\n [size]=\"data.visibleRect\"\n [attr.transform]=\"getTranslate(item.value, data.size) | async\"></g>\n <rect\n tetaZoomable\n fill-opacity=\"0\"\n [brushScale]=\"data.brushScale\"\n [scale]=\"data.xScaleMap.get(item.key)\"\n [axis]=\"item.value\"\n [config]=\"data.config\"\n [size]=\"data.visibleRect\"\n [attr.x]=\"0\"\n [attr.y]=\"item.value.options.opposite ? -item.value.selfSize : 0\"\n [attr.width]=\"data.visibleRect.width\"\n [attr.height]=\"item.value.selfSize\"\n [attr.transform]=\"getTranslate(item.value, data.size) | async\"></rect>\n </ng-container>\n </ng-container>\n </g>\n </svg>\n </ng-container>\n <ng-container *ngIf=\"data.visibleRect?.width > 0 && data.visibleRect?.height > 0 && data.xScaleMap && data.yScaleMap\">\n <svg\n tetaBrushable\n tetaZoomable\n class=\"position-absolute\"\n [size]=\"data.visibleRect\"\n [brushScale]=\"data.brushScale\"\n [scale]=\"data.brushScale\"\n [config]=\"data.config\"\n [axis]=\"data.config?.zoom?.type === zoomType.x ? data.xAxisMap.get(0) : data.yAxisMap.get(0)\"\n [attr.width]=\"data.visibleRect.width\"\n [attr.height]=\"data.visibleRect.height\"\n [attr.viewBox]=\"'0 0 ' + data.visibleRect.width + ' ' + data.visibleRect.height\"\n [style.transform]=\"'translate('+ data.visibleRect.x +'px, '+ data.visibleRect.y +'px)'\"\n (contextmenu)=\"contextMenu($event, data.xScaleMap, data.yScaleMap)\"\n (click)=\"click($event, data.xScaleMap, data.yScaleMap)\"\n (mouseleave)=\"mouseLeave($event)\"\n (mousemove)=\"mouseMove($event)\">\n\n <g class=\"gridlines\"\n teta-gridlines\n *ngIf=\"data.config.gridLines?.enable !== false\"\n [size]=\"data.size\"></g>\n\n <g class=\"x-axis-plotband-container\">\n <ng-container *ngFor=\"let axis of data.config.xAxis; let i = index\">\n <g teta-plot-band *ngFor=\"let plotBand of axis.plotBands\"\n [plotBand]=\"plotBand\"\n [scale]=\"data.xScaleMap.get(i)\"\n [size]=\"data.size\"\n [axis]=\"data.xAxisMap.get(i)\"></g>\n </ng-container>\n </g>\n <g class=\"y-axis-plotband-container\">\n <ng-container *ngFor=\"let axis of data.config.yAxis; let i = index\">\n <g teta-plot-band *ngFor=\"let plotBand of axis.plotBands\"\n [plotBand]=\"plotBand\"\n [scale]=\"data.yScaleMap.get(i)\"\n [size]=\"data.size\"\n [axis]=\"data.yAxisMap.get(i)\"></g>\n </ng-container>\n </g>\n <g class=\"x-axis-plotline-container\">\n <ng-container *ngFor=\"let axis of data.config.xAxis; let i = index\">\n <g teta-plot-line *ngFor=\"let plotLine of axis.plotLines\"\n [plotLine]=\"plotLine\"\n [scale]=\"data.xScaleMap.get(i)\"\n [size]=\"data.size\"\n [axis]=\"data.xAxisMap.get(i)\"></g>\n </ng-container>\n </g>\n <g class=\"y-axis-plotline-container\">\n <ng-container *ngFor=\"let axis of data.config.yAxis; let i = index\">\n <g teta-plot-line *ngFor=\"let plotLine of axis.plotLines\"\n [plotLine]=\"plotLine\"\n [scale]=\"data.yScaleMap.get(i)\"\n [size]=\"data.size\"\n [axis]=\"data.yAxisMap.get(i)\"></g>\n </ng-container>\n </g>\n <g class=\"series-container\">\n <ng-container *ngFor=\"let series of data.config.series\">\n <g teta-series-host\n *ngIf=\"series.visible\"\n [config]=\"data.config\"\n [series]=\"series\"></g>\n </ng-container>\n </g>\n <g class=\"annotations\">\n <g teta-annotation\n *ngFor=\"let annotation of data.config.annotations\"\n [annotation]=\"annotation\"></g>\n </g>\n <g class=\"crosshair\" *ngIf=\"data.config.tooltip?.showCrosshair\">\n <g teta-crosshair [size]=\"data.visibleRect\"></g>\n </g>\n </svg>\n\n </ng-container>\n</ng-container>\n", styles: [":host{display:flex;flex-direction:column;flex-grow:1;min-width:0;min-height:0}:host .zoomable:hover{cursor:grab}:host .zoomable:active{cursor:grabbing}:host .crosshair{cursor:crosshair}\n"] }]
2681
+ args: [{ selector: 'teta-chart-container', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"{\n size: size | async,\n config: config | async,\n yMap: yMap | async,\n xMap: xMap | async,\n visibleRect: visibleRect | async,\n brushScale: brushScale | async\n} as data\" xmlns:svg=\"http://www.w3.org/1999/html\">\n <teta-tooltip *ngIf=\"data.config?.tooltip?.enable\"\n [size]=\"data.size\"\n [config]=\"data.config\"></teta-tooltip>\n <ng-container *ngIf=\"data.visibleRect?.width > 0 && data.visibleRect?.height > 0 && data.xMap.size === data.config?.xAxis?.length && data.yMap.size === data.config?.yAxis?.length\">\n <svg height=\"100%\" width=\"100%\" class=\"position-absolute\">\n <g class=\"y-axis-container\">\n <ng-container *ngFor=\"let item of data.yMap | keyvalue; trackBy: identify\">\n <ng-container *ngIf=\"item.value.options.visible\">\n <g\n teta-y-axis\n [axis]=\"item.value\"\n [size]=\"data.visibleRect\"\n [attr.transform]=\"getTranslate(item.value, data.size) | async\"></g>\n <rect\n tetaZoomable\n fill-opacity=\"0\"\n [brushScale]=\"data.brushScale\"\n [scale]=\"data.yMap.get(item.key).scale\"\n [axis]=\"item.value\"\n [config]=\"data.config\"\n [size]=\"data.visibleRect\"\n [attr.x]=\"item.value.options.opposite ? 0 : -item.value.selfSize\"\n [attr.y]=\"0\"\n [attr.height]=\"data.visibleRect.height\"\n [attr.width]=\"item.value.selfSize\"\n [attr.transform]=\"getTranslate(item.value, data.size) | async\"></rect>\n </ng-container>\n\n </ng-container>\n </g>\n <g class=\"x-axis-container\">\n <ng-container *ngFor=\"let item of data.xMap | keyvalue; trackBy: identify\">\n <ng-container *ngIf=\"item.value.options.visible && data.xMap.size === data.config?.xAxis?.length && data.yMap.size === data.config?.yAxis?.length\">\n <g\n teta-x-axis\n [axis]=\"item.value\"\n [size]=\"data.visibleRect\"\n [attr.transform]=\"getTranslate(item.value, data.size) | async\"></g>\n <rect\n tetaZoomable\n fill-opacity=\"0\"\n [brushScale]=\"data.brushScale\"\n [scale]=\"data.xMap.get(item.key).scale\"\n [axis]=\"item.value\"\n [config]=\"data.config\"\n [size]=\"data.visibleRect\"\n [attr.x]=\"0\"\n [attr.y]=\"item.value.options.opposite ? -item.value.selfSize : 0\"\n [attr.width]=\"data.visibleRect.width\"\n [attr.height]=\"item.value.selfSize\"\n [attr.transform]=\"getTranslate(item.value, data.size) | async\"></rect>\n </ng-container>\n </ng-container>\n </g>\n </svg>\n </ng-container>\n <ng-container *ngIf=\"data.visibleRect?.width > 0 && data.visibleRect?.height > 0 && data.xMap.size === data.config?.xAxis?.length && data.yMap.size === data.config?.yAxis?.length\">\n <svg\n tetaBrushable\n tetaZoomable\n class=\"position-absolute\"\n [size]=\"data.visibleRect\"\n [brushScale]=\"data.brushScale\"\n [scale]=\"data.brushScale\"\n [config]=\"data.config\"\n [axis]=\"data.config?.zoom?.type === zoomType.x ? data.xMap.get(0) : data.yMap.get(0)\"\n [attr.width]=\"data.visibleRect.width\"\n [attr.height]=\"data.visibleRect.height\"\n [attr.viewBox]=\"'0 0 ' + data.visibleRect.width + ' ' + data.visibleRect.height\"\n [style.transform]=\"'translate('+ data.visibleRect.x +'px, '+ data.visibleRect.y +'px)'\"\n (contextmenu)=\"contextMenu($event, data.xMap, data.yMap)\"\n (click)=\"click($event, data.xMap, data.yMap)\"\n (mouseleave)=\"mouseLeave($event)\"\n (mousemove)=\"mouseMove($event)\">\n\n <g class=\"gridlines\"\n teta-gridlines\n *ngIf=\"data.config.gridLines?.enable !== false\"\n [size]=\"data.size\"></g>\n\n <g class=\"x-axis-plotband-container\">\n <ng-container *ngFor=\"let axis of data.config.xAxis; let i = index\">\n <g teta-plot-band *ngFor=\"let plotBand of axis.plotBands\"\n [plotBand]=\"plotBand\"\n [scale]=\"data.xMap.get(i).scale\"\n [size]=\"data.size\"\n [axis]=\"data.xMap.get(i)\"></g>\n </ng-container>\n </g>\n <g class=\"y-axis-plotband-container\">\n <ng-container *ngFor=\"let axis of data.config.yAxis; let i = index\">\n <g teta-plot-band *ngFor=\"let plotBand of axis.plotBands\"\n [plotBand]=\"plotBand\"\n [scale]=\"data.yMap.get(i).scale\"\n [size]=\"data.size\"\n [axis]=\"data.yMap.get(i)\"></g>\n </ng-container>\n </g>\n <g class=\"x-axis-plotline-container\">\n <ng-container *ngFor=\"let axis of data.config.xAxis; let i = index\">\n <g teta-plot-line *ngFor=\"let plotLine of axis.plotLines\"\n [plotLine]=\"plotLine\"\n [scale]=\"data.xMap.get(i).scale\"\n [size]=\"data.size\"\n [axis]=\"data.xMap.get(i)\"></g>\n </ng-container>\n </g>\n <g class=\"y-axis-plotline-container\">\n <ng-container *ngFor=\"let axis of data.config.yAxis; let i = index\">\n <g teta-plot-line *ngFor=\"let plotLine of axis.plotLines\"\n [plotLine]=\"plotLine\"\n [scale]=\"data.yMap.get(i).scale\"\n [size]=\"data.size\"\n [axis]=\"data.yMap.get(i)\"></g>\n </ng-container>\n </g>\n <g class=\"series-container\">\n <ng-container *ngFor=\"let series of data.config.series\">\n <g teta-series-host\n *ngIf=\"series.visible\"\n [config]=\"data.config\"\n [series]=\"series\"></g>\n </ng-container>\n </g>\n <g class=\"annotations\">\n <g teta-annotation\n *ngFor=\"let annotation of data.config.annotations\"\n [annotation]=\"annotation\"></g>\n </g>\n <g class=\"crosshair\" *ngIf=\"data.config.tooltip?.showCrosshair\">\n <g teta-crosshair [size]=\"data.visibleRect\"></g>\n </g>\n </svg>\n\n </ng-container>\n</ng-container>\n", styles: [":host{display:flex;flex-direction:column;flex-grow:1;min-width:0;min-height:0}:host .zoomable:hover{cursor:grab}:host .zoomable:active{cursor:grabbing}:host .crosshair{cursor:crosshair}\n"] }]
2563
2682
  }], ctorParameters: function () { return [{ type: ChartService }, { type: i0.ChangeDetectorRef }, { type: ScaleService }, { type: ZoomService }, { type: i0.ElementRef }, { type: i0.NgZone }]; } });
2564
2683
 
2565
2684
  class LegendComponent {
@@ -2609,6 +2728,7 @@ class ChartComponent {
2609
2728
  this.annotationContextMenu = new EventEmitter();
2610
2729
  this.annotationClick = new EventEmitter();
2611
2730
  this.annotationMove = new EventEmitter();
2731
+ this.zoomServiceInstance = new EventEmitter();
2612
2732
  this._alive = true;
2613
2733
  this.svcConfig = this.chartService.config;
2614
2734
  this.hasSeriesData = this.svcConfig.pipe(map((_) => _.series?.length > 0 && _.series?.some((_) => _.data?.length > 0)));
@@ -2689,6 +2809,11 @@ class ChartComponent {
2689
2809
  .subscribe((_) => {
2690
2810
  this.annotationMove.emit(_);
2691
2811
  });
2812
+ this.chartService.zoomInstance
2813
+ .pipe(takeWhile(() => this._alive))
2814
+ .subscribe((_) => {
2815
+ this.zoomServiceInstance.emit(_);
2816
+ });
2692
2817
  }
2693
2818
  ngAfterViewInit() {
2694
2819
  }
@@ -2700,7 +2825,7 @@ class ChartComponent {
2700
2825
  }
2701
2826
  }
2702
2827
  ChartComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: ChartComponent, deps: [{ token: ChartService }, { token: ZoomService }, { token: ScaleService }], target: i0.ɵɵFactoryTarget.Component });
2703
- ChartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.2", type: ChartComponent, selector: "teta-svg-chart", inputs: { config: "config" }, outputs: { pointerMove: "pointerMove", plotBandsMove: "plotBandsMove", plotBandClick: "plotBandClick", plotBandContextMenu: "plotBandContextMenu", plotLinesMove: "plotLinesMove", pointMove: "pointMove", chartClick: "chartClick", chartContextMenu: "chartContextMenu", annotationContextMenu: "annotationContextMenu", annotationClick: "annotationClick", annotationMove: "annotationMove" }, providers: [ChartService, ZoomService, ScaleService, BrushService], usesOnChanges: true, ngImport: i0, template: "<ng-container *ngIf=\"{\n hasSeriesData: hasSeriesData | async,\n svcConfig: svcConfig | async\n} as data\">\n <ng-container *ngIf=\"data.hasSeriesData === true else noData\">\n <div class=\"column column_auto\">\n <teta-chart-container class=\"chart-container position-relative\"></teta-chart-container>\n </div>\n <teta-legend *ngIf=\"data.svcConfig.legend?.enable === true\" [series]=\"data.svcConfig.series\"></teta-legend>\n </ng-container>\n</ng-container>\n<ng-template #noData>\n <div class=\"column column_auto align-center justify-content-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</ng-template>\n", styles: [":host{position:relative;display:flex;flex-direction:column;height:100%;width:100%}\n"], dependencies: [{ kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ChartContainerComponent, selector: "teta-chart-container" }, { kind: "component", type: LegendComponent, selector: "teta-legend", inputs: ["series"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2828
+ ChartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.2", type: ChartComponent, selector: "teta-svg-chart", inputs: { config: "config" }, outputs: { pointerMove: "pointerMove", plotBandsMove: "plotBandsMove", plotBandClick: "plotBandClick", plotBandContextMenu: "plotBandContextMenu", plotLinesMove: "plotLinesMove", pointMove: "pointMove", chartClick: "chartClick", chartContextMenu: "chartContextMenu", annotationContextMenu: "annotationContextMenu", annotationClick: "annotationClick", annotationMove: "annotationMove", zoomServiceInstance: "zoomServiceInstance" }, providers: [ChartService, ZoomService, ScaleService, BrushService], usesOnChanges: true, ngImport: i0, template: "<ng-container *ngIf=\"{\n hasSeriesData: hasSeriesData | async,\n svcConfig: svcConfig | async\n} as data\">\n <ng-container *ngIf=\"data.hasSeriesData === true else noData\">\n <div class=\"column column_auto\">\n <teta-chart-container class=\"chart-container position-relative\"></teta-chart-container>\n </div>\n <teta-legend *ngIf=\"data.svcConfig.legend?.enable === true\" [series]=\"data.svcConfig.series\"></teta-legend>\n </ng-container>\n</ng-container>\n<ng-template #noData>\n <div class=\"column column_auto align-center justify-content-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</ng-template>\n", styles: [":host{position:relative;display:flex;flex-direction:column;height:100%;width:100%}\n"], dependencies: [{ kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ChartContainerComponent, selector: "teta-chart-container" }, { kind: "component", type: LegendComponent, selector: "teta-legend", inputs: ["series"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2704
2829
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: ChartComponent, decorators: [{
2705
2830
  type: Component,
2706
2831
  args: [{ selector: 'teta-svg-chart', providers: [ChartService, ZoomService, ScaleService, BrushService], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"{\n hasSeriesData: hasSeriesData | async,\n svcConfig: svcConfig | async\n} as data\">\n <ng-container *ngIf=\"data.hasSeriesData === true else noData\">\n <div class=\"column column_auto\">\n <teta-chart-container class=\"chart-container position-relative\"></teta-chart-container>\n </div>\n <teta-legend *ngIf=\"data.svcConfig.legend?.enable === true\" [series]=\"data.svcConfig.series\"></teta-legend>\n </ng-container>\n</ng-container>\n<ng-template #noData>\n <div class=\"column column_auto align-center justify-content-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</ng-template>\n", styles: [":host{position:relative;display:flex;flex-direction:column;height:100%;width:100%}\n"] }]
@@ -2726,6 +2851,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImpor
2726
2851
  type: Output
2727
2852
  }], annotationMove: [{
2728
2853
  type: Output
2854
+ }], zoomServiceInstance: [{
2855
+ type: Output
2729
2856
  }], config: [{
2730
2857
  type: Input
2731
2858
  }] } });