@tetacom/svg-charts 1.2.30 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/chart/chart/chart.component.d.ts +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 -1
  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/i-broadcast-message.d.ts +18 -19
  8. package/chart/model/marker-options.d.ts +1 -1
  9. package/chart/service/broadcast.service.d.ts +1 -4
  10. package/chart/service/brush.service.d.ts +6 -13
  11. package/chart/service/chart.service.d.ts +0 -4
  12. package/chart/service/scale.service.d.ts +1 -1
  13. package/chart/service/zoom.service.d.ts +15 -15
  14. package/esm2020/chart/chart/chart.component.mjs +17 -17
  15. package/esm2020/chart/chart-container/chart-container.component.mjs +3 -3
  16. package/esm2020/chart/chart-container/crosshair/crosshair.component.mjs +1 -2
  17. package/esm2020/chart/chart-container/series/linear-series-base.mjs +1 -68
  18. package/esm2020/chart/core/axis/axis.mjs +2 -2
  19. package/esm2020/chart/directives/brushable.directive.mjs +120 -10
  20. package/esm2020/chart/directives/zoomable.directive.mjs +90 -197
  21. package/esm2020/chart/model/i-broadcast-message.mjs +4 -6
  22. package/esm2020/chart/model/marker-options.mjs +1 -1
  23. package/esm2020/chart/service/broadcast.service.mjs +4 -17
  24. package/esm2020/chart/service/brush.service.mjs +11 -147
  25. package/esm2020/chart/service/chart.service.mjs +17 -9
  26. package/esm2020/chart/service/scale.service.mjs +19 -21
  27. package/esm2020/chart/service/zoom.service.mjs +48 -53
  28. package/fesm2015/tetacom-svg-charts.mjs +363 -578
  29. package/fesm2015/tetacom-svg-charts.mjs.map +1 -1
  30. package/fesm2020/tetacom-svg-charts.mjs +346 -558
  31. package/fesm2020/tetacom-svg-charts.mjs.map +1 -1
  32. 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';
