@tetacom/svg-charts 1.2.28 → 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 (35) hide show
  1. package/chart/chart/chart.component.d.ts +5 -2
  2. package/chart/chart-container/chart-container.component.d.ts +1 -1
  3. package/chart/chart-container/series/linear-series-base.d.ts +0 -3
  4. package/chart/core/axis/axis.d.ts +2 -2
  5. package/chart/directives/brushable.directive.d.ts +15 -5
  6. package/chart/directives/zoomable.directive.d.ts +6 -11
  7. package/chart/model/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/plotband/plot-band.component.mjs +4 -2
  18. package/esm2020/chart/chart-container/series/line/line-series.component.mjs +4 -4
  19. package/esm2020/chart/chart-container/series/linear-series-base.mjs +4 -72
  20. package/esm2020/chart/core/axis/axis.mjs +2 -2
  21. package/esm2020/chart/directives/brushable.directive.mjs +120 -10
  22. package/esm2020/chart/directives/draggable-point.directive.mjs +2 -1
  23. package/esm2020/chart/directives/zoomable.directive.mjs +90 -197
  24. package/esm2020/chart/model/i-broadcast-message.mjs +4 -6
  25. package/esm2020/chart/model/marker-options.mjs +1 -1
  26. package/esm2020/chart/service/broadcast.service.mjs +4 -17
  27. package/esm2020/chart/service/brush.service.mjs +11 -147
  28. package/esm2020/chart/service/chart.service.mjs +17 -9
  29. package/esm2020/chart/service/scale.service.mjs +19 -21
  30. package/esm2020/chart/service/zoom.service.mjs +48 -53
  31. package/fesm2015/tetacom-svg-charts.mjs +373 -586
  32. package/fesm2015/tetacom-svg-charts.mjs.map +1 -1
  33. package/fesm2020/tetacom-svg-charts.mjs +356 -566
  34. package/fesm2020/tetacom-svg-charts.mjs.map +1 -1
  35. 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) {
@@ -1026,7 +863,7 @@ class LinearSeriesBase extends SeriesBaseComponent {
1026
863
  set series(series) {
1027
864
  var _a;
1028
865
  this.__series = series;
1029
- this.markers = (_a = this.__series.data) === null || _a === void 0 ? void 0 : _a.filter((_) => _ === null || _ === void 0 ? void 0 : _.marker);
866
+ this.markers = (_a = this.__series.data) === null || _a === void 0 ? void 0 : _a.filter((_) => (_ === null || _ === void 0 ? void 0 : _.marker) && (_ === null || _ === void 0 ? void 0 : _.x) !== undefined && (_ === null || _ === void 0 ? void 0 : _.y) !== undefined);
1030
867
  }
1031
868
  get series() {
1032
869
  return this.__series;
@@ -1064,7 +901,6 @@ class LinearSeriesBase extends SeriesBaseComponent {
1064
901
  }), tap(() => setTimeout(() => this.cdr.detectChanges())));
1065
902
  this.path = combineLatest([this.scaleService.scales, this._update]).pipe(map(([data]) => {
1066
903
  var _a, _b;
1067
- // console.log(data);
1068
904
  const { x, y } = data;
1069
905
  this.x = (_a = x.get(this.series.xAxisIndex)) === null || _a === void 0 ? void 0 : _a.scale;
1070
906
  this.y = (_b = y.get(this.series.yAxisIndex)) === null || _b === void 0 ? void 0 : _b.scale;
@@ -1096,18 +932,9 @@ class LinearSeriesBase extends SeriesBaseComponent {
1096
932
  filteredData = filteredData === null || filteredData === void 0 ? void 0 : filteredData.filter(filter(min, max));
1097
933
  }
1098
934
  return line(filteredData);
1099
- }), tap((_) => {
1100
- // console.log(_)
1101
- setTimeout(() => {
1102
- var _a;
1103
- if (((_a = this.markers) === null || _a === void 0 ? void 0 : _a.length) > 0) {
1104
- // this.addDragEvents();
1105
- }
1106
- });
1107
935
  }));
1108
936
  }
