@devexperts/dxcharts-lite 2.7.15 → 2.7.17

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 (54) hide show
  1. package/dist/chart/animation/canvas-animation.d.ts +1 -0
  2. package/dist/chart/animation/canvas-animation.js +2 -1
  3. package/dist/chart/animation/viewport-model-animation.d.ts +4 -1
  4. package/dist/chart/animation/viewport-model-animation.js +21 -3
  5. package/dist/chart/bootstrap.js +17 -5
  6. package/dist/chart/chart.config.js +1 -1
  7. package/dist/chart/components/chart/chart-area-pan.handler.d.ts +16 -16
  8. package/dist/chart/components/chart/chart-area-pan.handler.js +8 -2
  9. package/dist/chart/components/chart/chart.component.js +2 -0
  10. package/dist/chart/components/chart/chart.model.d.ts +11 -0
  11. package/dist/chart/components/chart/chart.model.js +20 -0
  12. package/dist/chart/components/chart/price-formatters/__tests__/treasury-price.formatter.test.d.ts +6 -0
  13. package/dist/chart/components/chart/price-formatters/__tests__/treasury-price.formatter.test.js +94 -0
  14. package/dist/chart/components/chart/price-formatters/treasury-price.formatter.d.ts +9 -0
  15. package/dist/chart/components/chart/price-formatters/treasury-price.formatter.js +22 -1
  16. package/dist/chart/components/cross_tool/cross-tool.component.d.ts +3 -1
  17. package/dist/chart/components/cross_tool/cross-tool.component.js +3 -2
  18. package/dist/chart/components/cross_tool/cross-tool.model.d.ts +6 -3
  19. package/dist/chart/components/cross_tool/cross-tool.model.js +9 -5
  20. package/dist/chart/components/grid/grid.component.d.ts +1 -1
  21. package/dist/chart/components/grid/grid.component.js +2 -2
  22. package/dist/chart/components/grid/grid.drawer.d.ts +2 -1
  23. package/dist/chart/components/grid/grid.drawer.js +3 -2
  24. package/dist/chart/components/pan/chart-pan.component.js +17 -1
  25. package/dist/chart/components/pane/pane.component.js +3 -1
  26. package/dist/chart/drawers/data-series-drawers/trend-points.drawer.d.ts +12 -0
  27. package/dist/chart/drawers/data-series-drawers/trend-points.drawer.js +70 -0
  28. package/dist/chart/drawers/drawing-manager.js +0 -1
  29. package/dist/chart/inputhandlers/chart-resize.handler.d.ts +5 -0
  30. package/dist/chart/inputhandlers/chart-resize.handler.js +9 -1
  31. package/dist/chart/inputlisteners/canvas-input-listener.component.d.ts +28 -0
  32. package/dist/chart/inputlisteners/canvas-input-listener.component.js +104 -7
  33. package/dist/chart/model/data-series.config.d.ts +1 -1
  34. package/dist/chart/model/hit-test-canvas.model.d.ts +15 -13
  35. package/dist/chart/model/hit-test-canvas.model.js +2 -2
  36. package/dist/chart/model/scale.model.d.ts +5 -0
  37. package/dist/chart/model/scale.model.js +72 -6
  38. package/dist/chart/utils/device/touchpad.utils.d.ts +1 -0
  39. package/dist/chart/utils/device/touchpad.utils.js +1 -1
  40. package/dist/chart/utils/math.utils.js +1 -1
  41. package/dist/chart/utils/performance/queue-microtask.utils.d.ts +5 -0
  42. package/dist/chart/utils/performance/queue-microtask.utils.js +12 -0
  43. package/dist/chart/utils/performance/request-animation-frame-throttle.utils.d.ts +1 -0
  44. package/dist/chart/utils/performance/request-animation-frame-throttle.utils.js +3 -0
  45. package/dist/chart/utils/performance/safari/components/animations/safari-canvas-animation.d.ts +77 -0
  46. package/dist/chart/utils/performance/safari/components/animations/safari-canvas-animation.js +137 -0
  47. package/dist/chart/utils/performance/safari/components/chart-area-pan.handler/safari-chart-area-pan.handler.d.ts +54 -0
  48. package/dist/chart/utils/performance/safari/components/chart-area-pan.handler/safari-chart-area-pan.handler.js +180 -0
  49. package/dist/chart/utils/performance/safari/safari-performance.model.d.ts +32 -0
  50. package/dist/chart/utils/performance/safari/safari-performance.model.js +31 -0
  51. package/dist/chart/utils/performance/safari/safari-performance.utils.d.ts +18 -0
  52. package/dist/chart/utils/performance/safari/safari-performance.utils.js +34 -0
  53. package/dist/dxchart.min.js +4 -4
  54. package/package.json +2 -2