@@ -139,8 +137,10 @@ const defaultSeriesConfig = () => ({
139
137
 
140
138
  class ChartService {
141
139
  constructor() {
140
+ // public zoomInstance: Observable<ZoomService>;
141
+ // public brushInstance: Observable<BrushService>;
142
142
  this.config$ = new BehaviorSubject(defaultChartConfig());
143
- this.size$ = new BehaviorSubject(new DOMRectReadOnly());
143
+ this.size$ = new BehaviorSubject(null);
144
144
  this.pointerMove$ = new Subject();
145
145
  this.tooltips$ = new BehaviorSubject(new Map());
146
146
  this.plotBandEvent$ = new Subject();
@@ -150,13 +150,12 @@ class ChartService {
150
150
  this.chartContextMenu$ = new Subject();
151
151
  this.annotationEvent$ = new Subject();
152
152
  this.annotationMove$ = new Subject();
153
- this.zoomInstance$ = new Subject();
154
153
  this.id = of((Date.now() + Math.random()).toString(36));
155
154
  this.config = this.config$.asObservable().pipe(withLatestFrom(this.id), map(this.setDefaults), map(this.setPreparationData), map(this.restoreLocalStorage), shareReplay({
156
155
  bufferSize: 1,
157
156
  refCount: true,
158
157
  }));
159
- this.size = this.size$.asObservable();
158
+ this.size = this.size$.asObservable().pipe(filter((size) => size != null));
160
159
  this.pointerMove = this.pointerMove$.asObservable();
161
160
  this.tooltips = this.tooltips$.asObservable();
162
161
  this.plotBandEvent = this.plotBandEvent$.asObservable();
@@ -177,7 +176,8 @@ class ChartService {
177
176
  this.plotBandContextMenu = this.plotBandEvent$
178
177
  .asObservable()
179
178
  .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();
179
+ // this.zoomInstance = this.zoomInstance$.asObservable();
180
+ // this.brushInstance = this.brushInstance$.asObservable();
181
181
  }
182
182
  setConfig(config) {
183
183
  this.clearTooltips();
@@ -246,9 +246,13 @@ class ChartService {
246
246
  emitChartContextMenu(event) {
247
247
  this.chartContextMenu$.next(event);
248
248
  }
249
- emitZoomInstance(event) {
250
- this.zoomInstance$.next(event);
251
- }
249
+ // public emitZoomInstance(event: ZoomService) {
250
+ // this.zoomInstance$.next(event);
251
+ // }
252
+ //
253
+ // public emitZoomInstance(event: ZoomService) {
254
+ // this.zoomInstance$.next(event);
255
+ // }
252
256
  saveCookie(config) {
253
257
  var _a;
254
258
  if (!config.name)
@@ -276,7 +280,7 @@ class ChartService {
276
280
  return config;
277
281
  }
278
282
  setDefaults(data) {
279
- var _a, _b, _c, _d, _e, _f;
283
+ var _a, _b, _c, _d, _e, _f, _g;
280
284
  let [config, id] = data;
281
285
  const defaultConfig = (defaultConfig) => {
282
286
  return (source) => {
@@ -284,7 +288,7 @@ class ChartService {
284
288
  };
285
289
  };
286
290
  config = Object.assign({}, defaultChartConfig(), config);
287
- config.id = id;
291
+ config.id = (_a = config.id) !== null && _a !== void 0 ? _a : id;
288
292
  config.xAxis = config.xAxis.map(defaultConfig(defaultAxisConfig));
289
293
  config.yAxis = config.yAxis.map(defaultConfig(defaultAxisConfig));
290
294
  config.series = config.series.map(defaultConfig(defaultSeriesConfig()));
@@ -292,10 +296,10 @@ class ChartService {
292
296
  var _a, _b;
293
297
  return Object.assign(Object.assign({}, _), { data: (_a = _.data) !== null && _a !== void 0 ? _a : [], id: (_b = _.id) !== null && _b !== void 0 ? _b : index });
294
298
  });
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);
299
+ const oppositeYCount = (_b = config.yAxis) === null || _b === void 0 ? void 0 : _b.filter((_) => _.opposite);
300
+ const oppositeXCount = (_c = config.xAxis) === null || _c === void 0 ? void 0 : _c.filter((_) => _.opposite);
301
+ const nonOppositeYCount = (_d = config.yAxis) === null || _d === void 0 ? void 0 : _d.filter((_) => !_.opposite);
302
+ const nonOppositeXCount = (_e = config.xAxis) === null || _e === void 0 ? void 0 : _e.filter((_) => !_.opposite);
299
303
  if ((nonOppositeXCount === null || nonOppositeXCount === void 0 ? void 0 : nonOppositeXCount.length) > 1) {
300
304
  config.bounds.bottom = 0;
301
305
  }
@@ -310,7 +314,7 @@ class ChartService {
310
314
  }
311
315
  config.tooltip = Object.assign({}, defaultChartConfig().tooltip, config.tooltip);
312
316
  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;
317
+ config.zoom.syncChannel = (_g = (_f = config.zoom) === null || _f === void 0 ? void 0 : _f.syncChannel) !== null && _g !== void 0 ? _g : id;
314
318
  return config;
315
319
  }
316
320
  setPreparationData(config) {
@@ -338,6 +342,8 @@ class ChartService {
338
342
  return config;
339
343
  }
340
344
  }
345
+ // private zoomInstance$ = new Subject<ZoomService>();
346
+ // private brushInstance$ = new Subject<BrushService>();
341
347
  ChartService._hiddenSeriesPostfix = 'hidden_series';
342
348
  ChartService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: ChartService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
343
349
  ChartService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: ChartService, providedIn: 'root' });
@@ -354,14 +360,31 @@ var AxisOrientation;
354
360
  AxisOrientation[AxisOrientation["y"] = 1] = "y";
355
361
  })(AxisOrientation || (AxisOrientation = {}));
356
362
 
357
- class ZoomService {
363
+ class BroadcastService {
358
364
  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({});
365
+ this.zoomEmitter = new ReplaySubject(1);
366
+ }
367
+ broadcastZoom(value) {
368
+ this.zoomEmitter.next(value);
369
+ }
370
+ subscribeToZoom(channel) {
371
+ return this.zoomEmitter.asObservable().pipe(filter((msg) => channel && msg.channel === channel));
372
+ }
373
+ }
374
+ BroadcastService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: BroadcastService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
375
+ BroadcastService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: BroadcastService, providedIn: 'root' });
376
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: BroadcastService, decorators: [{
377
+ type: Injectable,
378
+ args: [{
379
+ providedIn: 'root',
380
+ }]
381
+ }], ctorParameters: function () { return []; } });
382
+
383
+ class ZoomService {
384
+ constructor(_broadcast, _chart) {
385
+ this._broadcast = _broadcast;
386
+ this._chart = _chart;
387
+ this.zoomed$ = new BehaviorSubject(null);
365
388
  this.zoomed = this.zoomed$.asObservable().pipe(shareReplay({
366
389
  bufferSize: 1,
367
390
  refCount: true
@@ -370,64 +393,66 @@ class ZoomService {
370
393
  fireZoom(zoom) {
371
394
  this.zoomed$.next(zoom);
372
395
  }
396
+ broadcastZoom(zoom) {
397
+ var _a;
398
+ if ((_a = this.broadcastChannel) === null || _a === void 0 ? void 0 : _a.length) {
399
+ this._broadcast.broadcastZoom({
400
+ channel: this.broadcastChannel,
401
+ message: zoom
402
+ });
403
+ }
404
+ }
373
405
  setBroadcastChannel(channel) {
406
+ var _a, _b;
407
+ if (this.broadcastSub) {
408
+ (_a = this.broadcastSub) === null || _a === void 0 ? void 0 : _a.unsubscribe();
409
+ }
374
410
  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;
411
+ if ((_b = this.broadcastChannel) === null || _b === void 0 ? void 0 : _b.length) {
412
+ this.broadcastSub = combineLatest([this._broadcast.subscribeToZoom(this.broadcastChannel), this._chart.config])
413
+ .pipe(filter(([zoom, config]) => {
414
+ var _a;
415
+ return ((_a = zoom.message) === null || _a === void 0 ? void 0 : _a.chartId) !== config.id;
416
+ }))
417
+ .subscribe(([zoom, config]) => {
418
+ this.fireZoom(zoom.message);
419
+ });
380
420
  }
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);
421
+ }
422
+ getD3Transform(targetDomain, originalDomain, scale, orientation, inverted) {
423
+ const zoomScale = Math.abs(originalDomain[1] - originalDomain[0]) / Math.abs(targetDomain[1] - targetDomain[0]);
424
+ let transform = zoomIdentity.scale(zoomScale);
425
+ if (orientation === AxisOrientation.x) {
426
+ if (!!inverted) {
427
+ transform = transform.translate(-scale(Math.max(...targetDomain)), 0);
389
428
  }
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());
429
+ else {
430
+ transform = transform.translate(-scale(Math.min(...targetDomain)), 0);
394
431
  }
395
432
  }
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());
433
+ if (orientation === AxisOrientation.y) {
434
+ if (!!inverted) {
435
+ transform = transform.translate(0, -scale(Math.min(...targetDomain)));
402
436
  }
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());
437
+ else {
438
+ transform = transform.translate(0, -scale(Math.max(...targetDomain)));
408
439
  }
409
- transform = transform.translate(0, -currentScale(from));
410
440
  }
411
- currentElement.transition().call(currentZoom.transform, transform, null, new MouseEvent('setZoom'));
441
+ return transform;
412
442
  }
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'));
443
+ ngOnDestroy() {
444
+ var _a;
445
+ (_a = this.broadcastSub) === null || _a === void 0 ? void 0 : _a.unsubscribe();
421
446
  }
422
447
  }
423
- ZoomService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: ZoomService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
448
+ 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
449
  ZoomService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: ZoomService, providedIn: 'root' });
425
450
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: ZoomService, decorators: [{
426
451
  type: Injectable,
427
452
  args: [{
428
453
  providedIn: 'root',
429
454
  }]
430
- }], ctorParameters: function () { return []; } });
455
+ }], ctorParameters: function () { return [{ type: BroadcastService }, { type: ChartService }]; } });
431
456
 
