@devexperts/dxcharts-lite 2.6.0 → 2.6.2
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 +5 -4
- package/dist/chart/canvas/canvas-bounds-container.js +8 -5
- package/dist/chart/chart.config.d.ts +48 -12
- package/dist/chart/chart.config.js +27 -6
- package/dist/chart/components/chart/chart-area-pan.handler.d.ts +3 -2
- package/dist/chart/components/chart/chart-area-pan.handler.js +5 -4
- 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/events/events-custom-icons.d.ts +33 -0
- package/dist/chart/components/events/events-custom-icons.js +52 -0
- package/dist/chart/components/events/events.drawer.d.ts +5 -30
- package/dist/chart/components/events/events.drawer.js +33 -69
- package/dist/chart/components/high_low/high-low.drawer.js +1 -1
- package/dist/chart/components/pane/pane-manager.component.d.ts +6 -0
- package/dist/chart/components/pane/pane-manager.component.js +24 -3
- package/dist/chart/components/pane/pane.component.d.ts +16 -5
- package/dist/chart/components/pane/pane.component.js +27 -4
- package/dist/chart/components/resizer/bar-resizer.component.d.ts +1 -0
- package/dist/chart/components/resizer/bar-resizer.component.js +1 -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/components/y_axis/price_labels/y-axis-labels.model.d.ts +3 -1
- package/dist/chart/components/y_axis/price_labels/y-axis-labels.model.js +4 -1
- package/dist/chart/components/y_axis/y-axis-scale.handler.d.ts +2 -0
- package/dist/chart/components/y_axis/y-axis-scale.handler.js +12 -0
- 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/chart/model/data-series.model.js +18 -0
- package/dist/dxchart.min.js +4 -4
- package/package.json +1 -1
|
@@ -30,10 +30,12 @@ export declare class YAxisScaleHandler extends ChartBaseElement {
|
|
|
30
30
|
lastYEnd: Unit;
|
|
31
31
|
lastYHeight: Unit;
|
|
32
32
|
lastYPxHeight: Pixel;
|
|
33
|
+
private dragNDropYComponent;
|
|
33
34
|
private dblClickCallback;
|
|
34
35
|
private touches;
|
|
35
36
|
private dblTapCallback;
|
|
36
37
|
constructor(bus: EventBus, config: YAxisConfig, panning: ChartPanComponent, scale: ScaleModel, canvasInputListener: CanvasInputListenerComponent, bounds: CanvasBoundsContainer, hitTest: HitBoundsTest, hitTestCanvasModel: HitTestCanvasModel);
|
|
38
|
+
isDragging(): boolean;
|
|
37
39
|
protected doActivate(): void;
|
|
38
40
|
private onYDragStart;
|
|
39
41
|
private onYDragTick;
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (C) 2019 - 2024 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
|
+
*/
|
|
1
6
|
/*
|
|
2
7
|
* Copyright (C) 2019 - 2024 Devexperts Solutions IE Limited
|
|
3
8
|
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
|
@@ -87,7 +92,14 @@ export class YAxisScaleHandler extends ChartBaseElement {
|
|
|
87
92
|
dragPredicate: () => panning.chartAreaPanHandler.chartPanningOptions.vertical && config.type !== 'percent',
|
|
88
93
|
});
|
|
89
94
|
this.addChildEntity(dragNDropYComponent);
|
|
95
|
+
this.dragNDropYComponent = dragNDropYComponent;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
isDragging() {
|
|
99
|
+
if (!this.dragNDropYComponent) {
|
|
100
|
+
return false;
|
|
90
101
|
}
|
|
102
|
+
return Math.abs(this.dragNDropYComponent.draggedPixels) > 0;
|
|
91
103
|
}
|
|
92
104
|
doActivate() {
|
|
93
105
|
if (this.config.customScaleDblClick) {
|
|
@@ -8,15 +8,36 @@ import { CanvasBoundsContainer, HitBoundsTest, HitBoundsTestOptionsPartial } fro
|
|
|
8
8
|
import { CanvasInputListenerComponent } from '../inputlisteners/canvas-input-listener.component';
|
|
9
9
|
import { ChartBaseElement } from '../model/chart-base-element';
|
|
10
10
|
import { Unsubscriber } from '../utils/function.utils';
|
|
11
|
+
import { Pixel } from '../model/scaling/viewport.model';
|
|
12
|
+
import { Hover } from './hover-producer.component';
|
|
11
13
|
/**
|
|
12
14
|
* [x, y, uuid - Unique identifier for the subscription]
|
|
13
15
|
*/
|
|
14
16
|
export type CrossEvent = [number, number, string];
|
|
17
|
+
interface CrossToolTouchInfo {
|
|
18
|
+
fixed: {
|
|
19
|
+
x: Pixel;
|
|
20
|
+
y: Pixel;
|
|
21
|
+
};
|
|
22
|
+
temp: {
|
|
23
|
+
x: Pixel;
|
|
24
|
+
y: Pixel;
|
|
25
|
+
};
|
|
26
|
+
isSet: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* additional flag to determine ordinary and long taps
|
|
29
|
+
* crosstool shouldn't be hidden after longtouch event even if coordinates are the same
|
|
30
|
+
* becomes true after touchStart and false after longTouchStart
|
|
31
|
+
*/
|
|
32
|
+
isCommonTap: boolean;
|
|
33
|
+
}
|
|
15
34
|
export declare class CrossEventProducerComponent extends ChartBaseElement {
|
|
16
35
|
private canvasInputListener;
|
|
17
36
|
private canvasBoundsContainer;
|
|
18
37
|
panesSubscriptions: Partial<Record<string, Subscription>>;
|
|
19
38
|
crossSubject: BehaviorSubject<CrossEvent | null>;
|
|
39
|
+
crossToolHover: Hover | null;
|
|
40
|
+
crossToolTouchInfo: CrossToolTouchInfo;
|
|
20
41
|
constructor(canvasInputListener: CanvasInputListenerComponent, canvasBoundsContainer: CanvasBoundsContainer);
|
|
21
42
|
protected doActivate(): void;
|
|
22
43
|
/**
|
|
@@ -45,3 +66,4 @@ export declare class CrossEventProducerComponent extends ChartBaseElement {
|
|
|
45
66
|
*/
|
|
46
67
|
subscribeMouseOverHT(uuid: string, hitTest: HitBoundsTest): Unsubscriber;
|
|
47
68
|
}
|
|
69
|
+
export {};
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import { BehaviorSubject, combineLatest } from 'rxjs';
|
|
7
7
|
import { filter } from 'rxjs/operators';
|
|
8
8
|
import { ChartBaseElement } from '../model/chart-base-element';
|
|
9
|
+
import { isMobile } from '../utils/device/browser.utils';
|
|
9
10
|
export class CrossEventProducerComponent extends ChartBaseElement {
|
|
10
11
|
constructor(canvasInputListener, canvasBoundsContainer) {
|
|
11
12
|
super();
|
|
@@ -13,6 +14,14 @@ export class CrossEventProducerComponent extends ChartBaseElement {
|
|
|
13
14
|
this.canvasBoundsContainer = canvasBoundsContainer;
|
|
14
15
|
this.panesSubscriptions = {};
|
|
15
16
|
this.crossSubject = new BehaviorSubject(null);
|
|
17
|
+
// mobile specific crosstool hover and touch info
|
|
18
|
+
this.crossToolHover = null;
|
|
19
|
+
this.crossToolTouchInfo = {
|
|
20
|
+
fixed: { x: 0, y: 0 },
|
|
21
|
+
temp: { x: 0, y: 0 },
|
|
22
|
+
isSet: false,
|
|
23
|
+
isCommonTap: false,
|
|
24
|
+
};
|
|
16
25
|
}
|
|
17
26
|
doActivate() {
|
|
18
27
|
super.doActivate();
|
|
@@ -62,7 +71,8 @@ export class CrossEventProducerComponent extends ChartBaseElement {
|
|
|
62
71
|
this.crossSubject.next(cross);
|
|
63
72
|
closeHoverFired = false;
|
|
64
73
|
}
|
|
65
|
-
|
|
74
|
+
// crosstool should be hidden if hovering nonpane only on desktop
|
|
75
|
+
if (!enter && !isMobile()) {
|
|
66
76
|
this.crossSubject.next(null);
|
|
67
77
|
closeHoverFired = true;
|
|
68
78
|
}
|
|
@@ -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.
|
|
@@ -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 { DataSeriesYAxisLabelsProvider } from '../components/y_axis/price_labels/data-series-y-axis-labels.provider';
|
|
7
|
+
import { LabelsGroups } from '../components/y_axis/price_labels/y-axis-labels.model';
|
|
7
8
|
import { binarySearch, create2DArray, lastOf, slice2DArray } from '../utils/array.utils';
|
|
8
9
|
import { floorToDPR } from '../utils/device/device-pixel-ratio.utils';
|
|
9
10
|
import { MathUtils } from '../utils/math.utils';
|
|
@@ -141,6 +142,7 @@ export class DataSeriesModel extends ChartBaseElement {
|
|
|
141
142
|
this.addRxSubscription(this.scale.xChanged.subscribe(() => this.recalculateDataViewportIndexes()));
|
|
142
143
|
this.addRxSubscription(this.scale.scaleInversedSubject.subscribe(() => {
|
|
143
144
|
this.recalculateVisualPoints();
|
|
145
|
+
this.extentComponent.dynamicObjectsCanvasModel.fireDraw();
|
|
144
146
|
}));
|
|
145
147
|
}
|
|
146
148
|
/**
|
|
@@ -161,12 +163,28 @@ export class DataSeriesModel extends ChartBaseElement {
|
|
|
161
163
|
*/
|
|
162
164
|
moveToExtent(extent) {
|
|
163
165
|
var _a;
|
|
166
|
+
const prevExtent = Object.assign({}, this.extentComponent);
|
|
164
167
|
this.extentComponent.removeDataSeries(this);
|
|
165
168
|
this.extentComponent = extent;
|
|
166
169
|
this.scale = extent.scale;
|
|
167
170
|
this.view = new DataSeriesView(this, this.scale, () => this.extentComponent.yAxis.getAxisType(), this.getBaseline);
|
|
168
171
|
this.yAxisLabelProvider.yAxisBoundsProvider = extent.getYAxisBounds;
|
|
169
172
|
this.yAxisLabelProvider.axisState = (_a = extent.yAxis) === null || _a === void 0 ? void 0 : _a.state;
|
|
173
|
+
// move data series labels
|
|
174
|
+
const prevExtentMainLabels = prevExtent.yAxis.model.fancyLabelsModel.labelsProviders[LabelsGroups.MAIN];
|
|
175
|
+
const dataSeriesLabelsId = prevExtentMainLabels && Object.keys(prevExtentMainLabels).find(p => this.parentId && p === this.parentId);
|
|
176
|
+
const currentMainLabels = this.extentComponent.yAxis.model.fancyLabelsModel.labelsProviders[LabelsGroups.MAIN];
|
|
177
|
+
if (dataSeriesLabelsId) {
|
|
178
|
+
const labelsProvider = prevExtentMainLabels[dataSeriesLabelsId];
|
|
179
|
+
labelsProvider.yAxisBoundsProvider = extent.getYAxisBounds;
|
|
180
|
+
// main group is not created yet (new extent without labels) or main group exists but no data series labels so far
|
|
181
|
+
if (!currentMainLabels || (currentMainLabels && !currentMainLabels[dataSeriesLabelsId])) {
|
|
182
|
+
// create new data series labels group on the new extent
|
|
183
|
+
this.extentComponent.yAxis.model.fancyLabelsModel.registerYAxisLabelsProvider(LabelsGroups.MAIN, labelsProvider, dataSeriesLabelsId);
|
|
184
|
+
// remove labels from previous extent
|
|
185
|
+
prevExtent.yAxis.model.fancyLabelsModel.unregisterYAxisLabelsProvider(LabelsGroups.MAIN, dataSeriesLabelsId);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
170
188
|
// shut down old subscriptions
|
|
171
189
|
this.deactivate();
|
|
172
190
|
// and apply new ones (with updated scaleModel)
|