1109
937
  ngOnDestroy() {
1110
- // this.markerListeners?.on('start drag end', null);
1111
938
  this.svc.setTooltip({
1112
939
  point: null,
1113
940
  series: this.series,
@@ -1115,65 +942,6 @@ class LinearSeriesBase extends SeriesBaseComponent {
1115
942
  }
1116
943
  ngAfterViewInit() {
1117
944
  }
1118
- addDragEvents() {
1119
- // this.markerListeners?.on('start drag end', null);
1120
- // const drag = (node, event: d3.D3DragEvent<any, any, any>, d: BasePoint) => {
1121
- // if (
1122
- // d.marker?.dragType === DragPointType.x ||
1123
- // d.marker?.dragType === DragPointType.xy
1124
- // ) {
1125
- // d.x = this.x.invert(event.x);
1126
- // }
1127
- //
1128
- // if (
1129
- // d.marker?.dragType === DragPointType.y ||
1130
- // d.marker?.dragType === DragPointType.xy
1131
- // ) {
1132
- // d.y = this.y.invert(event.y);
1133
- // }
1134
- //
1135
- // this.svc.emitPoint({
1136
- // target: {
1137
- // series: this.series,
1138
- // point: d,
1139
- // },
1140
- // event,
1141
- // });
1142
- //
1143
- // this.cdr.detectChanges();
1144
- // };
1145
- // this.markerListeners = d3
1146
- // .drag()
1147
- // .subject(function (event, d: BasePoint) {
1148
- // const node = d3.select(this);
1149
- // return {x: node.attr('cx'), y: node.attr('cy')};
1150
- // });
1151
- // const dragMarkers =
1152
- // this.markerListeners.on(
1153
- // 'start drag end',
1154
- // function (event: d3.D3DragEvent<any, any, any>, d: BasePoint) {
1155
- // const node = d3.select(this);
1156
- //
1157
- // drag(node, event, d);
1158
- // }
1159
- // );
1160
- //
1161
- // const draggableMarkers = this.series.data?.filter(
1162
- // (_) => _?.marker && _?.marker?.draggable
1163
- // );
1164
- //
1165
- // const element = d3
1166
- // .select(this.element.nativeElement)
1167
- // .selectAll('.draggable-marker')
1168
- // .data(draggableMarkers);
1169
- //
1170
- // element.call(dragMarkers as any);
1171
- //
1172
- // this.svgElement = d3
1173
- // .select(this.element.nativeElement)
1174
- // .select('.line')
1175
- // .node() as SVGGeometryElement;
1176
- }
1177
945
  getTransform(event, scaleX, scaleY) {
1178
946
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
1179
947
  if (event.type === 'mouseleave') {
@@ -1211,7 +979,7 @@ class LinearSeriesBase extends SeriesBaseComponent {
1211
979
  }
1212
980
  const rightId = bisect(this.series.data, x0);
1213
981
  const range = scaleY.range();
1214
- const intersect = lineIntersection(pointer, range[0], pointer, range[1], scaleX((_c = this.series.data[rightId - 1]) === null || _c === void 0 ? void 0 : _c.x), scaleY((_d = this.series.data[rightId - 1]) === null || _d === void 0 ? void 0 : _d.y), scaleX((_e = this.series.data[rightId]) === null || _e === void 0 ? void 0 : _e.x), scaleY((_f = this.series.data[rightId]) === null || _f === void 0 ? void 0 : _f.y));
982
+ const intersect = lineIntersection(pointer, range[0], pointer, Number.MAX_SAFE_INTEGER, scaleX((_c = this.series.data[rightId - 1]) === null || _c === void 0 ? void 0 : _c.x), scaleY((_d = this.series.data[rightId - 1]) === null || _d === void 0 ? void 0 : _d.y), scaleX((_e = this.series.data[rightId]) === null || _e === void 0 ? void 0 : _e.x), scaleY((_f = this.series.data[rightId]) === null || _f === void 0 ? void 0 : _f.y));
1215
983
  const x = scaleX.invert(intersect.x);
1216
984
  const y = scaleY.invert(intersect.y);
1217
985
  if (x !== null && x !== undefined && !isNaN(x) && y !== null && y !== undefined && !isNaN(y)) {
@@ -1239,7 +1007,7 @@ class LinearSeriesBase extends SeriesBaseComponent {
1239
1007
  }
1240
1008
  const rightId = bisect(this.series.data, y0);
1241
1009
  const range = scaleX.range();
1242
- const intersect = lineIntersection(range[0], mouse[1], range[1], mouse[1], scaleX((_g = this.series.data[rightId - 1]) === null || _g === void 0 ? void 0 : _g.x), scaleY((_h = this.series.data[rightId - 1]) === null || _h === void 0 ? void 0 : _h.y), scaleX((_j = this.series.data[rightId]) === null || _j === void 0 ? void 0 : _j.x), scaleY((_k = this.series.data[rightId]) === null || _k === void 0 ? void 0 : _k.y));
1010
+ const intersect = lineIntersection(range[0], mouse[1], Number.MAX_SAFE_INTEGER, mouse[1], scaleX((_g = this.series.data[rightId - 1]) === null || _g === void 0 ? void 0 : _g.x), scaleY((_h = this.series.data[rightId - 1]) === null || _h === void 0 ? void 0 : _h.y), scaleX((_j = this.series.data[rightId]) === null || _j === void 0 ? void 0 : _j.x), scaleY((_k = this.series.data[rightId]) === null || _k === void 0 ? void 0 : _k.y));
1243
1011
  const x = scaleX.invert(intersect.x);
1244
1012
  const y = scaleY.invert(intersect.y);
1245
1013
  if (x !== null && x !== undefined && !isNaN(x) && y !== null && y !== undefined && !isNaN(y)) {
@@ -1314,6 +1082,7 @@ class DraggablePointDirective {
1314
1082
  deltaX,
1315
1083
  deltaY
1316
1084
  })) {
1085
+ this.startPosition = null;
1317
1086
  return;
1318
1087
  }
1319
1088
  if (this.transformCache) {
@@ -1432,7 +1201,7 @@ class LineSeriesComponent extends LinearSeriesBase {
1432
1201
  }
1433
1202
  }
1434
1203
  if (point.marker.maxX !== null && point.marker.maxX !== undefined) {
1435
- if (this.x.invert(this.x(this.start.x) + newPoint.deltaX) > point.marker.minX) {
1204
+ if (this.x.invert(this.x(this.start.x) + newPoint.deltaX) > point.marker.maxX) {
1436
1205
  return false;
1437
1206
  }
1438
1207
  }
@@ -1494,10 +1263,10 @@ class LineSeriesComponent extends LinearSeriesBase {
1494
1263
  }
1495
1264
  }
1496
1265
  LineSeriesComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: LineSeriesComponent, deps: [{ token: ChartService }, { token: i0.ChangeDetectorRef }, { token: ScaleService }, { token: ZoomService }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
1497
- LineSeriesComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.2", type: LineSeriesComponent, selector: "svg:svg[teta-line-series]", usesInheritance: true, ngImport: i0, template: "<svg:path\n class=\"line\"\n [attr.d]=\"path | async\"\n [attr.stroke]=\"series.color\"\n [attr.stroke-dasharray]=\"series.style?.strokeDasharray\"\n [attr.stroke-width]=\"series.style?.strokeWidth\"\n fill=\"none\">\n</svg:path>\n<ng-container *ngIf=\"transform | async as t\">\n <svg:circle\n *ngIf=\"t?.x !=null && t?.y!=null\"\n r=\"3\"\n [attr.fill]=\"series.color\"\n [attr.transform]=\"'translate('+ t.x +', '+ t.y +')'\"\n >\n </svg:circle>\n</ng-container>\n<ng-container *ngIf=\"markers as draggablePoints\">\n <svg:g\n *ngFor=\"let point of draggablePoints\"\n [attr.transform]=\"'translate(' + x(point.x)+ ',' +y(point.y) + ')'\">\n <svg:g [tetaDraggablePoint]=\"point.marker.draggable\"\n [dragDirection]=\"point.marker.dragType\"\n [allowDrag]=\"allowDrag(point)\"\n #dragPoint=\"tetaDraggablePoint\"\n (moveStart)=\"moveStart($event, point)\"\n (moveEnd)=\"moveEnd($event, point);dragPoint.resetTransform();\"\n (moveProcess)=\"moveProcess($event, point);dragPoint.resetTransform();\"\n [class.draggable-marker]=\"point?.marker?.draggable\">\n <svg:circle\n class=\"marker\"\n [attr.r]=\"point.marker.style?.radius ?? 5\"\n [attr.fill]=\"point.marker.style?.fill ?? 'transparent'\"\n [attr.stroke]=\"point.marker.style?.stroke ?? 'none'\"\n [attr.stroke-width]=\"point.marker.style?.strokeWidth\"\n [attr.stroke-dasharray]=\"point.marker.style?.strokeDasharray\"\n [attr.cx]=\"0\"\n [attr.cy]=\"0\">\n </svg:circle>\n <ng-container *ngIf=\"point.marker.label?.text\">\n <svg:line\n [attr.x1]=\"0\"\n [attr.y1]=\"0\"\n [attr.x2]=\"point.marker.label?.dx\"\n [attr.y2]=\"point.marker.label?.dy\"\n [attr.stroke]=\"point.marker.label?.style?.stroke ?? 'var(--color-text-90)'\"\n [attr.stroke-width]=\"point.marker.label?.style?.strokeWidth ?? 1\"\n [attr.stroke-dasharray]=\"point.marker.label?.style?.strokeDasharray ?? null\">\n </svg:line>\n <svg:foreignObject\n [tetaDraggablePoint]=\"point.marker.label?.draggable\"\n [dragDirection]=\"point.marker.label.dragType\"\n #labelPoint=\"tetaDraggablePoint\"\n (moveStart)=\"startLabel($event, point.marker.label)\"\n (moveProcess)=\"moveLabel($event, point.marker.label); labelPoint.resetTransform();\"\n (moveEnd)=\"labelPoint.resetTransform();\"\n [attr.width]=\"annotationNode?.offsetWidth ?? 0\"\n [attr.height]=\"annotationNode?.offsetHeight ?? 0\"\n [attr.x]=\"point.marker.label?.dx\"\n [attr.y]=\"point.marker.label?.dy\"\n class=\"position-absolute\">\n <div\n #annotationNode\n class=\"shadow-2 padding-2\"\n [style.color]=\"'var(--color-text-90)'\"\n [style.background-color]=\"'var(--color-background-50)'\"\n [style.cursor]=\"'move'\"\n style=\"border-radius: 2px; display: inline-block;\">\n {{point.marker.label?.text}}\n </div>\n </svg:foreignObject>\n </ng-container>\n </svg:g>\n </svg:g>\n</ng-container>\n\n\n\n", styles: [".draggable-marker{cursor:move}.active{stroke-opacity:.5}.marker-grab{opacity:0}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: DraggablePointDirective, selector: "[tetaDraggablePoint]", inputs: ["tetaDraggablePoint", "dragDirection", "allowDrag"], outputs: ["moveStart", "moveProcess", "moveEnd"], exportAs: ["tetaDraggablePoint"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1266
+ LineSeriesComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.2", type: LineSeriesComponent, selector: "svg:svg[teta-line-series]", usesInheritance: true, ngImport: i0, template: "<svg:path\n class=\"line\"\n [attr.d]=\"path | async\"\n [attr.stroke]=\"series.color\"\n [attr.stroke-dasharray]=\"series.style?.strokeDasharray\"\n [attr.stroke-width]=\"series.style?.strokeWidth\"\n fill=\"none\">\n</svg:path>\n<ng-container *ngIf=\"transform | async as t\">\n <svg:circle\n *ngIf=\"t?.x !=null && t?.y!=null\"\n r=\"3\"\n [attr.fill]=\"series.color\"\n [attr.transform]=\"'translate('+ t.x +', '+ t.y +')'\"\n >\n </svg:circle>\n</ng-container>\n<ng-container *ngIf=\"markers as draggablePoints\">\n <ng-container *ngIf=\"x && y\">\n <svg:g\n *ngFor=\"let point of draggablePoints\"\n [attr.transform]=\"'translate(' + x(point.x) + ',' + y(point.y) + ')'\">\n <svg:g [tetaDraggablePoint]=\"point.marker.draggable\"\n [dragDirection]=\"point.marker.dragType\"\n [allowDrag]=\"allowDrag(point)\"\n #dragPoint=\"tetaDraggablePoint\"\n (moveStart)=\"moveStart($event, point)\"\n (moveEnd)=\"moveEnd($event, point);dragPoint.resetTransform();\"\n (moveProcess)=\"moveProcess($event, point);dragPoint.resetTransform();\"\n [class.draggable-marker]=\"point?.marker?.draggable\">\n <svg:circle\n class=\"marker\"\n [attr.r]=\"point.marker.style?.radius ?? 5\"\n [attr.fill]=\"point.marker.style?.fill ?? 'transparent'\"\n [attr.stroke]=\"point.marker.style?.stroke ?? 'none'\"\n [attr.stroke-width]=\"point.marker.style?.strokeWidth\"\n [attr.stroke-dasharray]=\"point.marker.style?.strokeDasharray\"\n [attr.cx]=\"0\"\n [attr.cy]=\"0\">\n </svg:circle>\n <ng-container *ngIf=\"point.marker.label?.text\">\n <svg:line\n [attr.x1]=\"0\"\n [attr.y1]=\"0\"\n [attr.x2]=\"point.marker.label?.dx\"\n [attr.y2]=\"point.marker.label?.dy\"\n [attr.stroke]=\"point.marker.label?.style?.stroke ?? 'var(--color-text-90)'\"\n [attr.stroke-width]=\"point.marker.label?.style?.strokeWidth ?? 1\"\n [attr.stroke-dasharray]=\"point.marker.label?.style?.strokeDasharray ?? null\">\n </svg:line>\n <svg:foreignObject\n [tetaDraggablePoint]=\"point.marker.label?.draggable\"\n [dragDirection]=\"point.marker.label.dragType\"\n #labelPoint=\"tetaDraggablePoint\"\n (moveStart)=\"startLabel($event, point.marker.label)\"\n (moveProcess)=\"moveLabel($event, point.marker.label); labelPoint.resetTransform();\"\n (moveEnd)=\"labelPoint.resetTransform();\"\n [attr.width]=\"annotationNode?.offsetWidth ?? 0\"\n [attr.height]=\"annotationNode?.offsetHeight ?? 0\"\n [attr.x]=\"point.marker.label?.dx\"\n [attr.y]=\"point.marker.label?.dy\"\n class=\"position-absolute\">\n <div\n #annotationNode\n class=\"shadow-2 padding-2\"\n [style.color]=\"'var(--color-text-90)'\"\n [style.background-color]=\"'var(--color-background-50)'\"\n [style.cursor]=\"'move'\"\n style=\"border-radius: 2px; display: inline-block;\">\n {{point.marker.label?.text}}\n </div>\n </svg:foreignObject>\n </ng-container>\n </svg:g>\n </svg:g>\n </ng-container>\n\n</ng-container>\n\n\n\n", styles: [".draggable-marker{cursor:move}.active{stroke-opacity:.5}.marker-grab{opacity:0}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: DraggablePointDirective, selector: "[tetaDraggablePoint]", inputs: ["tetaDraggablePoint", "dragDirection", "allowDrag"], outputs: ["moveStart", "moveProcess", "moveEnd"], exportAs: ["tetaDraggablePoint"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1498
1267
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: LineSeriesComponent, decorators: [{
1499
1268
  type: Component,
1500
- args: [{ selector: 'svg:svg[teta-line-series]', changeDetection: ChangeDetectionStrategy.OnPush, template: "<svg:path\n class=\"line\"\n [attr.d]=\"path | async\"\n [attr.stroke]=\"series.color\"\n [attr.stroke-dasharray]=\"series.style?.strokeDasharray\"\n [attr.stroke-width]=\"series.style?.strokeWidth\"\n fill=\"none\">\n</svg:path>\n<ng-container *ngIf=\"transform | async as t\">\n <svg:circle\n *ngIf=\"t?.x !=null && t?.y!=null\"\n r=\"3\"\n [attr.fill]=\"series.color\"\n [attr.transform]=\"'translate('+ t.x +', '+ t.y +')'\"\n >\n </svg:circle>\n</ng-container>\n<ng-container *ngIf=\"markers as draggablePoints\">\n <svg:g\n *ngFor=\"let point of draggablePoints\"\n [attr.transform]=\"'translate(' + x(point.x)+ ',' +y(point.y) + ')'\">\n <svg:g [tetaDraggablePoint]=\"point.marker.draggable\"\n [dragDirection]=\"point.marker.dragType\"\n [allowDrag]=\"allowDrag(point)\"\n #dragPoint=\"tetaDraggablePoint\"\n (moveStart)=\"moveStart($event, point)\"\n (moveEnd)=\"moveEnd($event, point);dragPoint.resetTransform();\"\n (moveProcess)=\"moveProcess($event, point);dragPoint.resetTransform();\"\n [class.draggable-marker]=\"point?.marker?.draggable\">\n <svg:circle\n class=\"marker\"\n [attr.r]=\"point.marker.style?.radius ?? 5\"\n [attr.fill]=\"point.marker.style?.fill ?? 'transparent'\"\n [attr.stroke]=\"point.marker.style?.stroke ?? 'none'\"\n [attr.stroke-width]=\"point.marker.style?.strokeWidth\"\n [attr.stroke-dasharray]=\"point.marker.style?.strokeDasharray\"\n [attr.cx]=\"0\"\n [attr.cy]=\"0\">\n </svg:circle>\n <ng-container *ngIf=\"point.marker.label?.text\">\n <svg:line\n [attr.x1]=\"0\"\n [attr.y1]=\"0\"\n [attr.x2]=\"point.marker.label?.dx\"\n [attr.y2]=\"point.marker.label?.dy\"\n [attr.stroke]=\"point.marker.label?.style?.stroke ?? 'var(--color-text-90)'\"\n [attr.stroke-width]=\"point.marker.label?.style?.strokeWidth ?? 1\"\n [attr.stroke-dasharray]=\"point.marker.label?.style?.strokeDasharray ?? null\">\n </svg:line>\n <svg:foreignObject\n [tetaDraggablePoint]=\"point.marker.label?.draggable\"\n [dragDirection]=\"point.marker.label.dragType\"\n #labelPoint=\"tetaDraggablePoint\"\n (moveStart)=\"startLabel($event, point.marker.label)\"\n (moveProcess)=\"moveLabel($event, point.marker.label); labelPoint.resetTransform();\"\n (moveEnd)=\"labelPoint.resetTransform();\"\n [attr.width]=\"annotationNode?.offsetWidth ?? 0\"\n [attr.height]=\"annotationNode?.offsetHeight ?? 0\"\n [attr.x]=\"point.marker.label?.dx\"\n [attr.y]=\"point.marker.label?.dy\"\n class=\"position-absolute\">\n <div\n #annotationNode\n class=\"shadow-2 padding-2\"\n [style.color]=\"'var(--color-text-90)'\"\n [style.background-color]=\"'var(--color-background-50)'\"\n [style.cursor]=\"'move'\"\n style=\"border-radius: 2px; display: inline-block;\">\n {{point.marker.label?.text}}\n </div>\n </svg:foreignObject>\n </ng-container>\n </svg:g>\n </svg:g>\n</ng-container>\n\n\n\n", styles: [".draggable-marker{cursor:move}.active{stroke-opacity:.5}.marker-grab{opacity:0}\n"] }]
1269
+ args: [{ selector: 'svg:svg[teta-line-series]', changeDetection: ChangeDetectionStrategy.OnPush, template: "<svg:path\n class=\"line\"\n [attr.d]=\"path | async\"\n [attr.stroke]=\"series.color\"\n [attr.stroke-dasharray]=\"series.style?.strokeDasharray\"\n [attr.stroke-width]=\"series.style?.strokeWidth\"\n fill=\"none\">\n</svg:path>\n<ng-container *ngIf=\"transform | async as t\">\n <svg:circle\n *ngIf=\"t?.x !=null && t?.y!=null\"\n r=\"3\"\n [attr.fill]=\"series.color\"\n [attr.transform]=\"'translate('+ t.x +', '+ t.y +')'\"\n >\n </svg:circle>\n</ng-container>\n<ng-container *ngIf=\"markers as draggablePoints\">\n <ng-container *ngIf=\"x && y\">\n <svg:g\n *ngFor=\"let point of draggablePoints\"\n [attr.transform]=\"'translate(' + x(point.x) + ',' + y(point.y) + ')'\">\n <svg:g [tetaDraggablePoint]=\"point.marker.draggable\"\n [dragDirection]=\"point.marker.dragType\"\n [allowDrag]=\"allowDrag(point)\"\n #dragPoint=\"tetaDraggablePoint\"\n (moveStart)=\"moveStart($event, point)\"\n (moveEnd)=\"moveEnd($event, point);dragPoint.resetTransform();\"\n (moveProcess)=\"moveProcess($event, point);dragPoint.resetTransform();\"\n [class.draggable-marker]=\"point?.marker?.draggable\">\n <svg:circle\n class=\"marker\"\n [attr.r]=\"point.marker.style?.radius ?? 5\"\n [attr.fill]=\"point.marker.style?.fill ?? 'transparent'\"\n [attr.stroke]=\"point.marker.style?.stroke ?? 'none'\"\n [attr.stroke-width]=\"point.marker.style?.strokeWidth\"\n [attr.stroke-dasharray]=\"point.marker.style?.strokeDasharray\"\n [attr.cx]=\"0\"\n [attr.cy]=\"0\">\n </svg:circle>\n <ng-container *ngIf=\"point.marker.label?.text\">\n <svg:line\n [attr.x1]=\"0\"\n [attr.y1]=\"0\"\n [attr.x2]=\"point.marker.label?.dx\"\n [attr.y2]=\"point.marker.label?.dy\"\n [attr.stroke]=\"point.marker.label?.style?.stroke ?? 'var(--color-text-90)'\"\n [attr.stroke-width]=\"point.marker.label?.style?.strokeWidth ?? 1\"\n [attr.stroke-dasharray]=\"point.marker.label?.style?.strokeDasharray ?? null\">\n </svg:line>\n <svg:foreignObject\n [tetaDraggablePoint]=\"point.marker.label?.draggable\"\n [dragDirection]=\"point.marker.label.dragType\"\n #labelPoint=\"tetaDraggablePoint\"\n (moveStart)=\"startLabel($event, point.marker.label)\"\n (moveProcess)=\"moveLabel($event, point.marker.label); labelPoint.resetTransform();\"\n (moveEnd)=\"labelPoint.resetTransform();\"\n [attr.width]=\"annotationNode?.offsetWidth ?? 0\"\n [attr.height]=\"annotationNode?.offsetHeight ?? 0\"\n [attr.x]=\"point.marker.label?.dx\"\n [attr.y]=\"point.marker.label?.dy\"\n class=\"position-absolute\">\n <div\n #annotationNode\n class=\"shadow-2 padding-2\"\n [style.color]=\"'var(--color-text-90)'\"\n [style.background-color]=\"'var(--color-background-50)'\"\n [style.cursor]=\"'move'\"\n style=\"border-radius: 2px; display: inline-block;\">\n {{point.marker.label?.text}}\n </div>\n </svg:foreignObject>\n </ng-container>\n </svg:g>\n </svg:g>\n </ng-container>\n\n</ng-container>\n\n\n\n", styles: [".draggable-marker{cursor:move}.active{stroke-opacity:.5}.marker-grab{opacity:0}\n"] }]
1501
1270
  }], ctorParameters: function () { return [{ type: ChartService }, { type: i0.ChangeDetectorRef }, { type: ScaleService }, { type: ZoomService }, { type: i0.ElementRef }]; } });
1502
1271
 
1503
1272
  class BarSeriesComponent extends SeriesBaseComponent {
@@ -1974,7 +1743,9 @@ class PlotBandComponent {
1974
1743
  this.element = element;
1975
1744
  this.orientation = AxisOrientation;
1976
1745
  this.getTextPosition = () => {
1977
- const [min, max] = this.scale.domain();
1746
+ let [min, max] = this.scale.domain();
1747
+ min = min instanceof Date ? min.getTime() : min;
1748
+ max = max instanceof Date ? max.getTime() : max;
1978
1749
  const position = ((this.plotBand.from <= min ? min : this.plotBand.from) + (this.plotBand.to >= max ? max : this.plotBand.to)) / 2;
1979
1750
  return this.scale(position);
1980
1751
  };
@@ -2206,11 +1977,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImpor
2206
1977
  args: ['tooltip', { static: false, read: ElementRef }]
2207
1978
  }] } });
2208
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
+
2209
1997
  class ZoomableDirective {
2210
- constructor(elementRef, zoomService, broadcastService, chartService, zone) {
1998
+ constructor(elementRef, zoomService, chartService, zone) {
2211
1999
  this.elementRef = elementRef;
2212
2000
  this.zoomService = zoomService;
2213
- this.broadcastService = broadcastService;
2214
2001
  this.chartService = chartService;
2215
2002
  this.zone = zone;
2216
2003
  this.zoomable = false;
@@ -2218,31 +2005,25 @@ class ZoomableDirective {
2218
2005
  this.alive = true;
2219
2006
  this.currentTransform = zoomIdentity;
2220
2007
  this.zoomed = (event) => {
2221
- var _a, _b, _c;
2222
2008
  if (event.sourceEvent) {
2223
2009
  if (Object.keys(event.sourceEvent).length !== 0) {
2224
- if (this.currentTransform === event.transform) {
2225
- return;
2226
- }
2227
- const origin = this.brushScale.copy().domain(this.axis.extremes);
2228
- 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
2229
2012
  ? event.transform.rescaleY(origin).domain()
2230
2013
  : event.transform.rescaleX(origin).domain();
2231
2014
  const message = new ZoomMessage({
2232
- event,
2233
- axis: this.axis,
2234
- domain,
2235
- chartId: this.config.id,
2236
- });
2237
- this.broadcastService.broadcastZoom({
2238
- channel: (_c = (_b = this.config) === null || _b === void 0 ? void 0 : _b.zoom) === null || _c === void 0 ? void 0 : _c.syncChannel,
2239
- 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
2240
2023
  });
2024
+ this.zoomService.fireZoom(message);
2025
+ this.zoomService.broadcastZoom(message);
2241
2026
  }
2242
- this.zoomService.fireZoom({
2243
- event,
2244
- target: this.axis,
2245
- });
2246
2027
  this.currentTransform = event.transform;
2247
2028
  }
2248
2029
  };
@@ -2254,166 +2035,80 @@ class ZoomableDirective {
2254
2035
  this.crosshair = (_k = (_j = this.config) === null || _j === void 0 ? void 0 : _j.tooltip) === null || _k === void 0 ? void 0 : _k.showCrosshair;
2255
2036
  }
2256
2037
  }
2257
- ngOnChanges(changes) {
2258
- if (changes.hasOwnProperty('brushScale') || changes.hasOwnProperty('scale') || changes.hasOwnProperty('axis')) {
2259
- if (this.hash) {
2260
- this.zoomService.scaleHashMap.set(this.hash, this.scale);
2261
- 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;
2262
2070
  }
2263
- }
2071
+ });
2264
2072
  }
2265
- ngAfterViewInit() {
2266
- 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;
2267
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) ||
2268
2076
  ((_e = (_d = this.config) === null || _d === void 0 ? void 0 : _d.zoom) === null || _e === void 0 ? void 0 : _e.enable);
2269
2077
  if (!enable) {
2270
2078
  return;
2271
2079
  }
2272
- if (enable) {
2273
- this._element = d3.select(this.elementRef.nativeElement);
2274
- this.hash = objectHash.sha1({ index: this.axis.index, orientation: this.axis.orientation });
2275
- 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([
2276
2087
  [0, 0],
2277
2088
  [this.size.width, this.size.height],
2278
2089
  ]);
2279
- if ((_f = this.config.zoom) === null || _f === void 0 ? void 0 : _f.limitTranslateByData) {
2280
- this.zoom.translateExtent([
2281
- [0, 0],
2282
- [this.size.width, this.size.height],
2283
- ]);
2284
- }
2285
- if ((_g = this.config.zoom) === null || _g === void 0 ? void 0 : _g.wheelDelta) {
2286
- this.zoom.wheelDelta((_h = this.config.zoom) === null || _h === void 0 ? void 0 : _h.wheelDelta);
2287
- }
2288
- this.zoomService.axisHashMap.set(this.hash, this.axis);
2289
- this.zoomService.elementHashMap.set(this.hash, this._element);
2290
- this.zoomService.scaleHashMap.set(this.hash, this.scale);
2291
- this.zoomService.zoomHashMap.set(this.hash, this.zoom);
2292
- this.zoomService.setBroadcastChannel((_j = this.config) === null || _j === void 0 ? void 0 : _j.zoom.syncChannel);
2293
- const maxZoom = ((_k = this.config.zoom) === null || _k === void 0 ? void 0 : _k.max)
2294
- ? (this.axis.extremes[1] - this.axis.extremes[0]) /
2295
- ((_l = this.config.zoom) === null || _l === void 0 ? void 0 : _l.max)
2296
- : ((_m = this.config.zoom) === null || _m === void 0 ? void 0 : _m.limitZoomByData)
2297
- ? 1
2298
- : 0;
2299
- const minZoom = ((_o = this.config.zoom) === null || _o === void 0 ? void 0 : _o.min)
2300
- ? (this.axis.extremes[1] - this.axis.extremes[0]) /
2301
- ((_p = this.config.zoom) === null || _p === void 0 ? void 0 : _p.min)
2302
- : Infinity;
2303
- this.zoom.scaleExtent([maxZoom, minZoom]);
2304
- this.zoom.on('zoom end', this.zoomed);
2305
- this._element.call(this.zoom).on('dblclick.zoom', null); // Disable dbclick zoom
2306
- this.zone.runOutsideAngular(() => {
2307
- setTimeout(() => {
2308
- this.chartService.emitZoomInstance(this.zoomService);
2309
- });
2310
- });
2311
- if (((_r = (_q = this.config) === null || _q === void 0 ? void 0 : _q.zoom) === null || _r === void 0 ? void 0 : _r.zoomBehavior) === ZoomBehaviorType.wheel) {
2312
- this.runWheelZoom();
2313
- }
2314
2090
  }
2315
- // Subscribe to zoom events
2316
- this.broadcastService.subscribeToZoom((_s = this.config) === null || _s === void 0 ? void 0 : _s.zoom.syncChannel).pipe(takeWhile((_) => this.alive), tap$1((m) => {
2317
- var _a, _b, _c, _d, _e;
2318
- 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)) {
2319
- const currentZoom = d3.zoomTransform(this._element.node());
2320
- if (currentZoom !== m.message.event.transform && this.config.id === ((_e = m.message) === null || _e === void 0 ? void 0 : _e.chartId)) {
2321
- this._element.call(this.zoom.transform, m.message.event.transform);
2322
- }
2323
- }
2324
- }), filter((m) => m.message.event.sourceEvent instanceof MouseEvent ||
2325
- m.message.event.sourceEvent instanceof WheelEvent ||
2326
- (window.TouchEvent &&
2327
- m.message.event.sourceEvent instanceof TouchEvent)), filter((m) => {
2328
- var _a, _b, _c, _d;
2329
- return (this.axis.index === ((_b = (_a = m.message) === null || _a === void 0 ? void 0 : _a.axis) === null || _b === void 0 ? void 0 : _b.index) &&
2330
- this.axis.orientation === ((_d = (_c = m.message) === null || _c === void 0 ? void 0 : _c.axis) === null || _d === void 0 ? void 0 : _d.orientation));
2331
- }), tap$1((m) => {
2332
- var _a, _b, _c, _d, _e, _f, _g;
2333
- if (this.config.id !== ((_a = m.message) === null || _a === void 0 ? void 0 : _a.chartId)) {
2334
- this.brushScale.domain(this.axis.originDomain);
2335
- const scale = Math.abs(this.axis.originDomain[1] - this.axis.originDomain[0]) / Math.abs(m.message.domain[1] - m.message.domain[0]);
2336
- let transform = zoomIdentity.scale(scale);
2337
- if (((_c = (_b = this.config) === null || _b === void 0 ? void 0 : _b.zoom) === null || _c === void 0 ? void 0 : _c.type) === ZoomType.x) {
2338
- if ((_d = this.config.xAxis[0]) === null || _d === void 0 ? void 0 : _d.inverted) {
2339
- transform = transform.translate(this.brushScale(-m.message.domain[1]), 0);
2340
- }
2341
- else {
2342
- transform = transform.translate(-this.brushScale(m.message.domain[0]), 0);
2343
- }
2344
- }
2345
- if (((_f = (_e = this.config) === null || _e === void 0 ? void 0 : _e.zoom) === null || _f === void 0 ? void 0 : _f.type) === ZoomType.y) {
2346
- if ((_g = this.config.yAxis[0]) === null || _g === void 0 ? void 0 : _g.inverted) {
2347
- transform = transform.translate(0, -this.brushScale(m.message.domain[0]));
2348
- }
2349
- else {
2350
- transform = transform.translate(0, -this.brushScale(m.message.domain[1]));
2351
- }
2352
- }
2353
- this._element.call(this.zoom.transform, transform, null, {});
2354
- }
2355
- }))
2356
- .subscribe();
2357
- // Subscribe to brush events x or y
2358
- if ((((_t = this.config.brush) === null || _t === void 0 ? void 0 : _t.type) === BrushType.x &&
2359
- this.axis.orientation === AxisOrientation.x) ||
2360
- (((_u = this.config.brush) === null || _u === void 0 ? void 0 : _u.type) === BrushType.y &&
2361
- this.axis.orientation === AxisOrientation.y)) {
2362
- this.broadcastService.subscribeToBrush((_v = this.config) === null || _v === void 0 ? void 0 : _v.zoom.syncChannel)
2363
- .pipe(combineLatestWith(this.chartService.size), takeWhile((_) => this.alive), filter((data) => {
2364
- const [m] = data;
2365
- return Boolean(m.message.selection);
2366
- }), tap$1((data) => {
2367
- var _a, _b, _c, _d, _e, _f;
2368
- const [m] = data;
2369
- const currentTransform = d3.zoomTransform(this._element.node());
2370
- if (!m.message.event &&
2371
- this.currentSelection &&
2372
- currentTransform.k !== 1) {
2373
- return;
2374
- }
2375
- const s = m.message.selection;
2376
- this.brushScale.domain(this.axis.originDomain);
2377
- const domain = this.brushScale.domain();
2378
- const range = this.brushScale.range();
2379
- const scale = Math.abs(domain[1] - domain[0]) / Math.abs(s[1] - s[0]);
2380
- let transform = zoomIdentity.scale(scale);
2381
- if (((_a = m.message) === null || _a === void 0 ? void 0 : _a.brushType) === BrushType.x) {
2382
- this.brushScale.range([range[0], this.size.width]);
2383
- if ((_b = this.config.xAxis[0]) === null || _b === void 0 ? void 0 : _b.inverted) {
2384
- transform = transform.translate(-this.brushScale(s[0]), 0);
2385
- }
2386
- else {
2387
- transform = transform.translate(-this.brushScale(s[1]), 0);
2388
- }
2389
- }
2390
- if (((_c = m.message) === null || _c === void 0 ? void 0 : _c.brushType) === BrushType.y) {
2391
- this.brushScale.range([range[0], this.size.height]);
2392
- if ((_d = this.config.yAxis[0]) === null || _d === void 0 ? void 0 : _d.inverted) {
2393
- transform = transform.translate(0, -this.brushScale(s[0]));
2394
- }
2395
- else {
2396
- transform = transform.translate(0, -this.brushScale(s[1]));
2397
- }
2398
- }
2399
- if ((_f = (_e = m.message) === null || _e === void 0 ? void 0 : _e.style) === null || _f === void 0 ? void 0 : _f.transition) {
2400
- this._element.transition().call(this.zoom.transform, transform, null, {});
2401
- }
2402
- else {
2403
- this._element.call(this.zoom.transform, transform, null, {});
2404
- }
2405
- this.currentSelection = m.message.selection;
2406
- }))
2407
- .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();
2408
2109
  }
2409
2110
  }
2410
- ngOnDestroy() {
2411
- var _a, _b;
2412
- (_a = this.zoom) === null || _a === void 0 ? void 0 : _a.on('start zoom end', null);
2413
- (_b = this._element) === null || _b === void 0 ? void 0 : _b.on('wheel', null);
2414
- this.alive = false;
2415
- }
2416
- runWheelZoom() {
2111
+ runWheelTranslate() {
2417
2112
  let type = 'start';
2418
2113
  let wheeling;
2419
2114
  this.zoom
@@ -2429,48 +2124,38 @@ class ZoomableDirective {
2429
2124
  return delta * 0.002;
2430
2125
  });
2431
2126
  const emit = (type, event) => {
2432
- var _a, _b, _c, _d, _e, _f;
2433
- const origin = this.brushScale.copy().domain(this.axis.extremes);
2127
+ var _a;
2128
+ const origin = this.axis.scale.copy().domain(this.axis.originDomain);
2434
2129
  let transform = zoomIdentity;
2435
2130
  const delta = type === 'end'
2436
2131
  ? 0
2437
- : ((_a = this.config.zoom) === null || _a === void 0 ? void 0 : _a.type) === ZoomType.y
2132
+ : this.axis.orientation === AxisOrientation.y
2438
2133
  ? event.deltaY
2439
2134
  : event.deltaX;
2440
- if (((_b = this.config.zoom) === null || _b === void 0 ? void 0 : _b.type) === ZoomType.y) {
2135
+ if (this.axis.orientation === AxisOrientation.y) {
2441
2136
  transform = transform.translate(0, this.currentTransform.y - delta / 2);
2442
2137
  }
2443
- if (((_c = this.config.zoom) === null || _c === void 0 ? void 0 : _c.type) === ZoomType.x) {
2138
+ if (this.axis.orientation === AxisOrientation.x) {
2444
2139
  transform = transform.translate(this.currentTransform.x - delta / 2, 0);
2445
2140
  }
2446
2141
  transform = transform.scale(this.currentTransform.k);
2447
- let domain = ((_d = this.config.zoom) === null || _d === void 0 ? void 0 : _d.type) === ZoomType.y
2142
+ let domain = this.axis.orientation === AxisOrientation.y
2448
2143
  ? transform.rescaleY(origin).domain()
2449
2144
  : transform.rescaleX(origin).domain();
2450
2145
  const message = new ZoomMessage({
2451
- event: {
2452
- sourceEvent: event,
2453
- transform,
2454
- type,
2146
+ eventType: type,
2147
+ element: this.elementRef,
2148
+ axis: {
2149
+ index: this.axis.index,
2150
+ orientation: this.axis.orientation
2455
2151
  },
2456
- axis: this.axis,
2457
2152
  domain,
2458
2153
  chartId: this.config.id,
2459
2154
  });
2460
- this.zoomService.fireZoom({
2461
- event: {
2462
- sourceEvent: event,
2463
- transform,
2464
- type,
2465
- },
2466
- target: this.axis,
2467
- });
2468
- 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);
2469
2158
  this.currentTransform = transform;
2470
- this.broadcastService.broadcastZoom({
2471
- channel: (_f = (_e = this.config) === null || _e === void 0 ? void 0 : _e.zoom) === null || _f === void 0 ? void 0 : _f.syncChannel,
2472
- message,
2473
- });
2474
2159
  };
2475
2160
  this._element.on('wheel', (event) => {
2476
2161
  event.preventDefault();
@@ -2489,23 +2174,19 @@ class ZoomableDirective {
2489
2174
  });
2490
2175
  }
2491
2176
  }
2492
- 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 });
2493
- 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 });
2494
2179
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: ZoomableDirective, decorators: [{
2495
2180
  type: Directive,
2496
2181
  args: [{
2497
2182
  selector: '[tetaZoomable]',
2498
2183
  }]
2499
- }], 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: [{
2500
2185
  type: Input
2501
2186
  }], axis: [{
2502
2187
  type: Input
2503
2188
  }], size: [{
2504
2189
  type: Input
2505
- }], brushScale: [{
2506
- type: Input
2507
- }], scale: [{
2508
- type: Input
2509
2190
  }], zoomable: [{
2510
2191
  type: HostBinding,
2511
2192
  args: ['class.zoomable']
@@ -2515,33 +2196,141 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImpor
2515
2196
  }] } });