432
457
  const getTextWidth = (inputText, backupRatio = 0.5, fontSize = 10) => {
433
458
  let text = inputText !== null && inputText !== void 0 ? inputText : '';
@@ -500,7 +525,7 @@ class ExtremesBuilder {
500
525
  class Axis {
501
526
  constructor(config) {
502
527
  this._extremes = [0, 0];
503
- this._originDomain = [];
528
+ this._originDomain = [0, 0];
504
529
  this.defaultFormatters = new Map()
505
530
  .set(ScaleType.linear, d3.format(',.5~r'))
506
531
  .set(ScaleType.time, d3.timeFormat('%d.%m.%Y'))
@@ -671,22 +696,21 @@ class ScaleService {
671
696
  axis.setScale(scale);
672
697
  axis.setOriginDomain(scale.domain());
673
698
  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;
699
+ const shouldRestore = ((_a = zoom === null || zoom === void 0 ? void 0 : zoom.axis) === null || _a === void 0 ? void 0 : _a.orientation) !== AxisOrientation.x ||
700
+ ((_b = zoom.axis) === null || _b === void 0 ? void 0 : _b.index) !== axis.index;
676
701
  if (hasCache && shouldRestore) {
677
702
  const restoredTransform = this.transformCacheX.get(axis.index);
678
703
  axis.setScale(restoredTransform.rescaleX(scale));
679
704
  }
680
705
  });
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);
706
+ if (zoom && zoom.domain) {
707
+ if (((_a = zoom.axis) === null || _a === void 0 ? void 0 : _a.orientation) === AxisOrientation.x) {
708
+ if (xAxisMap.has(zoom.axis.index)) {
709
+ const x = xAxisMap.get(zoom.axis.index);
710
+ const transform = this.zoomService.getD3Transform(zoom.domain, x.originDomain, x.scale, AxisOrientation.x, x.options.inverted);
711
+ const rescaled = transform.rescaleX(x.scale.copy());
687
712
  x.setScale(rescaled);
688
- const axis = xAxisMap.get(zoom.target.index);
689
- this.transformCacheX.set(axis.index, event.transform);
713
+ this.transformCacheX.set(x.index, transform);
690
714
  }
691
715
  }
692
716
  }
@@ -724,22 +748,21 @@ class ScaleService {
724
748
  axis.setScale(scale);
725
749
  axis.setOriginDomain(scale.domain());
726
750
  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;
751
+ const shouldRestore = ((_a = zoom === null || zoom === void 0 ? void 0 : zoom.axis) === null || _a === void 0 ? void 0 : _a.orientation) !== AxisOrientation.y ||
752
+ ((_b = zoom.axis) === null || _b === void 0 ? void 0 : _b.index) !== axis.index;
729
753
  if (hasCache && shouldRestore) {
730
754
  const restoredTransform = this.transformCacheY.get(axis.index);
731
755
  axis.setScale(restoredTransform.rescaleY(scale));
732
756
  }
733
757
  });
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);
758
+ if (zoom && zoom.domain) {
759
+ if (((_d = zoom.axis) === null || _d === void 0 ? void 0 : _d.orientation) === AxisOrientation.y) {
760
+ if (yAxisMap.has(zoom.axis.index)) {
761
+ const y = yAxisMap.get(zoom.axis.index);
762
+ const transform = this.zoomService.getD3Transform(zoom.domain, y.originDomain, y.scale, AxisOrientation.y, y.options.inverted);
763
+ const rescaled = transform.rescaleY(y.scale.copy());
740
764
  y.setScale(rescaled);
741
- const axis = yAxisMap.get(zoom.target.index);
742
- this.transformCacheY.set(axis.index, event.transform);
765
+ this.transformCacheY.set(y.index, transform);
743
766
  }
744
767
  }
745
768
  }
@@ -762,218 +785,32 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImpor
762
785
  }]
763
786
  }], ctorParameters: function () { return [{ type: ChartService }, { type: ZoomService }]; } });
764
787
 
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
788
  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
- }
789
+ // private _outBrushDomain = new ReplaySubject<[number, number]>(1);
790
+ constructor() {
791
+ // outBrushDomain: Observable<[number, number]>;
792
+ this._brushDomain = new ReplaySubject(1);
793
+ this.brushDomain = this._brushDomain.asObservable();
964
794
  }
965
- clearPreviousSelection() {
966
- this.selection = null;
795
+ setBrush(brush) {
796
+ this._brushDomain.next(brush);
967
797
  }
968
798
  }
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 });
799
+ BrushService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: BrushService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
970
800
  BrushService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: BrushService, providedIn: 'root' });
971
801
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: BrushService, decorators: [{
972
802
  type: Injectable,
973
803
  args: [{
974
804
  providedIn: 'root',
975
805
  }]
976
- }], ctorParameters: function () { return [{ type: BroadcastService }, { type: i0.NgZone }]; } });
806
+ }], ctorParameters: function () { return []; } });
807
+
808
+ var BrushType;
809
+ (function (BrushType) {
810
+ BrushType[BrushType["x"] = 0] = "x";
811
+ BrushType[BrushType["y"] = 1] = "y";
812
+ BrushType[BrushType["xy"] = 2] = "xy";
813
+ })(BrushType || (BrushType = {}));
977
814
 
978
815
  class SeriesBaseComponent {
979
816
  constructor(svc, cdr, scaleService, zoomService, element, zone) {
@@ -1095,18 +932,9 @@ class LinearSeriesBase extends SeriesBaseComponent {
1095
932
  filteredData = filteredData === null || filteredData === void 0 ? void 0 : filteredData.filter(filter(min, max));
1096
933
  }
1097
934
  return line(filteredData);
1098
- }), tap((_) => {
1099
- // console.log(_)
1100
- setTimeout(() => {
1101
- var _a;
1102
- if (((_a = this.markers) === null || _a === void 0 ? void 0 : _a.length) > 0) {
1103
- // this.addDragEvents();
1104
- }
1105
- });
1106
935
  }));
1107
936
  }
1108
937
  ngOnDestroy() {
1109
- // this.markerListeners?.on('start drag end', null);
1110
938
  this.svc.setTooltip({
1111
939
  point: null,
1112
940
  series: this.series,
@@ -1114,65 +942,6 @@ class LinearSeriesBase extends SeriesBaseComponent {
1114
942
  }
1115
943
  ngAfterViewInit() {
1116
944
  }
1117
- addDragEvents() {
1118
- // this.markerListeners?.on('start drag end', null);
1119
- // const drag = (node, event: d3.D3DragEvent<any, any, any>, d: BasePoint) => {
1120
- // if (
1121
- // d.marker?.dragType === DragPointType.x ||
1122
- // d.marker?.dragType === DragPointType.xy
1123
- // ) {
1124
- // d.x = this.x.invert(event.x);
1125
- // }
1126
- //
1127
- // if (
1128
- // d.marker?.dragType === DragPointType.y ||
1129
- // d.marker?.dragType === DragPointType.xy
1130
- // ) {
1131
- // d.y = this.y.invert(event.y);
1132
- // }
1133
- //
1134
- // this.svc.emitPoint({
1135
- // target: {
1136
- // series: this.series,
1137
- // point: d,
1138
- // },
1139
- // event,
1140
- // });
1141
- //
1142
- // this.cdr.detectChanges();
1143
- // };
1144
- // this.markerListeners = d3
1145
- // .drag()
1146
- // .subject(function (event, d: BasePoint) {
1147
- // const node = d3.select(this);
1148
- // return {x: node.attr('cx'), y: node.attr('cy')};
1149
- // });
1150
- // const dragMarkers =
1151
- // this.markerListeners.on(
1152
- // 'start drag end',
1153
- // function (event: d3.D3DragEvent<any, any, any>, d: BasePoint) {
1154
- // const node = d3.select(this);
1155
- //
1156
- // drag(node, event, d);
1157
- // }
1158
- // );
1159
- //
1160
- // const draggableMarkers = this.series.data?.filter(
1161
- // (_) => _?.marker && _?.marker?.draggable
1162
- // );
1163
- //
1164
- // const element = d3
1165
- // .select(this.element.nativeElement)
1166
- // .selectAll('.draggable-marker')
1167
- // .data(draggableMarkers);
1168
- //
1169
- // element.call(dragMarkers as any);
1170
- //
1171
- // this.svgElement = d3
1172
- // .select(this.element.nativeElement)
1173
- // .select('.line')
1174
- // .node() as SVGGeometryElement;
1175
- }
1176
945
  getTransform(event, scaleX, scaleY) {
1177
946
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
1178
947
  if (event.type === 'mouseleave') {
@@ -2208,11 +1977,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImpor
2208
1977
  args: ['tooltip', { static: false, read: ElementRef }]
2209
1978
  }] } });
