@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.
Files changed (43) hide show
  1. package/dist/chart/bootstrap.js +1 -1
  2. package/dist/chart/canvas/canvas-bounds-container.d.ts +5 -4
  3. package/dist/chart/canvas/canvas-bounds-container.js +8 -5
  4. package/dist/chart/chart.config.d.ts +48 -12
  5. package/dist/chart/chart.config.js +27 -6
  6. package/dist/chart/components/chart/chart-area-pan.handler.d.ts +3 -2
  7. package/dist/chart/components/chart/chart-area-pan.handler.js +5 -4
  8. package/dist/chart/components/cross_tool/cross-tool.component.js +2 -2
  9. package/dist/chart/components/cross_tool/cross-tool.drawer.d.ts +3 -1
  10. package/dist/chart/components/cross_tool/cross-tool.drawer.js +4 -3
  11. package/dist/chart/components/cross_tool/cross-tool.model.d.ts +6 -6
  12. package/dist/chart/components/cross_tool/cross-tool.model.js +42 -11
  13. package/dist/chart/components/cross_tool/types/cross-and-labels.drawer.js +3 -3
  14. package/dist/chart/components/events/events-custom-icons.d.ts +33 -0
  15. package/dist/chart/components/events/events-custom-icons.js +52 -0
  16. package/dist/chart/components/events/events.drawer.d.ts +5 -30
  17. package/dist/chart/components/events/events.drawer.js +33 -69
  18. package/dist/chart/components/high_low/high-low.drawer.js +1 -1
  19. package/dist/chart/components/pane/pane-manager.component.d.ts +6 -0
  20. package/dist/chart/components/pane/pane-manager.component.js +24 -3
  21. package/dist/chart/components/pane/pane.component.d.ts +16 -5
  22. package/dist/chart/components/pane/pane.component.js +27 -4
  23. package/dist/chart/components/resizer/bar-resizer.component.d.ts +1 -0
  24. package/dist/chart/components/resizer/bar-resizer.component.js +1 -0
  25. package/dist/chart/components/x_axis/x-axis-draw.functions.js +2 -2
  26. package/dist/chart/components/x_axis/x-axis-scale.handler.d.ts +1 -0
  27. package/dist/chart/components/x_axis/x-axis-scale.handler.js +37 -8
  28. package/dist/chart/components/x_axis/x-axis-time-labels.drawer.js +2 -2
  29. package/dist/chart/components/y_axis/price_labels/y-axis-labels.model.d.ts +3 -1
  30. package/dist/chart/components/y_axis/price_labels/y-axis-labels.model.js +4 -1
  31. package/dist/chart/components/y_axis/y-axis-scale.handler.d.ts +2 -0
  32. package/dist/chart/components/y_axis/y-axis-scale.handler.js +12 -0
  33. package/dist/chart/inputhandlers/cross-event-producer.component.d.ts +22 -0
  34. package/dist/chart/inputhandlers/cross-event-producer.component.js +11 -1
  35. package/dist/chart/inputhandlers/hover-producer.component.d.ts +5 -3
  36. package/dist/chart/inputhandlers/hover-producer.component.js +70 -16
  37. package/dist/chart/inputhandlers/main-canvas-touch.handler.d.ts +10 -0
  38. package/dist/chart/inputhandlers/main-canvas-touch.handler.js +18 -0
  39. package/dist/chart/inputlisteners/canvas-input-listener.component.js +2 -7
  40. package/dist/chart/model/candle-series.model.js +1 -1
  41. package/dist/chart/model/data-series.model.js +18 -0
  42. package/dist/dxchart.min.js +4 -4
  43. 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
- else {
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
- private longTouchActivatedSubject;
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
- private createHover;
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
- const x = event.touches[0].clientX - this.canvasBoundsContainer.canvasOnPageLocation.x;
85
- const y = event.touches[0].clientY - this.canvasBoundsContainer.canvasOnPageLocation.y;
86
- const candle = this.chartModel.candleFromX(x, true);
87
- const paneId = ((_a = this.paneManager.getPaneIfHit({ x, y })) === null || _a === void 0 ? void 0 : _a.uuid) || '';
88
- if (candle) {
89
- this.createAndFireHover([x, y, paneId]);
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.paneManager.chartPanComponent.deactivatePanHandlers();
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
- this.paneManager.chartPanComponent.activateChartPanHandlers();
107
- if (this.longTouchActivatedSubject.getValue()) {
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
- this.addRxSubscription(merge(this.chartModel.candlesSetSubject, this.timeZoneModel.observeTimeZoneChanged()).subscribe(() => this.recalculateCrossToolXFormatter()));
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 long tap
255
+ // set active candle + show cross tool only when crosstool is active
205
256
  if (isMobile() && this.config.components.crossTool.type !== 'none') {
206
- const candle = (_a = hover.candleHover) === null || _a === void 0 ? void 0 : _a.visualCandle.candle;
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 = 700, pixelsForMoveReset = 3) => {
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 (Math.sqrt(Math.pow(coords.x - initialCoords.x, 2) + Math.pow(coords.y - initialCoords.y, 2)) >
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)