2516
2197
 
2517
2198
  class BrushableDirective {
2518
- constructor(brushService, chartService, element) {
2199
+ constructor(brushService, chartService, element, zone) {
2519
2200
  this.brushService = brushService;
2520
2201
  this.chartService = chartService;
2521
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() {
2522
2222
  }
2523
- ngOnInit() { }
2524
- ngAfterViewInit() { }
2525
2223
  ngOnChanges(changes) {
2526
2224
  var _a, _b;
2527
2225
  if (changes.hasOwnProperty('config')) {
2528
- this.brushService.clearPreviousSelection();
2226
+ this.clearPreviousSelection();
2529
2227
  }
2530
2228
  if ((_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.brush) === null || _b === void 0 ? void 0 : _b.enable) {
2531
- 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
+ });
2532
2318
  }
2533
2319
  }
2320
+ clearPreviousSelection() {
2321
+ this.selection = null;
2322
+ }
2534
2323
  }
2535
- 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 });
2536
- 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 });
2537
2326
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: BrushableDirective, decorators: [{
2538
2327
  type: Directive,
2539
2328
  args: [{
2540
2329
  selector: '[tetaBrushable]',
2541
2330
  }]
2542
- }], 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: [{
2543
2332
  type: Input
2544
- }], brushScale: [{
2333
+ }], axis: [{
2545
2334
  type: Input
2546
2335
  }] } });