2210
1979
 
1980
+ class ZoomMessage {
1981
+ constructor(options) {
1982
+ this.eventType = options === null || options === void 0 ? void 0 : options.eventType;
1983
+ this.element = options === null || options === void 0 ? void 0 : options.element;
1984
+ this.axis = options === null || options === void 0 ? void 0 : options.axis;
1985
+ this.domain = options.domain;
1986
+ this.chartId = options === null || options === void 0 ? void 0 : options.chartId;
1987
+ this.style = options === null || options === void 0 ? void 0 : options.style;
1988
+ }
1989
+ }
1990
+ class BrushMessage {
1991
+ constructor(options) {
1992
+ this.chartId = options === null || options === void 0 ? void 0 : options.chartId;
1993
+ this.selection = options === null || options === void 0 ? void 0 : options.selection;
1994
+ }
1995
+ }
1996
+
2211
1997
  class ZoomableDirective {
2212
- constructor(elementRef, zoomService, broadcastService, chartService, zone) {
1998
+ constructor(elementRef, zoomService, chartService, zone) {
2213
1999
  this.elementRef = elementRef;
2214
2000
  this.zoomService = zoomService;
2215
- this.broadcastService = broadcastService;
2216
2001
  this.chartService = chartService;
2217
2002
  this.zone = zone;
2218
2003
  this.zoomable = false;
@@ -2220,31 +2005,25 @@ class ZoomableDirective {
2220
2005
  this.alive = true;
2221
2006
  this.currentTransform = zoomIdentity;
2222
2007
  this.zoomed = (event) => {
2223
- var _a, _b, _c;
2224
2008
  if (event.sourceEvent) {
2225
2009
  if (Object.keys(event.sourceEvent).length !== 0) {
2226
- if (this.currentTransform === event.transform) {
2227
- return;
2228
- }
2229
- const origin = this.brushScale.copy().domain(this.axis.extremes);
2230
- let domain = ((_a = this.config.zoom) === null || _a === void 0 ? void 0 : _a.type) === ZoomType.y
2010
+ const origin = this.axis.scale.copy().domain(this.axis.originDomain);
2011
+ let domain = this.axis.orientation === AxisOrientation.y
2231
2012
  ? event.transform.rescaleY(origin).domain()
2232
2013
  : event.transform.rescaleX(origin).domain();
2233
2014
  const message = new ZoomMessage({
2234
- event,
2235
- axis: this.axis,
2236
- domain,
2237
- chartId: this.config.id,
2238
- });
2239
- this.broadcastService.broadcastZoom({
2240
- channel: (_c = (_b = this.config) === null || _b === void 0 ? void 0 : _b.zoom) === null || _c === void 0 ? void 0 : _c.syncChannel,
2241
- message,
2015
+ eventType: event.type,
2016
+ axis: {
2017
+ index: this.axis.index,
2018
+ orientation: this.axis.orientation,
2019
+ },
2020
+ element: this.elementRef,
2021
+ domain: domain,
2022
+ chartId: this.config.id
2242
2023
  });
2024
+ this.zoomService.fireZoom(message);
2025
+ this.zoomService.broadcastZoom(message);
2243
2026
  }
2244
- this.zoomService.fireZoom({
2245
- event,
2246
- target: this.axis,
2247
- });
2248
2027
  this.currentTransform = event.transform;
2249
2028
  }
2250
2029
  };
@@ -2256,166 +2035,80 @@ class ZoomableDirective {
2256
2035
  this.crosshair = (_k = (_j = this.config) === null || _j === void 0 ? void 0 : _j.tooltip) === null || _k === void 0 ? void 0 : _k.showCrosshair;
2257
2036
  }
2258
2037
  }
2259
- ngOnChanges(changes) {
2260
- if (changes.hasOwnProperty('brushScale') || changes.hasOwnProperty('scale') || changes.hasOwnProperty('axis')) {
2261
- if (this.hash) {
2262
- this.zoomService.scaleHashMap.set(this.hash, this.scale);
2263
- this.zoomService.axisHashMap.set(this.hash, this.axis);
2038
+ ngAfterViewInit() {
2039
+ this.initZoomListeners();
2040
+ this.initZoomSync();
2041
+ }
2042
+ ngOnDestroy() {
2043
+ var _a, _b;
2044
+ (_a = this.zoom) === null || _a === void 0 ? void 0 : _a.on('start zoom end', null);
2045
+ (_b = this._element) === null || _b === void 0 ? void 0 : _b.on('wheel', null);
2046
+ this.alive = false;
2047
+ }
2048
+ initZoomSync() {
2049
+ this.zoomService.zoomed.pipe(takeWhile(() => this.alive)).subscribe((zoomed) => {
2050
+ var _a, _b, _c;
2051
+ if (this._element && this.elementRef !== (zoomed === null || zoomed === void 0 ? void 0 : zoomed.element)
2052
+ && ((_a = zoomed === null || zoomed === void 0 ? void 0 : zoomed.axis) === null || _a === void 0 ? void 0 : _a.index) === this.axis.index
2053
+ && ((_b = zoomed === null || zoomed === void 0 ? void 0 : zoomed.axis) === null || _b === void 0 ? void 0 : _b.orientation) === this.axis.orientation) {
2054
+ const scale = this.axis.scale.copy().domain(this.axis.originDomain);
2055
+ let transform;
2056
+ if (zoomed.domain === null) {
2057
+ transform = zoomIdentity;
2058
+ }
2059
+ else {
2060
+ transform =
2061
+ this.zoomService.getD3Transform(zoomed.domain, this.axis.originDomain, scale, this.axis.orientation, this.axis.options.inverted);
2062
+ }
2063
+ if ((_c = zoomed.style) === null || _c === void 0 ? void 0 : _c.transition) {
2064
+ this._element.transition().call(this.zoom.transform, transform);
2065
+ }
2066
+ else {
2067
+ this._element.call(this.zoom.transform, transform);
2068
+ }
2069
+ this.currentTransform = transform;
2264
2070
  }
2265
- }
2071
+ });
2266
2072
  }
2267
- ngAfterViewInit() {
2268
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
2073
+ initZoomListeners() {
2074
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
2269
2075
  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) ||
2270
2076
  ((_e = (_d = this.config) === null || _d === void 0 ? void 0 : _d.zoom) === null || _e === void 0 ? void 0 : _e.enable);
2271
2077
  if (!enable) {
2272
2078
  return;
2273
2079
  }
2274
- if (enable) {
2275
- this._element = d3.select(this.elementRef.nativeElement);
2276
- this.hash = objectHash.sha1({ index: this.axis.index, orientation: this.axis.orientation });
2277
- this.zoom = d3.zoom().extent([
2080
+ this._element = d3.select(this.elementRef.nativeElement);
2081
+ this.zoom = d3.zoom().extent([
2082
+ [0, 0],
2083
+ [this.size.width, this.size.height],
2084
+ ]);
2085
+ if ((_f = this.config.zoom) === null || _f === void 0 ? void 0 : _f.limitTranslateByData) {
2086
+ this.zoom.translateExtent([
2278
2087
  [0, 0],
2279
2088
  [this.size.width, this.size.height],
2280
2089
  ]);
2281
- if ((_f = this.config.zoom) === null || _f === void 0 ? void 0 : _f.limitTranslateByData) {
2282
- this.zoom.translateExtent([
2283
- [0, 0],
2284
- [this.size.width, this.size.height],
2285
- ]);
2286
- }
2287
- if ((_g = this.config.zoom) === null || _g === void 0 ? void 0 : _g.wheelDelta) {
2288
- this.zoom.wheelDelta((_h = this.config.zoom) === null || _h === void 0 ? void 0 : _h.wheelDelta);
2289
- }
2290
- this.zoomService.axisHashMap.set(this.hash, this.axis);
2291
- this.zoomService.elementHashMap.set(this.hash, this._element);
2292
- this.zoomService.scaleHashMap.set(this.hash, this.scale);
2293
- this.zoomService.zoomHashMap.set(this.hash, this.zoom);
2294
- this.zoomService.setBroadcastChannel((_j = this.config) === null || _j === void 0 ? void 0 : _j.zoom.syncChannel);
2295
- const maxZoom = ((_k = this.config.zoom) === null || _k === void 0 ? void 0 : _k.max)
2296
- ? (this.axis.extremes[1] - this.axis.extremes[0]) /
2297
- ((_l = this.config.zoom) === null || _l === void 0 ? void 0 : _l.max)
2298
- : ((_m = this.config.zoom) === null || _m === void 0 ? void 0 : _m.limitZoomByData)
2299
- ? 1
2300
- : 0;
2301
- const minZoom = ((_o = this.config.zoom) === null || _o === void 0 ? void 0 : _o.min)
2302
- ? (this.axis.extremes[1] - this.axis.extremes[0]) /
2303
- ((_p = this.config.zoom) === null || _p === void 0 ? void 0 : _p.min)
2304
- : Infinity;
2305
- this.zoom.scaleExtent([maxZoom, minZoom]);
2306
- this.zoom.on('zoom end', this.zoomed);
2307
- this._element.call(this.zoom).on('dblclick.zoom', null); // Disable dbclick zoom
2308
- this.zone.runOutsideAngular(() => {
2309
- setTimeout(() => {
2310
- this.chartService.emitZoomInstance(this.zoomService);
2311
- });
2312
- });
2313
- if (((_r = (_q = this.config) === null || _q === void 0 ? void 0 : _q.zoom) === null || _r === void 0 ? void 0 : _r.zoomBehavior) === ZoomBehaviorType.wheel) {
2314
- this.runWheelZoom();
2315
- }
2316
2090
  }
2317
- // Subscribe to zoom events
2318
- this.broadcastService.subscribeToZoom((_s = this.config) === null || _s === void 0 ? void 0 : _s.zoom.syncChannel).pipe(takeWhile((_) => this.alive), tap$1((m) => {
2319
- var _a, _b, _c, _d, _e;
2320
- 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)) {
2321
- const currentZoom = d3.zoomTransform(this._element.node());
2322
- if (currentZoom !== m.message.event.transform && this.config.id === ((_e = m.message) === null || _e === void 0 ? void 0 : _e.chartId)) {
2323
- this._element.call(this.zoom.transform, m.message.event.transform);
2324
- }
2325
- }
2326
- }), filter((m) => m.message.event.sourceEvent instanceof MouseEvent ||
2327
- m.message.event.sourceEvent instanceof WheelEvent ||
2328
- (window.TouchEvent &&
2329
- m.message.event.sourceEvent instanceof TouchEvent)), filter((m) => {
2330
- var _a, _b, _c, _d;
2331
- return (this.axis.index === ((_b = (_a = m.message) === null || _a === void 0 ? void 0 : _a.axis) === null || _b === void 0 ? void 0 : _b.index) &&
2332
- this.axis.orientation === ((_d = (_c = m.message) === null || _c === void 0 ? void 0 : _c.axis) === null || _d === void 0 ? void 0 : _d.orientation));
2333
- }), tap$1((m) => {
2334
- var _a, _b, _c, _d, _e, _f, _g;
2335
- if (this.config.id !== ((_a = m.message) === null || _a === void 0 ? void 0 : _a.chartId)) {
2336
- this.brushScale.domain(this.axis.originDomain);
2337
- const scale = Math.abs(this.axis.originDomain[1] - this.axis.originDomain[0]) / Math.abs(m.message.domain[1] - m.message.domain[0]);
2338
- let transform = zoomIdentity.scale(scale);
2339
- if (((_c = (_b = this.config) === null || _b === void 0 ? void 0 : _b.zoom) === null || _c === void 0 ? void 0 : _c.type) === ZoomType.x) {
2340
- if ((_d = this.config.xAxis[0]) === null || _d === void 0 ? void 0 : _d.inverted) {
2341
- transform = transform.translate(this.brushScale(-m.message.domain[1]), 0);
2342
- }
2343
- else {
2344
- transform = transform.translate(-this.brushScale(m.message.domain[0]), 0);
2345
- }
2346
- }
2347
- if (((_f = (_e = this.config) === null || _e === void 0 ? void 0 : _e.zoom) === null || _f === void 0 ? void 0 : _f.type) === ZoomType.y) {
2348
- if ((_g = this.config.yAxis[0]) === null || _g === void 0 ? void 0 : _g.inverted) {
2349
- transform = transform.translate(0, -this.brushScale(m.message.domain[0]));
2350
- }
2351
- else {
2352
- transform = transform.translate(0, -this.brushScale(m.message.domain[1]));
2353
- }
2354
- }
2355
- this._element.call(this.zoom.transform, transform, null, {});
2356
- }
2357
- }))
2358
- .subscribe();
2359
- // Subscribe to brush events x or y
2360
- if ((((_t = this.config.brush) === null || _t === void 0 ? void 0 : _t.type) === BrushType.x &&
2361
- this.axis.orientation === AxisOrientation.x) ||
2362
- (((_u = this.config.brush) === null || _u === void 0 ? void 0 : _u.type) === BrushType.y &&
2363
- this.axis.orientation === AxisOrientation.y)) {
2364
- this.broadcastService.subscribeToBrush((_v = this.config) === null || _v === void 0 ? void 0 : _v.zoom.syncChannel)
2365
- .pipe(combineLatestWith(this.chartService.size), takeWhile((_) => this.alive), filter((data) => {
2366
- const [m] = data;
2367
- return Boolean(m.message.selection);
2368
- }), tap$1((data) => {
2369
- var _a, _b, _c, _d, _e, _f;
2370
- const [m] = data;
2371
- const currentTransform = d3.zoomTransform(this._element.node());
2372
- if (!m.message.event &&
2373
- this.currentSelection &&
2374
- currentTransform.k !== 1) {
2375
- return;
2376
- }
2377
- const s = m.message.selection;
2378
- this.brushScale.domain(this.axis.originDomain);
2379
- const domain = this.brushScale.domain();
2380
- const range = this.brushScale.range();
2381
- const scale = Math.abs(domain[1] - domain[0]) / Math.abs(s[1] - s[0]);
2382
- let transform = zoomIdentity.scale(scale);
2383
- if (((_a = m.message) === null || _a === void 0 ? void 0 : _a.brushType) === BrushType.x) {
2384
- this.brushScale.range([range[0], this.size.width]);
2385
- if ((_b = this.config.xAxis[0]) === null || _b === void 0 ? void 0 : _b.inverted) {
2386
- transform = transform.translate(-this.brushScale(s[0]), 0);
2387
- }
2388
- else {
2389
- transform = transform.translate(-this.brushScale(s[1]), 0);
2390
- }
2391
- }
2392
- if (((_c = m.message) === null || _c === void 0 ? void 0 : _c.brushType) === BrushType.y) {
2393
- this.brushScale.range([range[0], this.size.height]);
2394
- if ((_d = this.config.yAxis[0]) === null || _d === void 0 ? void 0 : _d.inverted) {
2395
- transform = transform.translate(0, -this.brushScale(s[0]));
2396
- }
2397
- else {
2398
- transform = transform.translate(0, -this.brushScale(s[1]));
2399
- }
2400
- }
2401
- if ((_f = (_e = m.message) === null || _e === void 0 ? void 0 : _e.style) === null || _f === void 0 ? void 0 : _f.transition) {
2402
- this._element.transition().call(this.zoom.transform, transform, null, {});
2403
- }
2404
- else {
2405
- this._element.call(this.zoom.transform, transform, null, {});
2406
- }
2407
- this.currentSelection = m.message.selection;
2408
- }))
2409
- .subscribe();
2091
+ if ((_g = this.config.zoom) === null || _g === void 0 ? void 0 : _g.wheelDelta) {
2092
+ this.zoom.wheelDelta((_h = this.config.zoom) === null || _h === void 0 ? void 0 : _h.wheelDelta);
2093
+ }
2094
+ const maxZoom = ((_j = this.config.zoom) === null || _j === void 0 ? void 0 : _j.max)
2095
+ ? (this.axis.extremes[1] - this.axis.extremes[0]) /
2096
+ ((_k = this.config.zoom) === null || _k === void 0 ? void 0 : _k.max)
2097
+ : ((_l = this.config.zoom) === null || _l === void 0 ? void 0 : _l.limitZoomByData)
2098
+ ? 1
2099
+ : 0;
2100
+ const minZoom = ((_m = this.config.zoom) === null || _m === void 0 ? void 0 : _m.min)
2101
+ ? (this.axis.extremes[1] - this.axis.extremes[0]) /
2102
+ ((_o = this.config.zoom) === null || _o === void 0 ? void 0 : _o.min)
2103
+ : Infinity;
2104
+ this.zoom.scaleExtent([maxZoom, minZoom]);
2105
+ this.zoom.on('zoom end', this.zoomed);
2106
+ this._element.call(this.zoom).on('dblclick.zoom', null); // Disable dbclick zoom
2107
+ if (((_q = (_p = this.config) === null || _p === void 0 ? void 0 : _p.zoom) === null || _q === void 0 ? void 0 : _q.zoomBehavior) === ZoomBehaviorType.wheel) {
2108
+ this.runWheelTranslate();
2410
2109
  }
2411
2110
  }
2412
- ngOnDestroy() {
2413
- var _a, _b;
2414
- (_a = this.zoom) === null || _a === void 0 ? void 0 : _a.on('start zoom end', null);
2415
- (_b = this._element) === null || _b === void 0 ? void 0 : _b.on('wheel', null);
2416
- this.alive = false;
2417
- }
2418
- runWheelZoom() {
2111
+ runWheelTranslate() {
2419
2112
  let type = 'start';
2420
2113
  let wheeling;
2421
2114
  this.zoom
@@ -2431,48 +2124,38 @@ class ZoomableDirective {
2431
2124
  return delta * 0.002;
2432
2125
  });
2433
2126
  const emit = (type, event) => {
2434
- var _a, _b, _c, _d, _e, _f;
2435
- const origin = this.brushScale.copy().domain(this.axis.extremes);
2127
+ var _a;
2128
+ const origin = this.axis.scale.copy().domain(this.axis.originDomain);
2436
2129
  let transform = zoomIdentity;
2437
2130
  const delta = type === 'end'
2438
2131
  ? 0
2439
- : ((_a = this.config.zoom) === null || _a === void 0 ? void 0 : _a.type) === ZoomType.y
2132
+ : this.axis.orientation === AxisOrientation.y
2440
2133
  ? event.deltaY
2441
2134
  : event.deltaX;
2442
- if (((_b = this.config.zoom) === null || _b === void 0 ? void 0 : _b.type) === ZoomType.y) {
2135
+ if (this.axis.orientation === AxisOrientation.y) {
2443
2136
  transform = transform.translate(0, this.currentTransform.y - delta / 2);
2444
2137
  }
2445
- if (((_c = this.config.zoom) === null || _c === void 0 ? void 0 : _c.type) === ZoomType.x) {
2138
+ if (this.axis.orientation === AxisOrientation.x) {
2446
2139
  transform = transform.translate(this.currentTransform.x - delta / 2, 0);
2447
2140
  }
2448
2141
  transform = transform.scale(this.currentTransform.k);
2449
- let domain = ((_d = this.config.zoom) === null || _d === void 0 ? void 0 : _d.type) === ZoomType.y
2142
+ let domain = this.axis.orientation === AxisOrientation.y
2450
2143
  ? transform.rescaleY(origin).domain()
2451
2144
  : transform.rescaleX(origin).domain();
2452
2145
  const message = new ZoomMessage({
2453
- event: {
2454
- sourceEvent: event,
2455
- transform,
2456
- type,
2146
+ eventType: type,
2147
+ element: this.elementRef,
2148
+ axis: {
2149
+ index: this.axis.index,
2150
+ orientation: this.axis.orientation
2457
2151
  },
2458
- axis: this.axis,
2459
2152
  domain,
2460
2153
  chartId: this.config.id,
2461
2154
  });
2462
- this.zoomService.fireZoom({
2463
- event: {
2464
- sourceEvent: event,
2465
- transform,
2466
- type,
2467
- },
2468
- target: this.axis,
2469
- });
2470
- this._element.call(this.zoom.transform, transform);
2155
+ (_a = this._element) === null || _a === void 0 ? void 0 : _a.call(this.zoom.transform, transform);
2156
+ this.zoomService.fireZoom(message);
2157
+ this.zoomService.broadcastZoom(message);
2471
2158
  this.currentTransform = transform;
2472
- this.broadcastService.broadcastZoom({
2473
- channel: (_f = (_e = this.config) === null || _e === void 0 ? void 0 : _e.zoom) === null || _f === void 0 ? void 0 : _f.syncChannel,
2474
- message,
2475
- });
2476
2159
  };
2477
2160
  this._element.on('wheel', (event) => {
2478
2161
  event.preventDefault();
@@ -2491,23 +2174,19 @@ class ZoomableDirective {
2491
2174
  });
2492
2175
  }
2493
2176
  }
2494
- 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 });
2495
- 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 });
2177
+ 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 });
2178
+ 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 });
2496
2179
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: ZoomableDirective, decorators: [{
2497
2180
  type: Directive,
2498
2181
  args: [{
2499
2182
  selector: '[tetaZoomable]',
2500
2183
  }]
2501
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: ZoomService }, { type: BroadcastService }, { type: ChartService }, { type: i0.NgZone }]; }, propDecorators: { config: [{
2184
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: ZoomService }, { type: ChartService }, { type: i0.NgZone }]; }, propDecorators: { config: [{
2502
2185
  type: Input
2503
2186
  }], axis: [{
2504
2187
  type: Input
2505
2188
  }], size: [{
2506
2189
  type: Input
2507
- }], brushScale: [{
2508
- type: Input
2509
- }], scale: [{
2510
- type: Input
2511
2190
  }], zoomable: [{
2512
2191
  type: HostBinding,
2513
2192
  args: ['class.zoomable']
@@ -2517,33 +2196,141 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImpor
2517
2196
  }] } });
