@tetacom/svg-charts 1.2.29 → 1.3.1

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 (36) hide show
  1. package/chart/chart/chart.component.d.ts +5 -2
  2. package/chart/chart-container/chart-container.component.d.ts +1 -1
  3. package/chart/chart-container/series/linear-series-base.d.ts +0 -3
  4. package/chart/core/axis/axis.d.ts +2 -2
  5. package/chart/directives/brushable.directive.d.ts +15 -5
  6. package/chart/directives/zoomable.directive.d.ts +6 -11
  7. package/chart/model/enum/clip-points-direction.d.ts +2 -1
  8. package/chart/model/i-broadcast-message.d.ts +18 -19
  9. package/chart/model/marker-options.d.ts +1 -1
  10. package/chart/service/broadcast.service.d.ts +1 -4
  11. package/chart/service/brush.service.d.ts +6 -13
  12. package/chart/service/chart.service.d.ts +0 -4
  13. package/chart/service/scale.service.d.ts +1 -1
  14. package/chart/service/zoom.service.d.ts +15 -15
  15. package/esm2020/chart/chart/chart.component.mjs +17 -17
  16. package/esm2020/chart/chart-container/chart-container.component.mjs +3 -3
  17. package/esm2020/chart/chart-container/crosshair/crosshair.component.mjs +1 -2
  18. package/esm2020/chart/chart-container/plotband/plot-band.component.mjs +4 -2
  19. package/esm2020/chart/chart-container/series/line/line-series.component.mjs +3 -3
  20. package/esm2020/chart/chart-container/series/linear-series-base.mjs +4 -72
  21. package/esm2020/chart/core/axis/axis.mjs +2 -2
  22. package/esm2020/chart/directives/brushable.directive.mjs +120 -10
  23. package/esm2020/chart/directives/zoomable.directive.mjs +90 -197
  24. package/esm2020/chart/model/enum/clip-points-direction.mjs +2 -1
  25. package/esm2020/chart/model/i-broadcast-message.mjs +4 -6
  26. package/esm2020/chart/model/marker-options.mjs +1 -1
  27. package/esm2020/chart/service/broadcast.service.mjs +4 -17
  28. package/esm2020/chart/service/brush.service.mjs +11 -147
  29. package/esm2020/chart/service/chart.service.mjs +17 -9
  30. package/esm2020/chart/service/scale.service.mjs +19 -21
  31. package/esm2020/chart/service/zoom.service.mjs +48 -53
  32. package/fesm2015/tetacom-svg-charts.mjs +372 -585
  33. package/fesm2015/tetacom-svg-charts.mjs.map +1 -1
  34. package/fesm2020/tetacom-svg-charts.mjs +355 -565
  35. package/fesm2020/tetacom-svg-charts.mjs.map +1 -1
  36. package/package.json +1 -1
