@tetacom/svg-charts 1.2.2 → 1.2.5

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 (39) 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/model/i-broadcast-message.d.ts +2 -2
  8. package/chart/model/i-scales-map.d.ts +5 -0
  9. package/chart/model/public-api.d.ts +1 -0
  10. package/chart/service/chart.service.d.ts +4 -0
  11. package/chart/service/scale.service.d.ts +2 -5
  12. package/esm2020/chart/chart/chart.component.mjs +14 -6
  13. package/esm2020/chart/chart-container/annotation/annotation.component.mjs +3 -3
  14. package/esm2020/chart/chart-container/chart-container.component.mjs +16 -25
  15. package/esm2020/chart/chart-container/gridlines/gridlines.component.mjs +11 -5
  16. package/esm2020/chart/chart-container/series/area-series/area-series.component.mjs +6 -9
  17. package/esm2020/chart/chart-container/series/bar/bar-series.component.mjs +5 -5
  18. package/esm2020/chart/chart-container/series/block-area-series/block-area-series.component.mjs +3 -3
  19. package/esm2020/chart/chart-container/series/block-series/block-series.component.mjs +3 -3
  20. package/esm2020/chart/chart-container/series/linear-series-base.mjs +21 -26
  21. package/esm2020/chart/chart-container/series/scatter-series/scatter-series.component.mjs +3 -3
  22. package/esm2020/chart/chart-container/x-axis/x-axis.component.mjs +3 -27
  23. package/esm2020/chart/chart-container/y-axis/y-axis.component.mjs +3 -3
  24. package/esm2020/chart/core/axis/axis.mjs +7 -1
  25. package/esm2020/chart/default/default-axis-config.mjs +2 -2
  26. package/esm2020/chart/directives/brushable.directive.mjs +1 -1
  27. package/esm2020/chart/directives/zoomable.directive.mjs +27 -7
  28. package/esm2020/chart/model/i-broadcast-message.mjs +2 -2
  29. package/esm2020/chart/model/i-scales-map.mjs +2 -0
  30. package/esm2020/chart/model/public-api.mjs +2 -1
  31. package/esm2020/chart/service/brush.service.mjs +20 -17
  32. package/esm2020/chart/service/chart.service.mjs +6 -1
  33. package/esm2020/chart/service/scale.service.mjs +37 -65
  34. package/esm2020/chart/service/zoom.service.mjs +2 -2
  35. package/fesm2015/tetacom-svg-charts.mjs +177 -197
  36. package/fesm2015/tetacom-svg-charts.mjs.map +1 -1
  37. package/fesm2020/tetacom-svg-charts.mjs +168 -190
  38. package/fesm2020/tetacom-svg-charts.mjs.map +1 -1
  39. 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
  }