2518
2197
 
2519
2198
  class BrushableDirective {
2520
- constructor(brushService, chartService, element) {
2199
+ constructor(brushService, chartService, element, zone) {
2521
2200
  this.brushService = brushService;
2522
2201
  this.chartService = chartService;
2523
2202
  this.element = element;
2203
+ this.zone = zone;
2204
+ this.brushMap = new Map()
2205
+ .set(BrushType.x, d3.brushX())
2206
+ .set(BrushType.y, d3.brushY());
2207
+ this._alive = true;
2208
+ this._container = d3.select(this.element.nativeElement);
2209
+ }
2210
+ ngOnInit() {
2211
+ this.brushService.brushDomain.pipe(takeWhile(() => this._alive), filter((brush) => brush.chartId !== this.config.id)).subscribe((brush) => {
2212
+ this._container.call(this.brush.move, [
2213
+ Math.floor(brush.selection[0]),
2214
+ Math.floor(brush.selection[1]),
2215
+ ].map(this.axis.scale));
2216
+ });
2217
+ }
2218
+ ngOnDestroy() {
2219
+ this._alive = false;
2220
+ }
2221
+ ngAfterViewInit() {
2524
2222
  }
2525
- ngOnInit() { }
2526
- ngAfterViewInit() { }
2527
2223
  ngOnChanges(changes) {
2528
2224
  var _a, _b;
2529
2225
  if (changes.hasOwnProperty('config')) {
2530
- this.brushService.clearPreviousSelection();
2226
+ this.clearPreviousSelection();
2531
2227
  }
2532
2228
  if ((_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.brush) === null || _b === void 0 ? void 0 : _b.enable) {
2533
- this.brushService.applyBrush(this.element, this.config, this.brushScale);
2229
+ this.applyBrush(this.config, this.axis.scale);
2230
+ }
2231
+ }
2232
+ applyBrush(config, brushScale) {
2233
+ var _a, _b, _c, _d;
2234
+ (_a = this.brush) === null || _a === void 0 ? void 0 : _a.on('start brush end', null);
2235
+ if ((_b = config.brush) === null || _b === void 0 ? void 0 : _b.enable) {
2236
+ 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);
2237
+ this.brush.on('start brush end', (_) => {
2238
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
2239
+ if (_.sourceEvent) {
2240
+ if (!_.selection)
2241
+ return;
2242
+ const [from, to] = _.selection;
2243
+ if (to - from === 0) {
2244
+ 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);
2245
+ const halfBrushHeight = (selection[1] - selection[0]) / 2;
2246
+ const invertedSelection = [
2247
+ from - halfBrushHeight,
2248
+ to + halfBrushHeight,
2249
+ ].map(brushScale.invert);
2250
+ if (invertedSelection[1] - invertedSelection[0] >
2251
+ ((_e = config.brush) === null || _e === void 0 ? void 0 : _e.max)) {
2252
+ this._container.call(this.brush.move, [
2253
+ Math.floor(invertedSelection[0]),
2254
+ Math.floor(invertedSelection[0] + ((_f = config.brush) === null || _f === void 0 ? void 0 : _f.max)),
2255
+ ].map(brushScale));
2256
+ return;
2257
+ }
2258
+ if (invertedSelection[1] - invertedSelection[0] <
2259
+ ((_g = config.brush) === null || _g === void 0 ? void 0 : _g.min)) {
2260
+ this._container.call(this.brush.move, [
2261
+ Math.floor(invertedSelection[0]),
2262
+ Math.ceil(invertedSelection[0] + ((_h = config.brush) === null || _h === void 0 ? void 0 : _h.min)),
2263
+ ].map(brushScale));
2264
+ return;
2265
+ }
2266
+ this._container.call(this.brush.move, [
2267
+ from - halfBrushHeight,
2268
+ to + halfBrushHeight,
2269
+ ]);
2270
+ return;
2271
+ }
2272
+ if (brushScale.invert(to) - brushScale.invert(from) >
2273
+ ((_j = config.brush) === null || _j === void 0 ? void 0 : _j.max)) {
2274
+ this._container.call(this.brush.move, this.selection
2275
+ ? [
2276
+ this.selection[0],
2277
+ this.selection[0] + ((_k = config.brush) === null || _k === void 0 ? void 0 : _k.max),
2278
+ ].map(brushScale)
2279
+ : [(_l = config.brush) === null || _l === void 0 ? void 0 : _l.from, (_m = config.brush) === null || _m === void 0 ? void 0 : _m.to].map(brushScale));
2280
+ return;
2281
+ }
2282
+ if (brushScale.invert(to) - brushScale.invert(from) <
2283
+ ((_o = config.brush) === null || _o === void 0 ? void 0 : _o.min)) {
2284
+ this._container.call(this.brush.move, this.selection
2285
+ ? [
2286
+ this.selection[0],
2287
+ this.selection[0] + ((_p = config.brush) === null || _p === void 0 ? void 0 : _p.min),
2288
+ ].map(brushScale)
2289
+ : [(_q = config.brush) === null || _q === void 0 ? void 0 : _q.from, (_r = config.brush) === null || _r === void 0 ? void 0 : _r.to].map(brushScale));
2290
+ return;
2291
+ }
2292
+ if (_.sourceEvent instanceof MouseEvent) {
2293
+ this.selection = _.selection.map(brushScale.invert);
2294
+ }
2295
+ const brushMessage = new BrushMessage({
2296
+ chartId: this.config.id,
2297
+ selection: [brushScale.invert(from), brushScale.invert(to)],
2298
+ });
2299
+ this.brushService.setBrush(brushMessage);
2300
+ }
2301
+ });
2302
+ this.zone.runOutsideAngular(() => {
2303
+ setTimeout(() => {
2304
+ var _a, _b;
2305
+ this._container.call(this.brush);
2306
+ let domain = brushScale.domain();
2307
+ if ((_a = config === null || config === void 0 ? void 0 : config.brush) === null || _a === void 0 ? void 0 : _a.from) {
2308
+ domain[0] = config.brush.from;
2309
+ }
2310
+ if ((_b = config === null || config === void 0 ? void 0 : config.brush) === null || _b === void 0 ? void 0 : _b.to) {
2311
+ domain[1] = config.brush.to;
2312
+ }
2313
+ this._container.call(this.brush.move, this.selection
2314
+ ? this.selection.map(brushScale)
2315
+ : domain.map(brushScale), {});
2316
+ }, 0);
2317
+ });
2534
2318
  }
2535
2319
  }