2547
2336
 
@@ -2627,7 +2416,6 @@ class CrosshairComponent {
2627
2416
  this.transform = this.chartService.pointerMove.pipe(map((event) => {
2628
2417
  const composedPath = event.composedPath();
2629
2418
  const classes = composedPath.map((_) => { var _a; return (_a = _.classList) === null || _a === void 0 ? void 0 : _a.contains('crosshair'); }).filter((_) => _);
2630
- console.log(classes);
2631
2419
  return {
2632
2420
  x: event.type === 'mouseleave' ? -9999 : event.offsetX,
2633
2421
  y: event.type === 'mouseleave' ? -9999 : event.offsetY
@@ -2807,10 +2595,10 @@ class ChartContainerComponent {
2807
2595
  }
2808
2596
  }
2809
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 });
2810
- 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 });
2811
2599
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: ChartContainerComponent, decorators: [{
2812
2600
  type: Component,
2813
- 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"] }]
2814
2602
  }], ctorParameters: function () { return [{ type: ChartService }, { type: i0.ChangeDetectorRef }, { type: ScaleService }, { type: ZoomService }, { type: i0.ElementRef }, { type: i0.NgZone }]; } });
2815
2603
 
2816
2604
  class LegendComponent {
@@ -2846,9 +2634,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImpor
2846
2634
  }] } });
