@devexperts/dxcharts-lite 2.7.28 → 2.7.29

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.
@@ -161,7 +161,7 @@ export default class ChartBootstrap {
161
161
  this.canvasBoundsContainer.setMainCandleSeries(this.chartModel.mainCandleSeries);
162
162
  hitTestCanvasModel.addSubscriber(paneManager.hitTestController);
163
163
  // X-axis component
164
- this.xAxisComponent = new XAxisComponent(eventBus, config, mainCanvasModel, chartComponent, scaleModel, canvasBoundsContainer, canvasInputListener, chartResizeHandler, this.drawingManager, timeZoneModel, chartPanComponent, this.cursorHandler, this.hitTestCanvasModel);
164
+ this.xAxisComponent = new XAxisComponent(eventBus, config, mainCanvasModel, chartComponent, scaleModel, canvasBoundsContainer, canvasInputListener, chartResizeHandler, this.drawingManager, timeZoneModel, chartPanComponent, this.cursorHandler, this.hitTestCanvasModel, this.mainPane.yAxis);
165
165
  this.chartComponents.push(this.xAxisComponent);
166
166
  this.userInputListenerComponents.push(this.xAxisComponent.xAxisScaleHandler);
167
167
  const mainCanvasClearDrawer = new ClearCanvasDrawer(mainCanvasModel);
@@ -10,6 +10,7 @@ import EventBus from '../../events/event-bus';
10
10
  import { CanvasInputListenerComponent, Point } from '../../inputlisteners/canvas-input-listener.component';
11
11
  import { ChartBaseElement } from '../../model/chart-base-element';
12
12
  import { ScaleModel } from '../../model/scale.model';
13
+ import { DragNDropXComponent } from '../dran-n-drop_helper/drag-n-drop-x.component';
13
14
  import { DragNDropYComponent } from '../dran-n-drop_helper/drag-n-drop-y.component';
14
15
  import { DragInfo } from '../dran-n-drop_helper/drag-n-drop.component';
15
16
  import { ChartPanComponent } from '../pan/chart-pan.component';
@@ -53,7 +54,12 @@ export declare class ChartAreaPanHandler extends ChartBaseElement {
53
54
  lastXStart: number;
54
55
  wheelThrottleTime: number;
55
56
  chartPanningOptions: ChartPanningOptions;
57
+ dragNDropXComponent: DragNDropXComponent;
56
58
  constructor(bus: EventBus, config: FullChartConfig, scale: ScaleModel, canvasInputListener: CanvasInputListenerComponent, canvasBoundsContainer: CanvasBoundsContainer, canvasAnimation: CanvasAnimation, chartPanComponent: ChartPanComponent, hitTestCanvasModel: HitTestCanvasModel);
59
+ /**
60
+ * Throttles chart-area horizontal drag to one animation frame when needed (percent Y-axis).
61
+ */
62
+ setChartAreaXDragThrottled(shouldThrottle: boolean): void;
57
63
  /**
58
64
  * It observes the wheel event on all panes of the canvas and throttles it to the specified time.
59
65
  * It then calculates the zoom sensitivity based on whether the event was triggered by a touchpad or not.
@@ -99,16 +99,22 @@ export class ChartAreaPanHandler extends ChartBaseElement {
99
99
  };
100
100
  const allPanesHitTest = this.canvasBoundsContainer.getBoundsHitTest(CanvasElement.ALL_PANES);
101
101
  //#region drag-n-drop logic
102
- const dragNDropXComponent = new DragNDropXComponent(allPanesHitTest, {
102
+ this.dragNDropXComponent = new DragNDropXComponent(allPanesHitTest, {
103
103
  onDragStart: this.onXDragStart,
104
104
  onDragTick: this.onXDragTick,
105
105
  onDragEnd: this.onXDragEnd,
106
106
  }, this.canvasInputListener, this.chartPanComponent, {
107
107
  dragPredicate: () => this.chartPanningOptions.horizontal,
108
- });
109
- this.addChildEntity(dragNDropXComponent);
108
+ }, this.config.components.yAxis.type === 'percent');
109
+ this.addChildEntity(this.dragNDropXComponent);
110
110
  //#endregion
111
111
  }
112
+ /**
113
+ * Throttles chart-area horizontal drag to one animation frame when needed (percent Y-axis).
114
+ */
115
+ setChartAreaXDragThrottled(shouldThrottle) {
116
+ this.dragNDropXComponent.setShouldThrottle(shouldThrottle);
117
+ }
112
118
  /**
113
119
  * This method is used to activate the zoom functionality of the canvas. It extends the doActivate method of the parent class.
114
120
  * @protected
@@ -8,7 +8,12 @@ import { CanvasInputListenerComponent } from '../../inputlisteners/canvas-input-
8
8
  import { ChartPanComponent } from '../pan/chart-pan.component';
9
9
  import { DragComponentOptions, DragNDropComponent, DragNDropComponentCallbacks } from './drag-n-drop.component';
10
10
  export declare class DragNDropXComponent extends DragNDropComponent {
11
- constructor(hitTest: HitBoundsTest, dragCallbacks: DragNDropComponentCallbacks, canvasInputListener: CanvasInputListenerComponent, chartPanComponent: ChartPanComponent, dragComponentOptions?: DragComponentOptions);
11
+ private shouldThrottleSubject;
12
+ constructor(hitTest: HitBoundsTest, dragCallbacks: DragNDropComponentCallbacks, canvasInputListener: CanvasInputListenerComponent, chartPanComponent: ChartPanComponent, dragComponentOptions?: DragComponentOptions, shouldThrottle?: boolean);
13
+ /**
14
+ * When true, X drag ticks are throttled to one animation frame (e.g. percent axis).
15
+ */
16
+ setShouldThrottle(value: boolean): void;
12
17
  /**
13
18
  * This method is used to activate the component and add the necessary subscriptions to the canvasInputListener.
14
19
  * It calls the super method doActivate() and then adds the following subscriptions:
@@ -3,10 +3,25 @@
3
3
  * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
4
4
  * If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
5
5
  */
6
+ /*
7
+ * Copyright (C) 2019 - 2024 Devexperts Solutions IE Limited
8
+ * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
9
+ * If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
10
+ */
11
+ import { animationFrameScheduler, BehaviorSubject, identity } from 'rxjs';
12
+ import { distinctUntilChanged, switchMap, throttleTime } from 'rxjs/operators';
6
13
  import { defaultDragComponentOptions, DragNDropComponent, } from './drag-n-drop.component';
14
+ import { ONE_FRAME_MS } from '../../utils/numeric-constants.utils';
7
15
  export class DragNDropXComponent extends DragNDropComponent {
8
- constructor(hitTest, dragCallbacks, canvasInputListener, chartPanComponent, dragComponentOptions = defaultDragComponentOptions) {
16
+ constructor(hitTest, dragCallbacks, canvasInputListener, chartPanComponent, dragComponentOptions = defaultDragComponentOptions, shouldThrottle) {
9
17
  super(hitTest, dragCallbacks, canvasInputListener, chartPanComponent, dragComponentOptions);
18
+ this.shouldThrottleSubject = new BehaviorSubject(!!shouldThrottle);
19
+ }
20
+ /**
21
+ * When true, X drag ticks are throttled to one animation frame (e.g. percent axis).
22
+ */
23
+ setShouldThrottle(value) {
24
+ this.shouldThrottleSubject.next(value);
10
25
  }
11
26
  /**
12
27
  * This method is used to activate the component and add the necessary subscriptions to the canvasInputListener.
@@ -17,9 +32,17 @@ export class DragNDropXComponent extends DragNDropComponent {
17
32
  * @returns {void}
18
33
  */
19
34
  doActivate() {
35
+ const dragThrottleTime = ONE_FRAME_MS;
20
36
  super.doActivate();
21
37
  this.addRxSubscription(this.canvasInputListener.observeXDragStart(this.hitTest).subscribe(this.onDragStart));
22
- this.addRxSubscription(this.canvasInputListener.observeXDrag().subscribe(this.onDragTick));
38
+ this.addRxSubscription(this.shouldThrottleSubject
39
+ .pipe(distinctUntilChanged(), switchMap(shouldThrottle => this.canvasInputListener.observeXDrag().pipe(shouldThrottle
40
+ ? throttleTime(dragThrottleTime, animationFrameScheduler, {
41
+ trailing: true,
42
+ leading: true,
43
+ })
44
+ : identity)))
45
+ .subscribe(this.onDragTick));
23
46
  this.addRxSubscription(this.canvasInputListener.observeXDragEnd().subscribe(this.onDragEnd));
24
47
  }
25
48
  }
@@ -4,8 +4,8 @@
4
4
  * If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
5
5
  */
6
6
  import { Subject } from 'rxjs';
7
- import { distinctUntilChanged } from 'rxjs/operators';
8
- import { areBoundsChanged, CanvasElement, } from '../../canvas/canvas-bounds-container';
7
+ import { distinctUntilChanged, map, startWith } from 'rxjs/operators';
8
+ import { areBoundsChanged, CHART_UUID, CanvasElement, } from '../../canvas/canvas-bounds-container';
9
9
  import { ChartBaseElement } from '../../model/chart-base-element';
10
10
  import { SyncedByXScaleModel } from '../../model/scale.model';
11
11
  import { firstOf, flatMap, lastOf } from '../../utils/array.utils';
@@ -80,6 +80,13 @@ export class PaneComponent extends ChartBaseElement {
80
80
  this.yExtentComponents.forEach(c => c.scale.recalculateZoomY());
81
81
  this.dynamicObjectsCanvasModel.fireDraw();
82
82
  }));
83
+ if (this.uuid === CHART_UUID) {
84
+ this.addRxSubscription(this.yAxis.axisTypeSetSubject
85
+ .pipe(startWith(this.yAxis.getAxisType()), distinctUntilChanged(), map((axisType) => axisType === 'percent'))
86
+ .subscribe(shouldThrottle => {
87
+ this.chartPanComponent.chartAreaPanHandler.setChartAreaXDragThrottled(shouldThrottle);
88
+ }));
89
+ }
83
90
  }