2320
+ clearPreviousSelection() {
2321
+ this.selection = null;
2322
+ }
2536
2323
  }
2537
- 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 });
2538
- 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 });
2324
+ 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 });
2325
+ 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 });
2539
2326
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: BrushableDirective, decorators: [{
2540
2327
  type: Directive,
2541
2328
  args: [{
2542
2329
  selector: '[tetaBrushable]',
2543
2330
  }]
2544
- }], ctorParameters: function () { return [{ type: BrushService }, { type: ChartService }, { type: i0.ElementRef }]; }, propDecorators: { config: [{
2331
+ }], ctorParameters: function () { return [{ type: BrushService }, { type: ChartService }, { type: i0.ElementRef }, { type: i0.NgZone }]; }, propDecorators: { config: [{
2545
2332
  type: Input
2546
- }], brushScale: [{
2333
+ }], axis: [{
2547
2334
  type: Input
2548
2335
  }] } });
2549
2336
 
@@ -2629,7 +2416,6 @@ class CrosshairComponent {
2629
2416
  this.transform = this.chartService.pointerMove.pipe(map((event) => {
2630
2417
  const composedPath = event.composedPath();
2631
2418
  const classes = composedPath.map((_) => { var _a; return (_a = _.classList) === null || _a === void 0 ? void 0 : _a.contains('crosshair'); }).filter((_) => _);
2632
- console.log(classes);
2633
2419
  return {
2634
2420
  x: event.type === 'mouseleave' ? -9999 : event.offsetX,
2635
2421
  y: event.type === 'mouseleave' ? -9999 : event.offsetY
@@ -2809,10 +2595,10 @@ class ChartContainerComponent {
2809
2595
  }
2810
2596
  }
2811
2597
  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 });
2812
- 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 });
2598
+ 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 });
2813
2599
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: ChartContainerComponent, decorators: [{
2814
2600
  type: Component,
2815
- 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"] }]
2601
+ 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"] }]
2816
2602
  }], ctorParameters: function () { return [{ type: ChartService }, { type: i0.ChangeDetectorRef }, { type: ScaleService }, { type: ZoomService }, { type: i0.ElementRef }, { type: i0.NgZone }]; } });