@@ -4,13 +4,20 @@
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 { startViewportModelAnimation } from '../animation/viewport-model-animation';
7
+ import { throttleTime } from 'rxjs/operators';
8
+ import { animationFrameScheduler } from 'rxjs';
8
9
  import { cloneUnsafe } from '../utils/object.utils';
9
10
  import { AutoScaleViewportSubModel } from './scaling/auto-scale.model';
10
11
  import { changeXToKeepRatio, changeYToKeepRatio } from './scaling/lock-ratio.model';
11
12
  import { moveXStart, moveYStart } from './scaling/move-chart.functions';
12
13
  import { ViewportModel, calculateZoom, compareStates, } from './scaling/viewport.model';
13
14
  import { zoomXToEndViewportCalculator, zoomXToPercentViewportCalculator } from './scaling/x-zooming.functions';
15
+ import { VIEWPORT_ANIMATION_ID } from '../animation/canvas-animation';
16
+ import { startViewportModelAnimation, startViewportModelAnimationSafari } from '../animation/viewport-model-animation';
17
+ import { ONE_FRAME_MS } from '../utils/numeric-constants.utils';
18
+ import { isSafari } from '../utils/device/touchpad.utils';
19
+ const autoScaleZoomSubject = new Subject();
20
+ const autoScalePanSubject = new Subject();
14
21
  export const getDefaultHighLowWithIndex = () => ({
15
22
  high: Number.NEGATIVE_INFINITY,
16
23
  low: Number.POSITIVE_INFINITY,
@@ -40,6 +47,8 @@ export class ScaleModel extends ViewportModel {
40
47
  // TODO rework, make a new history based on units
41
48
  this.history = [];
42
49
  this.xConstraints = [];
50
+ this.autoScaleZoomSubscription = null;
51
+ this.autoScalePanSubscription = null;
43
52
  this.scalePostProcessor = (initialState, state) => {
44
53
  // for now <s>reduceRight<s/> reduce bcs ChartModel#getZoomConstrait should be invoked first
45
54
  // if we will need more complex order handling -> add some managing
@@ -48,6 +57,7 @@ export class ScaleModel extends ViewportModel {
48
57
  this.state = cloneUnsafe(config.scale);
49
58
  this.autoScaleModel = new AutoScaleViewportSubModel(this);
50
59
  this.offsets = this.config.components.offsets;
60
+ this.initAutoScaleThrottling();
51
61
  }
52
62
  doActivate() {
53
63
  super.doActivate();
@@ -59,6 +69,15 @@ export class ScaleModel extends ViewportModel {
59
69
  }));
60
70
  }
61
71
  doDeactivate() {
72
+ // Clean up auto-scale throttling subscriptions to prevent memory leaks
73
+ if (this.autoScaleZoomSubscription) {
74
+ this.autoScaleZoomSubscription.unsubscribe();
75
+ this.autoScaleZoomSubscription = null;
76
+ }
77
+ if (this.autoScalePanSubscription) {
78
+ this.autoScalePanSubscription.unsubscribe();
79
+ this.autoScalePanSubscription = null;
80
+ }
62
81
  super.doDeactivate();
63
82
  this.scaleInversedSubject.complete();
64
83
  this.beforeStartAnimationSubject.complete();
@@ -119,8 +138,13 @@ export class ScaleModel extends ViewportModel {
119
138
  }
120
139
  haltAnimation() {
121
140
  var _a;
141
+ // Stop current animation if it exists
122
142
  if ((_a = this.currentAnimation) === null || _a === void 0 ? void 0 : _a.animationInProgress) {
123
143
  this.currentAnimation.finishAnimation();
144
+ // Clear the current animation reference
145
+ this.currentAnimation = undefined;
146
+ // CRITICAL: Force stop all viewport animations in the animation system to prevent accumulation
147
+ this.canvasAnimation.forceStopAnimation(VIEWPORT_ANIMATION_ID);
124
148
  this.doAutoScale();
125
149
  }
126
150
  }
@@ -196,9 +220,27 @@ export class ScaleModel extends ViewportModel {
196
220
  }
197
221
  else {
198
222
  (_a = this.currentAnimation) === null || _a === void 0 ? void 0 : _a.tick();
199
- startViewportModelAnimation(this.canvasAnimation, this, constrainedState);
223
+ // Big profit in performance for safari
224
+ isSafari
225
+ ? startViewportModelAnimationSafari(this.canvasAnimation, this, constrainedState, this.state.auto ? this.autoScaleModel : undefined)
226
+ : startViewportModelAnimation(this.canvasAnimation, this, constrainedState);
200
227
  }
201
228
  }
229
+ setXScaleWithoutYScale(visualCandleSource) {
230
+ var _a;
231
+ const initialStateCopy = this.export();
232
+ const vCandles = visualCandleSource.slice(Math.max(visualCandleSource.length - this.state.defaultViewportItems, 0));
233
+ const endCandle = vCandles[vCandles.length - 1];
234
+ const xEnd = endCandle.startUnit + endCandle.width + this.offsets.right;
235
+ const xStart = xEnd - (this.getBounds().width * this.zoomX);
236
+ const state = Object.assign(Object.assign({}, initialStateCopy), { xStart, xEnd });
237
+ const constrainedState = this.scalePostProcessor(initialStateCopy, state);
238
+ if (this.state.auto) {
239
+ this.autoScaleModel.doAutoYScale(constrainedState);
240
+ }
241
+ (_a = this.currentAnimation) === null || _a === void 0 ? void 0 : _a.tick();
242
+ startViewportModelAnimation(this.canvasAnimation, this, constrainedState);
243
+ }
202
244
  setYScale(yStart, yEnd, fire = false) {
203
245
  const initialState = this.export();
204
246
  if (initialState.yStart === yStart && initialState.yEnd === yEnd && initialState.zoomY > 0) {
@@ -238,15 +280,19 @@ export class ScaleModel extends ViewportModel {
238
280
  moveXStart(xStart) {
239
281
  const state = this.export();
240
282
  const initialStateCopy = Object.assign({}, state);
241
- // always stop the animations
242
283
  this.haltAnimation();
243
284
  moveXStart(state, xStart);
244
285
  // there we need only candles constraint
245
286
  const constrainedState = this.scalePostProcessor(initialStateCopy, state);
246
- if (this.state.auto) {
247
- this.autoScaleModel.doAutoYScale(constrainedState);
287
+ if (isSafari) {
288
+ startViewportModelAnimationSafari(this.canvasAnimation, this, constrainedState, this.state.auto ? this.autoScaleModel : undefined);
289
+ }
290
+ else {
291
+ if (this.state.auto) {
292
+ this.autoScaleModel.doAutoYScale(constrainedState);
293
+ }
294
+ this.apply(constrainedState);
248
295
  }
249
- this.apply(constrainedState);
250
296
  }
251
297
  /**
252
298
  * Moves both yStart and yEnd without changing the viewport height (zoom).
@@ -358,6 +404,26 @@ export class ScaleModel extends ViewportModel {
358
404
  }
359
405
  this.state.lockPriceToBarRatio = value;
360
406
  }
407
+ initAutoScaleThrottling() {
408
+ // Throttle zoom auto-scale to ONE_FRAME_MS
409
+ this.autoScaleZoomSubscription = autoScaleZoomSubject
410
+ .pipe(throttleTime(ONE_FRAME_MS, animationFrameScheduler, { trailing: true, leading: false }))
411
+ .subscribe(() => {
412
+ const state = this.export();
413
+ const initialStateCopy = Object.assign({}, state);
414
+ const constrainedState = this.scalePostProcessor(initialStateCopy, state);
415
+ this.autoScaleModel.doAutoYScale(constrainedState);
416
+ });
417
+ // Throttle pan auto-scale to 250ms
418
+ this.autoScalePanSubscription = autoScalePanSubject
419
+ .pipe(throttleTime(ONE_FRAME_MS, animationFrameScheduler, { trailing: true, leading: false }))
420
+ .subscribe(() => {
421
+ const state = this.export();
422
+ const initialStateCopy = Object.assign({}, state);
423
+ const constrainedState = this.scalePostProcessor(initialStateCopy, state);
424
+ this.autoScaleModel.doAutoYScale(constrainedState);
425
+ });
426
+ }
361
427
  }
362
428
  /**
363
429
  * The SyncedByXScaleModel class extends the ScaleModel class and adds support for synchronization with other ScaleModel instance, so both instances maintain the same X-axis bounds.
@@ -4,6 +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 { PriceAxisType } from '../../components/labels_generator/numeric-axis-labels.generator';
7
+ export declare const isSafari: boolean;
7
8
  export declare const isFirefox: boolean;
8
9
  /**
9
10
  * this function determines whether the event was triggered with the mouse or the touchpad
@@ -3,7 +3,7 @@
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
- const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
6
+ export const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
7
7
  //@ts-ignore
8
8
  const isChrome = !!window.chrome;
9
9
  //@ts-ignore
@@ -113,7 +113,7 @@ export function clamp(value, min, max) {
113
113
  return Math.max(min, Math.min(value, max));
114
114
  }
115
115
  export function easeExpOut(value) {
116
- return 1 - (Math.pow(2, -5 * value) - 0.0009765625) * 1.0009775171065494;
116
+ return 1 - (Math.pow(2, -10 * value) - 0.0009765625) * 1.0009775171065494;
117
117
  }
118
118
  /**
119
119
  * Returns the first finite number in a list of numbers. If no finite number is found,
@@ -0,0 +1,5 @@
1
+ /*
2
+ * Copyright (C) 2019 - 2025 Devexperts Solutions IE Limited
3
+ * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
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
+ */
@@ -0,0 +1,12 @@
1
+ /*
2
+ * Copyright (C) 2019 - 2025 Devexperts Solutions IE Limited
3
+ * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
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
+ */
6
+ "use strict";
7
+ // Polyfill for queueMicrotask in jsdom
8
+ if (typeof window.queueMicrotask === 'undefined') {
9
+ window.queueMicrotask = (callback) => {
10
+ Promise.resolve().then(callback);
11
+ };
12
+ }
@@ -6,6 +6,7 @@
6
6
  export declare let animationFrameId: number;
7
7
  export declare const animationFrameThrottled: (name: string, action: () => void) => void;
8
8
  export declare const cancelThrottledAnimationFrame: (name: string) => void;
9
+ export declare const cancelThrottledAnimationFramePrior: (name: string) => void;
9
10
  /**
10
11
  * Prior actions will be called before regular actions
11
12
  * An example of regular action - draw event
@@ -31,6 +31,9 @@ export const animationFrameThrottled = (name, action) => {
31
31
  export const cancelThrottledAnimationFrame = (name) => {
32
32
  actions.delete(name);
33
33
  };
34
+ export const cancelThrottledAnimationFramePrior = (name) => {
35
+ priorActions.delete(name);
36
+ };
34
37
  /**
35
38
  * Prior actions will be called before regular actions
36
39
  * An example of regular action - draw event
@@ -0,0 +1,77 @@
1
+ /*
2
+ * Copyright (C) 2019 - 2025 Devexperts Solutions IE Limited
3
+ * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
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
+ */
6
+ import { BehaviorSubject } from 'rxjs';
7
+ import EventBus from '../../../../../events/event-bus';
8
+ import { ViewportModel } from '../../../../../model/scaling/viewport.model';
9
+ import { ViewportMovementAnimation, ViewportMovementAnimationConfig } from '../../../../../animation/types/viewport-movement-animation';
10
+ import { AnimationConfig, CanvasAnimation } from '../../../../../animation/canvas-animation';
11
+ import { ColorAlphaAnimation, ColorAlphaAnimationConfig } from '../../../../../animation/types/color-alpha-animation';
12
+ import { ColorTransitionAnimation, ColorTransitionAnimationConfig } from '../../../../../animation/types/color-transition-animation';
13
+ export declare class SafariCanvasAnimation extends CanvasAnimation {
14
+ animations: Record<string, any>;
15
+ animFrameId: string;
16
+ animationInProgressSubject: BehaviorSubject<boolean>;
17
+ private microtaskQueued;
18
+ constructor(eventBus: EventBus);
19
+ /**
20
+ * Starts a viewport movement animation with the given configuration and adds it to the list of animations.
21
+ * @param {ViewportModel} viewportModel - The viewport model to animate.
22
+ * @param {ViewportMovementAnimationConfig} config - The configuration for the animation.
23
+ * @param {string} [uniqueAnimationId=VIEWPORT_ANIMATION_ID] - The unique ID for the animation.
24
+ * @param {Function} [onTickFunction] - The function to be called on each tick of the animation.
25
+ * @returns {ViewportMovementAnimation} The container for the created animation.
26
+ */
27
+ startViewportMovementAnimation(viewportModel: ViewportModel, config: ViewportMovementAnimationConfig, uniqueAnimationId: string | undefined, onTickFunction: {
28
+ (): boolean;
29
+ (): void;
30
+ }): ViewportMovementAnimation;
31
+ /**
32
+ * Starts a color alpha animation with the given configuration and adds it to the list of animations.
33
+ * @param {string} uniqueAnimationId - A unique identifier for the animation.
34
+ * @param {Array<ColorAlphaAnimationConfig>} colorConfigs - An array of color alpha animation configurations.
35
+ * @param {() => void} [onTickFunction] - A function to be called on each animation tick.
36
+ * @param {Partial<ACAnimationConfig>} [animationConfig] - An optional configuration for the animation.
37
+ * @returns {ColorAlphaAnimation} - The created animation container.
38
+ */
39
+ startColorAlphaAnimation(uniqueAnimationId: string, colorConfigs: Array<ColorAlphaAnimationConfig>, onTickFunction?: (() => void) | undefined, animationConfig?: AnimationConfig): ColorAlphaAnimation;
40
+ /**
41
+ * Starts a color transition animation with the given configurations and duration.
42
+ * @param {string} uniqueAnimationId - A unique identifier for the animation.
43
+ * @param {Array<ColorTransitionAnimationConfig>} colorConfigs - An array of color transition configurations.
44
+ * @param {number} [duration=DEFAULT_ANIMATION_TIME] - The duration of the animation in milliseconds.
45
+ * @param {Function} [onTickFunction] - A function to be called on each tick of the animation.
46
+ * @returns {ColorTransitionAnimation} - The created animation container.
47
+ */
48
+ startColorTransitionAnimation(uniqueAnimationId: string, colorConfigs: Array<ColorTransitionAnimationConfig>, duration?: number, onTickFunction?: () => void): ColorTransitionAnimation;
49
+ /**
50
+ * This function takes an id as a string and returns an animation container object of type T. It retrieves the animation container object from the animations object using the provided id. The @ts-ignore comment is used to ignore any TypeScript errors that may occur due to the dynamic nature of the function.
51
+ */
52
+ getAnimation(id: string | number): any;
53
+ /**
54
+ * Returns a ColorAlphaAnimation object for the given animation ID.
55
+ *
56
+ * @param {string} id - The ID of the animation to retrieve.
57
+ * @returns {ColorAlphaAnimation} - The ColorAlphaAnimation object for the given ID.
58
+ */
59
+ getColorAlphaAnimation(id: string): any;
60
+ /**
61
+ * Returns a ColorTransitionAnimation object for the given id.
62
+ * @param {string} id - The id of the animation to retrieve.
63
+ * @returns {ColorTransitionAnimation} - The ColorTransitionAnimation object for the given id.
64
+ */
65
+ getColorTransitionAnimation(id: string): any;
66
+ /**
67
+ * Stops the animation with the given ID.
68
+ * @param {string} id - The ID of the animation to be stopped.
69
+ * @returns {void}
70
+ */
71
+ forceStopAnimation(id: string): void;
72
+ /**
73
+ * This is a private method that iterates through all the animations in the container and calls their tick method. If any animation is still in progress, it sets the allCompleted flag to false. If all animations are completed, it stops the interval. If not, it fires the draw event.
74
+ */
75
+ tick(): void;
76
+ stopInterval(): void;
77
+ }
@@ -0,0 +1,137 @@
1
+ /*
2
+ * Copyright (C) 2019 - 2025 Devexperts Solutions IE Limited
3
+ * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
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
+ */
6
+ import { BehaviorSubject } from 'rxjs';
7
+ import { cancelThrottledAnimationFramePrior } from '../../../../../utils/performance/request-animation-frame-throttle.utils';
8
+ import { ViewportMovementAnimation, } from '../../../../../animation/types/viewport-movement-animation';
9
+ import { CanvasAnimation, DEFAULT_ANIMATION_TIME_MS, VIEWPORT_ANIMATION_ID, } from '../../../../../animation/canvas-animation';
10
+ import { ColorAlphaAnimation } from '../../../../../animation/types/color-alpha-animation';
11
+ import { ColorTransitionAnimation, } from '../../../../../animation/types/color-transition-animation';
12
+ export class SafariCanvasAnimation extends CanvasAnimation {
13
+ constructor(eventBus) {
14
+ super(eventBus);
15
+ this.animations = {};
16
+ this.animFrameId = 'animation';
17
+ this.animationInProgressSubject = new BehaviorSubject(false);
18
+ this.microtaskQueued = false; // Flag to prevent accumulation of queueMicrotask calls
19
+ }
20
+ /**
21
+ * Starts a viewport movement animation with the given configuration and adds it to the list of animations.
22
+ * @param {ViewportModel} viewportModel - The viewport model to animate.
23
+ * @param {ViewportMovementAnimationConfig} config - The configuration for the animation.
24
+ * @param {string} [uniqueAnimationId=VIEWPORT_ANIMATION_ID] - The unique ID for the animation.
25
+ * @param {Function} [onTickFunction] - The function to be called on each tick of the animation.
26
+ * @returns {ViewportMovementAnimation} The container for the created animation.
27
+ */
28
+ startViewportMovementAnimation(viewportModel, config, uniqueAnimationId = VIEWPORT_ANIMATION_ID, onTickFunction) {
29
+ const animation = new ViewportMovementAnimation(viewportModel, config, onTickFunction);
30
+ this.animations[uniqueAnimationId] = animation;
31
+ this.processAnimation();
32
+ return animation;
33
+ }
34
+ /**
35
+ * Starts a color alpha animation with the given configuration and adds it to the list of animations.
36
+ * @param {string} uniqueAnimationId - A unique identifier for the animation.
37
+ * @param {Array<ColorAlphaAnimationConfig>} colorConfigs - An array of color alpha animation configurations.
38
+ * @param {() => void} [onTickFunction] - A function to be called on each animation tick.
39
+ * @param {Partial<ACAnimationConfig>} [animationConfig] - An optional configuration for the animation.
40
+ * @returns {ColorAlphaAnimation} - The created animation container.
41
+ */
42
+ startColorAlphaAnimation(uniqueAnimationId, colorConfigs, onTickFunction, animationConfig) {
43
+ const animation = new ColorAlphaAnimation(Object.assign(Object.assign({}, animationConfig), { duration: (animationConfig && animationConfig.duration) || DEFAULT_ANIMATION_TIME_MS }), colorConfigs, onTickFunction);
44
+ this.animations[uniqueAnimationId] = animation;
45
+ this.processAnimation();
46
+ return animation;
47
+ }
48
+ /**
49
+ * Starts a color transition animation with the given configurations and duration.
50
+ * @param {string} uniqueAnimationId - A unique identifier for the animation.
51
+ * @param {Array<ColorTransitionAnimationConfig>} colorConfigs - An array of color transition configurations.
52
+ * @param {number} [duration=DEFAULT_ANIMATION_TIME] - The duration of the animation in milliseconds.
53
+ * @param {Function} [onTickFunction] - A function to be called on each tick of the animation.
54
+ * @returns {ColorTransitionAnimation} - The created animation container.
55
+ */
56
+ startColorTransitionAnimation(uniqueAnimationId, colorConfigs, duration = DEFAULT_ANIMATION_TIME_MS, onTickFunction) {
57
+ const animation = new ColorTransitionAnimation({ duration }, colorConfigs, onTickFunction);
58
+ this.animations[uniqueAnimationId] = animation;
59
+ this.processAnimation();
60
+ return animation;
61
+ }
62
+ /**
63
+ * This function takes an id as a string and returns an animation container object of type T. It retrieves the animation container object from the animations object using the provided id. The @ts-ignore comment is used to ignore any TypeScript errors that may occur due to the dynamic nature of the function.
64
+ */
65
+ getAnimation(id) {
66
+ // @ts-ignore
67
+ return this.animations[id];
68
+ }
69
+ /**
70
+ * Returns a ColorAlphaAnimation object for the given animation ID.
71
+ *
72
+ * @param {string} id - The ID of the animation to retrieve.
73
+ * @returns {ColorAlphaAnimation} - The ColorAlphaAnimation object for the given ID.
74
+ */
75
+ getColorAlphaAnimation(id) {
76
+ return this.getAnimation(id);
77
+ }
78
+ /**
79
+ * Returns a ColorTransitionAnimation object for the given id.
80
+ * @param {string} id - The id of the animation to retrieve.
81
+ * @returns {ColorTransitionAnimation} - The ColorTransitionAnimation object for the given id.
82
+ */
83
+ getColorTransitionAnimation(id) {
84
+ return this.getAnimation(id);
85
+ }
86
+ /**
87
+ * Stops the animation with the given ID.
88
+ * @param {string} id - The ID of the animation to be stopped.
89
+ * @returns {void}
90
+ */
91
+ forceStopAnimation(id) {
92
+ const animation = this.animations[id];
93
+ if (animation) {
94
+ animation.animationInProgress = false;
95
+ animation.animationStartTime = 0;
96
+ // CRITICAL: Completely remove the animation to prevent it from being processed in tick()
97
+ delete this.animations[id];
98
+ }
99
+ // Stop the animation loop if no animations are running
100
+ if (Object.keys(this.animations).length === 0) {
101
+ this.stopInterval();
102
+ }
103
+ }
104
+ /**
105
+ * This is a private method that iterates through all the animations in the container and calls their tick method. If any animation is still in progress, it sets the allCompleted flag to false. If all animations are completed, it stops the interval. If not, it fires the draw event.
106
+ */
107
+ tick() {
108
+ let allCompleted = true;
109
+ for (const i of Object.keys(this.animations)) {
110
+ const animation = this.animations[i];
111
+ animation.tick();
112
+ if (animation.animationInProgress) {
113
+ allCompleted = false;
114
+ }
115
+ }
116
+ this.animationInProgressSubject.next(!allCompleted);
117
+ if (!allCompleted) {
118
+ // CRITICAL: Prevent accumulation of queueMicrotask calls during rapid animation updates
119
+ if (!this.microtaskQueued) {
120
+ this.microtaskQueued = true;
121
+ queueMicrotask(() => {
122
+ this.microtaskQueued = false; // Reset flag when microtask executes
123
+ this.processAnimation();
124
+ this.eventBus.fireDraw();
125
+ });
126
+ }
127
+ }
128
+ else {
129
+ this.stopInterval();
130
+ }
131
+ }
132
+ stopInterval() {
133
+ cancelThrottledAnimationFramePrior(this.animFrameId);
134
+ // Reset microtask flag to ensure clean state
135
+ this.microtaskQueued = false;
136
+ }
137
+ }
@@ -0,0 +1,54 @@
1
+ /*
2
+ * Copyright (C) 2019 - 2025 Devexperts Solutions IE Limited
3
+ * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
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
+ */
6
+ import { CanvasAnimation } from '../../../../../animation/canvas-animation';
7
+ import { CanvasBoundsContainer } from '../../../../../canvas/canvas-bounds-container';
8
+ import { FullChartConfig } from '../../../../../chart.config';
9
+ import EventBus from '../../../../../events/event-bus';
10
+ import { CanvasInputListenerComponent, Point } from '../../../../../inputlisteners/canvas-input-listener.component';
11
+ import { ScaleModel } from '../../../../../model/scale.model';
12
+ import { HitTestCanvasModel } from '../../../../../model/hit-test-canvas.model';
13
+ import { ChartPanComponent } from '../../../../../components/pan/chart-pan.component';
14
+ import { ChartAreaPanHandler, ChartPanningOptions } from '../../../../../components/chart/chart-area-pan.handler';
15
+ /**
16
+ * SafariChartAreaPanHandler is a class that handles the panning and zooming of the chart area for Safari.
17
+ */
18
+ export declare class SafariChartAreaPanHandler extends ChartAreaPanHandler {
19
+ protected bus: EventBus;
20
+ protected config: FullChartConfig;
21
+ protected scale: ScaleModel;
22
+ protected canvasInputListener: CanvasInputListenerComponent;
23
+ protected canvasBoundsContainer: CanvasBoundsContainer;
24
+ protected canvasAnimation: CanvasAnimation;
25
+ protected chartPanComponent: ChartPanComponent;
26
+ protected hitTestCanvasModel: HitTestCanvasModel;
27
+ protected currentPoint: Point;
28
+ xDraggedCandlesDelta: number;
29
+ lastXStart: number;
30
+ wheelThrottleTime: number;
31
+ private wheelSubscription;
32
+ private initFrameId;
33
+ private isActivated;
34
+ private lastWheelTime;
35
+ private wheelCount;
36
+ private consecutiveLowWheelEvents;
37
+ chartPanningOptions: ChartPanningOptions;
38
+ constructor(bus: EventBus, config: FullChartConfig, scale: ScaleModel, canvasInputListener: CanvasInputListenerComponent, canvasBoundsContainer: CanvasBoundsContainer, canvasAnimation: CanvasAnimation, chartPanComponent: ChartPanComponent, hitTestCanvasModel: HitTestCanvasModel);
39
+ /**
40
+ * This method is used to activate the zoom functionality of the canvas. It extends the doActivate method of the parent class.
41
+ * @protected
42
+ * @returns {void}
43
+ */
44
+ protected doActivate(): void;
45
+ /**
46
+ * Creates wheel subscription with optimized throttling
47
+ */
48
+ private createWheelSubscription;
49
+ /**
50
+ * Manual cleanup trigger for immediate performance recovery
51
+ */
52
+ triggerPerformanceCleanup(): void;
53
+ protected doDeactivate(): void;
54
+ }