@@ -3,12 +3,10 @@ import { Injectable, Component, Input, EventEmitter, Directive, Output, HostList
3
3
  import * as i4 from '@angular/common';
4
4
  import { CommonModule } from '@angular/common';
5
5
  import { __awaiter } from 'tslib';
6
- import { BehaviorSubject, Subject, of, withLatestFrom, map, shareReplay, filter, lastValueFrom, take, combineLatest, ReplaySubject, tap, takeWhile, combineLatestWith, observeOn, animationFrameScheduler } from 'rxjs';
6
+ import { BehaviorSubject, Subject, of, withLatestFrom, map, shareReplay, filter, lastValueFrom, take, ReplaySubject, combineLatest, tap, takeWhile, observeOn, animationFrameScheduler } from 'rxjs';
7
7
  import * as d3 from 'd3';
8
8
  import { zoomIdentity } from 'd3';
9
- import objectHash from 'object-hash';
10
9
  import { maxIndex } from 'd3-array';
11
- import { debounceTime, tap as tap$1 } from 'rxjs/operators';
12
10
  import * as i5 from '@tetacom/ng-components';
13
11
  import { PositionUtil, Align, VerticalAlign, tetaZoneFull, LetModule } from '@tetacom/ng-components';
14
12
  import * as i3 from '@angular/platform-browser';
@@ -124,6 +122,7 @@ var ClipPointsDirection;
124
122
  (function (ClipPointsDirection) {
125
123
  ClipPointsDirection[ClipPointsDirection["x"] = 0] = "x";
126
124
  ClipPointsDirection[ClipPointsDirection["y"] = 1] = "y";
125
+ ClipPointsDirection[ClipPointsDirection["none"] = 2] = "none";
127
126
  })(ClipPointsDirection || (ClipPointsDirection = {}));
128
127
 
129
128
  const defaultSeriesConfig = () => ({
@@ -139,8 +138,10 @@ const defaultSeriesConfig = () => ({
139
138
 
140
139
  class ChartService {
141
140
  constructor() {
141
+ // public zoomInstance: Observable<ZoomService>;
142
+ // public brushInstance: Observable<BrushService>;
142
143
  this.config$ = new BehaviorSubject(defaultChartConfig());
143
- this.size$ = new BehaviorSubject(new DOMRectReadOnly());
144
+ this.size$ = new BehaviorSubject(null);
144
145
  this.pointerMove$ = new Subject();
145
146
  this.tooltips$ = new BehaviorSubject(new Map());
146
147
  this.plotBandEvent$ = new Subject();
@@ -150,13 +151,12 @@ class ChartService {
150
151
  this.chartContextMenu$ = new Subject();
151
152
  this.annotationEvent$ = new Subject();
152
153
  this.annotationMove$ = new Subject();
153
- this.zoomInstance$ = new Subject();
154
154
  this.id = of((Date.now() + Math.random()).toString(36));
155
155
  this.config = this.config$.asObservable().pipe(withLatestFrom(this.id), map(this.setDefaults), map(this.setPreparationData), map(this.restoreLocalStorage), shareReplay({
156
156
  bufferSize: 1,
157
157
  refCount: true,
158
158
  }));
159
- this.size = this.size$.asObservable();
159
+ this.size = this.size$.asObservable().pipe(filter((size) => size != null));
160
160
  this.pointerMove = this.pointerMove$.asObservable();
161
161
  this.tooltips = this.tooltips$.asObservable();
162
162
  this.plotBandEvent = this.plotBandEvent$.asObservable();
@@ -177,7 +177,8 @@ class ChartService {
177
177
  this.plotBandContextMenu = this.plotBandEvent$
178
178
  .asObservable()
179
179
  .pipe(filter((_) => { var _a; return ((_a = _ === null || _ === void 0 ? void 0 : _.event) === null || _a === void 0 ? void 0 : _a.type) === 'contextmenu'; }));
180
- this.zoomInstance = this.zoomInstance$.asObservable();
180
+ // this.zoomInstance = this.zoomInstance$.asObservable();
181
+ // this.brushInstance = this.brushInstance$.asObservable();
181
182
  }
182
183
  setConfig(config) {
183
184
  this.clearTooltips();
@@ -246,9 +247,13 @@ class ChartService {
246
247
  emitChartContextMenu(event) {
247
248
  this.chartContextMenu$.next(event);
248
249
  }
249
- emitZoomInstance(event) {
250
- this.zoomInstance$.next(event);
251
- }
250
+ // public emitZoomInstance(event: ZoomService) {
251
+ // this.zoomInstance$.next(event);
252
+ // }
253
+ //
254
+ // public emitZoomInstance(event: ZoomService) {
255
+ // this.zoomInstance$.next(event);
256
+ // }
252
257
  saveCookie(config) {
253
258
  var _a;
254
259
  if (!config.name)
@@ -276,7 +281,7 @@ class ChartService {
276
281
  return config;
277
282
  }
278
283
  setDefaults(data) {
279
- var _a, _b, _c, _d, _e, _f;
284
+ var _a, _b, _c, _d, _e, _f, _g;
280
285
  let [config, id] = data;
281
286
  const defaultConfig = (defaultConfig) => {
282
287
  return (source) => {
@@ -284,7 +289,7 @@ class ChartService {
284
289
  };
285
290
  };
286
291
  config = Object.assign({}, defaultChartConfig(), config);
287
- config.id = id;
292
+ config.id = (_a = config.id) !== null && _a !== void 0 ? _a : id;
288
293
  config.xAxis = config.xAxis.map(defaultConfig(defaultAxisConfig));
289
294
  config.yAxis = config.yAxis.map(defaultConfig(defaultAxisConfig));
290
295
  config.series = config.series.map(defaultConfig(defaultSeriesConfig()));
@@ -292,10 +297,10 @@ class ChartService {
292
297
  var _a, _b;
293
298
  return Object.assign(Object.assign({}, _), { data: (_a = _.data) !== null && _a !== void 0 ? _a : [], id: (_b = _.id) !== null && _b !== void 0 ? _b : index });
294
299
  });
295
- const oppositeYCount = (_a = config.yAxis) === null || _a === void 0 ? void 0 : _a.filter((_) => _.opposite);
296
- const oppositeXCount = (_b = config.xAxis) === null || _b === void 0 ? void 0 : _b.filter((_) => _.opposite);
297
- const nonOppositeYCount = (_c = config.yAxis) === null || _c === void 0 ? void 0 : _c.filter((_) => !_.opposite);
298
- const nonOppositeXCount = (_d = config.xAxis) === null || _d === void 0 ? void 0 : _d.filter((_) => !_.opposite);
300
+ const oppositeYCount = (_b = config.yAxis) === null || _b === void 0 ? void 0 : _b.filter((_) => _.opposite);
301
+ const oppositeXCount = (_c = config.xAxis) === null || _c === void 0 ? void 0 : _c.filter((_) => _.opposite);
302
+ const nonOppositeYCount = (_d = config.yAxis) === null || _d === void 0 ? void 0 : _d.filter((_) => !_.opposite);
303
+ const nonOppositeXCount = (_e = config.xAxis) === null || _e === void 0 ? void 0 : _e.filter((_) => !_.opposite);
299
304
  if ((nonOppositeXCount === null || nonOppositeXCount === void 0 ? void 0 : nonOppositeXCount.length) > 1) {
300
305
  config.bounds.bottom = 0;
301
306
  }
@@ -310,7 +315,7 @@ class ChartService {
310
315
  }
311
316
  config.tooltip = Object.assign({}, defaultChartConfig().tooltip, config.tooltip);
312
317
  config.zoom = Object.assign({}, defaultChartConfig().zoom, config.zoom);
313
- config.zoom.syncChannel = (_f = (_e = config.zoom) === null || _e === void 0 ? void 0 : _e.syncChannel) !== null && _f !== void 0 ? _f : id;
318
+ config.zoom.syncChannel = (_g = (_f = config.zoom) === null || _f === void 0 ? void 0 : _f.syncChannel) !== null && _g !== void 0 ? _g : id;
314
319
  return config;
315
320
  }
316
321
  setPreparationData(config) {
@@ -338,6 +343,8 @@ class ChartService {
338
343
  return config;
339
344
  }
340
345
  }
346
+ // private zoomInstance$ = new Subject<ZoomService>();
347
+ // private brushInstance$ = new Subject<BrushService>();
341
348
  ChartService._hiddenSeriesPostfix = 'hidden_series';
342
349
  ChartService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: ChartService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
343
350
  ChartService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: ChartService, providedIn: 'root' });
@@ -354,14 +361,31 @@ var AxisOrientation;
354
361
  AxisOrientation[AxisOrientation["y"] = 1] = "y";
355
362
  })(AxisOrientation || (AxisOrientation = {}));
356
363
 
357
- class ZoomService {
364
+ class BroadcastService {
358
365
  constructor() {
359
- this.broadcastSubscription = [];
360
- this.axisHashMap = new Map();
361
- this.scaleHashMap = new Map();
362
- this.elementHashMap = new Map();
363
- this.zoomHashMap = new Map();
364
- this.zoomed$ = new BehaviorSubject({});
366
+ this.zoomEmitter = new ReplaySubject(1);
367
+ }
368
+ broadcastZoom(value) {
369
+ this.zoomEmitter.next(value);
370
+ }
371
+ subscribeToZoom(channel) {
372
+ return this.zoomEmitter.asObservable().pipe(filter((msg) => channel && msg.channel === channel));
373
+ }
374
+ }
375
+ BroadcastService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: BroadcastService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
376
+ BroadcastService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: BroadcastService, providedIn: 'root' });
377
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: BroadcastService, decorators: [{
378
+ type: Injectable,
379
+ args: [{
380
+ providedIn: 'root',
381
+ }]
382
+ }], ctorParameters: function () { return []; } });
383
+
384
+ class ZoomService {
385
+ constructor(_broadcast, _chart) {
386
+ this._broadcast = _broadcast;
387
+ this._chart = _chart;
388
+ this.zoomed$ = new BehaviorSubject(null);
365
389
  this.zoomed = this.zoomed$.asObservable().pipe(shareReplay({
366
390
  bufferSize: 1,
367
391
  refCount: true
@@ -370,64 +394,66 @@ class ZoomService {
370
394
  fireZoom(zoom) {
371
395
  this.zoomed$.next(zoom);
372
396
  }
397
+ broadcastZoom(zoom) {
398
+ var _a;
399
+ if ((_a = this.broadcastChannel) === null || _a === void 0 ? void 0 : _a.length) {
400
+ this._broadcast.broadcastZoom({
401
+ channel: this.broadcastChannel,
402
+ message: zoom
403
+ });
404
+ }
405
+ }
373
406
  setBroadcastChannel(channel) {
407
+ var _a, _b;
408
+ if (this.broadcastSub) {
409
+ (_a = this.broadcastSub) === null || _a === void 0 ? void 0 : _a.unsubscribe();
410
+ }
374
411
  this.broadcastChannel = channel;
375
- }
376
- setZoom(from, to, axisIndex = 0, axisOrientation = AxisOrientation.x) {
377
- const hash = objectHash.sha1({ index: axisIndex, orientation: axisOrientation });
378
- if (!this.zoomHashMap.has(hash)) {
379
- return;
412
+ if ((_b = this.broadcastChannel) === null || _b === void 0 ? void 0 : _b.length) {
413
+ this.broadcastSub = combineLatest([this._broadcast.subscribeToZoom(this.broadcastChannel), this._chart.config])
414
+ .pipe(filter(([zoom, config]) => {
415
+ var _a;
416
+ return ((_a = zoom.message) === null || _a === void 0 ? void 0 : _a.chartId) !== config.id;
417
+ }))
418
+ .subscribe(([zoom, config]) => {
419
+ this.fireZoom(zoom.message);
420
+ });
380
421
  }
381
- const currentAxis = this.axisHashMap.get(hash);
382
- const currentScale = this.scaleHashMap.get(hash);
383
- const currentElement = this.elementHashMap.get(hash);
384
- const currentZoom = this.zoomHashMap.get(hash);
385
- currentScale.domain(currentAxis.originDomain);
386
- if (axisOrientation === AxisOrientation.x) {
387
- if (currentAxis.options.scaleType.type === ScaleType.log) {
388
- currentScale.domain(currentAxis.options.inverted ? [...currentAxis.originDomain].reverse() : currentAxis.originDomain);
422
+ }
423
+ getD3Transform(targetDomain, originalDomain, scale, orientation, inverted) {
424
+ const zoomScale = Math.abs(originalDomain[1] - originalDomain[0]) / Math.abs(targetDomain[1] - targetDomain[0]);
425
+ let transform = zoomIdentity.scale(zoomScale);
426
+ if (orientation === AxisOrientation.x) {
427
+ if (!!inverted) {
428
+ transform = transform.translate(-scale(Math.max(...targetDomain)), 0);
389
429
  }
390
- }
391
- if (axisOrientation === AxisOrientation.y) {
392
- if (currentAxis.options.scaleType.type === ScaleType.log) {
393
- currentScale.domain(currentAxis.options.inverted ? currentAxis.originDomain : [...currentAxis.originDomain].reverse());
430
+ else {
431
+ transform = transform.translate(-scale(Math.min(...targetDomain)), 0);
394
432
  }
395
433
  }
396
- const delta = Math.abs(currentScale(to) - currentScale(from));
397
- const scale = currentScale.range()[1] / delta;
398
- let transform = zoomIdentity.scale(scale);
399
- if (currentAxis.orientation === AxisOrientation.x) {
400
- if (currentAxis.options.scaleType.type === ScaleType.log) {
401
- currentScale.domain(currentAxis.options.inverted ? [...currentScale.domain()].reverse() : currentScale.domain());
434
+ if (orientation === AxisOrientation.y) {
435
+ if (!!inverted) {
436
+ transform = transform.translate(0, -scale(Math.min(...targetDomain)));
402
437
  }
403
- transform = transform.translate(-currentScale(from), 0);
404
- }
405
- if (currentAxis.orientation === AxisOrientation.y) {
406
- if (currentAxis.options.scaleType.type === ScaleType.log) {
407
- currentScale.domain(currentAxis.options.inverted ? currentScale.domain() : [...currentScale.domain()].reverse());
438
+ else {
439
+ transform = transform.translate(0, -scale(Math.max(...targetDomain)));
408
440
  }
409
- transform = transform.translate(0, -currentScale(from));
410
441
  }
411
- currentElement.transition().call(currentZoom.transform, transform, null, new MouseEvent('setZoom'));
442
+ return transform;
412
443
  }
413
- resetZoom(axisIndex = 0, axisOrientation = AxisOrientation.x) {
414
- const hash = objectHash.sha1({ index: axisIndex, orientation: axisOrientation });
415
- if (!this.zoomHashMap.has(hash)) {
416
- return;
417
- }
418
- const currentElement = this.elementHashMap.get(hash);
419
- const currentZoom = this.zoomHashMap.get(hash);
420
- currentElement.transition().call(currentZoom.transform, zoomIdentity, null, new MouseEvent('resetZoom'));
444
+ ngOnDestroy() {
445
+ var _a;
446
+ (_a = this.broadcastSub) === null || _a === void 0 ? void 0 : _a.unsubscribe();
421
447
  }
422
448
  }
423
- ZoomService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: ZoomService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
449
+ ZoomService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: ZoomService, deps: [{ token: BroadcastService }, { token: ChartService }], target: i0.ɵɵFactoryTarget.Injectable });
424
450
  ZoomService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: ZoomService, providedIn: 'root' });
425
451
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: ZoomService, decorators: [{
426
452
  type: Injectable,
427
453
  args: [{
428
454
  providedIn: 'root',
429
455
  }]
430
- }], ctorParameters: function () { return []; } });
456
+ }], ctorParameters: function () { return [{ type: BroadcastService }, { type: ChartService }]; } });
431
457
 
432
458
  const getTextWidth = (inputText, backupRatio = 0.5, fontSize = 10) => {
433
459
  let text = inputText !== null && inputText !== void 0 ? inputText : '';
@@ -500,7 +526,7 @@ class ExtremesBuilder {
500
526
  class Axis {
501
527
  constructor(config) {
502
528
  this._extremes = [0, 0];
503
- this._originDomain = [];
529
+ this._originDomain = [0, 0];
504
530
  this.defaultFormatters = new Map()
505
531
  .set(ScaleType.linear, d3.format(',.5~r'))
506
532
  .set(ScaleType.time, d3.timeFormat('%d.%m.%Y'))
@@ -671,22 +697,21 @@ class ScaleService {
671
697
  axis.setScale(scale);
672
698
  axis.setOriginDomain(scale.domain());
673
699
  const hasCache = this.transformCacheX.has(axis.index);
674
- const shouldRestore = ((_a = zoom === null || zoom === void 0 ? void 0 : zoom.target) === null || _a === void 0 ? void 0 : _a.orientation) !== AxisOrientation.x ||
675
- ((_b = zoom.target) === null || _b === void 0 ? void 0 : _b.index) !== axis.index;
700
+ const shouldRestore = ((_a = zoom === null || zoom === void 0 ? void 0 : zoom.axis) === null || _a === void 0 ? void 0 : _a.orientation) !== AxisOrientation.x ||
701
+ ((_b = zoom.axis) === null || _b === void 0 ? void 0 : _b.index) !== axis.index;
676
702
  if (hasCache && shouldRestore) {
677
703
  const restoredTransform = this.transformCacheX.get(axis.index);
678
704
  axis.setScale(restoredTransform.rescaleX(scale));
679
705
  }
680
706
  });
681
- if (zoom) {
682
- const event = zoom.event;
683
- if (((_a = zoom.target) === null || _a === void 0 ? void 0 : _a.orientation) === AxisOrientation.x) {
684
- if (xAxisMap.has(zoom.target.index)) {
685
- const x = xAxisMap.get(zoom.target.index);
686
- const rescaled = event.transform.rescaleX(x.scale);
707
+ if (zoom && zoom.domain) {
708
+ if (((_a = zoom.axis) === null || _a === void 0 ? void 0 : _a.orientation) === AxisOrientation.x) {
709
+ if (xAxisMap.has(zoom.axis.index)) {
710
+ const x = xAxisMap.get(zoom.axis.index);
711
+ const transform = this.zoomService.getD3Transform(zoom.domain, x.originDomain, x.scale, AxisOrientation.x, x.options.inverted);
712
+ const rescaled = transform.rescaleX(x.scale.copy());
687
713
  x.setScale(rescaled);
688
- const axis = xAxisMap.get(zoom.target.index);
689
- this.transformCacheX.set(axis.index, event.transform);
714
+ this.transformCacheX.set(x.index, transform);
690
715
  }
691
716
  }
692
717
  }
@@ -724,22 +749,21 @@ class ScaleService {
724
749
  axis.setScale(scale);
725
750
  axis.setOriginDomain(scale.domain());
726
751
  const hasCache = this.transformCacheY.has(axis.index);
727
- const shouldRestore = ((_a = zoom === null || zoom === void 0 ? void 0 : zoom.target) === null || _a === void 0 ? void 0 : _a.orientation) !== AxisOrientation.y ||
728
- ((_b = zoom.target) === null || _b === void 0 ? void 0 : _b.index) !== axis.index;
752
+ const shouldRestore = ((_a = zoom === null || zoom === void 0 ? void 0 : zoom.axis) === null || _a === void 0 ? void 0 : _a.orientation) !== AxisOrientation.y ||
753
+ ((_b = zoom.axis) === null || _b === void 0 ? void 0 : _b.index) !== axis.index;
729
754
  if (hasCache && shouldRestore) {
730
755
  const restoredTransform = this.transformCacheY.get(axis.index);
731
756
  axis.setScale(restoredTransform.rescaleY(scale));
732
757
  }
733
758
  });
734
- if (zoom) {
735
- const event = zoom.event;
736
- if (((_d = zoom.target) === null || _d === void 0 ? void 0 : _d.orientation) === AxisOrientation.y) {
737
- if (yAxisMap.has(zoom.target.index)) {
738
- const y = yAxisMap.get(zoom.target.index);
739
- const rescaled = event.transform.rescaleY(y.scale);
759
+ if (zoom && zoom.domain) {
760
+ if (((_d = zoom.axis) === null || _d === void 0 ? void 0 : _d.orientation) === AxisOrientation.y) {
761
+ if (yAxisMap.has(zoom.axis.index)) {
762
+ const y = yAxisMap.get(zoom.axis.index);
763
+ const transform = this.zoomService.getD3Transform(zoom.domain, y.originDomain, y.scale, AxisOrientation.y, y.options.inverted);
764
+ const rescaled = transform.rescaleY(y.scale.copy());
740
765
  y.setScale(rescaled);
741
- const axis = yAxisMap.get(zoom.target.index);
742
- this.transformCacheY.set(axis.index, event.transform);
766
+ this.transformCacheY.set(y.index, transform);
743
767
  }
744
768
  }
745
769
  }
@@ -762,218 +786,32 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImpor
762
786
  }]
763
787
  }], ctorParameters: function () { return [{ type: ChartService }, { type: ZoomService }]; } });
764
788
 
765
- var BrushType;
766
- (function (BrushType) {
767
- BrushType[BrushType["x"] = 0] = "x";
768
- BrushType[BrushType["y"] = 1] = "y";
769
- BrushType[BrushType["xy"] = 2] = "xy";
770
- })(BrushType || (BrushType = {}));
771
-
772
- class ZoomMessage {
773
- constructor(options) {
774
- this.event = options === null || options === void 0 ? void 0 : options.event;
775
- this.axis = options === null || options === void 0 ? void 0 : options.axis;
776
- this.domain = options.domain;
777
- this.chartId = options === null || options === void 0 ? void 0 : options.chartId;
778
- this.style = options === null || options === void 0 ? void 0 : options.style;
779
- }
780
- }
781
- class BrushMessage {
782
- constructor(options) {
783
- this.event = options === null || options === void 0 ? void 0 : options.event;
784
- this.brushType = options === null || options === void 0 ? void 0 : options.brushType;
785
- this.selection = options === null || options === void 0 ? void 0 : options.selection;
786
- this.brushScale = options === null || options === void 0 ? void 0 : options.brushScale;
787
- this.style = options === null || options === void 0 ? void 0 : options.style;
788
- }
789
- }
790
-
791
- class BroadcastService {
792
- constructor() {
793
- this.zoomEmitter = new Subject();
794
- this.brushEmitter = new ReplaySubject(1);
795
- }
796
- broadcastZoom(value) {
797
- this.zoomEmitter.next(value);
798
- }
799
- broadcastBrush(value) {
800
- this.brushEmitter.next(value);
801
- }
802
- subscribeToZoom(channel) {
803
- return this.zoomEmitter.asObservable().pipe(filter((msg) => channel && msg.channel === channel), shareReplay({
804
- bufferSize: 1,
805
- refCount: true
806
- }));
807
- }
808
- subscribeToBrush(channel) {
809
- return this.brushEmitter.asObservable().pipe(filter((msg) => channel && msg.channel === channel), shareReplay({
810
- bufferSize: 1,
811
- refCount: true
812
- }));
813
- }
814
- }
815
- BroadcastService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: BroadcastService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
816
- BroadcastService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: BroadcastService, providedIn: 'root' });
817
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: BroadcastService, decorators: [{
818
- type: Injectable,
819
- args: [{
820
- providedIn: 'root',
821
- }]
822
- }], ctorParameters: function () { return []; } });
823
-
824
789
  class BrushService {
825
- constructor(broadcastService, zone) {
826
- this.broadcastService = broadcastService;
827
- this.zone = zone;
828
- this.brushMap = new Map()
829
- .set(BrushType.x, d3.brushX())
830
- .set(BrushType.y, d3.brushY());
831
- }
832
- applyBrush(svgElement, config, brushScale) {
833
- var _a, _b, _c, _d, _e, _f;
834
- (_a = this.broadcastSubscribtion) === null || _a === void 0 ? void 0 : _a.unsubscribe();
835
- (_b = this.brush) === null || _b === void 0 ? void 0 : _b.on('start brush end', null);
836
- if ((_c = config.brush) === null || _c === void 0 ? void 0 : _c.enable) {
837
- this.brush = this.brushMap.get((_e = (_d = config === null || config === void 0 ? void 0 : config.brush) === null || _d === void 0 ? void 0 : _d.type) !== null && _e !== void 0 ? _e : BrushType.x);
838
- const container = d3.select(svgElement.nativeElement);
839
- this.brush.on('start brush end', (_) => {
840
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
841
- if (_.sourceEvent) {
842
- if (!_.selection)
843
- return;
844
- const [from, to] = _.selection;
845
- if (to - from === 0) {
846
- const selection = (_b = (_a = this.selection) === null || _a === void 0 ? void 0 : _a.map(brushScale)) !== null && _b !== void 0 ? _b : [(_c = config.brush) === null || _c === void 0 ? void 0 : _c.from, (_d = config.brush) === null || _d === void 0 ? void 0 : _d.to].map(brushScale);
847
- const halfBrushHeight = (selection[1] - selection[0]) / 2;
848
- const invertedSelection = [
849
- from - halfBrushHeight,
850
- to + halfBrushHeight,
851
- ].map(brushScale.invert);
852
- if (invertedSelection[1] - invertedSelection[0] >
853
- ((_e = config.brush) === null || _e === void 0 ? void 0 : _e.max)) {
854
- container.call(this.brush.move, [
855
- Math.floor(invertedSelection[0]),
856
- Math.floor(invertedSelection[0] + ((_f = config.brush) === null || _f === void 0 ? void 0 : _f.max)),
857
- ].map(brushScale));
858
- return;
859
- }
860
- if (invertedSelection[1] - invertedSelection[0] <
861
- ((_g = config.brush) === null || _g === void 0 ? void 0 : _g.min)) {
862
- container.call(this.brush.move, [
863
- Math.floor(invertedSelection[0]),
864
- Math.ceil(invertedSelection[0] + ((_h = config.brush) === null || _h === void 0 ? void 0 : _h.min)),
865
- ].map(brushScale));
866
- return;
867
- }
868
- container.call(this.brush.move, [
869
- from - halfBrushHeight,
870
- to + halfBrushHeight,
871
- ]);
872
- return;
873
- }
874
- if (brushScale.invert(to) - brushScale.invert(from) >
875
- ((_j = config.brush) === null || _j === void 0 ? void 0 : _j.max)) {
876
- container.call(this.brush.move, this.selection
877
- ? [
878
- this.selection[0],
879
- this.selection[0] + ((_k = config.brush) === null || _k === void 0 ? void 0 : _k.max),
880
- ].map(brushScale)
881
- : [(_l = config.brush) === null || _l === void 0 ? void 0 : _l.from, (_m = config.brush) === null || _m === void 0 ? void 0 : _m.to].map(brushScale));
882
- return;
883
- }
884
- if (brushScale.invert(to) - brushScale.invert(from) <
885
- ((_o = config.brush) === null || _o === void 0 ? void 0 : _o.min)) {
886
- container.call(this.brush.move, this.selection
887
- ? [
888
- this.selection[0],
889
- this.selection[0] + ((_p = config.brush) === null || _p === void 0 ? void 0 : _p.min),
890
- ].map(brushScale)
891
- : [(_q = config.brush) === null || _q === void 0 ? void 0 : _q.from, (_r = config.brush) === null || _r === void 0 ? void 0 : _r.to].map(brushScale));
892
- return;
893
- }
894
- if (_.sourceEvent instanceof MouseEvent) {
895
- this.selection = _.selection.map(brushScale.invert);
896
- }
897
- const brushMessage = new BrushMessage({
898
- event: _,
899
- selection: [brushScale.invert(from), brushScale.invert(to)],
900
- brushType: (_t = (_s = config === null || config === void 0 ? void 0 : config.brush) === null || _s === void 0 ? void 0 : _s.type) !== null && _t !== void 0 ? _t : BrushType.x,
901
- brushScale,
902
- });
903
- this.broadcastService.broadcastBrush({
904
- channel: (_u = config === null || config === void 0 ? void 0 : config.zoom) === null || _u === void 0 ? void 0 : _u.syncChannel,
905
- message: brushMessage,
906
- });
907
- }
908
- });
909
- this.zone.runOutsideAngular(() => {
910
- setTimeout(() => {
911
- var _a, _b;
912
- container.call(this.brush);
913
- let domain = brushScale.domain();
914
- if ((_a = config === null || config === void 0 ? void 0 : config.brush) === null || _a === void 0 ? void 0 : _a.from) {
915
- domain[0] = config.brush.from;
916
- }
917
- if ((_b = config === null || config === void 0 ? void 0 : config.brush) === null || _b === void 0 ? void 0 : _b.to) {
918
- domain[1] = config.brush.to;
919
- }
920
- container.call(this.brush.move, this.selection
921
- ? this.selection.map(brushScale)
922
- : domain.map(brushScale), {});
923
- }, 0);
924
- });
925
- this.broadcastSubscribtion = this.broadcastService
926
- .subscribeToZoom((_f = config === null || config === void 0 ? void 0 : config.zoom) === null || _f === void 0 ? void 0 : _f.syncChannel)
927
- .pipe(filter((m) => {
928
- return (m.message.event.sourceEvent instanceof MouseEvent ||
929
- m.message.event.sourceEvent instanceof WheelEvent ||
930
- (window.TouchEvent &&
931
- m.message.event.sourceEvent instanceof TouchEvent));
932
- }), tap((m) => {
933
- var _a, _b, _c, _d, _e;
934
- const { message: { domain }, } = m;
935
- if ((((_a = m.message) === null || _a === void 0 ? void 0 : _a.axis.index) === 0 &&
936
- ((_b = m.message) === null || _b === void 0 ? void 0 : _b.axis.orientation) === AxisOrientation.y &&
937
- ((_c = config.brush) === null || _c === void 0 ? void 0 : _c.type) === BrushType.y) ||
938
- (((_d = m.message) === null || _d === void 0 ? void 0 : _d.axis.orientation) === AxisOrientation.x &&
939
- ((_e = config.brush) === null || _e === void 0 ? void 0 : _e.type) === BrushType.x)) {
940
- container.call(this.brush.move, [
941
- brushScale(domain[0]),
942
- brushScale(domain[1]),
943
- ]);
944
- this.selection = domain;
945
- }
946
- }), debounceTime(30), tap((m) => {
947
- var _a, _b, _c;
948
- const { message: { domain }, } = m;
949
- if (m.message.event.type === 'zoom') {
950
- const brushMessage = new BrushMessage({
951
- event: null,
952
- selection: domain,
953
- brushType: (_b = (_a = config === null || config === void 0 ? void 0 : config.brush) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : BrushType.x,
954
- brushScale,
955
- });
956
- this.broadcastService.broadcastBrush({
957
- channel: (_c = config === null || config === void 0 ? void 0 : config.zoom) === null || _c === void 0 ? void 0 : _c.syncChannel,
958
- message: brushMessage,
959
- });
960
- }
961
- }))
962
- .subscribe();
963
- }
790
+ // private _outBrushDomain = new ReplaySubject<[number, number]>(1);
791
+ constructor() {
792
+ // outBrushDomain: Observable<[number, number]>;
793
+ this._brushDomain = new ReplaySubject(1);
794
+ this.brushDomain = this._brushDomain.asObservable();
964
795
  }
965
- clearPreviousSelection() {
966
- this.selection = null;
796
+ setBrush(brush) {
797
+ this._brushDomain.next(brush);
967
798
  }
968
799
  }
969
- BrushService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: BrushService, deps: [{ token: BroadcastService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
800
+ BrushService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: BrushService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
970
801
  BrushService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: BrushService, providedIn: 'root' });
971
802
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: BrushService, decorators: [{
972
803
  type: Injectable,
973
804
  args: [{
974
805
  providedIn: 'root',
975
806
  }]
976
- }], ctorParameters: function () { return [{ type: BroadcastService }, { type: i0.NgZone }]; } });
807
+ }], ctorParameters: function () { return []; } });
808
+
809
+ var BrushType;
810
+ (function (BrushType) {
811
+ BrushType[BrushType["x"] = 0] = "x";
812
+ BrushType[BrushType["y"] = 1] = "y";
813
+ BrushType[BrushType["xy"] = 2] = "xy";
814
+ })(BrushType || (BrushType = {}));
977
815
 
978
816
  class SeriesBaseComponent {
979
817
  constructor(svc, cdr, scaleService, zoomService, element, zone) {
@@ -1026,7 +864,7 @@ class LinearSeriesBase extends SeriesBaseComponent {
1026
864
  set series(series) {
1027
865
  var _a;
1028
866
  this.__series = series;
1029
- this.markers = (_a = this.__series.data) === null || _a === void 0 ? void 0 : _a.filter((_) => _ === null || _ === void 0 ? void 0 : _.marker);
867
+ this.markers = (_a = this.__series.data) === null || _a === void 0 ? void 0 : _a.filter((_) => (_ === null || _ === void 0 ? void 0 : _.marker) && (_ === null || _ === void 0 ? void 0 : _.x) !== undefined && (_ === null || _ === void 0 ? void 0 : _.y) !== undefined);
1030
868
  }
1031
869
  get series() {
1032
870
  return this.__series;
@@ -1064,7 +902,6 @@ class LinearSeriesBase extends SeriesBaseComponent {
1064
902
  }), tap(() => setTimeout(() => this.cdr.detectChanges())));
1065
903
  this.path = combineLatest([this.scaleService.scales, this._update]).pipe(map(([data]) => {
1066
904
  var _a, _b;
1067
- // console.log(data);
1068
905
  const { x, y } = data;
1069
906
  this.x = (_a = x.get(this.series.xAxisIndex)) === null || _a === void 0 ? void 0 : _a.scale;
1070
907
  this.y = (_b = y.get(this.series.yAxisIndex)) === null || _b === void 0 ? void 0 : _b.scale;
@@ -1096,18 +933,9 @@ class LinearSeriesBase extends SeriesBaseComponent {
1096
933
  filteredData = filteredData === null || filteredData === void 0 ? void 0 : filteredData.filter(filter(min, max));
1097
934
  }
1098
935
  return line(filteredData);
1099
- }), tap((_) => {
1100
- // console.log(_)
1101
- setTimeout(() => {
1102
- var _a;
1103
- if (((_a = this.markers) === null || _a === void 0 ? void 0 : _a.length) > 0) {
1104
- // this.addDragEvents();
1105
- }
1106
- });
1107
936
  }));
1108
937
  }
1109
938
  ngOnDestroy() {
1110
- // this.markerListeners?.on('start drag end', null);
1111
939
  this.svc.setTooltip({
1112
940
  point: null,
1113
941
  series: this.series,
@@ -1115,65 +943,6 @@ class LinearSeriesBase extends SeriesBaseComponent {
1115
943
  }
1116
944
  ngAfterViewInit() {
1117
945
  }
1118
- addDragEvents() {
1119
- // this.markerListeners?.on('start drag end', null);
1120
- // const drag = (node, event: d3.D3DragEvent<any, any, any>, d: BasePoint) => {
1121
- // if (
1122
- // d.marker?.dragType === DragPointType.x ||
1123
- // d.marker?.dragType === DragPointType.xy
1124
- // ) {
1125
- // d.x = this.x.invert(event.x);
1126
- // }
1127
- //
1128
- // if (
1129
- // d.marker?.dragType === DragPointType.y ||
1130
- // d.marker?.dragType === DragPointType.xy
1131
- // ) {
1132
- // d.y = this.y.invert(event.y);
1133
- // }
1134
- //
1135
- // this.svc.emitPoint({
1136
- // target: {
1137
- // series: this.series,
1138
- // point: d,
1139
- // },
1140
- // event,
1141
- // });
1142
- //
1143
- // this.cdr.detectChanges();
1144
- // };
1145
- // this.markerListeners = d3
1146
- // .drag()
1147
- // .subject(function (event, d: BasePoint) {
1148
- // const node = d3.select(this);
1149
- // return {x: node.attr('cx'), y: node.attr('cy')};
1150
- // });
1151
- // const dragMarkers =
1152
- // this.markerListeners.on(
1153
- // 'start drag end',
1154
- // function (event: d3.D3DragEvent<any, any, any>, d: BasePoint) {
1155
- // const node = d3.select(this);
1156
- //
1157
- // drag(node, event, d);
1158
- // }
1159
- // );
1160
- //
1161
- // const draggableMarkers = this.series.data?.filter(
1162
- // (_) => _?.marker && _?.marker?.draggable
1163
- // );
1164
- //
1165
- // const element = d3
1166
- // .select(this.element.nativeElement)
1167
- // .selectAll('.draggable-marker')
1168
- // .data(draggableMarkers);
1169
- //
1170
- // element.call(dragMarkers as any);
1171
- //
1172
- // this.svgElement = d3
1173
- // .select(this.element.nativeElement)
1174
- // .select('.line')
1175
- // .node() as SVGGeometryElement;
1176
- }
1177
946
  getTransform(event, scaleX, scaleY) {
1178
947
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
1179
948
  if (event.type === 'mouseleave') {
@@ -1211,7 +980,7 @@ class LinearSeriesBase extends SeriesBaseComponent {
1211
980
  }
1212
981
  const rightId = bisect(this.series.data, x0);
1213
982
  const range = scaleY.range();
1214
- const intersect = lineIntersection(pointer, range[0], pointer, range[1], scaleX((_c = this.series.data[rightId - 1]) === null || _c === void 0 ? void 0 : _c.x), scaleY((_d = this.series.data[rightId - 1]) === null || _d === void 0 ? void 0 : _d.y), scaleX((_e = this.series.data[rightId]) === null || _e === void 0 ? void 0 : _e.x), scaleY((_f = this.series.data[rightId]) === null || _f === void 0 ? void 0 : _f.y));
983
+ const intersect = lineIntersection(pointer, range[0], pointer, Number.MAX_SAFE_INTEGER, scaleX((_c = this.series.data[rightId - 1]) === null || _c === void 0 ? void 0 : _c.x), scaleY((_d = this.series.data[rightId - 1]) === null || _d === void 0 ? void 0 : _d.y), scaleX((_e = this.series.data[rightId]) === null || _e === void 0 ? void 0 : _e.x), scaleY((_f = this.series.data[rightId]) === null || _f === void 0 ? void 0 : _f.y));
1215
984
  const x = scaleX.invert(intersect.x);
1216
985
  const y = scaleY.invert(intersect.y);
1217
986
  if (x !== null && x !== undefined && !isNaN(x) && y !== null && y !== undefined && !isNaN(y)) {
@@ -1239,7 +1008,7 @@ class LinearSeriesBase extends SeriesBaseComponent {
1239
1008
  }
1240
1009
  const rightId = bisect(this.series.data, y0);
1241
1010
  const range = scaleX.range();
1242
- const intersect = lineIntersection(range[0], mouse[1], range[1], mouse[1], scaleX((_g = this.series.data[rightId - 1]) === null || _g === void 0 ? void 0 : _g.x), scaleY((_h = this.series.data[rightId - 1]) === null || _h === void 0 ? void 0 : _h.y), scaleX((_j = this.series.data[rightId]) === null || _j === void 0 ? void 0 : _j.x), scaleY((_k = this.series.data[rightId]) === null || _k === void 0 ? void 0 : _k.y));
1011
+ const intersect = lineIntersection(range[0], mouse[1], Number.MAX_SAFE_INTEGER, mouse[1], scaleX((_g = this.series.data[rightId - 1]) === null || _g === void 0 ? void 0 : _g.x), scaleY((_h = this.series.data[rightId - 1]) === null || _h === void 0 ? void 0 : _h.y), scaleX((_j = this.series.data[rightId]) === null || _j === void 0 ? void 0 : _j.x), scaleY((_k = this.series.data[rightId]) === null || _k === void 0 ? void 0 : _k.y));
1243
1012
  const x = scaleX.invert(intersect.x);
1244
1013
  const y = scaleY.invert(intersect.y);
1245
1014
  if (x !== null && x !== undefined && !isNaN(x) && y !== null && y !== undefined && !isNaN(y)) {
@@ -1495,10 +1264,10 @@ class LineSeriesComponent extends LinearSeriesBase {
1495
1264
  }
1496
1265
  }
1497
1266
  LineSeriesComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: LineSeriesComponent, deps: [{ token: ChartService }, { token: i0.ChangeDetectorRef }, { token: ScaleService }, { token: ZoomService }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
1498
- LineSeriesComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.2", type: LineSeriesComponent, selector: "svg:svg[teta-line-series]", usesInheritance: true, ngImport: i0, template: "<svg:path\n class=\"line\"\n [attr.d]=\"path | async\"\n [attr.stroke]=\"series.color\"\n [attr.stroke-dasharray]=\"series.style?.strokeDasharray\"\n [attr.stroke-width]=\"series.style?.strokeWidth\"\n fill=\"none\">\n</svg:path>\n<ng-container *ngIf=\"transform | async as t\">\n <svg:circle\n *ngIf=\"t?.x !=null && t?.y!=null\"\n r=\"3\"\n [attr.fill]=\"series.color\"\n [attr.transform]=\"'translate('+ t.x +', '+ t.y +')'\"\n >\n </svg:circle>\n</ng-container>\n<ng-container *ngIf=\"markers as draggablePoints\">\n <svg:g\n *ngFor=\"let point of draggablePoints\"\n [attr.transform]=\"'translate(' + x(point.x)+ ',' +y(point.y) + ')'\">\n <svg:g [tetaDraggablePoint]=\"point.marker.draggable\"\n [dragDirection]=\"point.marker.dragType\"\n [allowDrag]=\"allowDrag(point)\"\n #dragPoint=\"tetaDraggablePoint\"\n (moveStart)=\"moveStart($event, point)\"\n (moveEnd)=\"moveEnd($event, point);dragPoint.resetTransform();\"\n (moveProcess)=\"moveProcess($event, point);dragPoint.resetTransform();\"\n [class.draggable-marker]=\"point?.marker?.draggable\">\n <svg:circle\n class=\"marker\"\n [attr.r]=\"point.marker.style?.radius ?? 5\"\n [attr.fill]=\"point.marker.style?.fill ?? 'transparent'\"\n [attr.stroke]=\"point.marker.style?.stroke ?? 'none'\"\n [attr.stroke-width]=\"point.marker.style?.strokeWidth\"\n [attr.stroke-dasharray]=\"point.marker.style?.strokeDasharray\"\n [attr.cx]=\"0\"\n [attr.cy]=\"0\">\n </svg:circle>\n <ng-container *ngIf=\"point.marker.label?.text\">\n <svg:line\n [attr.x1]=\"0\"\n [attr.y1]=\"0\"\n [attr.x2]=\"point.marker.label?.dx\"\n [attr.y2]=\"point.marker.label?.dy\"\n [attr.stroke]=\"point.marker.label?.style?.stroke ?? 'var(--color-text-90)'\"\n [attr.stroke-width]=\"point.marker.label?.style?.strokeWidth ?? 1\"\n [attr.stroke-dasharray]=\"point.marker.label?.style?.strokeDasharray ?? null\">\n </svg:line>\n <svg:foreignObject\n [tetaDraggablePoint]=\"point.marker.label?.draggable\"\n [dragDirection]=\"point.marker.label.dragType\"\n #labelPoint=\"tetaDraggablePoint\"\n (moveStart)=\"startLabel($event, point.marker.label)\"\n (moveProcess)=\"moveLabel($event, point.marker.label); labelPoint.resetTransform();\"\n (moveEnd)=\"labelPoint.resetTransform();\"\n [attr.width]=\"annotationNode?.offsetWidth ?? 0\"\n [attr.height]=\"annotationNode?.offsetHeight ?? 0\"\n [attr.x]=\"point.marker.label?.dx\"\n [attr.y]=\"point.marker.label?.dy\"\n class=\"position-absolute\">\n <div\n #annotationNode\n class=\"shadow-2 padding-2\"\n [style.color]=\"'var(--color-text-90)'\"\n [style.background-color]=\"'var(--color-background-50)'\"\n [style.cursor]=\"'move'\"\n style=\"border-radius: 2px; display: inline-block;\">\n {{point.marker.label?.text}}\n </div>\n </svg:foreignObject>\n </ng-container>\n </svg:g>\n </svg:g>\n</ng-container>\n\n\n\n", styles: [".draggable-marker{cursor:move}.active{stroke-opacity:.5}.marker-grab{opacity:0}\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: "directive", type: DraggablePointDirective, selector: "[tetaDraggablePoint]", inputs: ["tetaDraggablePoint", "dragDirection", "allowDrag"], outputs: ["moveStart", "moveProcess", "moveEnd"], exportAs: ["tetaDraggablePoint"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1267
+ LineSeriesComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.2", type: LineSeriesComponent, selector: "svg:svg[teta-line-series]", usesInheritance: true, ngImport: i0, template: "<svg:path\n class=\"line\"\n [attr.d]=\"path | async\"\n [attr.stroke]=\"series.color\"\n [attr.stroke-dasharray]=\"series.style?.strokeDasharray\"\n [attr.stroke-width]=\"series.style?.strokeWidth\"\n fill=\"none\">\n</svg:path>\n<ng-container *ngIf=\"transform | async as t\">\n <svg:circle\n *ngIf=\"t?.x !=null && t?.y!=null\"\n r=\"3\"\n [attr.fill]=\"series.color\"\n [attr.transform]=\"'translate('+ t.x +', '+ t.y +')'\"\n >\n </svg:circle>\n</ng-container>\n<ng-container *ngIf=\"markers as draggablePoints\">\n <ng-container *ngIf=\"x && y\">\n <svg:g\n *ngFor=\"let point of draggablePoints\"\n [attr.transform]=\"'translate(' + x(point.x) + ',' + y(point.y) + ')'\">\n <svg:g [tetaDraggablePoint]=\"point.marker.draggable\"\n [dragDirection]=\"point.marker.dragType\"\n [allowDrag]=\"allowDrag(point)\"\n #dragPoint=\"tetaDraggablePoint\"\n (moveStart)=\"moveStart($event, point)\"\n (moveEnd)=\"moveEnd($event, point);dragPoint.resetTransform();\"\n (moveProcess)=\"moveProcess($event, point);dragPoint.resetTransform();\"\n [class.draggable-marker]=\"point?.marker?.draggable\">\n <svg:circle\n class=\"marker\"\n [attr.r]=\"point.marker.style?.radius ?? 5\"\n [attr.fill]=\"point.marker.style?.fill ?? 'transparent'\"\n [attr.stroke]=\"point.marker.style?.stroke ?? 'none'\"\n [attr.stroke-width]=\"point.marker.style?.strokeWidth\"\n [attr.stroke-dasharray]=\"point.marker.style?.strokeDasharray\"\n [attr.cx]=\"0\"\n [attr.cy]=\"0\">\n </svg:circle>\n <ng-container *ngIf=\"point.marker.label?.text\">\n <svg:line\n [attr.x1]=\"0\"\n [attr.y1]=\"0\"\n [attr.x2]=\"point.marker.label?.dx\"\n [attr.y2]=\"point.marker.label?.dy\"\n [attr.stroke]=\"point.marker.label?.style?.stroke ?? 'var(--color-text-90)'\"\n [attr.stroke-width]=\"point.marker.label?.style?.strokeWidth ?? 1\"\n [attr.stroke-dasharray]=\"point.marker.label?.style?.strokeDasharray ?? null\">\n </svg:line>\n <svg:foreignObject\n [tetaDraggablePoint]=\"point.marker.label?.draggable\"\n [dragDirection]=\"point.marker.label.dragType\"\n #labelPoint=\"tetaDraggablePoint\"\n (moveStart)=\"startLabel($event, point.marker.label)\"\n (moveProcess)=\"moveLabel($event, point.marker.label); labelPoint.resetTransform();\"\n (moveEnd)=\"labelPoint.resetTransform();\"\n [attr.width]=\"annotationNode?.offsetWidth ?? 0\"\n [attr.height]=\"annotationNode?.offsetHeight ?? 0\"\n [attr.x]=\"point.marker.label?.dx\"\n [attr.y]=\"point.marker.label?.dy\"\n class=\"position-absolute\">\n <div\n #annotationNode\n class=\"shadow-2 padding-2\"\n [style.color]=\"'var(--color-text-90)'\"\n [style.background-color]=\"'var(--color-background-50)'\"\n [style.cursor]=\"'move'\"\n style=\"border-radius: 2px; display: inline-block;\">\n {{point.marker.label?.text}}\n </div>\n </svg:foreignObject>\n </ng-container>\n </svg:g>\n </svg:g>\n </ng-container>\n\n</ng-container>\n\n\n\n", styles: [".draggable-marker{cursor:move}.active{stroke-opacity:.5}.marker-grab{opacity:0}\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: "directive", type: DraggablePointDirective, selector: "[tetaDraggablePoint]", inputs: ["tetaDraggablePoint", "dragDirection", "allowDrag"], outputs: ["moveStart", "moveProcess", "moveEnd"], exportAs: ["tetaDraggablePoint"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1499
1268
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: LineSeriesComponent, decorators: [{
1500
1269
  type: Component,
1501
- args: [{ selector: 'svg:svg[teta-line-series]', changeDetection: ChangeDetectionStrategy.OnPush, template: "<svg:path\n class=\"line\"\n [attr.d]=\"path | async\"\n [attr.stroke]=\"series.color\"\n [attr.stroke-dasharray]=\"series.style?.strokeDasharray\"\n [attr.stroke-width]=\"series.style?.strokeWidth\"\n fill=\"none\">\n</svg:path>\n<ng-container *ngIf=\"transform | async as t\">\n <svg:circle\n *ngIf=\"t?.x !=null && t?.y!=null\"\n r=\"3\"\n [attr.fill]=\"series.color\"\n [attr.transform]=\"'translate('+ t.x +', '+ t.y +')'\"\n >\n </svg:circle>\n</ng-container>\n<ng-container *ngIf=\"markers as draggablePoints\">\n <svg:g\n *ngFor=\"let point of draggablePoints\"\n [attr.transform]=\"'translate(' + x(point.x)+ ',' +y(point.y) + ')'\">\n <svg:g [tetaDraggablePoint]=\"point.marker.draggable\"\n [dragDirection]=\"point.marker.dragType\"\n [allowDrag]=\"allowDrag(point)\"\n #dragPoint=\"tetaDraggablePoint\"\n (moveStart)=\"moveStart($event, point)\"\n (moveEnd)=\"moveEnd($event, point);dragPoint.resetTransform();\"\n (moveProcess)=\"moveProcess($event, point);dragPoint.resetTransform();\"\n [class.draggable-marker]=\"point?.marker?.draggable\">\n <svg:circle\n class=\"marker\"\n [attr.r]=\"point.marker.style?.radius ?? 5\"\n [attr.fill]=\"point.marker.style?.fill ?? 'transparent'\"\n [attr.stroke]=\"point.marker.style?.stroke ?? 'none'\"\n [attr.stroke-width]=\"point.marker.style?.strokeWidth\"\n [attr.stroke-dasharray]=\"point.marker.style?.strokeDasharray\"\n [attr.cx]=\"0\"\n [attr.cy]=\"0\">\n </svg:circle>\n <ng-container *ngIf=\"point.marker.label?.text\">\n <svg:line\n [attr.x1]=\"0\"\n [attr.y1]=\"0\"\n [attr.x2]=\"point.marker.label?.dx\"\n [attr.y2]=\"point.marker.label?.dy\"\n [attr.stroke]=\"point.marker.label?.style?.stroke ?? 'var(--color-text-90)'\"\n [attr.stroke-width]=\"point.marker.label?.style?.strokeWidth ?? 1\"\n [attr.stroke-dasharray]=\"point.marker.label?.style?.strokeDasharray ?? null\">\n </svg:line>\n <svg:foreignObject\n [tetaDraggablePoint]=\"point.marker.label?.draggable\"\n [dragDirection]=\"point.marker.label.dragType\"\n #labelPoint=\"tetaDraggablePoint\"\n (moveStart)=\"startLabel($event, point.marker.label)\"\n (moveProcess)=\"moveLabel($event, point.marker.label); labelPoint.resetTransform();\"\n (moveEnd)=\"labelPoint.resetTransform();\"\n [attr.width]=\"annotationNode?.offsetWidth ?? 0\"\n [attr.height]=\"annotationNode?.offsetHeight ?? 0\"\n [attr.x]=\"point.marker.label?.dx\"\n [attr.y]=\"point.marker.label?.dy\"\n class=\"position-absolute\">\n <div\n #annotationNode\n class=\"shadow-2 padding-2\"\n [style.color]=\"'var(--color-text-90)'\"\n [style.background-color]=\"'var(--color-background-50)'\"\n [style.cursor]=\"'move'\"\n style=\"border-radius: 2px; display: inline-block;\">\n {{point.marker.label?.text}}\n </div>\n </svg:foreignObject>\n </ng-container>\n </svg:g>\n </svg:g>\n</ng-container>\n\n\n\n", styles: [".draggable-marker{cursor:move}.active{stroke-opacity:.5}.marker-grab{opacity:0}\n"] }]
1270
+ args: [{ selector: 'svg:svg[teta-line-series]', changeDetection: ChangeDetectionStrategy.OnPush, template: "<svg:path\n class=\"line\"\n [attr.d]=\"path | async\"\n [attr.stroke]=\"series.color\"\n [attr.stroke-dasharray]=\"series.style?.strokeDasharray\"\n [attr.stroke-width]=\"series.style?.strokeWidth\"\n fill=\"none\">\n</svg:path>\n<ng-container *ngIf=\"transform | async as t\">\n <svg:circle\n *ngIf=\"t?.x !=null && t?.y!=null\"\n r=\"3\"\n [attr.fill]=\"series.color\"\n [attr.transform]=\"'translate('+ t.x +', '+ t.y +')'\"\n >\n </svg:circle>\n</ng-container>\n<ng-container *ngIf=\"markers as draggablePoints\">\n <ng-container *ngIf=\"x && y\">\n <svg:g\n *ngFor=\"let point of draggablePoints\"\n [attr.transform]=\"'translate(' + x(point.x) + ',' + y(point.y) + ')'\">\n <svg:g [tetaDraggablePoint]=\"point.marker.draggable\"\n [dragDirection]=\"point.marker.dragType\"\n [allowDrag]=\"allowDrag(point)\"\n #dragPoint=\"tetaDraggablePoint\"\n (moveStart)=\"moveStart($event, point)\"\n (moveEnd)=\"moveEnd($event, point);dragPoint.resetTransform();\"\n (moveProcess)=\"moveProcess($event, point);dragPoint.resetTransform();\"\n [class.draggable-marker]=\"point?.marker?.draggable\">\n <svg:circle\n class=\"marker\"\n [attr.r]=\"point.marker.style?.radius ?? 5\"\n [attr.fill]=\"point.marker.style?.fill ?? 'transparent'\"\n [attr.stroke]=\"point.marker.style?.stroke ?? 'none'\"\n [attr.stroke-width]=\"point.marker.style?.strokeWidth\"\n [attr.stroke-dasharray]=\"point.marker.style?.strokeDasharray\"\n [attr.cx]=\"0\"\n [attr.cy]=\"0\">\n </svg:circle>\n <ng-container *ngIf=\"point.marker.label?.text\">\n <svg:line\n [attr.x1]=\"0\"\n [attr.y1]=\"0\"\n [attr.x2]=\"point.marker.label?.dx\"\n [attr.y2]=\"point.marker.label?.dy\"\n [attr.stroke]=\"point.marker.label?.style?.stroke ?? 'var(--color-text-90)'\"\n [attr.stroke-width]=\"point.marker.label?.style?.strokeWidth ?? 1\"\n [attr.stroke-dasharray]=\"point.marker.label?.style?.strokeDasharray ?? null\">\n </svg:line>\n <svg:foreignObject\n [tetaDraggablePoint]=\"point.marker.label?.draggable\"\n [dragDirection]=\"point.marker.label.dragType\"\n #labelPoint=\"tetaDraggablePoint\"\n (moveStart)=\"startLabel($event, point.marker.label)\"\n (moveProcess)=\"moveLabel($event, point.marker.label); labelPoint.resetTransform();\"\n (moveEnd)=\"labelPoint.resetTransform();\"\n [attr.width]=\"annotationNode?.offsetWidth ?? 0\"\n [attr.height]=\"annotationNode?.offsetHeight ?? 0\"\n [attr.x]=\"point.marker.label?.dx\"\n [attr.y]=\"point.marker.label?.dy\"\n class=\"position-absolute\">\n <div\n #annotationNode\n class=\"shadow-2 padding-2\"\n [style.color]=\"'var(--color-text-90)'\"\n [style.background-color]=\"'var(--color-background-50)'\"\n [style.cursor]=\"'move'\"\n style=\"border-radius: 2px; display: inline-block;\">\n {{point.marker.label?.text}}\n </div>\n </svg:foreignObject>\n </ng-container>\n </svg:g>\n </svg:g>\n </ng-container>\n\n</ng-container>\n\n\n\n", styles: [".draggable-marker{cursor:move}.active{stroke-opacity:.5}.marker-grab{opacity:0}\n"] }]
1502
1271
  }], ctorParameters: function () { return [{ type: ChartService }, { type: i0.ChangeDetectorRef }, { type: ScaleService }, { type: ZoomService }, { type: i0.ElementRef }]; } });
1503
1272
 
1504
1273
  class BarSeriesComponent extends SeriesBaseComponent {
@@ -1975,7 +1744,9 @@ class PlotBandComponent {
1975
1744
  this.element = element;
1976
1745
  this.orientation = AxisOrientation;
1977
1746
  this.getTextPosition = () => {
1978
- const [min, max] = this.scale.domain();
1747
+ let [min, max] = this.scale.domain();
1748
+ min = min instanceof Date ? min.getTime() : min;
1749
+ max = max instanceof Date ? max.getTime() : max;
1979
1750
  const position = ((this.plotBand.from <= min ? min : this.plotBand.from) + (this.plotBand.to >= max ? max : this.plotBand.to)) / 2;
1980
1751
  return this.scale(position);
1981
1752
  };
@@ -2207,11 +1978,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImpor
2207
1978
  args: ['tooltip', { static: false, read: ElementRef }]
2208
1979
  }] } });
2209
1980
 
1981
+ class ZoomMessage {
1982
+ constructor(options) {
1983
+ this.eventType = options === null || options === void 0 ? void 0 : options.eventType;
1984
+ this.element = options === null || options === void 0 ? void 0 : options.element;
1985
+ this.axis = options === null || options === void 0 ? void 0 : options.axis;
1986
+ this.domain = options.domain;
1987
+ this.chartId = options === null || options === void 0 ? void 0 : options.chartId;
1988
+ this.style = options === null || options === void 0 ? void 0 : options.style;
1989
+ }
1990
+ }
1991
+ class BrushMessage {
1992
+ constructor(options) {
1993
+ this.chartId = options === null || options === void 0 ? void 0 : options.chartId;
1994
+ this.selection = options === null || options === void 0 ? void 0 : options.selection;
1995
+ }
1996
+ }
1997
+
2210
1998
  class ZoomableDirective {
2211
- constructor(elementRef, zoomService, broadcastService, chartService, zone) {
1999
+ constructor(elementRef, zoomService, chartService, zone) {
2212
2000
  this.elementRef = elementRef;
2213
2001
  this.zoomService = zoomService;
2214
- this.broadcastService = broadcastService;
2215
2002
  this.chartService = chartService;
2216
2003
  this.zone = zone;
2217
2004
  this.zoomable = false;
@@ -2219,31 +2006,25 @@ class ZoomableDirective {
2219
2006
  this.alive = true;
2220
2007
  this.currentTransform = zoomIdentity;
2221
2008
  this.zoomed = (event) => {
2222
- var _a, _b, _c;
2223
2009
  if (event.sourceEvent) {
2224
2010
  if (Object.keys(event.sourceEvent).length !== 0) {
2225
- if (this.currentTransform === event.transform) {
2226
- return;
2227
- }
2228
- const origin = this.brushScale.copy().domain(this.axis.extremes);
2229
- let domain = ((_a = this.config.zoom) === null || _a === void 0 ? void 0 : _a.type) === ZoomType.y
2011
+ const origin = this.axis.scale.copy().domain(this.axis.originDomain);
2012
+ let domain = this.axis.orientation === AxisOrientation.y
2230
2013
  ? event.transform.rescaleY(origin).domain()
2231
2014
  : event.transform.rescaleX(origin).domain();
2232
2015
  const message = new ZoomMessage({
2233
- event,
2234
- axis: this.axis,
2235
- domain,
2236
- chartId: this.config.id,
2237
- });
2238
- this.broadcastService.broadcastZoom({
2239
- channel: (_c = (_b = this.config) === null || _b === void 0 ? void 0 : _b.zoom) === null || _c === void 0 ? void 0 : _c.syncChannel,
2240
- message,
2016
+ eventType: event.type,
2017
+ axis: {
2018
+ index: this.axis.index,
2019
+ orientation: this.axis.orientation,
2020
+ },
2021
+ element: this.elementRef,
2022
+ domain: domain,
2023
+ chartId: this.config.id
2241
2024
  });
2025
+ this.zoomService.fireZoom(message);
2026
+ this.zoomService.broadcastZoom(message);
2242
2027
  }
2243
- this.zoomService.fireZoom({
2244
- event,
2245
- target: this.axis,
2246
- });
2247
2028
  this.currentTransform = event.transform;
2248
2029
  }
2249
2030
  };
@@ -2255,166 +2036,80 @@ class ZoomableDirective {
2255
2036
  this.crosshair = (_k = (_j = this.config) === null || _j === void 0 ? void 0 : _j.tooltip) === null || _k === void 0 ? void 0 : _k.showCrosshair;
2256
2037
  }
2257
2038
  }
2258
- ngOnChanges(changes) {
2259
- if (changes.hasOwnProperty('brushScale') || changes.hasOwnProperty('scale') || changes.hasOwnProperty('axis')) {
2260
- if (this.hash) {
2261
- this.zoomService.scaleHashMap.set(this.hash, this.scale);
2262
- this.zoomService.axisHashMap.set(this.hash, this.axis);
2039
+ ngAfterViewInit() {
2040
+ this.initZoomListeners();
2041
+ this.initZoomSync();
2042
+ }
2043
+ ngOnDestroy() {
2044
+ var _a, _b;
2045
+ (_a = this.zoom) === null || _a === void 0 ? void 0 : _a.on('start zoom end', null);
2046
+ (_b = this._element) === null || _b === void 0 ? void 0 : _b.on('wheel', null);
2047
+ this.alive = false;
2048
+ }
2049
+ initZoomSync() {
2050
+ this.zoomService.zoomed.pipe(takeWhile(() => this.alive)).subscribe((zoomed) => {
2051
+ var _a, _b, _c;
2052
+ if (this._element && this.elementRef !== (zoomed === null || zoomed === void 0 ? void 0 : zoomed.element)
2053
+ && ((_a = zoomed === null || zoomed === void 0 ? void 0 : zoomed.axis) === null || _a === void 0 ? void 0 : _a.index) === this.axis.index
2054
+ && ((_b = zoomed === null || zoomed === void 0 ? void 0 : zoomed.axis) === null || _b === void 0 ? void 0 : _b.orientation) === this.axis.orientation) {
2055
+ const scale = this.axis.scale.copy().domain(this.axis.originDomain);
2056
+ let transform;
2057
+ if (zoomed.domain === null) {
2058
+ transform = zoomIdentity;
2059
+ }
2060
+ else {
2061
+ transform =
2062
+ this.zoomService.getD3Transform(zoomed.domain, this.axis.originDomain, scale, this.axis.orientation, this.axis.options.inverted);
2063
+ }
2064
+ if ((_c = zoomed.style) === null || _c === void 0 ? void 0 : _c.transition) {
2065
+ this._element.transition().call(this.zoom.transform, transform);
2066
+ }
2067
+ else {
2068
+ this._element.call(this.zoom.transform, transform);
2069
+ }
2070
+ this.currentTransform = transform;
2263
2071
  }
2264
- }
2072
+ });
2265
2073
  }
2266
- ngAfterViewInit() {
2267
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
2074
+ initZoomListeners() {
2075
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
2268
2076
  const enable = (((_b = (_a = this.axis) === null || _a === void 0 ? void 0 : _a.options) === null || _b === void 0 ? void 0 : _b.zoom) && ((_c = this.axis) === null || _c === void 0 ? void 0 : _c.options.visible) !== false) ||
2269
2077
  ((_e = (_d = this.config) === null || _d === void 0 ? void 0 : _d.zoom) === null || _e === void 0 ? void 0 : _e.enable);
2270
2078
  if (!enable) {
2271
2079
  return;
2272
2080
  }
2273
- if (enable) {
2274
- this._element = d3.select(this.elementRef.nativeElement);
2275
- this.hash = objectHash.sha1({ index: this.axis.index, orientation: this.axis.orientation });
2276
- this.zoom = d3.zoom().extent([
2081
+ this._element = d3.select(this.elementRef.nativeElement);
2082
+ this.zoom = d3.zoom().extent([
2083
+ [0, 0],
2084
+ [this.size.width, this.size.height],
2085
+ ]);
2086
+ if ((_f = this.config.zoom) === null || _f === void 0 ? void 0 : _f.limitTranslateByData) {
2087
+ this.zoom.translateExtent([
2277
2088
  [0, 0],
2278
2089
  [this.size.width, this.size.height],
2279
2090
  ]);
2280
- if ((_f = this.config.zoom) === null || _f === void 0 ? void 0 : _f.limitTranslateByData) {
2281
- this.zoom.translateExtent([
2282
- [0, 0],
2283
- [this.size.width, this.size.height],
2284
- ]);
2285
- }
2286
- if ((_g = this.config.zoom) === null || _g === void 0 ? void 0 : _g.wheelDelta) {
2287
- this.zoom.wheelDelta((_h = this.config.zoom) === null || _h === void 0 ? void 0 : _h.wheelDelta);
2288
- }
2289
- this.zoomService.axisHashMap.set(this.hash, this.axis);
2290
- this.zoomService.elementHashMap.set(this.hash, this._element);
2291
- this.zoomService.scaleHashMap.set(this.hash, this.scale);
2292
- this.zoomService.zoomHashMap.set(this.hash, this.zoom);
2293
- this.zoomService.setBroadcastChannel((_j = this.config) === null || _j === void 0 ? void 0 : _j.zoom.syncChannel);
2294
- const maxZoom = ((_k = this.config.zoom) === null || _k === void 0 ? void 0 : _k.max)
2295
- ? (this.axis.extremes[1] - this.axis.extremes[0]) /
2296
- ((_l = this.config.zoom) === null || _l === void 0 ? void 0 : _l.max)
2297
- : ((_m = this.config.zoom) === null || _m === void 0 ? void 0 : _m.limitZoomByData)
2298
- ? 1
2299
- : 0;
2300
- const minZoom = ((_o = this.config.zoom) === null || _o === void 0 ? void 0 : _o.min)
2301
- ? (this.axis.extremes[1] - this.axis.extremes[0]) /
2302
- ((_p = this.config.zoom) === null || _p === void 0 ? void 0 : _p.min)
2303
- : Infinity;
2304
- this.zoom.scaleExtent([maxZoom, minZoom]);
2305
- this.zoom.on('zoom end', this.zoomed);
2306
- this._element.call(this.zoom).on('dblclick.zoom', null); // Disable dbclick zoom
2307
- this.zone.runOutsideAngular(() => {
2308
- setTimeout(() => {
2309
- this.chartService.emitZoomInstance(this.zoomService);
2310
- });
2311
- });
2312
- if (((_r = (_q = this.config) === null || _q === void 0 ? void 0 : _q.zoom) === null || _r === void 0 ? void 0 : _r.zoomBehavior) === ZoomBehaviorType.wheel) {
2313
- this.runWheelZoom();
2314
- }
2315
2091
  }
2316
- // Subscribe to zoom events
2317
- this.broadcastService.subscribeToZoom((_s = this.config) === null || _s === void 0 ? void 0 : _s.zoom.syncChannel).pipe(takeWhile((_) => this.alive), tap$1((m) => {
2318
- var _a, _b, _c, _d, _e;
2319
- if (this.axis.index === ((_b = (_a = m.message) === null || _a === void 0 ? void 0 : _a.axis) === null || _b === void 0 ? void 0 : _b.index) && this.axis.orientation === ((_d = (_c = m.message) === null || _c === void 0 ? void 0 : _c.axis) === null || _d === void 0 ? void 0 : _d.orientation)) {
2320
- const currentZoom = d3.zoomTransform(this._element.node());
2321
- if (currentZoom !== m.message.event.transform && this.config.id === ((_e = m.message) === null || _e === void 0 ? void 0 : _e.chartId)) {
2322
- this._element.call(this.zoom.transform, m.message.event.transform);
2323
- }
2324
- }
2325
- }), filter((m) => m.message.event.sourceEvent instanceof MouseEvent ||
2326
- m.message.event.sourceEvent instanceof WheelEvent ||
2327
- (window.TouchEvent &&
2328
- m.message.event.sourceEvent instanceof TouchEvent)), filter((m) => {
2329
- var _a, _b, _c, _d;
2330
- return (this.axis.index === ((_b = (_a = m.message) === null || _a === void 0 ? void 0 : _a.axis) === null || _b === void 0 ? void 0 : _b.index) &&
2331
- this.axis.orientation === ((_d = (_c = m.message) === null || _c === void 0 ? void 0 : _c.axis) === null || _d === void 0 ? void 0 : _d.orientation));
2332
- }), tap$1((m) => {
2333
- var _a, _b, _c, _d, _e, _f, _g;
2334
- if (this.config.id !== ((_a = m.message) === null || _a === void 0 ? void 0 : _a.chartId)) {
2335
- this.brushScale.domain(this.axis.originDomain);
2336
- const scale = Math.abs(this.axis.originDomain[1] - this.axis.originDomain[0]) / Math.abs(m.message.domain[1] - m.message.domain[0]);
2337
- let transform = zoomIdentity.scale(scale);
2338
- if (((_c = (_b = this.config) === null || _b === void 0 ? void 0 : _b.zoom) === null || _c === void 0 ? void 0 : _c.type) === ZoomType.x) {
2339
- if ((_d = this.config.xAxis[0]) === null || _d === void 0 ? void 0 : _d.inverted) {
2340
- transform = transform.translate(this.brushScale(-m.message.domain[1]), 0);
2341
- }
2342
- else {
2343
- transform = transform.translate(-this.brushScale(m.message.domain[0]), 0);
2344
- }
2345
- }
2346
- if (((_f = (_e = this.config) === null || _e === void 0 ? void 0 : _e.zoom) === null || _f === void 0 ? void 0 : _f.type) === ZoomType.y) {
2347
- if ((_g = this.config.yAxis[0]) === null || _g === void 0 ? void 0 : _g.inverted) {
2348
- transform = transform.translate(0, -this.brushScale(m.message.domain[0]));
2349
- }
2350
- else {
2351
- transform = transform.translate(0, -this.brushScale(m.message.domain[1]));
2352
- }
2353
- }
2354
- this._element.call(this.zoom.transform, transform, null, {});
2355
- }
2356
- }))
2357
- .subscribe();
2358
- // Subscribe to brush events x or y
2359
- if ((((_t = this.config.brush) === null || _t === void 0 ? void 0 : _t.type) === BrushType.x &&
2360
- this.axis.orientation === AxisOrientation.x) ||
2361
- (((_u = this.config.brush) === null || _u === void 0 ? void 0 : _u.type) === BrushType.y &&
2362
- this.axis.orientation === AxisOrientation.y)) {
2363
- this.broadcastService.subscribeToBrush((_v = this.config) === null || _v === void 0 ? void 0 : _v.zoom.syncChannel)
2364
- .pipe(combineLatestWith(this.chartService.size), takeWhile((_) => this.alive), filter((data) => {
2365
- const [m] = data;
2366
- return Boolean(m.message.selection);
2367
- }), tap$1((data) => {
2368
- var _a, _b, _c, _d, _e, _f;
2369
- const [m] = data;
2370
- const currentTransform = d3.zoomTransform(this._element.node());
2371
- if (!m.message.event &&
2372
- this.currentSelection &&
2373
- currentTransform.k !== 1) {
2374
- return;
2375
- }
2376
- const s = m.message.selection;
2377
- this.brushScale.domain(this.axis.originDomain);
2378
- const domain = this.brushScale.domain();
2379
- const range = this.brushScale.range();
2380
- const scale = Math.abs(domain[1] - domain[0]) / Math.abs(s[1] - s[0]);
2381
- let transform = zoomIdentity.scale(scale);
2382
- if (((_a = m.message) === null || _a === void 0 ? void 0 : _a.brushType) === BrushType.x) {
2383
- this.brushScale.range([range[0], this.size.width]);
2384
- if ((_b = this.config.xAxis[0]) === null || _b === void 0 ? void 0 : _b.inverted) {
2385
- transform = transform.translate(-this.brushScale(s[0]), 0);
2386
- }
2387
- else {
2388
- transform = transform.translate(-this.brushScale(s[1]), 0);
2389
- }
2390
- }
2391
- if (((_c = m.message) === null || _c === void 0 ? void 0 : _c.brushType) === BrushType.y) {
2392
- this.brushScale.range([range[0], this.size.height]);
2393
- if ((_d = this.config.yAxis[0]) === null || _d === void 0 ? void 0 : _d.inverted) {
2394
- transform = transform.translate(0, -this.brushScale(s[0]));
2395
- }
2396
- else {
2397
- transform = transform.translate(0, -this.brushScale(s[1]));
2398
- }
2399
- }
2400
- if ((_f = (_e = m.message) === null || _e === void 0 ? void 0 : _e.style) === null || _f === void 0 ? void 0 : _f.transition) {
2401
- this._element.transition().call(this.zoom.transform, transform, null, {});
2402
- }
2403
- else {
2404
- this._element.call(this.zoom.transform, transform, null, {});
2405
- }
2406
- this.currentSelection = m.message.selection;
2407
- }))
2408
- .subscribe();
2092
+ if ((_g = this.config.zoom) === null || _g === void 0 ? void 0 : _g.wheelDelta) {
2093
+ this.zoom.wheelDelta((_h = this.config.zoom) === null || _h === void 0 ? void 0 : _h.wheelDelta);
2094
+ }
2095
+ const maxZoom = ((_j = this.config.zoom) === null || _j === void 0 ? void 0 : _j.max)
2096
+ ? (this.axis.extremes[1] - this.axis.extremes[0]) /
2097
+ ((_k = this.config.zoom) === null || _k === void 0 ? void 0 : _k.max)
2098
+ : ((_l = this.config.zoom) === null || _l === void 0 ? void 0 : _l.limitZoomByData)
2099
+ ? 1
2100
+ : 0;
2101
+ const minZoom = ((_m = this.config.zoom) === null || _m === void 0 ? void 0 : _m.min)
2102
+ ? (this.axis.extremes[1] - this.axis.extremes[0]) /
2103
+ ((_o = this.config.zoom) === null || _o === void 0 ? void 0 : _o.min)
2104
+ : Infinity;
2105
+ this.zoom.scaleExtent([maxZoom, minZoom]);
2106
+ this.zoom.on('zoom end', this.zoomed);
2107
+ this._element.call(this.zoom).on('dblclick.zoom', null); // Disable dbclick zoom
2108
+ if (((_q = (_p = this.config) === null || _p === void 0 ? void 0 : _p.zoom) === null || _q === void 0 ? void 0 : _q.zoomBehavior) === ZoomBehaviorType.wheel) {
2109
+ this.runWheelTranslate();
2409
2110
  }
2410
2111
  }
2411
- ngOnDestroy() {
2412
- var _a, _b;
2413
- (_a = this.zoom) === null || _a === void 0 ? void 0 : _a.on('start zoom end', null);
2414
- (_b = this._element) === null || _b === void 0 ? void 0 : _b.on('wheel', null);
2415
- this.alive = false;
2416
- }
2417
- runWheelZoom() {
2112
+ runWheelTranslate() {
2418
2113
  let type = 'start';
2419
2114
  let wheeling;
2420
2115
  this.zoom
@@ -2430,48 +2125,38 @@ class ZoomableDirective {
2430
2125
  return delta * 0.002;
2431
2126
  });
2432
2127
  const emit = (type, event) => {
2433
- var _a, _b, _c, _d, _e, _f;
2434
- const origin = this.brushScale.copy().domain(this.axis.extremes);
2128
+ var _a;
2129
+ const origin = this.axis.scale.copy().domain(this.axis.originDomain);
2435
2130
  let transform = zoomIdentity;
2436
2131
  const delta = type === 'end'
2437
2132
  ? 0
2438
- : ((_a = this.config.zoom) === null || _a === void 0 ? void 0 : _a.type) === ZoomType.y
2133
+ : this.axis.orientation === AxisOrientation.y
2439
2134
  ? event.deltaY
2440
2135
  : event.deltaX;
2441
- if (((_b = this.config.zoom) === null || _b === void 0 ? void 0 : _b.type) === ZoomType.y) {
2136
+ if (this.axis.orientation === AxisOrientation.y) {
2442
2137
  transform = transform.translate(0, this.currentTransform.y - delta / 2);
2443
2138
  }
2444
- if (((_c = this.config.zoom) === null || _c === void 0 ? void 0 : _c.type) === ZoomType.x) {
2139
+ if (this.axis.orientation === AxisOrientation.x) {
2445
2140
  transform = transform.translate(this.currentTransform.x - delta / 2, 0);
2446
2141
  }
2447
2142
  transform = transform.scale(this.currentTransform.k);
2448
- let domain = ((_d = this.config.zoom) === null || _d === void 0 ? void 0 : _d.type) === ZoomType.y
2143
+ let domain = this.axis.orientation === AxisOrientation.y
2449
2144
  ? transform.rescaleY(origin).domain()
2450
2145
  : transform.rescaleX(origin).domain();
2451
2146
  const message = new ZoomMessage({
2452
- event: {
2453
- sourceEvent: event,
2454
- transform,
2455
- type,
2147
+ eventType: type,
2148
+ element: this.elementRef,
2149
+ axis: {
2150
+ index: this.axis.index,
2151
+ orientation: this.axis.orientation
2456
2152
  },
2457
- axis: this.axis,
2458
2153
  domain,
2459
2154
  chartId: this.config.id,
2460
2155
  });
2461
- this.zoomService.fireZoom({
2462
- event: {
2463
- sourceEvent: event,
2464
- transform,
2465
- type,
2466
- },
2467
- target: this.axis,
2468
- });
2469
- this._element.call(this.zoom.transform, transform);
2156
+ (_a = this._element) === null || _a === void 0 ? void 0 : _a.call(this.zoom.transform, transform);
2157
+ this.zoomService.fireZoom(message);
2158
+ this.zoomService.broadcastZoom(message);
2470
2159
  this.currentTransform = transform;
2471
- this.broadcastService.broadcastZoom({
2472
- channel: (_f = (_e = this.config) === null || _e === void 0 ? void 0 : _e.zoom) === null || _f === void 0 ? void 0 : _f.syncChannel,
2473
- message,
2474
- });
2475
2160
  };
2476
2161
  this._element.on('wheel', (event) => {
2477
2162
  event.preventDefault();
@@ -2490,23 +2175,19 @@ class ZoomableDirective {
2490
2175
  });
2491
2176
  }
2492
2177
  }
2493
- ZoomableDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: ZoomableDirective, deps: [{ token: i0.ElementRef }, { token: ZoomService }, { token: BroadcastService }, { token: ChartService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive });
2494
- ZoomableDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.0.2", type: ZoomableDirective, selector: "[tetaZoomable]", inputs: { config: "config", axis: "axis", size: "size", brushScale: "brushScale", scale: "scale" }, host: { properties: { "class.zoomable": "this.zoomable", "class.crosshair": "this.crosshair" } }, usesOnChanges: true, ngImport: i0 });
2178
+ ZoomableDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: ZoomableDirective, deps: [{ token: i0.ElementRef }, { token: ZoomService }, { token: ChartService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive });
2179
+ ZoomableDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.0.2", type: ZoomableDirective, selector: "[tetaZoomable]", inputs: { config: "config", axis: "axis", size: "size" }, host: { properties: { "class.zoomable": "this.zoomable", "class.crosshair": "this.crosshair" } }, ngImport: i0 });
2495
2180
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: ZoomableDirective, decorators: [{
2496
2181
  type: Directive,
2497
2182
  args: [{
2498
2183
  selector: '[tetaZoomable]',
2499
2184
  }]
2500
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: ZoomService }, { type: BroadcastService }, { type: ChartService }, { type: i0.NgZone }]; }, propDecorators: { config: [{
2185
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: ZoomService }, { type: ChartService }, { type: i0.NgZone }]; }, propDecorators: { config: [{
2501
2186
  type: Input
2502
2187
  }], axis: [{
2503
2188
  type: Input
2504
2189
  }], size: [{
2505
2190
  type: Input
2506
- }], brushScale: [{
2507
- type: Input
2508
- }], scale: [{
2509
- type: Input
2510
2191
  }], zoomable: [{
2511
2192
  type: HostBinding,
2512
2193
  args: ['class.zoomable']
@@ -2516,33 +2197,141 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImpor
2516
2197
  }] } });
2517
2198
 
2518
2199
  class BrushableDirective {
2519
- constructor(brushService, chartService, element) {
2200
+ constructor(brushService, chartService, element, zone) {
2520
2201
  this.brushService = brushService;
2521
2202
  this.chartService = chartService;
2522
2203
  this.element = element;
2204
+ this.zone = zone;
2205
+ this.brushMap = new Map()
2206
+ .set(BrushType.x, d3.brushX())
2207
+ .set(BrushType.y, d3.brushY());
2208
+ this._alive = true;
2209
+ this._container = d3.select(this.element.nativeElement);
2210
+ }
2211
+ ngOnInit() {
2212
+ this.brushService.brushDomain.pipe(takeWhile(() => this._alive), filter((brush) => brush.chartId !== this.config.id)).subscribe((brush) => {
2213
+ this._container.call(this.brush.move, [
2214
+ Math.floor(brush.selection[0]),
2215
+ Math.floor(brush.selection[1]),
2216
+ ].map(this.axis.scale));
2217
+ });
2218
+ }
2219
+ ngOnDestroy() {
2220
+ this._alive = false;
2221
+ }
2222
+ ngAfterViewInit() {
2523
2223
  }
2524
- ngOnInit() { }
2525
- ngAfterViewInit() { }
2526
2224
  ngOnChanges(changes) {
2527
2225
  var _a, _b;
2528
2226
  if (changes.hasOwnProperty('config')) {
2529
- this.brushService.clearPreviousSelection();
2227
+ this.clearPreviousSelection();
2530
2228
  }
2531
2229
  if ((_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.brush) === null || _b === void 0 ? void 0 : _b.enable) {
2532
- this.brushService.applyBrush(this.element, this.config, this.brushScale);
2230
+ this.applyBrush(this.config, this.axis.scale);
2231
+ }
2232
+ }
2233
+ applyBrush(config, brushScale) {
2234
+ var _a, _b, _c, _d;
2235
+ (_a = this.brush) === null || _a === void 0 ? void 0 : _a.on('start brush end', null);
2236
+ if ((_b = config.brush) === null || _b === void 0 ? void 0 : _b.enable) {
2237
+ this.brush = this.brushMap.get((_d = (_c = config === null || config === void 0 ? void 0 : config.brush) === null || _c === void 0 ? void 0 : _c.type) !== null && _d !== void 0 ? _d : BrushType.x);
2238
+ this.brush.on('start brush end', (_) => {
2239
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
2240
+ if (_.sourceEvent) {
2241
+ if (!_.selection)
2242
+ return;
2243
+ const [from, to] = _.selection;
2244
+ if (to - from === 0) {
2245
+ const selection = (_b = (_a = this.selection) === null || _a === void 0 ? void 0 : _a.map(brushScale)) !== null && _b !== void 0 ? _b : [(_c = config.brush) === null || _c === void 0 ? void 0 : _c.from, (_d = config.brush) === null || _d === void 0 ? void 0 : _d.to].map(brushScale);
2246
+ const halfBrushHeight = (selection[1] - selection[0]) / 2;
2247
+ const invertedSelection = [
2248
+ from - halfBrushHeight,
2249
+ to + halfBrushHeight,
2250
+ ].map(brushScale.invert);
2251
+ if (invertedSelection[1] - invertedSelection[0] >
2252
+ ((_e = config.brush) === null || _e === void 0 ? void 0 : _e.max)) {
2253
+ this._container.call(this.brush.move, [
2254
+ Math.floor(invertedSelection[0]),
2255
+ Math.floor(invertedSelection[0] + ((_f = config.brush) === null || _f === void 0 ? void 0 : _f.max)),
2256
+ ].map(brushScale));
2257
+ return;
2258
+ }
2259
+ if (invertedSelection[1] - invertedSelection[0] <
2260
+ ((_g = config.brush) === null || _g === void 0 ? void 0 : _g.min)) {
2261
+ this._container.call(this.brush.move, [
2262
+ Math.floor(invertedSelection[0]),
2263
+ Math.ceil(invertedSelection[0] + ((_h = config.brush) === null || _h === void 0 ? void 0 : _h.min)),
2264
+ ].map(brushScale));
2265
+ return;
2266
+ }
2267
+ this._container.call(this.brush.move, [
2268
+ from - halfBrushHeight,
2269
+ to + halfBrushHeight,
2270
+ ]);
2271
+ return;
2272
+ }
2273
+ if (brushScale.invert(to) - brushScale.invert(from) >
2274
+ ((_j = config.brush) === null || _j === void 0 ? void 0 : _j.max)) {
2275
+ this._container.call(this.brush.move, this.selection
2276
+ ? [
2277
+ this.selection[0],
2278
+ this.selection[0] + ((_k = config.brush) === null || _k === void 0 ? void 0 : _k.max),
2279
+ ].map(brushScale)
2280
+ : [(_l = config.brush) === null || _l === void 0 ? void 0 : _l.from, (_m = config.brush) === null || _m === void 0 ? void 0 : _m.to].map(brushScale));
2281
+ return;
2282
+ }
2283
+ if (brushScale.invert(to) - brushScale.invert(from) <
2284
+ ((_o = config.brush) === null || _o === void 0 ? void 0 : _o.min)) {
2285
+ this._container.call(this.brush.move, this.selection
2286
+ ? [
2287
+ this.selection[0],
2288
+ this.selection[0] + ((_p = config.brush) === null || _p === void 0 ? void 0 : _p.min),
2289
+ ].map(brushScale)
2290
+ : [(_q = config.brush) === null || _q === void 0 ? void 0 : _q.from, (_r = config.brush) === null || _r === void 0 ? void 0 : _r.to].map(brushScale));
2291
+ return;
2292
+ }
2293
+ if (_.sourceEvent instanceof MouseEvent) {
2294
+ this.selection = _.selection.map(brushScale.invert);
2295
+ }
2296
+ const brushMessage = new BrushMessage({
2297
+ chartId: this.config.id,
2298
+ selection: [brushScale.invert(from), brushScale.invert(to)],
2299
+ });
2300
+ this.brushService.setBrush(brushMessage);
2301
+ }
2302
+ });
2303
+ this.zone.runOutsideAngular(() => {
2304
+ setTimeout(() => {
2305
+ var _a, _b;
2306
+ this._container.call(this.brush);
2307
+ let domain = brushScale.domain();
2308
+ if ((_a = config === null || config === void 0 ? void 0 : config.brush) === null || _a === void 0 ? void 0 : _a.from) {
2309
+ domain[0] = config.brush.from;
2310
+ }
2311
+ if ((_b = config === null || config === void 0 ? void 0 : config.brush) === null || _b === void 0 ? void 0 : _b.to) {
2312
+ domain[1] = config.brush.to;
2313
+ }
2314
+ this._container.call(this.brush.move, this.selection
2315
+ ? this.selection.map(brushScale)
2316
+ : domain.map(brushScale), {});
2317
+ }, 0);
2318
+ });
2533
2319
  }
2534
2320
  }
2321
+ clearPreviousSelection() {
2322
+ this.selection = null;
2323
+ }
2535
2324
  }
2536
- BrushableDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: BrushableDirective, deps: [{ token: BrushService }, { token: ChartService }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
2537
- BrushableDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.0.2", type: BrushableDirective, selector: "[tetaBrushable]", inputs: { config: "config", brushScale: "brushScale" }, usesOnChanges: true, ngImport: i0 });
2325
+ BrushableDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: BrushableDirective, deps: [{ token: BrushService }, { token: ChartService }, { token: i0.ElementRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive });
2326
+ BrushableDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.0.2", type: BrushableDirective, selector: "[tetaBrushable]", inputs: { config: "config", axis: "axis" }, usesOnChanges: true, ngImport: i0 });
2538
2327
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: BrushableDirective, decorators: [{
2539
2328
  type: Directive,
2540
2329
  args: [{
2541
2330
  selector: '[tetaBrushable]',
2542
2331
  }]
2543
- }], ctorParameters: function () { return [{ type: BrushService }, { type: ChartService }, { type: i0.ElementRef }]; }, propDecorators: { config: [{
2332
+ }], ctorParameters: function () { return [{ type: BrushService }, { type: ChartService }, { type: i0.ElementRef }, { type: i0.NgZone }]; }, propDecorators: { config: [{
2544
2333
  type: Input
2545
- }], brushScale: [{
2334
+ }], axis: [{
2546
2335
  type: Input
2547
2336
  }] } });
2548
2337
 
@@ -2628,7 +2417,6 @@ class CrosshairComponent {
2628
2417
  this.transform = this.chartService.pointerMove.pipe(map((event) => {
2629
2418
  const composedPath = event.composedPath();
2630
2419
  const classes = composedPath.map((_) => { var _a; return (_a = _.classList) === null || _a === void 0 ? void 0 : _a.contains('crosshair'); }).filter((_) => _);
2631
- console.log(classes);
2632
2420
  return {
2633
2421
  x: event.type === 'mouseleave' ? -9999 : event.offsetX,
2634
2422
  y: event.type === 'mouseleave' ? -9999 : event.offsetY
@@ -2808,10 +2596,10 @@ class ChartContainerComponent {
2808
2596
  }
2809
2597
  }
2810
2598
  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 });
2811
- 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.size?.height > 0 && data.size?.width > 0 && data.scales?.x.size === data.config.xAxis.length && data.scales?.y.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.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.size > 0 && data.scales.y.size > 0\">\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.size?.height > 0 && data.size?.width > 0 && data.scales?.x.size === data.config.xAxis.length && data.scales?.y.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.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.visibleRect\"\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.visibleRect\"\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.y.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 });
2599
+ 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} 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.size?.height > 0 && data.size?.width > 0 && data.scales?.x.size === data.config.xAxis.length && data.scales?.y.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.scales.y | keyvalue; trackBy: identify\">\n <ng-container *ngIf=\"item.value.options.visible && data.scales.x.size > 0 && data.scales.y.size > 0\">\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 [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.size > 0 && data.scales.y.size > 0\">\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 [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.size?.height > 0 && data.size?.width > 0 && data.scales?.x.size === data.config.xAxis.length && data.scales?.y.size === data.config.yAxis.length\">\n <svg\n tetaZoomable\n tetaBrushable\n class=\"position-absolute\"\n [size]=\"data.visibleRect\"\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.visibleRect\"\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.visibleRect\"\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.y.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"] }, { kind: "directive", type: BrushableDirective, selector: "[tetaBrushable]", inputs: ["config", "axis"] }, { 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 });
2812
2600
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: ChartContainerComponent, decorators: [{
2813
2601
  type: Component,
2814
- 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.size?.height > 0 && data.size?.width > 0 && data.scales?.x.size === data.config.xAxis.length && data.scales?.y.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.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.size > 0 && data.scales.y.size > 0\">\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.size?.height > 0 && data.size?.width > 0 && data.scales?.x.size === data.config.xAxis.length && data.scales?.y.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.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.visibleRect\"\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.visibleRect\"\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.y.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"] }]
2602
+ 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} 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.size?.height > 0 && data.size?.width > 0 && data.scales?.x.size === data.config.xAxis.length && data.scales?.y.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.scales.y | keyvalue; trackBy: identify\">\n <ng-container *ngIf=\"item.value.options.visible && data.scales.x.size > 0 && data.scales.y.size > 0\">\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 [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.size > 0 && data.scales.y.size > 0\">\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 [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.size?.height > 0 && data.size?.width > 0 && data.scales?.x.size === data.config.xAxis.length && data.scales?.y.size === data.config.yAxis.length\">\n <svg\n tetaZoomable\n tetaBrushable\n class=\"position-absolute\"\n [size]=\"data.visibleRect\"\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.visibleRect\"\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.visibleRect\"\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.y.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"] }]
2815
2603
  }], ctorParameters: function () { return [{ type: ChartService }, { type: i0.ChangeDetectorRef }, { type: ScaleService }, { type: ZoomService }, { type: i0.ElementRef }, { type: i0.NgZone }]; } });
2816
2604
 
2817
2605
  class LegendComponent {
@@ -2847,9 +2635,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImpor
2847
2635
  }] } });
2848
2636
 
2849
2637
  class ChartComponent {
2850
- constructor(chartService, zoomService, scaleService) {
2638
+ constructor(chartService, zoomService, brushService, scaleService) {
2851
2639
  this.chartService = chartService;
2852
2640
  this.zoomService = zoomService;
2641
+ this.brushService = brushService;
2853
2642
  this.scaleService = scaleService;
2854
2643
  this.pointerMove = new EventEmitter();
2855
2644
  this.plotBandsMove = new EventEmitter();
@@ -2863,16 +2652,21 @@ class ChartComponent {
2863
2652
  this.annotationClick = new EventEmitter();
2864
2653
  this.annotationMove = new EventEmitter();
2865
2654
  this.zoomServiceInstance = new EventEmitter();
2655
+ this.brushServiceInstance = new EventEmitter();
2866
2656
  this._alive = true;
2867
2657
  this.svcConfig = this.chartService.config;
2868
2658
  this.hasSeriesData = this.svcConfig.pipe(map((_) => { var _a, _b; return ((_a = _.series) === null || _a === void 0 ? void 0 : _a.length) > 0 && ((_b = _.series) === null || _b === void 0 ? void 0 : _b.some((_) => { var _a; return ((_a = _.data) === null || _a === void 0 ? void 0 : _a.length) > 0; })); }));
2869
2659
  }
2870
2660
  set config(config) {
2661
+ var _a;
2871
2662
  this.chartService.setConfig(config);
2663
+ this.zoomService.setBroadcastChannel((_a = config === null || config === void 0 ? void 0 : config.zoom) === null || _a === void 0 ? void 0 : _a.syncChannel);
2872
2664
  }
2873
2665
  ngOnChanges(changes) {
2874
2666
  }
2875
2667
  ngOnInit() {
2668
+ this.zoomServiceInstance.emit(this.zoomService);
2669
+ this.brushServiceInstance.emit(this.brushService);
2876
2670
  this.chartService.pointerMove
2877
2671
  .pipe(takeWhile(() => this._alive), withLatestFrom(this.scaleService.scales, this.chartService.config))
2878
2672
  .subscribe((data) => {
@@ -2944,28 +2738,19 @@ class ChartComponent {
2944
2738
  .subscribe((_) => {
2945
2739
  this.annotationMove.emit(_);
2946
2740
  });
2947
- this.chartService.zoomInstance
2948
- .pipe(takeWhile(() => this._alive))
2949
- .subscribe((_) => {
2950
- this.zoomServiceInstance.emit(_);
2951
- });
2952
2741
  }
2953
2742
  ngAfterViewInit() {
2954
2743
  }
2955
2744
  ngOnDestroy() {
2956
- var _a;
2957
2745
  this._alive = false;
2958
- (_a = this.zoomService.broadcastSubscription) === null || _a === void 0 ? void 0 : _a.forEach((sub) => {
2959
- sub.unsubscribe();
2960
- });
2961
2746
  }
2962
2747
  }
2963
- 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 });
2964
- 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 justify-content-center\">\n <span class=\"font-body-3 color-text-40 overflow-hidden text-overflow-ellipsis nowrap text-align-center\">\n <div #ref><ng-content></ng-content></div>\n <span *ngIf=\"!ref.hasChildNodes()\">\n No data\n </span>\n </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 });
2748
+ ChartComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: ChartComponent, deps: [{ token: ChartService }, { token: ZoomService }, { token: BrushService }, { token: ScaleService }], target: i0.ɵɵFactoryTarget.Component });
2749
+ 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", brushServiceInstance: "brushServiceInstance" }, 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 justify-content-center\">\n <span class=\"font-body-3 color-text-40 overflow-hidden text-overflow-ellipsis nowrap text-align-center\">\n <div #ref><ng-content></ng-content></div>\n <span *ngIf=\"!ref.hasChildNodes()\">\n No data\n </span>\n </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 });
2965
2750
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: ChartComponent, decorators: [{
2966
2751
  type: Component,
2967
2752
  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 justify-content-center\">\n <span class=\"font-body-3 color-text-40 overflow-hidden text-overflow-ellipsis nowrap text-align-center\">\n <div #ref><ng-content></ng-content></div>\n <span *ngIf=\"!ref.hasChildNodes()\">\n No data\n </span>\n </span>\n </div>\n</ng-template>\n", styles: [":host{position:relative;display:flex;flex-direction:column;height:100%;width:100%}\n"] }]
2968
- }], ctorParameters: function () { return [{ type: ChartService }, { type: ZoomService }, { type: ScaleService }]; }, propDecorators: { pointerMove: [{
2753
+ }], ctorParameters: function () { return [{ type: ChartService }, { type: ZoomService }, { type: BrushService }, { type: ScaleService }]; }, propDecorators: { pointerMove: [{
2969
2754
  type: Output
2970
2755
  }], plotBandsMove: [{
2971
2756
  type: Output
@@ -2989,6 +2774,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImpor
2989
2774
  type: Output
2990
2775
  }], zoomServiceInstance: [{
2991
2776
  type: Output
2777
+ }], brushServiceInstance: [{
2778
+ type: Output
2992
2779
  }], config: [{
2993
2780
  type: Input
2994
2781
  }] } });