2817
2603
 
2818
2604
  class LegendComponent {
@@ -2848,9 +2634,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImpor
2848
2634
  }] } });
2849
2635
 
2850
2636
  class ChartComponent {
2851
- constructor(chartService, zoomService, scaleService) {
2637
+ constructor(chartService, zoomService, brushService, scaleService) {
2852
2638
  this.chartService = chartService;
2853
2639
  this.zoomService = zoomService;
2640
+ this.brushService = brushService;
2854
2641
  this.scaleService = scaleService;
2855
2642
  this.pointerMove = new EventEmitter();
2856
2643
  this.plotBandsMove = new EventEmitter();
@@ -2864,16 +2651,21 @@ class ChartComponent {
2864
2651
  this.annotationClick = new EventEmitter();
2865
2652
  this.annotationMove = new EventEmitter();
2866
2653
  this.zoomServiceInstance = new EventEmitter();
2654
+ this.brushServiceInstance = new EventEmitter();
2867
2655
  this._alive = true;
2868
2656
  this.svcConfig = this.chartService.config;
2869
2657
  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; })); }));
2870
2658
  }
2871
2659
  set config(config) {
2660
+ var _a;
2872
2661
  this.chartService.setConfig(config);
2662
+ this.zoomService.setBroadcastChannel((_a = config === null || config === void 0 ? void 0 : config.zoom) === null || _a === void 0 ? void 0 : _a.syncChannel);
2873
2663
  }