@@ -622,49 +633,29 @@ class ScaleService {
622
633
  .set(ScaleType.symlog, d3.scaleSymlog)
623
634
  .set(ScaleType.pow, d3.scalePow)
624
635
  .set(ScaleType.sqrt, d3.scaleSqrt);
625
- this.xAxisMap = combineLatest([
626
- this.chartService.size,
627
- this.chartService.config,
628
- ]).pipe(map((data) => {
629
- const [, config] = data;
630
- const map = new Map();
631
- config.xAxis.map((_, index) => {
632
- map.set(index, Axis.createAxis(AxisOrientation.x, config, index));
633
- });
634
- return map;
635
- }), shareReplay({
636
- bufferSize: 1,
637
- refCount: true,
638
- }));
639
- this.yAxisMap = combineLatest([
636
+ this.scales = combineLatest([
640
637
  this.chartService.size,
641
638
  this.chartService.config,
639
+ this.zoomService.zoomed,
642
640
  ]).pipe(map((data) => {
643
- const [, config] = data;
644
- const map = new Map();
641
+ const [size, config, zoom] = data;
642
+ const xAxisMap = new Map();
643
+ const yAxisMap = new Map();
645
644
  config.yAxis.map((_, index) => {
646
- map.set(index, Axis.createAxis(AxisOrientation.y, config, index));
645
+ yAxisMap.set(index, Axis.createAxis(AxisOrientation.y, config, index));
647
646
  });
648
- return map;
649
- }), shareReplay({
650
- bufferSize: 1,
651
- refCount: true,
652
- }));
653
- this.xScaleMap = combineLatest([
654
- this.chartService.size,
655
- this.chartService.config,
656
- this.zoomService.zoomed,
657
- ]).pipe(withLatestFrom(this.yAxisMap, this.xAxisMap), map((data) => {
658
- const [[size, config, zoom], yAxes, xAxes] = data;
659
- const map = new Map();
660
- const left = [...yAxes.values()]
647
+ config.xAxis.map((_, index) => {
648
+ xAxisMap.set(index, Axis.createAxis(AxisOrientation.x, config, index));
649
+ });
650
+ // Generate x scales
651
+ const left = Array.from(yAxisMap.values())
661
652
  .filter((_) => _.options?.visible && _.options?.opposite)
662
653
  .reduce((acc, cur) => acc + cur.selfSize, 0);
663
- const right = [...yAxes.values()]
654
+ const right = Array.from(yAxisMap.values())
664
655
  .filter((_) => _.options?.visible && _.options?.opposite !== true)
665
656
  .reduce((acc, cur) => acc + cur.selfSize, 0);
666
657
  const finalWidth = (size.width || 0) - left - right;
667
- xAxes.forEach((axis) => {
658
+ xAxisMap.forEach((axis) => {
668
659
  let domain = axis.extremes;
669
660
  if (axis?.options.inverted) {
670
661
  domain = [...axis.extremes].reverse();
@@ -679,44 +670,33 @@ class ScaleService {
679
670
  if (axis.options.scaleType.type === ScaleType.log) {
680
671
  scale.base(axis.options.scaleType.base);
681
672
  }
682
- map.set(axis.index, scale);
673
+ axis.setScale(scale);
683
674
  axis.setOriginDomain(scale.domain());
684
675
  const hasCache = this.transformCacheX.has(axis.index);
685
676
  const shouldRestore = zoom?.target?.orientation !== AxisOrientation.x ||
686
677
  zoom.target?.index !== axis.index;
687
678
  if (hasCache && shouldRestore) {
688
679
  const restoredTransform = this.transformCacheX.get(axis.index);
689
- map.set(axis.index, restoredTransform.rescaleX(scale));
680
+ axis.setScale(restoredTransform.rescaleX(scale));
690
681
  }
691
682
  });
692
683
  if (zoom) {
693
684
  const event = zoom.event;
694
685
  if (zoom.target?.orientation === AxisOrientation.x) {
695
- if (map.has(zoom.target.index)) {
696
- const currentScale = map.get(zoom.target.index);
697
- const rescaled = event.transform.rescaleX(currentScale);
698
- map.set(zoom.target.index, rescaled);
699
- const axis = xAxes.get(zoom.target.index);
686
+ if (xAxisMap.has(zoom.target.index)) {
687
+ const x = xAxisMap.get(zoom.target.index);
688
+ const rescaled = event.transform.rescaleX(x.scale);
689
+ x.setScale(rescaled);
690
+ const axis = xAxisMap.get(zoom.target.index);
700
691
  this.transformCacheX.set(axis.index, event.transform);
701
692
  }
702
693
  }
703
694
  }
704
- return map;
705
- }), shareReplay({
706
- bufferSize: 1,
707
- refCount: true,
708
- }));
709
- this.yScaleMap = combineLatest([
710
- this.chartService.size,
711
- this.chartService.config,
712
- this.zoomService.zoomed,
713
- ]).pipe(withLatestFrom(this.yAxisMap, this.xAxisMap), map((data) => {
714
- const [[size, config, zoom], yAxes, xAxes] = data;
715
- const map = new Map();
716
- const top = [...xAxes.values()]
695
+ // Generate y axis
696
+ const top = Array.from(xAxisMap.values())
717
697
  .filter((_) => _.options?.visible && _.options?.opposite)
718
698
  .reduce((acc, cur) => acc + cur.selfSize, 0);
719
- const bottom = [...xAxes.values()]
699
+ const bottom = Array.from(xAxisMap.values())
720
700
  .filter((_) => _.options?.visible && _.options?.opposite !== true)
721
701
  .reduce((acc, cur) => acc + cur.selfSize, 0);
722
702
  const finalHeight = (size.height || 0) -
@@ -724,7 +704,7 @@ class ScaleService {
724
704
  bottom -
725
705
  config?.bounds?.top -
726
706
  config.bounds?.bottom;
727
- yAxes.forEach((axis) => {
707
+ yAxisMap.forEach((axis) => {
728
708
  let domain = axis.extremes;
729
709
  if (axis.orientation === AxisOrientation.y) {
730
710
  domain = [...axis.extremes].reverse();
@@ -742,29 +722,32 @@ class ScaleService {
742
722
  if (axis.options.scaleType.type === ScaleType.log) {
743
723
  scale.base(axis.options.scaleType.base);
744
724
  }
745
- map.set(axis.index, scale);
725
+ axis.setScale(scale);
746
726
  axis.setOriginDomain(scale.domain());
747
727
  const hasCache = this.transformCacheY.has(axis.index);
748
728
  const shouldRestore = zoom?.target?.orientation !== AxisOrientation.y ||
749
729
  zoom.target?.index !== axis.index;
750
730
  if (hasCache && shouldRestore) {
751
731
  const restoredTransform = this.transformCacheY.get(axis.index);
752
- map.set(axis.index, restoredTransform.rescaleY(scale));
732
+ axis.setScale(restoredTransform.rescaleY(scale));
753
733
  }
754
734
  });
755
735
  if (zoom) {
756
736
  const event = zoom.event;
757
737
  if (zoom.target?.orientation === AxisOrientation.y) {
758
- if (map.has(zoom.target.index)) {
759
- const currentScale = map.get(zoom.target.index);
760
- const rescaled = event.transform.rescaleY(currentScale);
761
- map.set(zoom.target.index, rescaled);
762
- const axis = yAxes.get(zoom.target.index);
738
+ if (yAxisMap.has(zoom.target.index)) {
739
+ const y = yAxisMap.get(zoom.target.index);
740
+ const rescaled = event.transform.rescaleY(y.scale);
741
+ y.setScale(rescaled);
742
+ const axis = yAxisMap.get(zoom.target.index);
763
743
  this.transformCacheY.set(axis.index, event.transform);
764
744
  }
765
745
  }
766
746
  }
767
- return map;
747
+ return {
748
+ x: xAxisMap,
749
+ y: yAxisMap
750
+ };
768
751
  }), shareReplay({
769
752
  bufferSize: 1,
770
753
  refCount: true,
@@ -791,7 +774,7 @@ class ZoomMessage {
791
774
  constructor(options) {
792
775
  this.event = options?.event;
793
776
  this.axis = options?.axis;
794
- this.brushDomain = options.brushDomain;
777
+ this.domain = options.domain;
795
778
  this.chartId = options?.chartId;
796
779
  this.style = options?.style;
797
780
  }
@@ -946,29 +929,31 @@ class BrushService {
946
929
  (window.TouchEvent &&
947
930
  m.message.event.sourceEvent instanceof TouchEvent));
948
931
  }), tap((m) => {
949
- const { message: { brushDomain }, } = m;
932
+ const { message: { domain }, } = m;
950
933
  if ((m.message?.axis.index === 0 &&
951
934
  m.message?.axis.orientation === AxisOrientation.y &&
952
935
  config.brush?.type === BrushType.y) ||
953
936
  (m.message?.axis.orientation === AxisOrientation.x &&
954
937
  config.brush?.type === BrushType.x)) {
955
938
  container.call(this.brush.move, [
956
- brushScale(brushDomain[0]),
957
- brushScale(brushDomain[1]),
939
+ brushScale(domain[0]),
940
+ brushScale(domain[1]),
958
941
  ]);
959
- if (m.message.event.type === 'end') {
960
- const brushMessage = new BrushMessage({
961
- event: null,
962
- selection: brushDomain,
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
- this.selection = brushDomain;
942
+ this.selection = domain;
943
+ }
944
+ }), debounceTime(30), tap((m) => {
945
+ const { message: { domain }, } = m;
946
+ if (m.message.event.type === 'zoom') {
947
+ const brushMessage = new BrushMessage({
948
+ event: null,
949
+ selection: domain,
950
+ brushType: config?.brush?.type ?? BrushType.x,
951
+ brushScale,
952
+ });
953
+ this.broadcastService.broadcastBrush({
954
+ channel: config?.zoom?.syncChannel,
955
+ message: brushMessage,
956
+ });
972
957
  }
973
958
  }))
974
959
  .subscribe();
@@ -1067,17 +1052,14 @@ class LinearSeriesBase extends SeriesBaseComponent {
1067
1052
  };
1068
1053
  this.defaultClipPointsMapping.set(ClipPointsDirection.x, filterX);
1069
1054
  this.defaultClipPointsMapping.set(ClipPointsDirection.y, filterY);
1070
- this.transform = this.svc.pointerMove.pipe(withLatestFrom(this.scaleService.xScaleMap, this.scaleService.yScaleMap), map((data) => {
1071
- const [event, x, y] = data;
1072
- return this.getTransform(event, x, y);
1055
+ this.transform = this.svc.pointerMove.pipe(withLatestFrom(this.scaleService.scales), map((data) => {
1056
+ const [event, { x, y }] = data;
1057
+ return this.getTransform(event, x.get(this.series.xAxisIndex).scale, y.get(this.series.yAxisIndex).scale);
1073
1058
  }), tap(() => setTimeout(() => this.cdr.detectChanges())));
1074
- this.path = combineLatest([
1075
- this.scaleService.xScaleMap,
1076
- this.scaleService.yScaleMap,
1077
- ]).pipe(map((data) => {
1078
- const [x, y] = data;
1079
- this.x = x.get(this.series.xAxisIndex);
1080
- this.y = y.get(this.series.yAxisIndex);
1059
+ this.path = this.scaleService.scales.pipe(map((data) => {
1060
+ const { x, y } = data;
1061
+ this.x = x.get(this.series.xAxisIndex).scale;
1062
+ this.y = y.get(this.series.yAxisIndex).scale;
1081
1063
  const filter = this.defaultClipPointsMapping.get(this.series.clipPointsDirection);
1082
1064
  const line = d3
1083
1065
  .line()
@@ -1160,8 +1142,6 @@ class LinearSeriesBase extends SeriesBaseComponent {
1160
1142
  return null;
1161
1143
  }
1162
1144
  const mouse = [event?.offsetX, event?.offsetY];
1163
- const foundX = scaleX.get(this.series.xAxisIndex);
1164
- const foundY = scaleY.get(this.series.yAxisIndex);
1165
1145
  const tooltipTracking = this.config?.tooltip?.tracking;
1166
1146
  const lineIntersection = (p0_x, p0_y, p1_x, p1_y, p2_x, p2_y, p3_x, p3_y) => {
1167
1147
  const rV = {};
@@ -1187,18 +1167,18 @@ class LinearSeriesBase extends SeriesBaseComponent {
1187
1167
  if (tooltipTracking === TooltipTracking.x) {
1188
1168
  const bisect = d3.bisector((_) => _.x).right;
1189
1169
  const pointer = mouse[0];
1190
- let x0 = foundX.invert(pointer);
1170
+ let x0 = scaleX.invert(pointer);
1191
1171
  if (x0 instanceof Date) {
1192
1172
  x0 = x0.getTime();
1193
1173
  }
1194
1174
  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);
1175
+ const range = scaleY.range();
1176
+ 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));
1177
+ const x = scaleX.invert(intersect.x);
1178
+ const y = scaleY.invert(intersect.y);
1199
1179
  if (x !== null && x !== undefined && !isNaN(x) && y !== null && y !== undefined && !isNaN(y)) {
1200
1180
  this.svc.setTooltip({
1201
- point: { x: foundX.invert(intersect.x), y: foundY.invert(intersect.y) },
1181
+ point: { x: scaleX.invert(intersect.x), y: scaleY.invert(intersect.y) },
1202
1182
  series: this.series,
1203
1183
  });
1204
1184
  }
@@ -1215,18 +1195,18 @@ class LinearSeriesBase extends SeriesBaseComponent {
1215
1195
  }
1216
1196
  if (tooltipTracking === TooltipTracking.y) {
1217
1197
  const bisect = d3.bisector((_) => _.y).right;
1218
- let y0 = foundY.invert(mouse[1]);
1198
+ let y0 = scaleY.invert(mouse[1]);
1219
1199
  if (y0 instanceof Date) {
1220
1200
  y0 = y0.getTime();
1221
1201
  }
1222
1202
  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);
1203
+ const range = scaleX.range();
1204
+ 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));
1205
+ const x = scaleX.invert(intersect.x);
1206
+ const y = scaleY.invert(intersect.y);
1227
1207
  if (x !== null && x !== undefined && !isNaN(x) && y !== null && y !== undefined && !isNaN(y)) {
1228
1208
  this.svc.setTooltip({
1229
- point: { x: foundX.invert(intersect.x), y: foundY.invert(intersect.y) },
1209
+ point: { x: scaleX.invert(intersect.x), y: scaleY.invert(intersect.y) },
1230
1210
  series: this.series,
1231
1211
  });
1232
1212
  }
@@ -1284,8 +1264,8 @@ class BarSeriesComponent extends SeriesBaseComponent {
1284
1264
  const count = _.series.filter((_) => _.type === SeriesType.bar && _.xAxisIndex === this.series.xAxisIndex);
1285
1265
  return count.length;
1286
1266
  }));
1287
- this.x1 = this.scaleService.xScaleMap.pipe(map((_) => {
1288
- const x = _.get(this.series.xAxisIndex);
1267
+ this.x1 = this.scaleService.scales.pipe(map((_) => {
1268
+ const x = _.x.get(this.series.xAxisIndex).scale;
1289
1269
  const range = x.range();
1290
1270
  const domain = this.series.data.map((_) => _.x);
1291
1271
  return d3
@@ -1294,8 +1274,8 @@ class BarSeriesComponent extends SeriesBaseComponent {
1294
1274
  .domain(domain)
1295
1275
  .padding(0.1);
1296
1276
  }));
1297
- this.x = this.scaleService.xScaleMap.pipe(map((_) => _.get(this.series.xAxisIndex)));
1298
- this.y = this.scaleService.yScaleMap.pipe(map((_) => _.get(this.series.yAxisIndex)));
1277
+ this.x = this.scaleService.scales.pipe(map((_) => _.x.get(this.series.xAxisIndex).scale));
1278
+ this.y = this.scaleService.scales.pipe(map((_) => _.y.get(this.series.yAxisIndex).scale));
1299
1279
  }
1300
1280
  mouseenter(point) {
1301
1281
  this.svc.setTooltip({
@@ -1328,8 +1308,8 @@ class ScatterSeriesComponent extends SeriesBaseComponent {
1328
1308
  this.element = element;
1329
1309
  }
1330
1310
  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)));
1311
+ this.x = this.scaleService.scales.pipe(map(_ => _.x.get(this.series.xAxisIndex).scale));
1312
+ this.y = this.scaleService.scales.pipe(map(_ => _.y.get(this.series.yAxisIndex).scale));
1333
1313
  }
1334
1314
  ngAfterViewInit() {
1335
1315
  }
@@ -1367,8 +1347,8 @@ class BlockSeriesComponent extends SeriesBaseComponent {
1367
1347
  }
1368
1348
  ngOnInit() {
1369
1349
  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)));
1350
+ this.x = this.scaleService.scales.pipe(map((_) => _.x.get(this.series.xAxisIndex).scale));
1351
+ this.y = this.scaleService.scales.pipe(map((_) => _.y.get(this.series.yAxisIndex).scale));
1372
1352
  this.displayPoints = this.y.pipe(map((y) => {
1373
1353
  return this.series.data.filter((point, index, arr) => {
1374
1354
  const [min, max] = y.domain();
@@ -1419,8 +1399,8 @@ class BlockAreaSeriesComponent extends SeriesBaseComponent {
1419
1399
  }
1420
1400
  ngOnInit() {
1421
1401
  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)));
1402
+ this.x = this.scaleService.scales.pipe(map((_) => _.x.get(this.series.xAxisIndex).scale));
1403
+ this.y = this.scaleService.scales.pipe(map((_) => _.y.get(this.series.yAxisIndex).scale));
1424
1404
  this.displayPoints = this.y.pipe(map((y) => {
1425
1405
  return this.series.data.filter((point, index, arr) => {
1426
1406
  const [min, max] = y.domain();
@@ -1471,13 +1451,10 @@ class AreaSeriesComponent extends LinearSeriesBase {
1471
1451
  }
1472
1452
  ngOnInit() {
1473
1453
  super.ngOnInit();
1474
- this.areaPath = combineLatest([
1475
- this.scaleService.xScaleMap,
1476
- this.scaleService.yScaleMap,
1477
- ]).pipe(map((data) => {
1478
- const [x, y] = data;
1479
- this.x = x.get(this.series.xAxisIndex);
1480
- this.y = y.get(this.series.yAxisIndex);
1454
+ this.areaPath = this.scaleService.scales.pipe(map((data) => {
1455
+ const { x, y } = data;
1456
+ this.x = x.get(this.series.xAxisIndex).scale;
1457
+ this.y = y.get(this.series.yAxisIndex).scale;
1481
1458
  const area = d3
1482
1459
  .area()
1483
1460
  .defined((point) => point.x !== null &&
@@ -1567,10 +1544,16 @@ class GridlinesComponent {
1567
1544
  this.svc = svc;
1568
1545
  this.chartService = chartService;
1569
1546
  this.config = this.chartService.config;
1570
- this.tickYValues = this.svc.yScaleMap.pipe(map((_) => _.get(0).ticks()));
1571
- this.tickXValues = this.svc.xScaleMap.pipe(map((_) => _.get(0).ticks()));
1572
- this.y = this.svc.yScaleMap.pipe(map((_) => _.get(0)));
1573
- this.x = this.svc.xScaleMap.pipe(map((_) => _.get(0)));
1547
+ this.tickYValues = this.svc.scales.pipe(map((_) => {
1548
+ const ratio = this.size.height / 40;
1549
+ return _.y.get(0).scale.ticks(ratio);
1550
+ }));
1551
+ this.tickXValues = this.svc.scales.pipe(map((_) => {
1552
+ const ratio = this.size.width / 40;
1553
+ return _.x.get(0).scale.ticks(ratio);
1554
+ }));
1555
+ this.y = this.svc.scales.pipe(map((_) => _.y.get(0).scale));
1556
+ this.x = this.svc.scales.pipe(map((_) => _.x.get(0).scale));
1574
1557
  }
1575
1558
  ngAfterViewInit() {
1576
1559
  }
@@ -1588,8 +1571,8 @@ class XAxisComponent {
1588
1571
  constructor(scaleService) {
1589
1572
  this.scaleService = scaleService;
1590
1573
  this._alive = true;
1591
- this.x = this.scaleService.xScaleMap.pipe(map((_) => {
1592
- return _.get(this.axis.index);
1574
+ this.x = this.scaleService.scales.pipe(map((_) => {
1575
+ return _.x.get(this.axis.index)?.scale;
1593
1576
  }));
1594
1577
  }
1595
1578
  getLabelTransform() {
@@ -1599,30 +1582,6 @@ class XAxisComponent {
1599
1582
  ngOnDestroy() {
1600
1583
  this._alive = false;
1601
1584
  }
1602
- ngAfterViewInit() {
1603
- // this.draw();
1604
- }
1605
- draw() {
1606
- // if (!this.node || !this.axis) {
1607
- // return;
1608
- // }
1609
- //
1610
- // const axis = this.axis.options.opposite
1611
- // ? d3
1612
- // .axisTop(this.scale)
1613
- // .tickFormat(
1614
- // this.axis.options.tickFormat ?? this.axis.defaultFormatter()
1615
- // )
1616
- // : d3
1617
- // .axisBottom(this.scale)
1618
- // .tickFormat(
1619
- // this.axis.options.tickFormat ?? this.axis.defaultFormatter()
1620
- // );
1621
- //
1622
- // d3.select(this.node.nativeElement)
1623
- // .call(axis)
1624
- // .call((_) => _.select('.domain').remove());
1625
- }
1626
1585
  }
1627
1586
  XAxisComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: XAxisComponent, deps: [{ token: ScaleService }], target: i0.ɵɵFactoryTarget.Component });
1628
1587
  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 });
@@ -1639,8 +1598,8 @@ class YAxisComponent {
1639
1598
  constructor(scaleService) {
1640
1599
  this.scaleService = scaleService;
1641
1600
  this._alive = true;
1642
- this.y = this.scaleService.yScaleMap.pipe(map((_) => {
1643
- return _.get(this.axis.index);
1601
+ this.y = this.scaleService.scales.pipe(map((_) => {
1602
+ return _.y.get(this.axis.index)?.scale;
1644
1603
  }));
1645
1604
  }
1646
1605
  ngOnInit() { }
@@ -1996,7 +1955,7 @@ class ZoomableDirective {
1996
1955
  const message = new ZoomMessage({
1997
1956
  event,
1998
1957
  axis: this.axis,
1999
- brushDomain: domain,
1958
+ domain,
2000
1959
  chartId: this.config.id,
2001
1960
  });
2002
1961
  this.broadcastService.broadcastZoom({
@@ -2063,6 +2022,7 @@ class ZoomableDirective {
2063
2022
  this.zoom.scaleExtent([maxZoom, minZoom]);
2064
2023
  this.zoom.on('zoom end', this.zoomed);
2065
2024
  this._element.call(this.zoom).on('dblclick.zoom', null); // Disable dbclick zoom
2025
+ this.chartService.emitZoomInstance(this.zoomService);
2066
2026
  if (this.config?.zoom?.zoomBehavior === ZoomBehaviorType.wheel) {
2067
2027
  this.runWheelZoom();
2068
2028
  }
@@ -2083,7 +2043,26 @@ class ZoomableDirective {
2083
2043
  this.axis.orientation === m.message?.axis?.orientation);
2084
2044
  }), tap$1((m) => {
2085
2045
  if (this.config.id !== m.message?.chartId) {
2086
- this._element.call(this.zoom.transform, m.message.event.transform, null, {});
2046
+ this.brushScale.domain(this.axis.originDomain);
2047
+ const scale = Math.abs(this.axis.originDomain[1] - this.axis.originDomain[0]) / Math.abs(m.message.domain[1] - m.message.domain[0]);
2048
+ let transform = zoomIdentity.scale(scale);
2049
+ if (this.config?.zoom?.type === ZoomType.x) {
2050
+ if (this.config.xAxis[0]?.inverted) {
2051
+ transform = transform.translate(-this.brushScale(m.message.domain[0]), 0);
2052
+ }
2053
+ else {
2054
+ transform = transform.translate(this.brushScale(-m.message.domain[1]), 0);
2055
+ }
2056
+ }
2057
+ if (this.config?.zoom?.type === ZoomType.y) {
2058
+ if (this.config.yAxis[0]?.inverted) {
2059
+ transform = transform.translate(0, -this.brushScale(m.message.domain[0]));
2060
+ }
2061
+ else {
2062
+ transform = transform.translate(0, -this.brushScale(m.message.domain[1]));
2063
+ }
2064
+ }
2065
+ this._element.call(this.zoom.transform, transform, null, {});
2087
2066
  }
2088
2067
  }))
2089
2068
  .subscribe();
@@ -2096,7 +2075,7 @@ class ZoomableDirective {
2096
2075
  .pipe(combineLatestWith(this.chartService.size), takeWhile((_) => this.alive), filter((data) => {
2097
2076
  const [m] = data;
2098
2077
  return Boolean(m.message.selection);
2099
- }), debounceTime(150), tap$1((data) => {
2078
+ }), tap$1((data) => {
2100
2079
  const [m] = data;
2101
2080
  const currentTransform = d3.zoomTransform(this._element.node());
2102
2081
  if (!m.message.event &&
@@ -2180,7 +2159,7 @@ class ZoomableDirective {
2180
2159
  type,
2181
2160
  },
2182
2161
  axis: this.axis,
2183
- brushDomain: domain,
2162
+ domain,
2184
2163
  chartId: this.config.id,
2185
2164
  });
2186
2165
  this.zoomService.fireZoom({
@@ -2275,8 +2254,8 @@ class AnnotationComponent {
2275
2254
  this.scaleService = scaleService;
2276
2255
  this.cdr = cdr;
2277
2256
  this.chartService = chartService;
2278
- this.x = this.scaleService.xScaleMap.pipe(map((_) => _.get(this.annotation.xAxisIndex ?? 0)));
2279
- this.y = this.scaleService.yScaleMap.pipe(map((_) => _.get(this.annotation.yAxisIndex ?? 0)));
2257
+ this.x = this.scaleService.scales.pipe(map((_) => _.x.get(this.annotation.xAxisIndex ?? 0).scale));
2258
+ this.y = this.scaleService.scales.pipe(map((_) => _.y.get(this.annotation.yAxisIndex ?? 0).scale));
2280
2259
  this.drag = d3.drag();
2281
2260
  }
2282
2261
  set annotation(annotation) {
@@ -2390,30 +2369,21 @@ class ChartContainerComponent {
2390
2369
  this.sumSize = (acc, curr) => acc + curr.selfSize;
2391
2370
  this.config = this._svc.config;
2392
2371
  this.size = this._svc.size;
2393
- this.yAxisMap = this._scaleService.yAxisMap;
2394
- this.xAxisMap = this._scaleService.xAxisMap;
2395
- this.yScaleMap = this._scaleService.yScaleMap.pipe(observeOn(animationFrameScheduler, 10), tetaZoneFull(this._zone), shareReplay({
2396
- bufferSize: 1,
2397
- refCount: true,
2398
- }));
2399
- this.xScaleMap = this._scaleService.xScaleMap.pipe(observeOn(animationFrameScheduler, 10), tetaZoneFull(this._zone), shareReplay({
2372
+ this.scales = this._scaleService.scales.pipe(observeOn(animationFrameScheduler), tetaZoneFull(this._zone), shareReplay({
2400
2373
  bufferSize: 1,
2401
2374
  refCount: true,
2402
2375
  }));
2403
- this.brushScale = combineLatest([
2404
- this._scaleService.xScaleMap,
2405
- this._scaleService.yScaleMap,
2406
- ]).pipe(withLatestFrom(this.config), map((data) => {
2407
- const [[x, y], config] = data;
2408
- return config.brush?.type === BrushType.x || config?.zoom?.type === ZoomType.x ? x.get(0) : y.get(0);
2376
+ this.brushScale = this._scaleService.scales.pipe(withLatestFrom(this.config), map((data) => {
2377
+ const [{ x, y }, config] = data;
2378
+ return config.brush?.type === BrushType.x || config?.zoom?.type === ZoomType.x ? x.get(0).scale : y.get(0).scale;
2409
2379
  }), shareReplay({
2410
2380
  bufferSize: 1,
2411
2381
  refCount: true,
2412
2382
  }));
2413
- this.visibleRect = this.size.pipe(combineLatestWith(this.xAxisMap, this.yAxisMap)).pipe(withLatestFrom(this.config), map((data) => {
2414
- const [[size, x, y], config] = data;
2415
- const yAxesArray = [...y.values()];
2416
- const xAxesArray = [...x.values()];
2383
+ this.visibleRect = this.size.pipe(combineLatestWith(this.scales)).pipe(withLatestFrom(this.config), map((data) => {
2384
+ const [[size, { x, y }], config] = data;
2385
+ const yAxesArray = Array.from(y.values());
2386
+ const xAxesArray = Array.from(x.values());
2417
2387
  const left = yAxesArray
2418
2388
  .filter((_) => _.options.opposite !== true && _.options.visible)
2419
2389
  .reduce(this.sumSize, 0);
@@ -2465,10 +2435,10 @@ class ChartContainerComponent {
2465
2435
  this._observer.disconnect();
2466
2436
  }
2467
2437
  getTranslate(axis, size) {
2468
- return combineLatest([this.xAxisMap, this.yAxisMap]).pipe(withLatestFrom(this.config), map((data) => {
2469
- const [[x, y], config] = data;
2470
- const xAxesArray = [...x.values()];
2471
- const yAxesArray = [...y.values()];
2438
+ return this.scales.pipe(withLatestFrom(this.config), map((data) => {
2439
+ const [{ x, y }, config] = data;
2440
+ const xAxesArray = Array.from(x.values());
2441
+ const yAxesArray = Array.from(y.values());
2472
2442
  const oppositeFilter = this.filterPositionMap.get(true);
2473
2443
  const nonOppositeFilter = this.filterPositionMap.get(false);
2474
2444
  const oppositeOffsetY = yAxesArray.filter(oppositeFilter(axis));
@@ -2531,10 +2501,10 @@ class ChartContainerComponent {
2531
2501
  }
2532
2502
  }
2533
2503
  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 });
2534
- 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 });
2504
+ 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 scales: scales | 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.scales.x && data.scales.y\">\n <svg height=\"100%\" width=\"100%\" class=\"position-absolute\">\n <g class=\"y-axis-container\">\n <ng-container *ngFor=\"let item of data.scales.y | 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.scales.y.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.scales.x | keyvalue; trackBy: identify\">\n <ng-container *ngIf=\"item.value.options.visible && data.scales.x && data.scales.y\">\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.scales.x.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.scales.x && data.scales.y\">\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.scales.x.get(0) : data.scales.y.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.scales.x, data.scales.y)\"\n (click)=\"click($event, data.scales.x, data.scales.y)\"\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.scales.x.get(i).scale\"\n [size]=\"data.size\"\n [axis]=\"data.scales.x.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.scales.y.get(i).scale\"\n [size]=\"data.size\"\n [axis]=\"data.scales.y.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.scales.x.get(i).scale\"\n [size]=\"data.size\"\n [axis]=\"data.scales.x.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.scales.y.get(i).scale\"\n [size]=\"data.size\"\n [axis]=\"data.scales.x.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 });
2535
2505
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: ChartContainerComponent, decorators: [{
2536
2506
  type: Component,
2537
- 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"] }]
2507
+ args: [{ selector: 'teta-chart-container', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"{\n size: size | async,\n config: config | async,\n scales: scales | 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.scales.x && data.scales.y\">\n <svg height=\"100%\" width=\"100%\" class=\"position-absolute\">\n <g class=\"y-axis-container\">\n <ng-container *ngFor=\"let item of data.scales.y | 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.scales.y.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.scales.x | keyvalue; trackBy: identify\">\n <ng-container *ngIf=\"item.value.options.visible && data.scales.x && data.scales.y\">\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.scales.x.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.scales.x && data.scales.y\">\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.scales.x.get(0) : data.scales.y.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.scales.x, data.scales.y)\"\n (click)=\"click($event, data.scales.x, data.scales.y)\"\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.scales.x.get(i).scale\"\n [size]=\"data.size\"\n [axis]=\"data.scales.x.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.scales.y.get(i).scale\"\n [size]=\"data.size\"\n [axis]=\"data.scales.y.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.scales.x.get(i).scale\"\n [size]=\"data.size\"\n [axis]=\"data.scales.x.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.scales.y.get(i).scale\"\n [size]=\"data.size\"\n [axis]=\"data.scales.x.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"] }]
2538
2508
  }], ctorParameters: function () { return [{ type: ChartService }, { type: i0.ChangeDetectorRef }, { type: ScaleService }, { type: ZoomService }, { type: i0.ElementRef }, { type: i0.NgZone }]; } });
2539
2509
 
2540
2510
  class LegendComponent {
@@ -2584,6 +2554,7 @@ class ChartComponent {
2584
2554
  this.annotationContextMenu = new EventEmitter();
2585
2555
  this.annotationClick = new EventEmitter();
2586
2556
  this.annotationMove = new EventEmitter();
2557
+ this.zoomServiceInstance = new EventEmitter();
2587
2558
  this._alive = true;
2588
2559
  this.svcConfig = this.chartService.config;
2589
2560
  this.hasSeriesData = this.svcConfig.pipe(map((_) => _.series?.length > 0 && _.series?.some((_) => _.data?.length > 0)));
@@ -2595,14 +2566,14 @@ class ChartComponent {
2595
2566
  }
2596
2567
  ngOnInit() {
2597
2568
  this.chartService.pointerMove
2598
- .pipe(takeWhile(() => this._alive), withLatestFrom(this.scaleService.xScaleMap, this.scaleService.yScaleMap, this.chartService.config))
2569
+ .pipe(takeWhile(() => this._alive), withLatestFrom(this.scaleService.scales, this.chartService.config))
2599
2570
  .subscribe((data) => {
2600
- const [event, x, y, config] = data;
2571
+ const [event, { x, y }, config] = data;
2601
2572
  const tooltipTracking = config?.tooltip?.tracking;
2602
2573
  if (tooltipTracking === TooltipTracking.y) {
2603
2574
  const result = new Map();
2604
2575
  y.forEach((value, key) => {
2605
- result.set(key, value.invert(event.offsetY));
2576
+ result.set(key, value.scale.invert(event.offsetY));
2606
2577
  });
2607
2578
  this.pointerMove.emit({
2608
2579
  event: event,
@@ -2612,7 +2583,7 @@ class ChartComponent {
2612
2583
  else {
2613
2584
  const result = new Map();
2614
2585
  x.forEach((value, key) => {
2615
- result.set(key, value.invert(event.offsetX));
2586
+ result.set(key, value.scale.invert(event.offsetX));
2616
2587
  });
2617
2588
  this.pointerMove.emit({
2618
2589
  event: event,
@@ -2664,6 +2635,11 @@ class ChartComponent {
2664
2635
  .subscribe((_) => {
2665
2636
  this.annotationMove.emit(_);
2666
2637
  });
2638
+ this.chartService.zoomInstance
2639
+ .pipe(takeWhile(() => this._alive))
2640
+ .subscribe((_) => {
2641
+ this.zoomServiceInstance.emit(_);
2642
+ });
2667
2643
  }
2668
2644
  ngAfterViewInit() {
2669
2645
  }
@@ -2675,7 +2651,7 @@ class ChartComponent {
2675
2651
  }
2676
2652
  }
2677
2653
  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 });
2678
- 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 });
2654
+ 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 });
2679
2655
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: ChartComponent, decorators: [{
2680
2656
  type: Component,
2681
2657
  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"] }]
@@ -2701,6 +2677,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImpor
2701
2677
  type: Output
2702
2678
  }], annotationMove: [{
2703
2679
  type: Output
2680
+ }], zoomServiceInstance: [{
2681
+ type: Output
2704
2682
  }], config: [{
2705
2683
  type: Input
2706
2684
  }] } });