@devexperts/dxcharts-lite 1.0.2 → 2.0.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/README.md +2 -2
- package/dist/chart/animation/canvas-animation.js +134 -1
- package/dist/chart/animation/types/animation.js +43 -1
- package/dist/chart/animation/types/color-alpha-animation.d.ts +1 -1
- package/dist/chart/animation/types/color-alpha-animation.js +60 -1
- package/dist/chart/animation/types/color-transition-animation.d.ts +1 -1
- package/dist/chart/animation/types/color-transition-animation.js +86 -1
- package/dist/chart/animation/types/viewport-movement-animation.js +63 -1
- package/dist/chart/animation/viewport-model-animation.js +20 -1
- package/dist/chart/bootstrap.d.ts +51 -48
- package/dist/chart/bootstrap.js +449 -1
- package/dist/chart/canvas/canvas-bounds-container.d.ts +0 -5
- package/dist/chart/canvas/canvas-bounds-container.js +815 -1
- package/dist/chart/canvas/canvas-chart-html.js +16 -18
- package/dist/chart/canvas/chart-elements.d.ts +1 -4
- package/dist/chart/canvas/chart-elements.js +22 -1
- package/dist/chart/canvas/cursor.handler.js +122 -1
- package/dist/chart/canvas/layout-creator.js +34 -1
- package/dist/chart/canvas/y-axis-bounds.container.d.ts +2 -2
- package/dist/chart/canvas/y-axis-bounds.container.js +67 -1
- package/dist/chart/chart-container.js +1 -1
- package/dist/chart/chart.config.d.ts +4 -5
- package/dist/chart/chart.config.js +645 -1
- package/dist/chart/chart.d.ts +62 -0
- package/dist/chart/chart.js +106 -0
- package/dist/chart/components/chart/basic-scale.d.ts +2 -2
- package/dist/chart/components/chart/basic-scale.js +31 -1
- package/dist/chart/components/chart/candle-transformer.functions.js +15 -1
- package/dist/chart/components/chart/candle-width-calculator.functions.js +2 -1
- package/dist/chart/components/chart/candle.functions.js +44 -1
- package/dist/chart/components/chart/chart-area-pan.handler.d.ts +3 -3
- package/dist/chart/components/chart/chart-area-pan.handler.js +197 -1
- package/dist/chart/components/chart/chart-base.model.js +66 -1
- package/dist/chart/components/chart/chart.component.d.ts +7 -3
- package/dist/chart/components/chart/chart.component.js +408 -1
- package/dist/chart/components/chart/chart.model.d.ts +4 -11
- package/dist/chart/components/chart/chart.model.js +954 -1
- package/dist/chart/components/chart/data-series.high-low-provider.js +34 -1
- package/dist/chart/components/chart/fake-candles.js +97 -1
- package/dist/chart/components/chart/price.formatter.js +35 -1
- package/dist/chart/components/chart/secondary-chart-colors-pool.js +68 -1
- package/dist/chart/components/cross_tool/cross-tool.component.js +85 -1
- package/dist/chart/components/cross_tool/cross-tool.drawer.js +32 -1
- package/dist/chart/components/cross_tool/cross-tool.model.js +107 -1
- package/dist/chart/components/cross_tool/types/cross-and-labels.drawer.js +137 -1
- package/dist/chart/components/cross_tool/types/none.drawer.js +3 -1
- package/dist/chart/components/dran-n-drop_helper/drag-n-drop-x.component.js +28 -1
- package/dist/chart/components/dran-n-drop_helper/drag-n-drop-y.component.js +24 -1
- package/dist/chart/components/dran-n-drop_helper/drag-n-drop.component.js +53 -1
- package/dist/chart/components/dynamic-objects/dynamic-objects.component.d.ts +13 -0
- package/dist/chart/components/dynamic-objects/dynamic-objects.component.js +20 -0
- package/dist/chart/components/dynamic-objects/dynamic-objects.drawer.d.ts +18 -0
- package/dist/chart/components/dynamic-objects/dynamic-objects.drawer.js +23 -0
- package/dist/chart/components/dynamic-objects/dynamic-objects.model.d.ts +63 -0
- package/dist/chart/components/dynamic-objects/dynamic-objects.model.js +136 -0
- package/dist/chart/components/events/events-hit-test.drawer.js +63 -1
- package/dist/chart/components/events/events.component.js +61 -1
- package/dist/chart/components/events/events.drawer.js +195 -1
- package/dist/chart/components/events/events.model.js +69 -1
- package/dist/chart/components/grid/grid.component.d.ts +2 -2
- package/dist/chart/components/grid/grid.component.js +31 -1
- package/dist/chart/components/grid/grid.drawer.d.ts +4 -3
- package/dist/chart/components/grid/grid.drawer.js +106 -1
- package/dist/chart/components/high_low/high-low.component.js +12 -1
- package/dist/chart/components/high_low/high-low.drawer.js +126 -1
- package/dist/chart/components/highlights/highlights.component.js +46 -1
- package/dist/chart/components/highlights/highlights.drawer.js +154 -1
- package/dist/chart/components/highlights/highlights.model.js +75 -1
- package/dist/chart/components/labels_generator/numeric-axis-labels.generator.d.ts +1 -1
- package/dist/chart/components/labels_generator/numeric-axis-labels.generator.js +199 -1
- package/dist/chart/components/navigation_map/navigation-map-move.handler.d.ts +2 -2
- package/dist/chart/components/navigation_map/navigation-map-move.handler.js +108 -1
- package/dist/chart/components/navigation_map/navigation-map.component.js +112 -1
- package/dist/chart/components/navigation_map/navigation-map.drawer.js +244 -1
- package/dist/chart/components/navigation_map/navigation-map.model.js +33 -2
- package/dist/chart/components/pan/chart-pan.component.d.ts +2 -2
- package/dist/chart/components/pan/chart-pan.component.js +51 -1
- package/dist/chart/components/pane/extent/y-extent-component.d.ts +12 -18
- package/dist/chart/components/pane/extent/y-extent-component.js +120 -1
- package/dist/chart/components/pane/pane-hit-test.controller.d.ts +2 -2
- package/dist/chart/components/pane/pane-hit-test.controller.js +55 -1
- package/dist/chart/components/pane/pane-manager.component.d.ts +12 -6
- package/dist/chart/components/pane/pane-manager.component.js +149 -1
- package/dist/chart/components/pane/pane.component.d.ts +16 -32
- package/dist/chart/components/pane/pane.component.js +278 -1
- package/dist/chart/components/resizer/bar-resizer.component.js +139 -1
- package/dist/chart/components/resizer/bar-resizer.drawer.js +46 -1
- package/dist/chart/components/snapshot/snapshot.component.js +48 -1
- package/dist/chart/components/volumes/separate-volumes.component.d.ts +6 -10
- package/dist/chart/components/volumes/separate-volumes.component.js +63 -1
- package/dist/chart/components/volumes/volume-color-resolvers.functions.js +18 -1
- package/dist/chart/components/volumes/volumes.component.d.ts +6 -7
- package/dist/chart/components/volumes/volumes.component.js +94 -1
- package/dist/chart/components/volumes/volumes.drawer.d.ts +5 -12
- package/dist/chart/components/volumes/volumes.drawer.js +140 -1
- package/dist/chart/components/volumes/volumes.formatter.js +31 -1
- package/dist/chart/components/volumes/volumes.model.d.ts +2 -2
- package/dist/chart/components/volumes/volumes.model.js +43 -1
- package/dist/chart/components/watermark/water-mark.component.js +103 -1
- package/dist/chart/components/watermark/water-mark.drawer.js +187 -1
- package/dist/chart/components/x_axis/numeric-x-axis-labels.generator.js +27 -1
- package/dist/chart/components/x_axis/time/parser/time-formats-matchers.functions.js +187 -1
- package/dist/chart/components/x_axis/time/parser/time-formats-parser.functions.js +76 -1
- package/dist/chart/components/x_axis/time/parser/time-formats-validators.functions.js +79 -1
- package/dist/chart/components/x_axis/time/parser/time-formats.model.js +14 -1
- package/dist/chart/components/x_axis/time/x-axis-weights.functions.d.ts +1 -1
- package/dist/chart/components/x_axis/time/x-axis-weights.functions.js +143 -1
- package/dist/chart/components/x_axis/time/x-axis-weights.generator.js +73 -1
- package/dist/chart/components/x_axis/x-axis-draw.functions.js +49 -1
- package/dist/chart/components/x_axis/x-axis-labels.drawer.js +70 -1
- package/dist/chart/components/x_axis/x-axis-labels.generator.d.ts +2 -2
- package/dist/chart/components/x_axis/x-axis-labels.generator.js +332 -1
- package/dist/chart/components/x_axis/x-axis-labels.model.js +35 -1
- package/dist/chart/components/x_axis/x-axis-scale.handler.d.ts +2 -2
- package/dist/chart/components/x_axis/x-axis-scale.handler.js +60 -1
- package/dist/chart/components/x_axis/x-axis-time-labels.drawer.js +82 -1
- package/dist/chart/components/x_axis/x-axis.component.d.ts +2 -2
- package/dist/chart/components/x_axis/x-axis.component.js +119 -1
- package/dist/chart/components/y_axis/label-color.functions.js +53 -1
- package/dist/chart/components/y_axis/numeric-y-axis-labels.generator.d.ts +4 -4
- package/dist/chart/components/y_axis/numeric-y-axis-labels.generator.js +33 -1
- package/dist/chart/components/y_axis/price_labels/data-series-y-axis-labels.provider.d.ts +3 -3
- package/dist/chart/components/y_axis/price_labels/data-series-y-axis-labels.provider.js +67 -1
- package/dist/chart/components/y_axis/price_labels/labels-positions-calculator.js +56 -1
- package/dist/chart/components/y_axis/price_labels/last-candle-labels.provider.d.ts +4 -3
- package/dist/chart/components/y_axis/price_labels/last-candle-labels.provider.js +96 -1
- package/dist/chart/components/y_axis/price_labels/price-label.drawer.d.ts +2 -2
- package/dist/chart/components/y_axis/price_labels/price-label.drawer.js +119 -1
- package/dist/chart/components/y_axis/price_labels/y-axis-labels.model.d.ts +9 -8
- package/dist/chart/components/y_axis/price_labels/y-axis-labels.model.js +201 -1
- package/dist/chart/components/y_axis/price_labels/y-axis-price-labels.drawer.d.ts +6 -7
- package/dist/chart/components/y_axis/price_labels/y-axis-price-labels.drawer.js +58 -1
- package/dist/chart/components/y_axis/y-axis-base-labels.model.d.ts +6 -4
- package/dist/chart/components/y_axis/y-axis-base-labels.model.js +47 -1
- package/dist/chart/components/y_axis/y-axis-labels.drawer.d.ts +4 -4
- package/dist/chart/components/y_axis/y-axis-labels.drawer.js +161 -1
- package/dist/chart/components/y_axis/y-axis-scale.handler.d.ts +2 -2
- package/dist/chart/components/y_axis/y-axis-scale.handler.js +72 -1
- package/dist/chart/components/y_axis/y-axis.component.d.ts +32 -41
- package/dist/chart/components/y_axis/y-axis.component.js +220 -1
- package/dist/chart/components/y_axis/y-axis.drawer.d.ts +9 -12
- package/dist/chart/components/y_axis/y-axis.drawer.js +96 -1
- package/dist/chart/components/y_axis/y-axis.model.d.ts +10 -17
- package/dist/chart/components/y_axis/y-axis.model.js +34 -1
- package/dist/chart/drawers/chart-background.drawer.js +69 -1
- package/dist/chart/drawers/chart-type-drawers/area.drawer.js +69 -1
- package/dist/chart/drawers/chart-type-drawers/bar.drawer.js +57 -1
- package/dist/chart/drawers/chart-type-drawers/baseline.drawer.js +84 -1
- package/dist/chart/drawers/chart-type-drawers/candle.drawer.js +162 -1
- package/dist/chart/drawers/chart-type-drawers/histogram.drawer.js +57 -1
- package/dist/chart/drawers/chart-type-drawers/line.drawer.js +38 -1
- package/dist/chart/drawers/chart-type-drawers/scatter-plot.drawer.js +19 -1
- package/dist/chart/drawers/clear-canvas.drawer.js +14 -1
- package/dist/chart/drawers/composite.drawer.js +67 -1
- package/dist/chart/drawers/data-series-drawers/candle-series-wrapper.js +50 -1
- package/dist/chart/drawers/data-series-drawers/color-candle.drawer.js +35 -1
- package/dist/chart/drawers/data-series-drawers/data-series-drawers.utils.js +16 -1
- package/dist/chart/drawers/data-series-drawers/difference-cloud.drawer.js +106 -1
- package/dist/chart/drawers/data-series-drawers/histogram.drawer.js +23 -1
- package/dist/chart/drawers/data-series-drawers/linear.drawer.js +19 -1
- package/dist/chart/drawers/data-series-drawers/points.drawer.js +19 -1
- package/dist/chart/drawers/data-series-drawers/rectangular-tool.drawer.js +7 -1
- package/dist/chart/drawers/data-series-drawers/text.drawer.js +25 -1
- package/dist/chart/drawers/data-series-drawers/trend-histogram.drawer.js +35 -1
- package/dist/chart/drawers/data-series-drawers/triangle.drawer.js +22 -1
- package/dist/chart/drawers/data-series.drawer.d.ts +5 -7
- package/dist/chart/drawers/data-series.drawer.js +56 -1
- package/dist/chart/drawers/drawing-manager.d.ts +1 -1
- package/dist/chart/drawers/drawing-manager.js +177 -1
- package/dist/chart/drawers/ht-data-series.drawer.js +37 -1
- package/dist/chart/events/event-bus.js +73 -1
- package/dist/chart/events/events.js +3 -1
- package/dist/chart/inputhandlers/candle-tap.handler.js +46 -1
- package/dist/chart/inputhandlers/chart-resize.handler.js +98 -1
- package/dist/chart/inputhandlers/cross-event-producer.component.js +67 -1
- package/dist/chart/inputhandlers/hover-producer.component.d.ts +2 -2
- package/dist/chart/inputhandlers/hover-producer.component.js +228 -1
- package/dist/chart/inputhandlers/main-canvas-touch.handler.d.ts +2 -2
- package/dist/chart/inputhandlers/main-canvas-touch.handler.js +80 -1
- package/dist/chart/inputlisteners/canvas-input-listener.component.js +629 -1
- package/dist/chart/model/baseline.model.js +88 -1
- package/dist/chart/model/bounds.model.js +1 -1
- package/dist/chart/model/candle-hover.js +70 -1
- package/dist/chart/model/candle-series-high-low.provider.js +45 -1
- package/dist/chart/model/candle-series.model.d.ts +3 -3
- package/dist/chart/model/candle-series.model.js +245 -1
- package/dist/chart/model/candle.model.js +69 -1
- package/dist/chart/model/canvas.model.js +228 -1
- package/dist/chart/model/chart-base-element.js +129 -1
- package/dist/chart/model/compare-series-hover.js +25 -1
- package/dist/chart/model/data-series-view.d.ts +5 -5
- package/dist/chart/model/data-series-view.js +111 -1
- package/dist/chart/model/data-series.config.js +14 -1
- package/dist/chart/model/data-series.model.d.ts +4 -4
- package/dist/chart/model/data-series.model.js +281 -1
- package/dist/chart/model/date-time.formatter.js +151 -1
- package/dist/chart/model/hit-test-canvas.model.d.ts +1 -1
- package/dist/chart/model/hit-test-canvas.model.js +256 -1
- package/dist/chart/model/main-candle-series.model.d.ts +1 -1
- package/dist/chart/model/main-candle-series.model.js +29 -1
- package/dist/chart/model/scale.model.d.ts +3 -2
- package/dist/chart/model/scale.model.js +316 -1
- package/dist/chart/model/scaling/auto-scale.model.d.ts +2 -4
- package/dist/chart/model/scaling/auto-scale.model.js +91 -1
- package/dist/chart/model/scaling/constrait.functions.js +61 -1
- package/dist/chart/model/scaling/lock-ratio.model.js +17 -1
- package/dist/chart/model/scaling/move-chart.functions.js +22 -1
- package/dist/chart/model/scaling/viewport.model.d.ts +2 -2
- package/dist/chart/model/scaling/viewport.model.js +279 -1
- package/dist/chart/model/scaling/x-zooming.functions.js +35 -1
- package/dist/chart/model/time-zone.model.js +109 -1
- package/dist/chart/model/visual-candle.js +134 -1
- package/dist/chart/utils/__tests__/array.utils.test.js +135 -1
- package/dist/chart/utils/__tests__/math.utils.test.js +14 -1
- package/dist/chart/utils/__tests__/object.utils.test.js +11 -1
- package/dist/chart/utils/__tests__/priceIncrementsUtils.test.js +29 -1
- package/dist/chart/utils/array.utils.d.ts +1 -1
- package/dist/chart/utils/array.utils.js +269 -1
- package/dist/chart/utils/auto-period-detector.utils.js +39 -1
- package/dist/chart/utils/candles-generator-ts.utils.js +20 -1
- package/dist/chart/utils/candles-generator.utils.js +161 -1
- package/dist/chart/utils/candles.utils.js +42 -1
- package/dist/chart/utils/canvas/canvas-drawing-functions.utils.js +144 -1
- package/dist/chart/utils/canvas/canvas-font-measure-tool.utils.js +51 -1
- package/dist/chart/utils/canvas/canvas-text-functions.utils.js +156 -1
- package/dist/chart/utils/color.utils.js +31 -1
- package/dist/chart/utils/device/browser.utils.js +10 -1
- package/dist/chart/utils/device/device-detector.utils.js +24 -1
- package/dist/chart/utils/device/device-pixel-ratio.utils.js +21 -1
- package/dist/chart/utils/device/touchpad.utils.js +91 -1
- package/dist/chart/utils/dom.utils.js +15 -1
- package/dist/chart/utils/function.utils.js +16 -1
- package/dist/chart/utils/linkedList.utils.d.ts +28 -0
- package/dist/chart/utils/linkedList.utils.js +138 -0
- package/dist/chart/utils/math.utils.js +115 -1
- package/dist/chart/utils/merge.utils.js +56 -1
- package/dist/chart/utils/object.utils.js +43 -1
- package/dist/chart/utils/performance/animation-frame-cache.utils.js +77 -0
- package/dist/chart/utils/{perfomance → performance}/debounce.utils.js +7 -1
- package/dist/chart/utils/performance/memoize.utils.js +74 -0
- package/dist/chart/utils/performance/request-animation-frame-throttle.utils.js +43 -0
- package/dist/chart/utils/performance/throttle.utils.js +26 -0
- package/dist/chart/utils/price-increments.utils.d.ts +1 -0
- package/dist/chart/utils/price-increments.utils.js +127 -1
- package/dist/chart/utils/uuid.utils.js +4 -1
- package/dist/dxchart.min.js +9 -12
- package/dist/index.d.ts +3 -3
- package/dist/index.js +20 -1
- package/package.json +4 -4
- package/dist/chart/utils/perfomance/animation-frame-cache.utils.js +0 -6
- package/dist/chart/utils/perfomance/memoize.utils.js +0 -6
- package/dist/chart/utils/perfomance/request-animation-frame-throttle.utils.js +0 -6
- package/dist/chart/utils/perfomance/throttle.utils.js +0 -6
- /package/dist/chart/utils/{perfomance → performance}/animation-frame-cache.utils.d.ts +0 -0
- /package/dist/chart/utils/{perfomance → performance}/debounce.utils.d.ts +0 -0
- /package/dist/chart/utils/{perfomance → performance}/memoize.utils.d.ts +0 -0
- /package/dist/chart/utils/{perfomance → performance}/request-animation-frame-throttle.utils.d.ts +0 -0
- /package/dist/chart/utils/{perfomance → performance}/throttle.utils.d.ts +0 -0
|
@@ -3,4 +3,259 @@
|
|
|
3
3
|
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
|
4
4
|
* If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
5
5
|
*/
|
|
6
|
-
import
|
|
6
|
+
import { merge, Subject } from 'rxjs';
|
|
7
|
+
import { map, throttleTime } from 'rxjs/operators';
|
|
8
|
+
import { CanvasElement } from '../canvas/canvas-bounds-container';
|
|
9
|
+
import { CanvasModel, initCanvasWithConfig } from './canvas.model';
|
|
10
|
+
import { animationFrameId } from '../utils/performance/request-animation-frame-throttle.utils';
|
|
11
|
+
const bigPrimeNumber = 317;
|
|
12
|
+
export const HIT_TEST_ID_RANGE = {
|
|
13
|
+
DRAWINGS: [1, 199],
|
|
14
|
+
NEWS: [200, 299],
|
|
15
|
+
DATA_SERIES: [300, 2999],
|
|
16
|
+
EVENTS: [3000, 4000],
|
|
17
|
+
EXECUTED_ORDERS: [4001, 5000],
|
|
18
|
+
};
|
|
19
|
+
/** HitTestCanvasModel
|
|
20
|
+
* Canvas layer for testing mouse events over the models such as Charts, Drawings, Volumes and etc.
|
|
21
|
+
* !!! always add new drawers to hit-test drawingManager BEFORE the DrawerType.HIT_TEST_DRAWINGS to save the hierarchy
|
|
22
|
+
*
|
|
23
|
+
* @doc-tags chart-core,hit-test
|
|
24
|
+
*/
|
|
25
|
+
export class HitTestCanvasModel extends CanvasModel {
|
|
26
|
+
constructor(eventBus, canvas, canvasInputListener, canvasBoundsContainer, drawingManager, chartConfig, canvasModels, resizer) {
|
|
27
|
+
super(eventBus, canvas, drawingManager, canvasModels, resizer, {
|
|
28
|
+
willReadFrequently: true,
|
|
29
|
+
desynchronized: true,
|
|
30
|
+
});
|
|
31
|
+
this.canvasInputListener = canvasInputListener;
|
|
32
|
+
this.canvasBoundsContainer = canvasBoundsContainer;
|
|
33
|
+
this.hitTestSubscribers = [];
|
|
34
|
+
this.eventsSubscriptions = [];
|
|
35
|
+
this.hoverSubject = new Subject();
|
|
36
|
+
this.touchStartSubject = new Subject();
|
|
37
|
+
this.dblClickSubject = new Subject();
|
|
38
|
+
this.rightClickSubject = new Subject();
|
|
39
|
+
this.curImgData = new Uint8ClampedArray(4);
|
|
40
|
+
this.prevAnimationFrameId = -1;
|
|
41
|
+
initCanvasWithConfig(this, chartConfig);
|
|
42
|
+
canvas.style.visibility = 'hidden';
|
|
43
|
+
this.enableUserControls();
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Enables HitTestCanvasModel events listeners.
|
|
47
|
+
*/
|
|
48
|
+
enableUserControls() {
|
|
49
|
+
if (this.eventsSubscriptions.length === 0) {
|
|
50
|
+
const bounds = this.canvasBoundsContainer.getBoundsHitTest(CanvasElement.ALL_PANES);
|
|
51
|
+
const hoverSub = this.canvasInputListener
|
|
52
|
+
.observeMouseMove()
|
|
53
|
+
.pipe(throttleTime(100, undefined, { trailing: true }))
|
|
54
|
+
.subscribe(point => this.eventHandler(point, 'hover'));
|
|
55
|
+
const touchStartSub = this.canvasInputListener
|
|
56
|
+
.observeTouchStart()
|
|
57
|
+
.pipe(map(() => this.canvasInputListener.currentPoint))
|
|
58
|
+
.subscribe(point => this.eventHandler(point, 'touchstart'));
|
|
59
|
+
const clickSub = merge(this.canvasInputListener.observeMouseDown(bounds),
|
|
60
|
+
// should probably be deleted, touch event is a separate event and sometimes it doesn't work while being a part of click event
|
|
61
|
+
this.canvasInputListener.observeTouchStart().pipe(map(() => this.canvasInputListener.currentPoint))).subscribe(point => this.eventHandler(point, 'mousedown'));
|
|
62
|
+
const mouseUpSub = merge(this.canvasInputListener.observeMouseUp(bounds),
|
|
63
|
+
// should probably be deleted, touch event is a separate event and sometimes it doesn't work while being a part of click event
|
|
64
|
+
this.canvasInputListener
|
|
65
|
+
.observeTouchEndDocument()
|
|
66
|
+
.pipe(map(() => this.canvasInputListener.currentPoint))).subscribe(point => this.eventHandler(point, 'mouseup'));
|
|
67
|
+
const dblClickSub = this.canvasInputListener
|
|
68
|
+
.observeDbClick(bounds)
|
|
69
|
+
.subscribe(point => this.eventHandler(point, 'dblclick'));
|
|
70
|
+
const rightClickSub = this.canvasInputListener
|
|
71
|
+
.observeContextMenu(bounds)
|
|
72
|
+
.pipe(map(() => (Object.assign({}, this.canvasInputListener.currentPoint))))
|
|
73
|
+
.subscribe(point => {
|
|
74
|
+
this.eventHandler(point, 'contextmenu');
|
|
75
|
+
});
|
|
76
|
+
const zoomSub = this.canvasInputListener
|
|
77
|
+
.observeWheel(bounds)
|
|
78
|
+
.subscribe(point => setTimeout(() => this.eventHandler(point, 'zoom'), 0));
|
|
79
|
+
this.eventsSubscriptions.push(hoverSub, clickSub, dblClickSub, rightClickSub, zoomSub, touchStartSub, mouseUpSub);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Disables HitTestCanvasModel events listeners.
|
|
84
|
+
*/
|
|
85
|
+
disableUserControls() {
|
|
86
|
+
this.eventsSubscriptions.forEach(sub => sub.unsubscribe());
|
|
87
|
+
this.eventsSubscriptions = [];
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Adds a new subscriber to the list of hit test subscribers.
|
|
91
|
+
* @param {HitTestSubscriber<unknown>} subscriber - The subscriber to be added.
|
|
92
|
+
* @returns {void}
|
|
93
|
+
*/
|
|
94
|
+
addSubscriber(subscriber) {
|
|
95
|
+
this.hitTestSubscribers.push(subscriber);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Removes a subscriber from the list of hit test subscribers.
|
|
99
|
+
*
|
|
100
|
+
* @param {HitTestSubscriber<unknown>} subscriber - The subscriber to be removed.
|
|
101
|
+
* @returns {void}
|
|
102
|
+
*/
|
|
103
|
+
removeSubscriber(subscriber) {
|
|
104
|
+
this.hitTestSubscribers = this.hitTestSubscribers.filter(sub => sub === subscriber);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Converts a number to a hexadecimal color code.
|
|
108
|
+
* @param {number} id - The number to be converted.
|
|
109
|
+
* @returns {string} - The hexadecimal color code.
|
|
110
|
+
*/
|
|
111
|
+
idToColor(id) {
|
|
112
|
+
const hex = (id * bigPrimeNumber).toString(16);
|
|
113
|
+
return '#000000'.substr(0, 7 - hex.length) + hex;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* This function takes a number representing a color and returns the corresponding ID by dividing it by a big prime number.
|
|
117
|
+
*
|
|
118
|
+
* @param {number} color - The number representing the color.
|
|
119
|
+
* @returns {number} - The ID corresponding to the color.
|
|
120
|
+
*/
|
|
121
|
+
colorToId(color) {
|
|
122
|
+
return color / bigPrimeNumber;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Observes hovered on element event, provides hovered element model when move in.
|
|
126
|
+
*/
|
|
127
|
+
observeHoverOnElement() {
|
|
128
|
+
return this.hoverSubject.asObservable();
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Observes touch start on element event, provides element model.
|
|
132
|
+
*/
|
|
133
|
+
observeTouchStartOnElement() {
|
|
134
|
+
return this.touchStartSubject.asObservable();
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Observes dblclicked on element event, provides dblclicked element model.
|
|
138
|
+
*/
|
|
139
|
+
observeDblClickOnElement() {
|
|
140
|
+
return this.dblClickSubject.asObservable();
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Observes rightclicked on element event, provides rightclicked element model.
|
|
144
|
+
*/
|
|
145
|
+
observeRightClickOnElement() {
|
|
146
|
+
return this.rightClickSubject.asObservable();
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Retrieves the pixel data at the specified coordinates.
|
|
150
|
+
*
|
|
151
|
+
* @private
|
|
152
|
+
* @param {number} x - The x-coordinate of the pixel.
|
|
153
|
+
* @param {number} y - The y-coordinate of the pixel.
|
|
154
|
+
* @returns {Uint8ClampedArray} - The pixel data at the specified coordinates.
|
|
155
|
+
*/
|
|
156
|
+
getPixel(x, y) {
|
|
157
|
+
const dpr = window.devicePixelRatio;
|
|
158
|
+
// it's heavy operation, so use cached value if possible
|
|
159
|
+
if (this.prevAnimationFrameId !== animationFrameId) {
|
|
160
|
+
this.curImgData = this.ctx.getImageData(x * dpr, y * dpr, 1, 1).data;
|
|
161
|
+
this.prevAnimationFrameId = animationFrameId;
|
|
162
|
+
}
|
|
163
|
+
return this.curImgData;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Resolves ht model based on the provided point
|
|
167
|
+
* @param point - The point for which to resolve model
|
|
168
|
+
*/
|
|
169
|
+
resolveModel(point) {
|
|
170
|
+
const data = this.getPixel(point.x, point.y);
|
|
171
|
+
const id = this.colorToId(data[0] * 65536 + data[1] * 256 + data[2]);
|
|
172
|
+
const idNumber = Number(id);
|
|
173
|
+
const [subscriberToHit] = sortSubscribers(this.hitTestSubscribers, idNumber);
|
|
174
|
+
const model = subscriberToHit === null || subscriberToHit === void 0 ? void 0 : subscriberToHit.lookup(id);
|
|
175
|
+
return model;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Resolves cursor type based on the provided point
|
|
179
|
+
* @param point - The point for which to resolve cursor type
|
|
180
|
+
* @returns - The resolved cursor type, if any
|
|
181
|
+
*/
|
|
182
|
+
resolveCursor(point) {
|
|
183
|
+
var _a;
|
|
184
|
+
// do not spend time on resolving cursor if there are no subscribers that need it
|
|
185
|
+
if (!this.hitTestSubscribers.some(s => s.resolveCursor !== undefined)) {
|
|
186
|
+
return undefined;
|
|
187
|
+
}
|
|
188
|
+
const data = this.getPixel(point.x, point.y);
|
|
189
|
+
const id = this.colorToId(data[0] * 65536 + data[1] * 256 + data[2]);
|
|
190
|
+
const idNumber = Number(id);
|
|
191
|
+
const [subscriberToHit] = sortSubscribers(this.hitTestSubscribers, idNumber);
|
|
192
|
+
const model = subscriberToHit === null || subscriberToHit === void 0 ? void 0 : subscriberToHit.lookup(id);
|
|
193
|
+
return (_a = subscriberToHit === null || subscriberToHit === void 0 ? void 0 : subscriberToHit.resolveCursor) === null || _a === void 0 ? void 0 : _a.call(subscriberToHit, point, model);
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Private method that handles hit test events.
|
|
197
|
+
* @param {Point} point - The point where the event occurred.
|
|
198
|
+
* @param {HitTestEvents} event - The type of event that occurred.
|
|
199
|
+
* @returns {void}
|
|
200
|
+
*/
|
|
201
|
+
eventHandler(point, event) {
|
|
202
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
203
|
+
const data = this.getPixel(point.x, point.y);
|
|
204
|
+
const id = this.colorToId(data[0] * 65536 + data[1] * 256 + data[2]);
|
|
205
|
+
const idNumber = Number(id);
|
|
206
|
+
const [subscriberToHit, restSubs] = sortSubscribers(this.hitTestSubscribers, idNumber);
|
|
207
|
+
const model = subscriberToHit === null || subscriberToHit === void 0 ? void 0 : subscriberToHit.lookup(id);
|
|
208
|
+
const hitTestEvent = {
|
|
209
|
+
point,
|
|
210
|
+
model,
|
|
211
|
+
};
|
|
212
|
+
switch (event) {
|
|
213
|
+
case 'mousedown':
|
|
214
|
+
model && ((_a = subscriberToHit === null || subscriberToHit === void 0 ? void 0 : subscriberToHit.onMouseDown) === null || _a === void 0 ? void 0 : _a.call(subscriberToHit, model, point));
|
|
215
|
+
restSubs.forEach(sub => sub.onMouseDown && sub.onMouseDown(null, point));
|
|
216
|
+
break;
|
|
217
|
+
case 'mouseup':
|
|
218
|
+
model && ((_b = subscriberToHit === null || subscriberToHit === void 0 ? void 0 : subscriberToHit.onMouseUp) === null || _b === void 0 ? void 0 : _b.call(subscriberToHit, model, point));
|
|
219
|
+
restSubs.forEach(sub => sub.onMouseUp && sub.onMouseUp(null, point));
|
|
220
|
+
break;
|
|
221
|
+
case 'hover':
|
|
222
|
+
model && ((_c = subscriberToHit === null || subscriberToHit === void 0 ? void 0 : subscriberToHit.onHover) === null || _c === void 0 ? void 0 : _c.call(subscriberToHit, model, point));
|
|
223
|
+
restSubs.forEach(sub => sub.onHover && sub.onHover(null, point));
|
|
224
|
+
this.hoverSubject.next(hitTestEvent);
|
|
225
|
+
break;
|
|
226
|
+
case 'touchstart':
|
|
227
|
+
model && ((_d = subscriberToHit === null || subscriberToHit === void 0 ? void 0 : subscriberToHit.onTouchStart) === null || _d === void 0 ? void 0 : _d.call(subscriberToHit, model, point));
|
|
228
|
+
restSubs.forEach(sub => sub.onTouchStart && sub.onTouchStart(null, point));
|
|
229
|
+
this.touchStartSubject.next(hitTestEvent);
|
|
230
|
+
break;
|
|
231
|
+
case 'dblclick':
|
|
232
|
+
model && ((_e = subscriberToHit === null || subscriberToHit === void 0 ? void 0 : subscriberToHit.onDblClick) === null || _e === void 0 ? void 0 : _e.call(subscriberToHit, model, point));
|
|
233
|
+
this.dblClickSubject.next(hitTestEvent);
|
|
234
|
+
break;
|
|
235
|
+
case 'contextmenu':
|
|
236
|
+
model && ((_f = subscriberToHit === null || subscriberToHit === void 0 ? void 0 : subscriberToHit.onRightClick) === null || _f === void 0 ? void 0 : _f.call(subscriberToHit, model, point));
|
|
237
|
+
this.rightClickSubject.next(hitTestEvent);
|
|
238
|
+
break;
|
|
239
|
+
case 'zoom':
|
|
240
|
+
model && ((_g = subscriberToHit === null || subscriberToHit === void 0 ? void 0 : subscriberToHit.onZoom) === null || _g === void 0 ? void 0 : _g.call(subscriberToHit, model, point));
|
|
241
|
+
restSubs.forEach(sub => sub.onZoom && sub.onZoom(null, point));
|
|
242
|
+
break;
|
|
243
|
+
default:
|
|
244
|
+
break;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
const sortSubscribers = (subs, id) => {
|
|
249
|
+
let mainSubscriber = undefined;
|
|
250
|
+
const restSubs = [];
|
|
251
|
+
subs.forEach(sub => {
|
|
252
|
+
const [start, end] = sub.getIdRange();
|
|
253
|
+
if (id >= start && id <= end) {
|
|
254
|
+
mainSubscriber = sub;
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
restSubs.push(sub);
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
return [mainSubscriber, restSubs];
|
|
261
|
+
};
|
|
@@ -18,7 +18,7 @@ import VisualCandle from './visual-candle';
|
|
|
18
18
|
*/
|
|
19
19
|
export declare class MainCandleSeriesModel extends CandleSeriesModel {
|
|
20
20
|
private readonly baseModel;
|
|
21
|
-
constructor(baseModel: ChartBaseModel<'candle'>, extentComponent: YExtentComponent, id: number, eventBus: EventBus,
|
|
21
|
+
constructor(baseModel: ChartBaseModel<'candle'>, extentComponent: YExtentComponent, id: number, eventBus: EventBus, scale: ScaleModel, instrument: ChartInstrument, candlesTransformersByChartType: Partial<Record<DataSeriesType, VisualCandleCalculator>>, candleWidthByChartType: Partial<Record<DataSeriesType, CandleWidthCalculator>>, colors: CandleSeriesColors);
|
|
22
22
|
set visualPoints(candles: VisualCandle[] | VisualCandle[][]);
|
|
23
23
|
get visualPoints(): VisualCandle[];
|
|
24
24
|
set dataPoints(candles: Candle[] | Candle[][]);
|
|
@@ -3,4 +3,32 @@
|
|
|
3
3
|
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
|
4
4
|
* If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
5
5
|
*/
|
|
6
|
-
import{CandleSeriesModel
|
|
6
|
+
import { CandleSeriesModel } from './candle-series.model';
|
|
7
|
+
/**
|
|
8
|
+
* This model represents main chart data series and is highly tied to chartBaseModel, @see ChartBaseModel
|
|
9
|
+
*/
|
|
10
|
+
export class MainCandleSeriesModel extends CandleSeriesModel {
|
|
11
|
+
constructor(baseModel, extentComponent, id, eventBus, scale, instrument, candlesTransformersByChartType, candleWidthByChartType, colors) {
|
|
12
|
+
super(extentComponent, id, eventBus, scale, instrument, candlesTransformersByChartType, candleWidthByChartType, colors);
|
|
13
|
+
this.baseModel = baseModel;
|
|
14
|
+
}
|
|
15
|
+
set visualPoints(candles) {
|
|
16
|
+
super.visualPoints = candles;
|
|
17
|
+
// super.visualPoints will transform 2D array if necessary to 1D array
|
|
18
|
+
this.baseModel.mainVisualPoints = super.visualPoints;
|
|
19
|
+
}
|
|
20
|
+
get visualPoints() {
|
|
21
|
+
return super.visualPoints;
|
|
22
|
+
}
|
|
23
|
+
set dataPoints(candles) {
|
|
24
|
+
super.dataPoints = candles;
|
|
25
|
+
this.baseModel.mainDataPoints = super.dataPoints;
|
|
26
|
+
}
|
|
27
|
+
get dataPoints() {
|
|
28
|
+
return super.dataPoints;
|
|
29
|
+
}
|
|
30
|
+
recalculateMeanCandleWidth(visualCandles) {
|
|
31
|
+
super.recalculateMeanCandleWidth(visualCandles);
|
|
32
|
+
this.baseModel.meanDataWidth = this.meanCandleWidth;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -40,6 +40,7 @@ export declare class ScaleModel extends ViewportModel {
|
|
|
40
40
|
getBounds: BoundsProvider;
|
|
41
41
|
private canvasAnimation;
|
|
42
42
|
scaleInversedSubject: Subject<boolean>;
|
|
43
|
+
beforeStartAnimationSubject: Subject<void>;
|
|
43
44
|
history: ScaleHistoryItem[];
|
|
44
45
|
autoScaleModel: AutoScaleViewportSubModel;
|
|
45
46
|
zoomXYRatio: ZoomXToZoomYRatio;
|
|
@@ -49,7 +50,7 @@ export declare class ScaleModel extends ViewportModel {
|
|
|
49
50
|
constructor(config: FullChartConfig, getBounds: BoundsProvider, canvasAnimation: CanvasAnimation);
|
|
50
51
|
/**
|
|
51
52
|
* The method adds a new "constraint" to the existing list of x-axis constraints for charting.
|
|
52
|
-
* The "
|
|
53
|
+
* The "constraint" is expected to be an object containing information about the constraints, such as the minimum and maximum values for the x-axis.
|
|
53
54
|
* @param constraint
|
|
54
55
|
*/
|
|
55
56
|
addXConstraint(constraint: Constraints): void;
|
|
@@ -77,7 +78,7 @@ export declare class ScaleModel extends ViewportModel {
|
|
|
77
78
|
* @param zoomSensitivity - The sensitivity of the zoom. Default value is taken from the configuration object.
|
|
78
79
|
*/
|
|
79
80
|
zoomXToEnd(zoomIn: boolean, zoomSensitivity?: number): void;
|
|
80
|
-
|
|
81
|
+
haltAnimation(): void;
|
|
81
82
|
private zoomXTo;
|
|
82
83
|
/**
|
|
83
84
|
* Moves the viewport to exactly xStart..xEnd place.
|
|
@@ -3,4 +3,319 @@
|
|
|
3
3
|
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
|
4
4
|
* If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
5
5
|
*/
|
|
6
|
-
import
|
|
6
|
+
import { Subject } from 'rxjs';
|
|
7
|
+
import { startViewportModelAnimation } from '../animation/viewport-model-animation';
|
|
8
|
+
import { cloneUnsafe } from '../utils/object.utils';
|
|
9
|
+
import { AutoScaleViewportSubModel } from './scaling/auto-scale.model';
|
|
10
|
+
import { zoomConstraint } from './scaling/constrait.functions';
|
|
11
|
+
import { lockedYEndViewportCalculator, ratioFromZoomXY } from './scaling/lock-ratio.model';
|
|
12
|
+
import { moveXStart, moveYStart } from './scaling/move-chart.functions';
|
|
13
|
+
import { ViewportModel, compareStates } from './scaling/viewport.model';
|
|
14
|
+
import { zoomXToEndViewportCalculator, zoomXToPercentViewportCalculator } from './scaling/x-zooming.functions';
|
|
15
|
+
export const getDefaultHighLowWithIndex = () => ({
|
|
16
|
+
high: Number.NEGATIVE_INFINITY,
|
|
17
|
+
low: Number.POSITIVE_INFINITY,
|
|
18
|
+
highIdx: 0,
|
|
19
|
+
lowIdx: 0,
|
|
20
|
+
});
|
|
21
|
+
/**
|
|
22
|
+
* The ScaleModel class represents the state of a chart's scale, including the current viewport, zoom level, and auto-scaling settings.
|
|
23
|
+
* It extends the ViewportModel class, which provides the underlying implementation for handling viewports and zoom levels.
|
|
24
|
+
* Controls current visible CHART viewport.
|
|
25
|
+
* Has additional logic:
|
|
26
|
+
* - auto-scale
|
|
27
|
+
* - locked scale
|
|
28
|
+
* - zooming functions
|
|
29
|
+
* - history
|
|
30
|
+
*/
|
|
31
|
+
export class ScaleModel extends ViewportModel {
|
|
32
|
+
constructor(config, getBounds, canvasAnimation) {
|
|
33
|
+
super();
|
|
34
|
+
this.config = config;
|
|
35
|
+
this.getBounds = getBounds;
|
|
36
|
+
this.canvasAnimation = canvasAnimation;
|
|
37
|
+
this.scaleInversedSubject = new Subject();
|
|
38
|
+
// y-axis component needs this subject in order to halt prev animation if axis type is percent
|
|
39
|
+
this.beforeStartAnimationSubject = new Subject();
|
|
40
|
+
// TODO rework, make a new history based on units
|
|
41
|
+
this.history = [];
|
|
42
|
+
this.zoomXYRatio = 0;
|
|
43
|
+
this.xConstraints = [];
|
|
44
|
+
this.scalePostProcessor = (initialState, state) => {
|
|
45
|
+
// for now <s>reduceRight<s/> reduce bcs ChartModel#getZoomConstrait should be invoked first
|
|
46
|
+
// if we will need more complex order handling -> add some managing
|
|
47
|
+
return this.xConstraints.reduce((acc, cur) => cur(initialState, acc), state);
|
|
48
|
+
};
|
|
49
|
+
this.state = cloneUnsafe(config.scale);
|
|
50
|
+
this.autoScaleModel = new AutoScaleViewportSubModel(this);
|
|
51
|
+
this.offsets = this.config.components.offsets;
|
|
52
|
+
this.addXConstraint((initialState, state) => zoomConstraint(initialState, state, this.config.components.chart, this.getBounds));
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* The method adds a new "constraint" to the existing list of x-axis constraints for charting.
|
|
56
|
+
* The "constraint" is expected to be an object containing information about the constraints, such as the minimum and maximum values for the x-axis.
|
|
57
|
+
* @param constraint
|
|
58
|
+
*/
|
|
59
|
+
addXConstraint(constraint) {
|
|
60
|
+
this.xConstraints = [...this.xConstraints, constraint];
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* The method updates the offsets for the scale model based on the provided "offsets" object.
|
|
64
|
+
* Note that the method modifies the offsets and triggers an autoscale
|
|
65
|
+
* @param offsets
|
|
66
|
+
*/
|
|
67
|
+
updateOffsets(offsets) {
|
|
68
|
+
this.offsets = Object.assign(Object.assign({}, this.offsets), offsets);
|
|
69
|
+
this.doAutoScale(true);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* @returns current offsets
|
|
73
|
+
*/
|
|
74
|
+
getOffsets() {
|
|
75
|
+
return this.offsets;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Zooms the X axis of the chart to a specified percentage of the viewport.
|
|
79
|
+
* @param viewportPercent The percentage of the viewport width to zoom to.
|
|
80
|
+
* @param zoomIn Whether to zoom in or out.
|
|
81
|
+
* @param forceNoAnimation Whether to skip animation.
|
|
82
|
+
* @param zoomSensitivity The sensitivity of the zoom.
|
|
83
|
+
*/
|
|
84
|
+
zoomXToPercent(viewportPercent, zoomIn, forceNoAnimation = false, zoomSensitivity = this.config.scale.zoomSensitivity) {
|
|
85
|
+
this.beforeStartAnimationSubject.next();
|
|
86
|
+
const state = this.export();
|
|
87
|
+
zoomXToPercentViewportCalculator(this, state, viewportPercent, zoomSensitivity, zoomIn);
|
|
88
|
+
this.zoomXTo(state, forceNoAnimation);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Zooms the X axis of the chart relativly to the end of the data range.
|
|
92
|
+
* @param zoomIn - If true, the chart will be zoomed in. If false, the chart will be zoomed out.
|
|
93
|
+
* @param zoomSensitivity - The sensitivity of the zoom. Default value is taken from the configuration object.
|
|
94
|
+
*/
|
|
95
|
+
zoomXToEnd(zoomIn, zoomSensitivity = this.config.scale.zoomSensitivity) {
|
|
96
|
+
this.beforeStartAnimationSubject.next();
|
|
97
|
+
const state = this.export();
|
|
98
|
+
zoomXToEndViewportCalculator(this, state, zoomSensitivity, zoomIn);
|
|
99
|
+
this.zoomXTo(state);
|
|
100
|
+
}
|
|
101
|
+
haltAnimation() {
|
|
102
|
+
var _a;
|
|
103
|
+
if ((_a = this.currentAnimation) === null || _a === void 0 ? void 0 : _a.animationInProgress) {
|
|
104
|
+
this.currentAnimation.finishAnimation();
|
|
105
|
+
this.doAutoScale();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
zoomXTo(state, forceNoAnimation) {
|
|
109
|
+
const initialStateCopy = Object.assign({}, state);
|
|
110
|
+
const constrainedState = this.scalePostProcessor(initialStateCopy, state);
|
|
111
|
+
if (this.state.lockPriceToBarRatio) {
|
|
112
|
+
lockedYEndViewportCalculator(constrainedState, this.zoomXYRatio);
|
|
113
|
+
}
|
|
114
|
+
if (this.state.auto) {
|
|
115
|
+
this.autoScaleModel.doAutoYScale(constrainedState);
|
|
116
|
+
}
|
|
117
|
+
if (forceNoAnimation) {
|
|
118
|
+
this.apply(constrainedState);
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
startViewportModelAnimation(this.canvasAnimation, this, constrainedState);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Moves the viewport to exactly xStart..xEnd place.
|
|
126
|
+
* (you need to fire DRAW event after this)
|
|
127
|
+
* @param xStart - viewport start in units
|
|
128
|
+
* @param xEnd - viewport end in units
|
|
129
|
+
* @param fireChanged
|
|
130
|
+
* @param forceNoAutoScale - force NOT apply auto-scaling (for lazy loading)
|
|
131
|
+
*/
|
|
132
|
+
setXScale(xStart, xEnd) {
|
|
133
|
+
const initialState = this.export();
|
|
134
|
+
super.setXScale(xStart, xEnd, false);
|
|
135
|
+
const state = this.export();
|
|
136
|
+
const constrainedState = this.scalePostProcessor(initialState, state);
|
|
137
|
+
if (this.state.lockPriceToBarRatio) {
|
|
138
|
+
lockedYEndViewportCalculator(constrainedState, this.zoomXYRatio);
|
|
139
|
+
}
|
|
140
|
+
if (this.state.auto) {
|
|
141
|
+
this.autoScaleModel.doAutoYScale(constrainedState);
|
|
142
|
+
}
|
|
143
|
+
this.apply(constrainedState);
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Moves both xStart and xEnd without changing the viewport width (zoom).
|
|
147
|
+
* WILL CHANGE the Y axis if scale.auto=true.
|
|
148
|
+
* @param xStart - starting point in units
|
|
149
|
+
*/
|
|
150
|
+
moveXStart(xStart) {
|
|
151
|
+
const state = this.export();
|
|
152
|
+
const initialStateCopy = Object.assign({}, state);
|
|
153
|
+
// always stop the animations
|
|
154
|
+
this.haltAnimation();
|
|
155
|
+
moveXStart(state, xStart);
|
|
156
|
+
// there we need only candles constraint
|
|
157
|
+
const constrainedState = this.scalePostProcessor(initialStateCopy, state);
|
|
158
|
+
if (this.state.auto) {
|
|
159
|
+
this.autoScaleModel.doAutoYScale(constrainedState);
|
|
160
|
+
}
|
|
161
|
+
this.apply(constrainedState);
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Moves both yStart and yEnd without changing the viewport height (zoom).
|
|
165
|
+
* Will not move viewport if scale.auto=true
|
|
166
|
+
* @param yStart - starting point in units
|
|
167
|
+
*/
|
|
168
|
+
moveYStart(yStart) {
|
|
169
|
+
this.haltAnimation();
|
|
170
|
+
if (this.state.auto) {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
const state = this.export();
|
|
175
|
+
moveYStart(state, yStart);
|
|
176
|
+
this.apply(state);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Automatically scales the chart to fit the data range.
|
|
181
|
+
* @param forceApply - If true, the chart will be forcefully auto-scaled even if animation is in progress.
|
|
182
|
+
*/
|
|
183
|
+
doAutoScale(forceApply = false) {
|
|
184
|
+
// dont auto-scale if animation, otherwise - forced or config
|
|
185
|
+
if ((!this.isViewportAnimationInProgress() && this.state.auto) || forceApply) {
|
|
186
|
+
const state = this.export();
|
|
187
|
+
this.autoScaleModel.doAutoYScale(state);
|
|
188
|
+
if (!compareStates(state, this.export())) {
|
|
189
|
+
this.apply(state);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Checks if viewport animation is currently in progress.
|
|
195
|
+
* @returns returns true if viewport animation is in progress, false otherwise.
|
|
196
|
+
*/
|
|
197
|
+
isViewportAnimationInProgress() {
|
|
198
|
+
const animation = this.currentAnimation;
|
|
199
|
+
return animation === null || animation === void 0 ? void 0 : animation.animationInProgress;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Adds an item to the scale history.
|
|
203
|
+
* @param item - The item to add to the history.
|
|
204
|
+
*/
|
|
205
|
+
pushToHistory(item) {
|
|
206
|
+
this.history.push(item);
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Removes the most recent item from the scale history and returns it.
|
|
210
|
+
* @returns - The most recent item from the history, or undefined if the history is empty.
|
|
211
|
+
*/
|
|
212
|
+
popFromHistory() {
|
|
213
|
+
return this.history.pop();
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Clears the scale history.
|
|
217
|
+
*/
|
|
218
|
+
clearHistory() {
|
|
219
|
+
this.history = [];
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Checks if the X axis bounds are the default values.
|
|
223
|
+
* @returns if false - it means there are candles and it's possible to do scaling and add drawings
|
|
224
|
+
*/
|
|
225
|
+
isDefaultXBounds() {
|
|
226
|
+
return this.xStart === 0 && this.xEnd === 0;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Checks if the Y axis bounds are the default values.
|
|
230
|
+
* @returns if false - it means there are candles and it's possible to do scaling and add drawings
|
|
231
|
+
*/
|
|
232
|
+
isDefaultYBounds() {
|
|
233
|
+
return this.yStart === 0 && this.yEnd === 0;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Checks if the scale is ready to be used.
|
|
237
|
+
* @returns - Returns true if the scale is ready, false otherwise.
|
|
238
|
+
*/
|
|
239
|
+
isScaleReady() {
|
|
240
|
+
return !this.isDefaultXBounds() && !this.isDefaultYBounds();
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Enables or disables auto-scaling of the chart.
|
|
244
|
+
* @param auto - If true, the chart will be automatically scaled. If false, auto-scaling will be disabled.
|
|
245
|
+
*/
|
|
246
|
+
autoScale(auto = true) {
|
|
247
|
+
// TODO rework, make this a separate feature toggle, describe in docs; this should be a business-logic level
|
|
248
|
+
if (this.config.components.yAxis.type === 'percent') {
|
|
249
|
+
this.state.auto = true;
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
this.state.auto = auto;
|
|
253
|
+
}
|
|
254
|
+
if (auto) {
|
|
255
|
+
this.clearHistory();
|
|
256
|
+
this.doAutoScale();
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Sets whether the price-to-bar ratio should be locked or not.
|
|
261
|
+
* @param value - If true, the price-to-bar ratio will be locked. If false, it will not be locked.
|
|
262
|
+
*/
|
|
263
|
+
setLockPriceToBarRatio(value = false) {
|
|
264
|
+
const { type } = this.config.components.yAxis;
|
|
265
|
+
// TODO rework, why such logic? same as above, if we have business-logic like this one => make it separate code
|
|
266
|
+
if (type === 'percent' || type === 'logarithmic') {
|
|
267
|
+
this.state.lockPriceToBarRatio = false;
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
if (value) {
|
|
271
|
+
this.recalculateZoomXYRatio();
|
|
272
|
+
}
|
|
273
|
+
this.state.lockPriceToBarRatio = value;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Recalculates the zoom X/Y ratio based on the current zoom levels.
|
|
277
|
+
*/
|
|
278
|
+
recalculateZoomXYRatio() {
|
|
279
|
+
this.zoomXYRatio = ratioFromZoomXY(this.zoomX, this.zoomY);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* The SyncedByXScaleModel class extends the ScaleModel class and adds support for synchronization with other ScaleModel instance, so both instances maintain the same X-axis bounds.
|
|
284
|
+
* This is useful for scenarios where multiple charts need to display the same X-axis data, but with different Y-axis scales.
|
|
285
|
+
*/
|
|
286
|
+
export class SyncedByXScaleModel extends ScaleModel {
|
|
287
|
+
constructor(delegate, config, getBounds, canvasAnimation) {
|
|
288
|
+
super(config, getBounds, canvasAnimation);
|
|
289
|
+
this.delegate = delegate;
|
|
290
|
+
this.config = config;
|
|
291
|
+
this.getBounds = getBounds;
|
|
292
|
+
}
|
|
293
|
+
doActivate() {
|
|
294
|
+
this.addRxSubscription(this.delegate.xChanged.subscribe(() => this.doAutoScale(this.state.auto)));
|
|
295
|
+
}
|
|
296
|
+
get xStart() {
|
|
297
|
+
return this.delegate.xStart;
|
|
298
|
+
}
|
|
299
|
+
set xStart(value) {
|
|
300
|
+
this.delegate.xStart = value;
|
|
301
|
+
}
|
|
302
|
+
get xEnd() {
|
|
303
|
+
return this.delegate.xEnd;
|
|
304
|
+
}
|
|
305
|
+
set xEnd(value) {
|
|
306
|
+
this.delegate.xEnd = value;
|
|
307
|
+
}
|
|
308
|
+
get zoomX() {
|
|
309
|
+
return this.delegate.zoomX;
|
|
310
|
+
}
|
|
311
|
+
set zoomX(value) {
|
|
312
|
+
this.delegate.zoomX = value;
|
|
313
|
+
}
|
|
314
|
+
observeXChanged() {
|
|
315
|
+
return this.delegate.xChanged;
|
|
316
|
+
}
|
|
317
|
+
fireChanged() {
|
|
318
|
+
this.delegate.changed.next();
|
|
319
|
+
this.changed.next();
|
|
320
|
+
}
|
|
321
|
+
}
|