2874
2664
  ngOnChanges(changes) {
2875
2665
  }
2876
2666
  ngOnInit() {
2667
+ this.zoomServiceInstance.emit(this.zoomService);
2668
+ this.brushServiceInstance.emit(this.brushService);
2877
2669
  this.chartService.pointerMove
2878
2670
  .pipe(takeWhile(() => this._alive), withLatestFrom(this.scaleService.scales, this.chartService.config))
2879
2671
  .subscribe((data) => {
@@ -2945,28 +2737,19 @@ class ChartComponent {
2945
2737
  .subscribe((_) => {
2946
2738
  this.annotationMove.emit(_);
2947
2739
  });
2948
- this.chartService.zoomInstance
2949
- .pipe(takeWhile(() => this._alive))
2950
- .subscribe((_) => {
2951
- this.zoomServiceInstance.emit(_);
2952
- });
2953
2740
  }
2954
2741
  ngAfterViewInit() {
2955
2742
  }
2956
2743
  ngOnDestroy() {
2957
- var _a;
2958
2744
  this._alive = false;
2959
- (_a = this.zoomService.broadcastSubscription) === null || _a === void 0 ? void 0 : _a.forEach((sub) => {
2960
- sub.unsubscribe();
2961
- });
2962
2745
  }
2963
2746
  }
2964
- 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 });
2965
- 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 });
2747
+ 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 });
2748
+ 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 });
2966
2749
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: ChartComponent, decorators: [{
2967
2750
  type: Component,
2968
2751
  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"] }]
2969
- }], ctorParameters: function () { return [{ type: ChartService }, { type: ZoomService }, { type: ScaleService }]; }, propDecorators: { pointerMove: [{
2752
+ }], ctorParameters: function () { return [{ type: ChartService }, { type: ZoomService }, { type: BrushService }, { type: ScaleService }]; }, propDecorators: { pointerMove: [{
2970
2753
  type: Output
2971
2754
  }], plotBandsMove: [{
2972
2755
  type: Output
@@ -2990,6 +2773,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImpor
2990
2773
  type: Output
2991
2774
  }], zoomServiceInstance: [{
2992
2775
  type: Output
2776
+ }], brushServiceInstance: [{
2777
+ type: Output
2993
2778
  }], config: [{
2994
2779
  type: Input
2995
2780
  }] } });