84
91
  toY(price) {
85
92
  var _a, _b;
@@ -9,6 +9,7 @@ import { CanvasInputListenerComponent } from '../../inputlisteners/canvas-input-
9
9
  import { ScaleModel } from '../../model/scale.model';
10
10
  import { Pixel, Unit } from '../../model/scaling/viewport.model';
11
11
  import { ChartModel } from '../chart/chart.model';
12
+ import { DragNDropXComponent } from '../dran-n-drop_helper/drag-n-drop-x.component';
12
13
  import { ChartPanComponent } from '../pan/chart-pan.component';
13
14
  import { HitTestCanvasModel } from '../../model/hit-test-canvas.model';
14
15
  /**
@@ -30,7 +31,12 @@ export declare class XAxisScaleHandler extends ChartBaseElement {
30
31
  private dblClickCallback;
31
32
  private touches;
32
33
  private dblTapCallback;
34
+ dragNDropXComponent: DragNDropXComponent;
33
35
  constructor(scale: ScaleModel, canvasInputListener: CanvasInputListenerComponent, canvasBoundsContainer: CanvasBoundsContainer, chartPanComponent: ChartPanComponent, chartModel: ChartModel, hitTest: HitBoundsTest, hitTestCanvasModel: HitTestCanvasModel);
36
+ /**
37
+ * Throttles chart-area horizontal drag to one animation frame when needed (percent Y-axis).
38
+ */
39
+ setChartAreaXDragThrottled(shouldThrottle: boolean): void;
34
40
  /**
35
41
  * This method is used to activate the canvas input listener and add a subscription to it.
36
42
  * It calls the parent class's doActivate method and then subscribes to the canvasInputListener's observeDbClick method.
@@ -85,14 +85,22 @@ export class XAxisScaleHandler extends ChartBaseElement {
85
85
  this.setDblClickCallback = (cb) => (this.dblClickCallback = cb);
86
86
  this.dblClickCallback = () => chartModel.doBasicScale();
87
87
  this.dblTapCallback = () => chartModel.doBasicScale();
88
- const dragNDropXComponent = new DragNDropXComponent(hitTest, {
88
+ //#region drag-n-drop logic
89
+ this.dragNDropXComponent = new DragNDropXComponent(hitTest, {
89
90
  onDragStart: this.onXDragStart,
90
91
  onDragTick: this.onXDragTick,
91
92
  onDragEnd: this.onXDragEnd,
92
93
  }, this.canvasInputListener, this.chartPanComponent, {
93
94
  dragPredicate: () => chartPanComponent.chartAreaPanHandler.chartPanningOptions.horizontal,
94
95
  });
95
- this.addChildEntity(dragNDropXComponent);
96
+ this.addChildEntity(this.dragNDropXComponent);
97
+ //#endregion
98
+ }
99
+ /**
100
+ * Throttles chart-area horizontal drag to one animation frame when needed (percent Y-axis).
101
+ */
102
+ setChartAreaXDragThrottled(shouldThrottle) {
103
+ this.dragNDropXComponent.setShouldThrottle(shouldThrottle);
96
104
  }
97
105
  /**
98
106
  * This method is used to activate the canvas input listener and add a subscription to it.
@@ -23,6 +23,7 @@ import { XAxisLabelsModel, XAxisLabelsProvider } from './x-axis-labels.model';
23
23
  import { XAxisScaleHandler } from './x-axis-scale.handler';
24
24
  import { XAxisTimeLabelsDrawer } from './x-axis-time-labels.drawer';
25
25
  import { HitTestCanvasModel } from '../../model/hit-test-canvas.model';
26
+ import { YAxisComponent } from '../y_axis/y-axis.component';
26
27
  /**
27
28
  * X-axis component, contains all x-axis calculation and rendering logic.
28
29
  */
@@ -34,12 +35,13 @@ export declare class XAxisComponent extends ChartBaseElement {
34
35
  private scale;
35
36
  private chartResizeHandler;
36
37
  private timeZoneModel;
38
+ private yAxis;
37
39
  xAxisDrawer: XAxisTimeLabelsDrawer;
38
40
  xAxisLabelsDrawer: XAxisLabelsDrawer;
39
41
  xAxisLabelsGenerator: XAxisLabelsGenerator;
40
42
  readonly xAxisLabelsModel: XAxisLabelsModel;
41
43
  xAxisScaleHandler: XAxisScaleHandler;
42
- constructor(eventBus: EventBus, config: FullChartConfig, canvasModel: CanvasModel, chartComponent: ChartComponent, scale: ScaleModel, canvasBoundsContainer: CanvasBoundsContainer, canvasInputListener: CanvasInputListenerComponent, chartResizeHandler: ChartResizeHandler, drawingManager: DrawingManager, timeZoneModel: TimeZoneModel, chartPanComponent: ChartPanComponent, cursorHandler: CursorHandler, hitTestCanvasModel: HitTestCanvasModel);
44
+ constructor(eventBus: EventBus, config: FullChartConfig, canvasModel: CanvasModel, chartComponent: ChartComponent, scale: ScaleModel, canvasBoundsContainer: CanvasBoundsContainer, canvasInputListener: CanvasInputListenerComponent, chartResizeHandler: ChartResizeHandler, drawingManager: DrawingManager, timeZoneModel: TimeZoneModel, chartPanComponent: ChartPanComponent, cursorHandler: CursorHandler, hitTestCanvasModel: HitTestCanvasModel, yAxis: YAxisComponent);
43
45
  /**
44
46
  * This method is used to activate the chart and update the labels if there is a new data set or equivolume type.
45
47
  * It subscribes to the chart type change, candles set subject, candles updated subject, and time zone change to generate new labels.
@@ -4,7 +4,7 @@
4
4
  * If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
5
5
  */
6
6
  import { merge, animationFrameScheduler } from 'rxjs';
7
- import { distinctUntilChanged, map, throttleTime, filter } from 'rxjs/operators';
7
+ import { distinctUntilChanged, map, throttleTime, filter, startWith } from 'rxjs/operators';
8
8
  import { CanvasElement } from '../../canvas/canvas-bounds-container';
9
9
  import { ChartBaseElement } from '../../model/chart-base-element';
10
10
  import { CompositeDrawer } from '../../drawers/composite.drawer';
@@ -20,7 +20,7 @@ import { availableBarTypes } from '../../chart.config';
20
20
  * X-axis component, contains all x-axis calculation and rendering logic.
21
21
  */
22
22
  export class XAxisComponent extends ChartBaseElement {
23
- constructor(eventBus, config, canvasModel, chartComponent, scale, canvasBoundsContainer, canvasInputListener, chartResizeHandler, drawingManager, timeZoneModel, chartPanComponent, cursorHandler, hitTestCanvasModel) {
23
+ constructor(eventBus, config, canvasModel, chartComponent, scale, canvasBoundsContainer, canvasInputListener, chartResizeHandler, drawingManager, timeZoneModel, chartPanComponent, cursorHandler, hitTestCanvasModel, yAxis) {
24
24
  super();
25
25
  this.eventBus = eventBus;
26
26
  this.config = config;
@@ -29,6 +29,7 @@ export class XAxisComponent extends ChartBaseElement {
29
29
  this.scale = scale;
30
30
  this.chartResizeHandler = chartResizeHandler;
31
31
  this.timeZoneModel = timeZoneModel;
32
+ this.yAxis = yAxis;
32
33
  /* This function assigns a callback to be executed when a double-click event is detected.
33
34
  * It accepts one parameter `cb`, which is a callback function.
34
35
  * When a double-click event occurs, the specified callback function `cb` will be invoked.
@@ -91,6 +92,11 @@ export class XAxisComponent extends ChartBaseElement {
91
92
  this.addRxSubscription(this.chartComponent.chartModel.candlesUpdatedSubject
92
93
  .pipe(map(() => lastOf(this.chartComponent.chartModel.mainCandleSeries.visualPoints)), distinctUntilChanged((a, b) => { var _a, _b; return ((_a = a === null || a === void 0 ? void 0 : a.candle) === null || _a === void 0 ? void 0 : _a.id) === ((_b = b === null || b === void 0 ? void 0 : b.candle) === null || _b === void 0 ? void 0 : _b.id); }), filter(notEmpty))
93
94
  .subscribe(x => { var _a, _b; return (_b = (_a = this.xAxisLabelsGenerator) === null || _a === void 0 ? void 0 : _a.updateLastLabel) === null || _b === void 0 ? void 0 : _b.call(_a, x); }));
95
+ this.addRxSubscription(this.yAxis.axisTypeSetSubject
96
+ .pipe(startWith(this.yAxis.getAxisType()), distinctUntilChanged(), map((axisType) => axisType === 'percent'))
97
+ .subscribe(shouldThrottle => {
98
+ this.xAxisScaleHandler.setChartAreaXDragThrottled(shouldThrottle);
99
+ }));
94
100
  }
95
101
  /**
96
102
  * Returns the xAxisDrawer object.