2847
2635
 
2848
2636
  class ChartComponent {
2849
- constructor(chartService, zoomService, scaleService) {
2637
+ constructor(chartService, zoomService, brushService, scaleService) {
2850
2638
  this.chartService = chartService;
2851
2639
  this.zoomService = zoomService;
2640
+ this.brushService = brushService;
2852
2641
  this.scaleService = scaleService;
2853
2642
  this.pointerMove = new EventEmitter();
2854
2643
  this.plotBandsMove = new EventEmitter();
@@ -2862,16 +2651,21 @@ class ChartComponent {
2862
2651
  this.annotationClick = new EventEmitter();
2863
2652
  this.annotationMove = new EventEmitter();
2864
2653
  this.zoomServiceInstance = new EventEmitter();
2654
+ this.brushServiceInstance = new EventEmitter();
2865
2655
  this._alive = true;
2866
2656
  this.svcConfig = this.chartService.config;
2867
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; })); }));
2868
2658
  }
2869
2659
  set config(config) {
2660
+ var _a;
2870
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);
2871
2663
  }
2872
2664
  ngOnChanges(changes) {
2873
2665
  }
2874
2666
  ngOnInit() {
2667
+ this.zoomServiceInstance.emit(this.zoomService);
2668
+ this.brushServiceInstance.emit(this.brushService);
2875
2669
  this.chartService.pointerMove
2876
2670
  .pipe(takeWhile(() => this._alive), withLatestFrom(this.scaleService.scales, this.chartService.config))
2877
2671
  .subscribe((data) => {
@@ -2943,28 +2737,19 @@ class ChartComponent {
2943
2737
  .subscribe((_) => {
2944
2738
  this.annotationMove.emit(_);
2945
2739
  });
2946
- this.chartService.zoomInstance
2947
- .pipe(takeWhile(() => this._alive))
2948
- .subscribe((_) => {
2949
- this.zoomServiceInstance.emit(_);
2950
- });
2951
2740
  }
2952
2741
  ngAfterViewInit() {
2953
2742
  }
2954
2743
  ngOnDestroy() {
2955
- var _a;
2956
2744
  this._alive = false;
2957
- (_a = this.zoomService.broadcastSubscription) === null || _a === void 0 ? void 0 : _a.forEach((sub) => {
2958
- sub.unsubscribe();
2959
- });
2960
2745
  }
2961
2746
  }
2962
- 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 });
2963
- 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 });
2964
2749
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: ChartComponent, decorators: [{
2965
2750
  type: Component,
2966
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"] }]
2967
- }], 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: [{
2968
2753
  type: Output
2969
2754
  }], plotBandsMove: [{
2970
2755
  type: Output
@@ -2988,6 +2773,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImpor
2988
2773
  type: Output
2989
2774
  }], zoomServiceInstance: [{
2990
2775
  type: Output
2776
+ }], brushServiceInstance: [{
2777
+ type: Output
2991
2778
  }], config: [{
2992
2779
  type: Input
2993
2780
  }] } });