@devexperts/dxcharts-lite 2.6.0 → 2.6.1
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/bootstrap.js +1 -1
- package/dist/chart/canvas/canvas-bounds-container.d.ts +1 -0
- package/dist/chart/canvas/canvas-bounds-container.js +4 -1
- package/dist/chart/chart.config.d.ts +8 -0
- package/dist/chart/chart.config.js +2 -1
- package/dist/chart/components/cross_tool/cross-tool.component.js +2 -2
- package/dist/chart/components/cross_tool/cross-tool.drawer.d.ts +3 -1
- package/dist/chart/components/cross_tool/cross-tool.drawer.js +4 -3
- package/dist/chart/components/cross_tool/cross-tool.model.d.ts +6 -6
- package/dist/chart/components/cross_tool/cross-tool.model.js +42 -11
- package/dist/chart/components/cross_tool/types/cross-and-labels.drawer.js +3 -3
- package/dist/chart/components/high_low/high-low.drawer.js +1 -1
- package/dist/chart/components/pane/pane-manager.component.d.ts +5 -0
- package/dist/chart/components/pane/pane-manager.component.js +20 -0
- package/dist/chart/components/pane/pane.component.d.ts +9 -1
- package/dist/chart/components/pane/pane.component.js +16 -0
- package/dist/chart/components/x_axis/x-axis-draw.functions.js +2 -2
- package/dist/chart/components/x_axis/x-axis-scale.handler.d.ts +1 -0
- package/dist/chart/components/x_axis/x-axis-scale.handler.js +37 -8
- package/dist/chart/components/x_axis/x-axis-time-labels.drawer.js +2 -2
- package/dist/chart/inputhandlers/cross-event-producer.component.d.ts +22 -0
- package/dist/chart/inputhandlers/cross-event-producer.component.js +11 -1
- package/dist/chart/inputhandlers/hover-producer.component.d.ts +5 -3
- package/dist/chart/inputhandlers/hover-producer.component.js +70 -16
- package/dist/chart/inputhandlers/main-canvas-touch.handler.d.ts +10 -0
- package/dist/chart/inputhandlers/main-canvas-touch.handler.js +18 -0
- package/dist/chart/inputlisteners/canvas-input-listener.component.js +2 -7
- package/dist/chart/model/candle-series.model.js +1 -1
- package/dist/dxchart.min.js +4 -4
- package/package.json +1 -1
|
@@ -17,6 +17,7 @@ import { ScaleModel } from '../model/scale.model';
|
|
|
17
17
|
import VisualCandle from '../model/visual-candle';
|
|
18
18
|
import { CrossEvent, CrossEventProducerComponent } from './cross-event-producer.component';
|
|
19
19
|
import { TimeZoneModel } from '../model/time-zone.model';
|
|
20
|
+
import { MainCanvasTouchHandler } from './main-canvas-touch.handler';
|
|
20
21
|
export interface BaseHover {
|
|
21
22
|
readonly x: number;
|
|
22
23
|
readonly y: number;
|
|
@@ -52,13 +53,14 @@ export declare class HoverProducerComponent extends ChartBaseElement {
|
|
|
52
53
|
private canvasBoundsContainer;
|
|
53
54
|
private paneManager;
|
|
54
55
|
private timeZoneModel;
|
|
56
|
+
private mainCanvasTouchHandler;
|
|
55
57
|
private formatterFactory;
|
|
56
58
|
hoverSubject: BehaviorSubject<Hover | null>;
|
|
57
59
|
get hover(): Hover | null;
|
|
58
|
-
|
|
60
|
+
longTouchActivatedSubject: BehaviorSubject<boolean>;
|
|
59
61
|
private hoverProducerParts;
|
|
60
62
|
xFormatter: DateTimeFormatter;
|
|
61
|
-
constructor(crossEventProducer: CrossEventProducerComponent, scale: ScaleModel, config: FullChartConfig, chartModel: ChartModel, canvasInputListener: CanvasInputListenerComponent, canvasBoundsContainer: CanvasBoundsContainer, paneManager: PaneManager, timeZoneModel: TimeZoneModel, formatterFactory: (format: string) => (timestamp: number) => string);
|
|
63
|
+
constructor(crossEventProducer: CrossEventProducerComponent, scale: ScaleModel, config: FullChartConfig, chartModel: ChartModel, canvasInputListener: CanvasInputListenerComponent, canvasBoundsContainer: CanvasBoundsContainer, paneManager: PaneManager, timeZoneModel: TimeZoneModel, mainCanvasTouchHandler: MainCanvasTouchHandler, formatterFactory: (format: string) => (timestamp: number) => string);
|
|
62
64
|
/**
|
|
63
65
|
* This method is responsible for activating the chart hover functionality. It subscribes to several observables to
|
|
64
66
|
* update the hover when the chart is updated or when the user interacts with it. It also handles special behavior
|
|
@@ -89,7 +91,7 @@ export declare class HoverProducerComponent extends ChartBaseElement {
|
|
|
89
91
|
* @returns {Hover | undefined} - The hover object or undefined if there are no candles in the chart model.
|
|
90
92
|
* @todo Check if uuid is still useful here.
|
|
91
93
|
*/
|
|
92
|
-
|
|
94
|
+
createHover(x: number, y: number, uuid: string): Hover | undefined;
|
|
93
95
|
/**
|
|
94
96
|
* Creates a hover from a VisualCandle object and fires it.
|
|
95
97
|
* @param {VisualCandle} candle - The VisualCandle object to create the hover from.
|
|
@@ -11,6 +11,7 @@ import { ChartBaseElement } from '../model/chart-base-element';
|
|
|
11
11
|
import { CompareSeriesHoverProducerPart } from '../model/compare-series-hover';
|
|
12
12
|
import { recalculateXFormatter } from '../model/date-time.formatter';
|
|
13
13
|
import { isMobile } from '../utils/device/browser.utils';
|
|
14
|
+
import { checkChartIsMoving } from './main-canvas-touch.handler';
|
|
14
15
|
/**
|
|
15
16
|
* Produces the Hover event.
|
|
16
17
|
* Hover is used for displaying values in legend and NOT related to displaying cross tool.
|
|
@@ -19,7 +20,7 @@ export class HoverProducerComponent extends ChartBaseElement {
|
|
|
19
20
|
get hover() {
|
|
20
21
|
return this.hoverSubject.getValue();
|
|
21
22
|
}
|
|
22
|
-
constructor(crossEventProducer, scale, config, chartModel, canvasInputListener, canvasBoundsContainer, paneManager, timeZoneModel, formatterFactory) {
|
|
23
|
+
constructor(crossEventProducer, scale, config, chartModel, canvasInputListener, canvasBoundsContainer, paneManager, timeZoneModel, mainCanvasTouchHandler, formatterFactory) {
|
|
23
24
|
super();
|
|
24
25
|
this.crossEventProducer = crossEventProducer;
|
|
25
26
|
this.scale = scale;
|
|
@@ -29,6 +30,7 @@ export class HoverProducerComponent extends ChartBaseElement {
|
|
|
29
30
|
this.canvasBoundsContainer = canvasBoundsContainer;
|
|
30
31
|
this.paneManager = paneManager;
|
|
31
32
|
this.timeZoneModel = timeZoneModel;
|
|
33
|
+
this.mainCanvasTouchHandler = mainCanvasTouchHandler;
|
|
32
34
|
this.formatterFactory = formatterFactory;
|
|
33
35
|
this.hoverSubject = new BehaviorSubject(null);
|
|
34
36
|
this.longTouchActivatedSubject = new BehaviorSubject(false);
|
|
@@ -79,37 +81,86 @@ export class HoverProducerComponent extends ChartBaseElement {
|
|
|
79
81
|
}
|
|
80
82
|
}));
|
|
81
83
|
this.addRxSubscription(this.scale.xChanged.subscribe(() => this.fireLastCross()));
|
|
84
|
+
this.addRxSubscription(merge(this.chartModel.candlesSetSubject, this.timeZoneModel.observeTimeZoneChanged()).subscribe(() => this.recalculateCrossToolXFormatter()));
|
|
85
|
+
//#region crosstool touch events, special handling for mobile
|
|
82
86
|
this.addRxSubscription(this.canvasInputListener.observeTouchStart().subscribe(event => {
|
|
83
87
|
var _a;
|
|
84
|
-
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
this.createAndFireHover([
|
|
88
|
+
this.crossEventProducer.crossToolTouchInfo.isCommonTap = true;
|
|
89
|
+
const { clientX, clientY } = event.touches[0];
|
|
90
|
+
// if common tap - fire hover
|
|
91
|
+
if (!this.longTouchActivatedSubject.getValue()) {
|
|
92
|
+
const paneId = ((_a = this.paneManager.getPaneIfHit({ x: clientX, y: clientY })) === null || _a === void 0 ? void 0 : _a.uuid) || '';
|
|
93
|
+
this.createAndFireHover([clientX, clientY, paneId]);
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
// update crosstool placement coordinates
|
|
97
|
+
this.crossEventProducer.crossToolTouchInfo.temp = {
|
|
98
|
+
x: clientX - this.canvasBoundsContainer.canvasOnPageLocation.x,
|
|
99
|
+
y: clientY - this.canvasBoundsContainer.canvasOnPageLocation.y,
|
|
100
|
+
};
|
|
90
101
|
}
|
|
91
102
|
}));
|
|
92
|
-
// special handling for mobile
|
|
93
103
|
// on long touch - disable panning and show cross tool
|
|
94
104
|
const hitTest = this.canvasBoundsContainer.getBoundsHitTest(CanvasElement.ALL_PANES);
|
|
95
105
|
this.addRxSubscription(this.canvasInputListener.observeLongTouchStart(hitTest).subscribe(event => {
|
|
96
106
|
var _a;
|
|
97
|
-
this.
|
|
107
|
+
this.crossEventProducer.crossToolHover = null;
|
|
108
|
+
this.crossEventProducer.crossToolTouchInfo.isCommonTap = false;
|
|
109
|
+
// don't lock chart and show crosshair if chart is being moved, crosstool is not enabled or we do pinch event
|
|
110
|
+
const longTouchCrosshairPredicate = this.mainCanvasTouchHandler.canvasTouchInfo.isMoving ||
|
|
111
|
+
this.chartModel.config.components.crossTool.type === 'none' ||
|
|
112
|
+
event.touches.length > 1;
|
|
113
|
+
if (longTouchCrosshairPredicate) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
98
116
|
this.longTouchActivatedSubject.next(true);
|
|
117
|
+
this.crossEventProducer.crossToolTouchInfo.isSet = false;
|
|
99
118
|
const x = event.touches[0].clientX - this.canvasBoundsContainer.canvasOnPageLocation.x;
|
|
100
119
|
const y = event.touches[0].clientY - this.canvasBoundsContainer.canvasOnPageLocation.y;
|
|
120
|
+
this.crossEventProducer.crossToolTouchInfo.fixed = {
|
|
121
|
+
x,
|
|
122
|
+
y,
|
|
123
|
+
};
|
|
101
124
|
const paneId = ((_a = this.paneManager.getPaneIfHit({ x, y })) === null || _a === void 0 ? void 0 : _a.uuid) || '';
|
|
102
125
|
this.createAndFireHover([x, y, paneId]);
|
|
103
126
|
this.crossEventProducer.crossSubject.next([x, y, paneId]);
|
|
127
|
+
this.paneManager.chartPanComponent.setChartPanningOptions(false, false);
|
|
104
128
|
}));
|
|
105
|
-
this.addRxSubscription(this.canvasInputListener.observeTouchEndDocument().subscribe(
|
|
106
|
-
|
|
107
|
-
|
|
129
|
+
this.addRxSubscription(this.canvasInputListener.observeTouchEndDocument().subscribe(event => {
|
|
130
|
+
var _a, _b;
|
|
131
|
+
const { clientX, clientY } = event.changedTouches[0];
|
|
132
|
+
const { fixed, temp } = this.crossEventProducer.crossToolTouchInfo;
|
|
133
|
+
const x = clientX - this.canvasBoundsContainer.canvasOnPageLocation.x;
|
|
134
|
+
const y = clientY - this.canvasBoundsContainer.canvasOnPageLocation.y;
|
|
135
|
+
// common tap without moving, hide crosstool
|
|
136
|
+
if (this.crossEventProducer.crossToolTouchInfo.isCommonTap &&
|
|
137
|
+
!checkChartIsMoving(x, temp.x, y, temp.y)) {
|
|
138
|
+
this.paneManager.chartPanComponent.setChartPanningOptions(true, true);
|
|
108
139
|
this.longTouchActivatedSubject.next(false);
|
|
109
140
|
this.crossEventProducer.fireCrossClose();
|
|
141
|
+
this.crossEventProducer.crossToolHover = null;
|
|
142
|
+
}
|
|
143
|
+
if (!this.crossEventProducer.crossToolTouchInfo.isSet) {
|
|
144
|
+
this.crossEventProducer.crossToolTouchInfo.isSet = true;
|
|
145
|
+
this.crossEventProducer.crossToolTouchInfo.fixed = {
|
|
146
|
+
x,
|
|
147
|
+
y,
|
|
148
|
+
};
|
|
149
|
+
this.crossEventProducer.crossToolTouchInfo.isSet = true;
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
const pane = (_b = (_a = this.crossEventProducer.crossToolHover) === null || _a === void 0 ? void 0 : _a.paneId) !== null && _b !== void 0 ? _b : 'CHART';
|
|
153
|
+
const paneBounds = this.canvasBoundsContainer.getBounds(CanvasElement.PANE_UUID(pane));
|
|
154
|
+
const paneYStart = paneBounds.y + 5;
|
|
155
|
+
const paneYEnd = paneBounds.y + paneBounds.height - 5;
|
|
156
|
+
const xDiff = x - temp.x;
|
|
157
|
+
const yDiff = y - temp.y;
|
|
158
|
+
const newX = fixed.x < 0 ? 0 : fixed.x > paneBounds.width ? paneBounds.width : (fixed.x += xDiff);
|
|
159
|
+
const newY = fixed.y < paneYStart ? paneYStart : fixed.y > paneYEnd ? paneYEnd : (fixed.y += yDiff);
|
|
160
|
+
this.crossEventProducer.crossToolTouchInfo.fixed = { x: newX, y: newY };
|
|
110
161
|
}
|
|
111
162
|
}));
|
|
112
|
-
|
|
163
|
+
//#endregion
|
|
113
164
|
}
|
|
114
165
|
/**
|
|
115
166
|
* Recalculates the cross tool X formatter.
|
|
@@ -198,12 +249,15 @@ export class HoverProducerComponent extends ChartBaseElement {
|
|
|
198
249
|
* @returns {void}
|
|
199
250
|
*/
|
|
200
251
|
fireHover(hover) {
|
|
201
|
-
var _a;
|
|
252
|
+
var _a, _b;
|
|
202
253
|
if (hover) {
|
|
203
254
|
// special handling for mobile
|
|
204
|
-
// set active candle + show cross tool only when
|
|
255
|
+
// set active candle + show cross tool only when crosstool is active
|
|
205
256
|
if (isMobile() && this.config.components.crossTool.type !== 'none') {
|
|
206
|
-
const
|
|
257
|
+
const crossToolHover = this.crossEventProducer.crossToolHover;
|
|
258
|
+
const candle = crossToolHover
|
|
259
|
+
? (_a = crossToolHover.candleHover) === null || _a === void 0 ? void 0 : _a.visualCandle.candle
|
|
260
|
+
: (_b = hover.candleHover) === null || _b === void 0 ? void 0 : _b.visualCandle.candle;
|
|
207
261
|
candle && this.chartModel.mainCandleSeries.setActiveCandle(candle);
|
|
208
262
|
}
|
|
209
263
|
this.hoverSubject.next(hover);
|
|
@@ -8,6 +8,8 @@ import { CanvasInputListenerComponent } from '../inputlisteners/canvas-input-lis
|
|
|
8
8
|
import { ScaleModel } from '../model/scale.model';
|
|
9
9
|
import { ChartAreaPanHandler } from '../components/chart/chart-area-pan.handler';
|
|
10
10
|
import { HitBoundsTest } from '../canvas/canvas-bounds-container';
|
|
11
|
+
import { Pixel } from '../model/scaling/viewport.model';
|
|
12
|
+
export declare const PIXELS_FOR_MOVE = 2;
|
|
11
13
|
/**
|
|
12
14
|
* Handles chart touch events.
|
|
13
15
|
*/
|
|
@@ -18,6 +20,13 @@ export declare class MainCanvasTouchHandler extends ChartBaseElement {
|
|
|
18
20
|
private mainCanvasParent;
|
|
19
21
|
private hitTest;
|
|
20
22
|
private touchedCandleIndexes;
|
|
23
|
+
canvasTouchInfo: {
|
|
24
|
+
touchStart: {
|
|
25
|
+
x: Pixel;
|
|
26
|
+
y: Pixel;
|
|
27
|
+
};
|
|
28
|
+
isMoving?: boolean;
|
|
29
|
+
};
|
|
21
30
|
constructor(chartAreaPanHandler: ChartAreaPanHandler, scale: ScaleModel, canvasInputListeners: CanvasInputListenerComponent, mainCanvasParent: Element, hitTest: HitBoundsTest);
|
|
22
31
|
/**
|
|
23
32
|
* Activates canvas input listeners for touch start and touch move events.
|
|
@@ -56,3 +65,4 @@ export declare class MainCanvasTouchHandler extends ChartBaseElement {
|
|
|
56
65
|
*/
|
|
57
66
|
pinchHandler(candleIndexes: Array<number>, touchPositions: number[]): void;
|
|
58
67
|
}
|
|
68
|
+
export declare const checkChartIsMoving: (x1: Pixel, x2: Pixel, y1: Pixel, y2: Pixel, pixelsToMove?: Pixel) => boolean;
|
|
@@ -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 { ChartBaseElement } from '../model/chart-base-element';
|
|
7
|
+
export const PIXELS_FOR_MOVE = 2;
|
|
7
8
|
/**
|
|
8
9
|
* Handles chart touch events.
|
|
9
10
|
*/
|
|
@@ -17,6 +18,12 @@ export class MainCanvasTouchHandler extends ChartBaseElement {
|
|
|
17
18
|
this.hitTest = hitTest;
|
|
18
19
|
// 2 candles indexes touched by 2 fingers when pinching
|
|
19
20
|
this.touchedCandleIndexes = [0, 0];
|
|
21
|
+
// stores the information about touch events
|
|
22
|
+
this.canvasTouchInfo = {
|
|
23
|
+
touchStart: { x: 0, y: 0 },
|
|
24
|
+
// uses touch start to determine if chart is being moved
|
|
25
|
+
isMoving: false,
|
|
26
|
+
};
|
|
20
27
|
}
|
|
21
28
|
/**
|
|
22
29
|
* Activates canvas input listeners for touch start and touch move events.
|
|
@@ -34,6 +41,10 @@ export class MainCanvasTouchHandler extends ChartBaseElement {
|
|
|
34
41
|
* @returns {void}
|
|
35
42
|
*/
|
|
36
43
|
handleTouchStartEvent(e) {
|
|
44
|
+
const { clientX, clientY } = e.touches[0];
|
|
45
|
+
if (e.touches.length === 1) {
|
|
46
|
+
this.canvasTouchInfo.touchStart = { x: clientX, y: clientY };
|
|
47
|
+
}
|
|
37
48
|
if (e.touches.length === 2) {
|
|
38
49
|
this.chartAreaPanHandler.deactivate();
|
|
39
50
|
// @ts-ignore
|
|
@@ -47,6 +58,11 @@ export class MainCanvasTouchHandler extends ChartBaseElement {
|
|
|
47
58
|
* @returns {void}
|
|
48
59
|
*/
|
|
49
60
|
handleTouchMoveEvent(e) {
|
|
61
|
+
const { clientX, clientY } = e.touches[0];
|
|
62
|
+
const { touchStart } = this.canvasTouchInfo;
|
|
63
|
+
if (e.touches.length === 1) {
|
|
64
|
+
this.canvasTouchInfo.isMoving = checkChartIsMoving(clientX, touchStart.x, clientY, touchStart.y);
|
|
65
|
+
}
|
|
50
66
|
if (e.touches.length === 2) {
|
|
51
67
|
this.pinchHandler(this.touchedCandleIndexes, this.getXPositions(e));
|
|
52
68
|
}
|
|
@@ -56,6 +72,7 @@ export class MainCanvasTouchHandler extends ChartBaseElement {
|
|
|
56
72
|
* @returns {void}
|
|
57
73
|
*/
|
|
58
74
|
handleTouchEndEvent(e) {
|
|
75
|
+
this.canvasTouchInfo.isMoving = false;
|
|
59
76
|
// zero touches means the user stopped resizing completely (both fingers are up)
|
|
60
77
|
if (e.touches.length === 0) {
|
|
61
78
|
this.chartAreaPanHandler.activate();
|
|
@@ -95,3 +112,4 @@ export class MainCanvasTouchHandler extends ChartBaseElement {
|
|
|
95
112
|
this.scale.setXScale(first, last);
|
|
96
113
|
}
|
|
97
114
|
}
|
|
115
|
+
export const checkChartIsMoving = (x1, x2, y1, y2, pixelsToMove = PIXELS_FOR_MOVE) => Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2)) > pixelsToMove;
|
|
@@ -200,10 +200,8 @@ class CanvasInputListenerComponent extends ChartBaseElement {
|
|
|
200
200
|
};
|
|
201
201
|
this.addSubscription(subscribeListener(this.element, doubleTapListenerProducer, 'touchend'));
|
|
202
202
|
// workaround to handle long touch start/end for iOS
|
|
203
|
-
const longTouchListeners = (e, delay =
|
|
203
|
+
const longTouchListeners = (e, delay = 200) => {
|
|
204
204
|
e.preventDefault();
|
|
205
|
-
const initialCoords = { x: e.touches[0].clientX, y: e.touches[0].clientY };
|
|
206
|
-
let coords = { x: 0, y: 0 };
|
|
207
205
|
let longTouchStart = false;
|
|
208
206
|
let timerLongTouchStart = null;
|
|
209
207
|
// start timeout for long touch
|
|
@@ -213,11 +211,8 @@ class CanvasInputListenerComponent extends ChartBaseElement {
|
|
|
213
211
|
}, delay);
|
|
214
212
|
const touchMoveHandler = (e) => {
|
|
215
213
|
e.preventDefault();
|
|
216
|
-
coords = { x: e.touches[0].clientX, y: e.touches[0].clientY };
|
|
217
214
|
// clear long touch timeout if move area is bigger than pixelsForMove
|
|
218
|
-
if (
|
|
219
|
-
pixelsForMoveReset ||
|
|
220
|
-
e.touches.length > 1) {
|
|
215
|
+
if (e.touches.length > 1) {
|
|
221
216
|
timerLongTouchStart && clearTimeout(timerLongTouchStart);
|
|
222
217
|
}
|
|
223
218
|
};
|
|
@@ -123,7 +123,7 @@ export class CandleSeriesModel extends DataSeriesModel {
|
|
|
123
123
|
* @returns {HighLowWithIndex} - An object containing the high-low values along with their corresponding indexes.
|
|
124
124
|
*/
|
|
125
125
|
recalculateZippedHighLow() {
|
|
126
|
-
return (this.zippedHighLow = calculateCandlesHighLow(this.visualPoints.slice(this.dataIdxStart, this.dataIdxEnd)));
|
|
126
|
+
return (this.zippedHighLow = calculateCandlesHighLow(this.visualPoints.slice(this.dataIdxStart, this.dataIdxEnd + 1)));
|
|
127
127
|
}
|
|
128
128
|
/**
|
|
129
129
|
* Updates the current price and the last price movement.
|