@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.
- package/dist/chart/animation/canvas-animation.d.ts +1 -0
- package/dist/chart/animation/canvas-animation.js +2 -1
- package/dist/chart/animation/viewport-model-animation.d.ts +4 -1
- package/dist/chart/animation/viewport-model-animation.js +21 -3
- package/dist/chart/bootstrap.js +17 -5
- package/dist/chart/chart.config.js +1 -1
- package/dist/chart/components/chart/chart-area-pan.handler.d.ts +16 -16
- package/dist/chart/components/chart/chart-area-pan.handler.js +8 -2
- package/dist/chart/components/chart/chart.component.js +2 -0
- package/dist/chart/components/chart/chart.model.d.ts +11 -0
- package/dist/chart/components/chart/chart.model.js +20 -0
- package/dist/chart/components/chart/price-formatters/__tests__/treasury-price.formatter.test.d.ts +6 -0
- package/dist/chart/components/chart/price-formatters/__tests__/treasury-price.formatter.test.js +94 -0
- package/dist/chart/components/chart/price-formatters/treasury-price.formatter.d.ts +9 -0
- package/dist/chart/components/chart/price-formatters/treasury-price.formatter.js +22 -1
- package/dist/chart/components/cross_tool/cross-tool.component.d.ts +3 -1
- package/dist/chart/components/cross_tool/cross-tool.component.js +3 -2
- package/dist/chart/components/cross_tool/cross-tool.model.d.ts +6 -3
- package/dist/chart/components/cross_tool/cross-tool.model.js +9 -5
- package/dist/chart/components/grid/grid.component.d.ts +1 -1
- package/dist/chart/components/grid/grid.component.js +2 -2
- package/dist/chart/components/grid/grid.drawer.d.ts +2 -1
- package/dist/chart/components/grid/grid.drawer.js +3 -2
- package/dist/chart/components/pan/chart-pan.component.js +17 -1
- package/dist/chart/components/pane/pane.component.js +3 -1
- package/dist/chart/drawers/data-series-drawers/trend-points.drawer.d.ts +12 -0
- package/dist/chart/drawers/data-series-drawers/trend-points.drawer.js +70 -0
- package/dist/chart/drawers/drawing-manager.js +0 -1
- package/dist/chart/inputhandlers/chart-resize.handler.d.ts +5 -0
- package/dist/chart/inputhandlers/chart-resize.handler.js +9 -1
- package/dist/chart/inputlisteners/canvas-input-listener.component.d.ts +28 -0
- package/dist/chart/inputlisteners/canvas-input-listener.component.js +104 -7
- package/dist/chart/model/data-series.config.d.ts +1 -1
- package/dist/chart/model/hit-test-canvas.model.d.ts +15 -13
- package/dist/chart/model/hit-test-canvas.model.js +2 -2
- package/dist/chart/model/scale.model.d.ts +5 -0
- package/dist/chart/model/scale.model.js +72 -6
- package/dist/chart/utils/device/touchpad.utils.d.ts +1 -0
- package/dist/chart/utils/device/touchpad.utils.js +1 -1
- package/dist/chart/utils/math.utils.js +1 -1
- package/dist/chart/utils/performance/queue-microtask.utils.d.ts +5 -0
- package/dist/chart/utils/performance/queue-microtask.utils.js +12 -0
- package/dist/chart/utils/performance/request-animation-frame-throttle.utils.d.ts +1 -0
- package/dist/chart/utils/performance/request-animation-frame-throttle.utils.js +3 -0
- package/dist/chart/utils/performance/safari/components/animations/safari-canvas-animation.d.ts +77 -0
- package/dist/chart/utils/performance/safari/components/animations/safari-canvas-animation.js +137 -0
- package/dist/chart/utils/performance/safari/components/chart-area-pan.handler/safari-chart-area-pan.handler.d.ts +54 -0
- package/dist/chart/utils/performance/safari/components/chart-area-pan.handler/safari-chart-area-pan.handler.js +180 -0
- package/dist/chart/utils/performance/safari/safari-performance.model.d.ts +32 -0
- package/dist/chart/utils/performance/safari/safari-performance.model.js +31 -0
- package/dist/chart/utils/performance/safari/safari-performance.utils.d.ts +18 -0
- package/dist/chart/utils/performance/safari/safari-performance.utils.js +34 -0
- package/dist/dxchart.min.js +4 -4
- package/package.json +2 -2
|
@@ -0,0 +1,180 @@
|
|
|
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 { animationFrameScheduler } from 'rxjs';
|
|
7
|
+
import { throttleTime, filter, debounceTime } from 'rxjs/operators';
|
|
8
|
+
import { CanvasElement } from '../../../../../canvas/canvas-bounds-container';
|
|
9
|
+
import { pixelsToUnits } from '../../../../../model/scaling/viewport.model';
|
|
10
|
+
import { deviceDetector } from '../../../../../utils/device/device-detector.utils';
|
|
11
|
+
import { ONE_FRAME_MS } from '../../../../../utils/numeric-constants.utils';
|
|
12
|
+
import { EVENT_RESIZED } from '../../../../../events/events';
|
|
13
|
+
import { DEFAULT_THROTTLE_MS, LARGE_SCREEN_PIXEL_THRESHOLD, LARGE_SCREEN_THROTTLE_MS, LOW_WHEEL_EVENTS_THRESHOLD, SAFARI_THROTTLE_MS, WHEEL_MONITORING_INTERVAL_MS, } from '../../safari-performance.model';
|
|
14
|
+
import { ChartAreaPanHandler } 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 class SafariChartAreaPanHandler extends ChartAreaPanHandler {
|
|
19
|
+
constructor(bus, config, scale, canvasInputListener, canvasBoundsContainer, canvasAnimation, chartPanComponent, hitTestCanvasModel) {
|
|
20
|
+
super(bus, config, scale, canvasInputListener, canvasBoundsContainer, canvasAnimation, chartPanComponent, hitTestCanvasModel);
|
|
21
|
+
this.bus = bus;
|
|
22
|
+
this.config = config;
|
|
23
|
+
this.scale = scale;
|
|
24
|
+
this.canvasInputListener = canvasInputListener;
|
|
25
|
+
this.canvasBoundsContainer = canvasBoundsContainer;
|
|
26
|
+
this.canvasAnimation = canvasAnimation;
|
|
27
|
+
this.chartPanComponent = chartPanComponent;
|
|
28
|
+
this.hitTestCanvasModel = hitTestCanvasModel;
|
|
29
|
+
this.currentPoint = { x: 0, y: 0 };
|
|
30
|
+
this.xDraggedCandlesDelta = 0;
|
|
31
|
+
this.lastXStart = 0;
|
|
32
|
+
this.wheelThrottleTime = ONE_FRAME_MS;
|
|
33
|
+
this.wheelSubscription = null;
|
|
34
|
+
this.initFrameId = null;
|
|
35
|
+
this.isActivated = false;
|
|
36
|
+
this.lastWheelTime = 0;
|
|
37
|
+
this.wheelCount = 0;
|
|
38
|
+
this.consecutiveLowWheelEvents = 0;
|
|
39
|
+
this.chartPanningOptions = { horizontal: true, vertical: true };
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* This method is used to activate the zoom functionality of the canvas. It extends the doActivate method of the parent class.
|
|
43
|
+
* @protected
|
|
44
|
+
* @returns {void}
|
|
45
|
+
*/
|
|
46
|
+
doActivate() {
|
|
47
|
+
if (this.isActivated) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
this.isActivated = true;
|
|
51
|
+
super.doActivate();
|
|
52
|
+
this.canvasInputListener.initializeRectCache();
|
|
53
|
+
this.createWheelSubscription();
|
|
54
|
+
this.initFrameId = requestAnimationFrame(() => {
|
|
55
|
+
this.bus.fireDraw();
|
|
56
|
+
});
|
|
57
|
+
this.addRxSubscription(this.chartPanComponent.chartBaseModel.dataPrependSubject
|
|
58
|
+
.asObservable()
|
|
59
|
+
.subscribe(({ prependedCandlesWidth }) => {
|
|
60
|
+
this.lastXStart += prependedCandlesWidth;
|
|
61
|
+
}));
|
|
62
|
+
this.addRxSubscription(this.bus
|
|
63
|
+
.observe(EVENT_RESIZED)
|
|
64
|
+
.pipe(debounceTime(100))
|
|
65
|
+
.subscribe(() => {
|
|
66
|
+
if (this.scale && typeof this.scale.haltAnimation === 'function') {
|
|
67
|
+
this.scale.haltAnimation();
|
|
68
|
+
}
|
|
69
|
+
}));
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Creates wheel subscription with optimized throttling
|
|
73
|
+
*/
|
|
74
|
+
createWheelSubscription() {
|
|
75
|
+
if (this.wheelSubscription) {
|
|
76
|
+
this.wheelSubscription.unsubscribe();
|
|
77
|
+
this.wheelSubscription = null;
|
|
78
|
+
}
|
|
79
|
+
const allPanesHitTest = this.canvasBoundsContainer.getBoundsHitTest(CanvasElement.ALL_PANES);
|
|
80
|
+
const canvasBounds = this.canvasBoundsContainer.getBounds(CanvasElement.CANVAS);
|
|
81
|
+
const totalPixels = canvasBounds.width * canvasBounds.height;
|
|
82
|
+
if (totalPixels > 0) {
|
|
83
|
+
if (totalPixels > LARGE_SCREEN_PIXEL_THRESHOLD) {
|
|
84
|
+
this.wheelThrottleTime = LARGE_SCREEN_THROTTLE_MS;
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
this.wheelThrottleTime = SAFARI_THROTTLE_MS;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
this.wheelThrottleTime = DEFAULT_THROTTLE_MS;
|
|
92
|
+
}
|
|
93
|
+
this.wheelSubscription = this.canvasInputListener
|
|
94
|
+
.observeWheel(allPanesHitTest)
|
|
95
|
+
.pipe(filter(() => this.chartPanningOptions.horizontal && this.chartPanningOptions.vertical), filter((e) => {
|
|
96
|
+
const device = deviceDetector();
|
|
97
|
+
if (device === 'apple') {
|
|
98
|
+
const minDelta = 1.0;
|
|
99
|
+
return Math.abs(e.deltaY) > minDelta || Math.abs(e.deltaX) > minDelta;
|
|
100
|
+
}
|
|
101
|
+
return true;
|
|
102
|
+
}), throttleTime(this.wheelThrottleTime, animationFrameScheduler, { trailing: true, leading: true }))
|
|
103
|
+
.subscribe(e => {
|
|
104
|
+
const now = performance.now();
|
|
105
|
+
if (!this.lastWheelTime) {
|
|
106
|
+
this.lastWheelTime = now;
|
|
107
|
+
this.wheelCount = 0;
|
|
108
|
+
}
|
|
109
|
+
this.wheelCount++;
|
|
110
|
+
if (now - this.lastWheelTime > WHEEL_MONITORING_INTERVAL_MS) {
|
|
111
|
+
const wheelEventsPerSecond = Math.round((this.wheelCount * 1000) / (now - this.lastWheelTime));
|
|
112
|
+
if (wheelEventsPerSecond < LOW_WHEEL_EVENTS_THRESHOLD) {
|
|
113
|
+
this.consecutiveLowWheelEvents++;
|
|
114
|
+
if (this.consecutiveLowWheelEvents >= 1) {
|
|
115
|
+
this.triggerPerformanceCleanup();
|
|
116
|
+
this.consecutiveLowWheelEvents = 0;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
this.consecutiveLowWheelEvents = 0;
|
|
121
|
+
}
|
|
122
|
+
this.lastWheelTime = now;
|
|
123
|
+
this.wheelCount = 0;
|
|
124
|
+
}
|
|
125
|
+
const device = deviceDetector();
|
|
126
|
+
const direction = device === 'apple' || device === 'mobile' ? -1 : 1;
|
|
127
|
+
const deltaX = 0 + e.deltaX * direction;
|
|
128
|
+
const deltaY = 0 + e.deltaY * direction;
|
|
129
|
+
if (e.ctrlKey) {
|
|
130
|
+
const zoomSensitivity = this.calculateDynamicSesitivity(e, this.config.scale.zoomSensitivity.wheel);
|
|
131
|
+
this.zoomXHandler(e, zoomSensitivity);
|
|
132
|
+
this.bus.fireDraw();
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
if (deltaY !== 0 && Math.abs(deltaY) > Math.abs(deltaX)) {
|
|
136
|
+
const zoomSensitivity = this.calculateDynamicSesitivity(e, this.config.scale.zoomSensitivity.wheel);
|
|
137
|
+
this.zoomXHandler(e, zoomSensitivity);
|
|
138
|
+
this.bus.fireDraw();
|
|
139
|
+
}
|
|
140
|
+
if (deltaX !== 0 && Math.abs(deltaX) > Math.abs(deltaY)) {
|
|
141
|
+
const unitsDelta = pixelsToUnits(deltaX, this.scale.zoomX);
|
|
142
|
+
this.scale.moveXStart(this.scale.xStart - unitsDelta);
|
|
143
|
+
this.bus.fireDraw();
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
this.addRxSubscription(this.wheelSubscription);
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Manual cleanup trigger for immediate performance recovery
|
|
151
|
+
*/
|
|
152
|
+
triggerPerformanceCleanup() {
|
|
153
|
+
window.dispatchEvent(new Event('resize'));
|
|
154
|
+
if (window.gc) {
|
|
155
|
+
window.gc();
|
|
156
|
+
}
|
|
157
|
+
if (this.initFrameId) {
|
|
158
|
+
cancelAnimationFrame(this.initFrameId);
|
|
159
|
+
this.initFrameId = null;
|
|
160
|
+
}
|
|
161
|
+
if (this.scale && typeof this.scale.haltAnimation === 'function') {
|
|
162
|
+
this.scale.haltAnimation();
|
|
163
|
+
}
|
|
164
|
+
this.consecutiveLowWheelEvents = 0;
|
|
165
|
+
this.wheelCount = 0;
|
|
166
|
+
this.lastWheelTime = 0;
|
|
167
|
+
}
|
|
168
|
+
doDeactivate() {
|
|
169
|
+
if (this.wheelSubscription) {
|
|
170
|
+
this.wheelSubscription.unsubscribe();
|
|
171
|
+
this.wheelSubscription = null;
|
|
172
|
+
}
|
|
173
|
+
if (this.initFrameId) {
|
|
174
|
+
cancelAnimationFrame(this.initFrameId);
|
|
175
|
+
this.initFrameId = null;
|
|
176
|
+
}
|
|
177
|
+
this.isActivated = false;
|
|
178
|
+
super.doDeactivate();
|
|
179
|
+
}
|
|
180
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
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
|
+
export type SafariThrottleTimeMS = number;
|
|
7
|
+
/**
|
|
8
|
+
* Safari canvas performance limits because of Safari's GPU limits
|
|
9
|
+
*/
|
|
10
|
+
export declare const SAFARI_CANVAS_LIMITS: {
|
|
11
|
+
readonly MAX_DIMENSION: 2048;
|
|
12
|
+
readonly MAX_TOTAL_PIXELS: 1800000;
|
|
13
|
+
readonly ZOOM_OPTIMIZED_PIXELS: 1200000;
|
|
14
|
+
};
|
|
15
|
+
export declare const LARGE_SCREEN_PIXEL_THRESHOLD = 2000000;
|
|
16
|
+
export declare const LARGE_SCREEN_THROTTLE_MS = 24;
|
|
17
|
+
export declare const SAFARI_THROTTLE_MS = 20;
|
|
18
|
+
export declare const DEFAULT_THROTTLE_MS = 16;
|
|
19
|
+
export declare const LOW_WHEEL_EVENTS_THRESHOLD = 10;
|
|
20
|
+
export declare const WHEEL_MONITORING_INTERVAL_MS = 1000;
|
|
21
|
+
/**
|
|
22
|
+
* Threshold for significant canvas area change to trigger subscription recreation
|
|
23
|
+
* Prevents unnecessary recreation for minor size adjustments
|
|
24
|
+
*/
|
|
25
|
+
export declare const CANVAS_AREA_CHANGE_THRESHOLD = 50000;
|
|
26
|
+
export declare const SafariThrottleTimeMSMap: {
|
|
27
|
+
readonly MIN: 60;
|
|
28
|
+
readonly LOW: 80;
|
|
29
|
+
readonly MEDIUM: 100;
|
|
30
|
+
readonly HIGH: 120;
|
|
31
|
+
readonly MAX: 150;
|
|
32
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
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
|
+
/**
|
|
7
|
+
* Safari canvas performance limits because of Safari's GPU limits
|
|
8
|
+
*/
|
|
9
|
+
export const SAFARI_CANVAS_LIMITS = {
|
|
10
|
+
MAX_DIMENSION: 2048,
|
|
11
|
+
MAX_TOTAL_PIXELS: 1800000,
|
|
12
|
+
ZOOM_OPTIMIZED_PIXELS: 1200000,
|
|
13
|
+
};
|
|
14
|
+
export const LARGE_SCREEN_PIXEL_THRESHOLD = 2000000; // 2M pixels
|
|
15
|
+
export const LARGE_SCREEN_THROTTLE_MS = 24;
|
|
16
|
+
export const SAFARI_THROTTLE_MS = 20;
|
|
17
|
+
export const DEFAULT_THROTTLE_MS = 16;
|
|
18
|
+
export const LOW_WHEEL_EVENTS_THRESHOLD = 10; // Minimum wheel events per second
|
|
19
|
+
export const WHEEL_MONITORING_INTERVAL_MS = 1000;
|
|
20
|
+
/**
|
|
21
|
+
* Threshold for significant canvas area change to trigger subscription recreation
|
|
22
|
+
* Prevents unnecessary recreation for minor size adjustments
|
|
23
|
+
*/
|
|
24
|
+
export const CANVAS_AREA_CHANGE_THRESHOLD = 50000;
|
|
25
|
+
export const SafariThrottleTimeMSMap = {
|
|
26
|
+
MIN: 60,
|
|
27
|
+
LOW: 80,
|
|
28
|
+
MEDIUM: 100,
|
|
29
|
+
HIGH: 120,
|
|
30
|
+
MAX: 150,
|
|
31
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
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 { SafariThrottleTimeMS } from './safari-performance.model';
|
|
7
|
+
/**
|
|
8
|
+
* Safari Performance Optimization Utilities
|
|
9
|
+
*
|
|
10
|
+
* This module contains utilities specifically designed to address Safari performance issues
|
|
11
|
+
* during drag/zoom operations on charts.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Calculates optimal throttle time for hit-test wheel events based on canvas size and browser
|
|
15
|
+
* @param canvasArea - Total canvas area in pixels (width * height)
|
|
16
|
+
* @returns Throttle time in milliseconds
|
|
17
|
+
*/
|
|
18
|
+
export declare function calculateHitTestThrottleTime(canvasArea: number): SafariThrottleTimeMS;
|
|
@@ -0,0 +1,34 @@
|
|
|
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 { SAFARI_CANVAS_LIMITS, SafariThrottleTimeMSMap } from './safari-performance.model';
|
|
7
|
+
/**
|
|
8
|
+
* Safari Performance Optimization Utilities
|
|
9
|
+
*
|
|
10
|
+
* This module contains utilities specifically designed to address Safari performance issues
|
|
11
|
+
* during drag/zoom operations on charts.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Calculates optimal throttle time for hit-test wheel events based on canvas size and browser
|
|
15
|
+
* @param canvasArea - Total canvas area in pixels (width * height)
|
|
16
|
+
* @returns Throttle time in milliseconds
|
|
17
|
+
*/
|
|
18
|
+
export function calculateHitTestThrottleTime(canvasArea) {
|
|
19
|
+
if (canvasArea > SAFARI_CANVAS_LIMITS.ZOOM_OPTIMIZED_PIXELS) {
|
|
20
|
+
return SafariThrottleTimeMSMap.MAX;
|
|
21
|
+
}
|
|
22
|
+
else if (canvasArea > SAFARI_CANVAS_LIMITS.ZOOM_OPTIMIZED_PIXELS * 0.75) {
|
|
23
|
+
return SafariThrottleTimeMSMap.HIGH;
|
|
24
|
+
}
|
|
25
|
+
else if (canvasArea > SAFARI_CANVAS_LIMITS.ZOOM_OPTIMIZED_PIXELS * 0.5) {
|
|
26
|
+
return SafariThrottleTimeMSMap.MEDIUM;
|
|
27
|
+
}
|
|
28
|
+
else if (canvasArea > SAFARI_CANVAS_LIMITS.ZOOM_OPTIMIZED_PIXELS * 0.25) {
|
|
29
|
+
return SafariThrottleTimeMSMap.LOW;
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
return SafariThrottleTimeMSMap.MIN;
|
|
33
|
+
}
|
|
34
|
+
}
|