@devexperts/dxcharts-lite 2.5.8 → 2.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chart/__tests__/chart.test.js +5 -5
- package/dist/chart/__tests__/env.js +1 -1
- package/dist/chart/bootstrap.js +1 -1
- package/dist/chart/canvas/canvas-bounds-container.d.ts +1 -0
- package/dist/chart/canvas/canvas-bounds-container.js +28 -4
- package/dist/chart/chart.config.d.ts +10 -0
- package/dist/chart/chart.config.js +4 -2
- package/dist/chart/components/chart/candle-transformer.functions.js +1 -1
- package/dist/chart/components/chart/candle.functions.d.ts +1 -1
- package/dist/chart/components/chart/candle.functions.js +3 -2
- package/dist/chart/components/chart/chart.component.d.ts +29 -8
- package/dist/chart/components/chart/chart.component.js +33 -4
- package/dist/chart/components/chart/chart.model.d.ts +41 -4
- package/dist/chart/components/chart/chart.model.js +90 -16
- package/dist/chart/components/chart/fake-candles.js +2 -0
- package/dist/chart/components/chart/fake-visual-candle.d.ts +4 -4
- package/dist/chart/components/chart/fake-visual-candle.js +4 -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/high_low/high-low.drawer.js +1 -1
- package/dist/chart/components/pane/pane-manager.component.d.ts +5 -0
- package/dist/chart/components/pane/pane-manager.component.js +20 -0
- package/dist/chart/components/pane/pane.component.d.ts +9 -1
- package/dist/chart/components/pane/pane.component.js +16 -0
- package/dist/chart/components/volumes/separate-volumes.component.d.ts +1 -3
- package/dist/chart/components/volumes/separate-volumes.component.js +1 -3
- package/dist/chart/components/volumes/volumes.component.js +1 -1
- package/dist/chart/components/volumes/volumes.drawer.js +3 -3
- package/dist/chart/components/watermark/water-mark.component.d.ts +3 -12
- package/dist/chart/components/watermark/water-mark.component.js +1 -1
- package/dist/chart/components/x_axis/time/parser/time-formats-parser.functions.js +1 -1
- 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 +39 -10
- package/dist/chart/components/x_axis/x-axis-time-labels.drawer.js +2 -2
- package/dist/chart/components/x_axis/x-axis.component.js +1 -1
- package/dist/chart/components/y_axis/y-axis-scale.handler.js +3 -3
- package/dist/chart/drawers/drawing-manager.d.ts +1 -1
- package/dist/chart/drawers/drawing-manager.js +0 -1
- 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 +78 -18
- 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/candle.model.d.ts +3 -0
- package/dist/chart/model/candle.model.js +7 -1
- package/dist/chart/model/data-series.model.d.ts +3 -3
- package/dist/chart/model/data-series.model.js +1 -1
- package/dist/chart/model/scale.model.js +1 -1
- package/dist/chart/model/scaling/viewport.model.d.ts +2 -1
- package/dist/chart/model/scaling/viewport.model.js +6 -1
- package/dist/chart/model/time-zone.model.js +1 -3
- package/dist/chart/utils/candles-generator-ts.utils.d.ts +1 -0
- package/dist/chart/utils/candles-generator.utils.d.ts +1 -0
- package/dist/chart/utils/candles-generator.utils.js +2 -0
- package/dist/chart/utils/string.utils.d.ts +6 -0
- package/dist/chart/utils/string.utils.js +19 -0
- package/dist/chart/utils/types.utils.d.ts +9 -0
- package/dist/chart/utils/types.utils.js +6 -0
- package/dist/dxchart.min.js +4 -4
- package/package.json +1 -1
|
@@ -3,10 +3,10 @@
|
|
|
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 { Candle } from
|
|
7
|
-
import { DataSeriesPoint, VisualSeriesPoint } from
|
|
8
|
-
import { Index } from
|
|
9
|
-
import VisualCandle from
|
|
6
|
+
import { Candle } from '../../model/candle.model';
|
|
7
|
+
import { DataSeriesPoint, VisualSeriesPoint } from '../../model/data-series.model';
|
|
8
|
+
import { Index } from '../../model/scaling/viewport.model';
|
|
9
|
+
import VisualCandle from '../../model/visual-candle';
|
|
10
10
|
/**
|
|
11
11
|
* Generates fake candle for left and right "out of data range" zones.
|
|
12
12
|
* Requires period to calculate the fake timestamp.
|
|
@@ -3,10 +3,10 @@
|
|
|
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 { nameDirection } from
|
|
7
|
-
import { VisualSeriesPoint } from
|
|
8
|
-
import VisualCandle from
|
|
9
|
-
import { DEFAULT_PERIOD, fakeCandle, fakeDataPoint } from
|
|
6
|
+
import { nameDirection } from '../../model/candle.model';
|
|
7
|
+
import { VisualSeriesPoint } from '../../model/data-series.model';
|
|
8
|
+
import VisualCandle from '../../model/visual-candle';
|
|
9
|
+
import { DEFAULT_PERIOD, fakeCandle, fakeDataPoint } from './fake-candles';
|
|
10
10
|
/**
|
|
11
11
|
* Generates fake candle for left and right "out of data range" zones.
|
|
12
12
|
* Requires period to calculate the fake timestamp.
|
|
@@ -22,11 +22,11 @@ export class CrossToolComponent extends ChartBaseElement {
|
|
|
22
22
|
this.drawingManager = drawingManager;
|
|
23
23
|
this.paneManager = paneManager;
|
|
24
24
|
this.crossToolTypeDrawers = {};
|
|
25
|
-
this.model = new CrossToolModel(config.components.crossTool, this.crossToolCanvasModel, crossEventProducer, hoverProducer);
|
|
25
|
+
this.model = new CrossToolModel(config.components.crossTool, this.crossToolCanvasModel, crossEventProducer, hoverProducer, this.canvasBoundsContainer);
|
|
26
26
|
this.addChildEntity(this.model);
|
|
27
27
|
const clearCanvasDrawer = new ClearCanvasDrawer(this.crossToolCanvasModel);
|
|
28
28
|
this.registerDefaultDrawerTypes();
|
|
29
|
-
const crossToolDrawer = new CrossToolDrawer(this.model, this.crossToolCanvasModel, this.crossToolTypeDrawers);
|
|
29
|
+
const crossToolDrawer = new CrossToolDrawer(this.model, this.config, this.crossToolCanvasModel, this.crossToolTypeDrawers);
|
|
30
30
|
const compositeDrawer = new CompositeDrawer();
|
|
31
31
|
compositeDrawer.addDrawer(clearCanvasDrawer, 'CLEAR_CANVAS');
|
|
32
32
|
compositeDrawer.addDrawer(crossToolDrawer, 'CROSS_TOOL_DRAWER');
|
|
@@ -6,14 +6,16 @@
|
|
|
6
6
|
import { CanvasModel } from '../../model/canvas.model';
|
|
7
7
|
import { Drawer } from '../../drawers/drawing-manager';
|
|
8
8
|
import { CrossToolHover, CrossToolModel, CrossToolType } from './cross-tool.model';
|
|
9
|
+
import { FullChartConfig } from '../../chart.config';
|
|
9
10
|
export interface CrossToolTypeDrawer {
|
|
10
11
|
draw: (ctx: CanvasRenderingContext2D, hover: CrossToolHover) => void;
|
|
11
12
|
}
|
|
12
13
|
export declare class CrossToolDrawer implements Drawer {
|
|
13
14
|
private model;
|
|
15
|
+
private config;
|
|
14
16
|
private crossToolCanvasModel;
|
|
15
17
|
private readonly crossToolTypeDrawers;
|
|
16
|
-
constructor(model: CrossToolModel, crossToolCanvasModel: CanvasModel, crossToolTypeDrawers: Record<CrossToolType, CrossToolTypeDrawer>);
|
|
18
|
+
constructor(model: CrossToolModel, config: FullChartConfig, crossToolCanvasModel: CanvasModel, crossToolTypeDrawers: Record<CrossToolType, CrossToolTypeDrawer>);
|
|
17
19
|
/**
|
|
18
20
|
* Draws the cross tool on the canvas.
|
|
19
21
|
* @function
|
|
@@ -4,8 +4,9 @@
|
|
|
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
|
export class CrossToolDrawer {
|
|
7
|
-
constructor(model, crossToolCanvasModel, crossToolTypeDrawers) {
|
|
7
|
+
constructor(model, config, crossToolCanvasModel, crossToolTypeDrawers) {
|
|
8
8
|
this.model = model;
|
|
9
|
+
this.config = config;
|
|
9
10
|
this.crossToolCanvasModel = crossToolCanvasModel;
|
|
10
11
|
this.crossToolTypeDrawers = crossToolTypeDrawers;
|
|
11
12
|
}
|
|
@@ -18,12 +19,12 @@ export class CrossToolDrawer {
|
|
|
18
19
|
* @returns {void}
|
|
19
20
|
*/
|
|
20
21
|
draw() {
|
|
21
|
-
const drawer = this.crossToolTypeDrawers[this.
|
|
22
|
+
const drawer = this.crossToolTypeDrawers[this.config.components.crossTool.type];
|
|
22
23
|
if (drawer) {
|
|
23
24
|
this.model.currentHover && drawer.draw(this.crossToolCanvasModel.ctx, this.model.currentHover);
|
|
24
25
|
}
|
|
25
26
|
else {
|
|
26
|
-
console.error(`No cross tool drawer type registered for drawer type ${this.
|
|
27
|
+
console.error(`No cross tool drawer type registered for drawer type ${this.config.components.crossTool.type}`);
|
|
27
28
|
}
|
|
28
29
|
}
|
|
29
30
|
/**
|
|
@@ -9,6 +9,7 @@ import { CrossEventProducerComponent } from '../../inputhandlers/cross-event-pro
|
|
|
9
9
|
import { Hover, HoverProducerComponent } from '../../inputhandlers/hover-producer.component';
|
|
10
10
|
import { CanvasModel } from '../../model/canvas.model';
|
|
11
11
|
import { ChartBaseElement } from '../../model/chart-base-element';
|
|
12
|
+
import { CanvasBoundsContainer } from '../../canvas/canvas-bounds-container';
|
|
12
13
|
export type CrossToolType = 'cross-and-labels' | 'only-labels' | 'none' | string;
|
|
13
14
|
export interface CrossToolHover {
|
|
14
15
|
x: number;
|
|
@@ -21,11 +22,11 @@ export declare class CrossToolModel extends ChartBaseElement {
|
|
|
21
22
|
private crossToolCanvasModel;
|
|
22
23
|
private crossEventProducer;
|
|
23
24
|
private hoverProducer;
|
|
25
|
+
private canvasBoundsContainer;
|
|
24
26
|
currentHoverSubject: BehaviorSubject<CrossToolHover | null>;
|
|
25
27
|
get currentHover(): CrossToolHover | null;
|
|
26
28
|
set currentHover(value: CrossToolHover | null);
|
|
27
|
-
|
|
28
|
-
constructor(config: Required<ChartConfigComponentsCrossTool>, crossToolCanvasModel: CanvasModel, crossEventProducer: CrossEventProducerComponent, hoverProducer: HoverProducerComponent);
|
|
29
|
+
constructor(config: Required<ChartConfigComponentsCrossTool>, crossToolCanvasModel: CanvasModel, crossEventProducer: CrossEventProducerComponent, hoverProducer: HoverProducerComponent, canvasBoundsContainer: CanvasBoundsContainer);
|
|
29
30
|
/**
|
|
30
31
|
* Sets the type of the CrossTool object.
|
|
31
32
|
*
|
|
@@ -35,9 +36,7 @@ export declare class CrossToolModel extends ChartBaseElement {
|
|
|
35
36
|
setType(type: CrossToolType): void;
|
|
36
37
|
/**
|
|
37
38
|
* Method to activate the cross tool.
|
|
38
|
-
* It subscribes to the
|
|
39
|
-
* It also subscribes to the eventBus's hover and close hover events and updates the hover and fires the draw event accordingly.
|
|
40
|
-
* It also subscribes to the chartModel's candlesSetSubject and timeZoneModel's observeTimeZoneChanged events and recalculates the cross tool X formatter.
|
|
39
|
+
* It subscribes to the hoverProducer's hover event and updates the crosstool.
|
|
41
40
|
*/
|
|
42
41
|
protected doActivate(): void;
|
|
43
42
|
/**
|
|
@@ -59,5 +58,6 @@ export declare class CrossToolModel extends ChartBaseElement {
|
|
|
59
58
|
* @param {number} hover.candleHover.closestOHLCY - The y coordinate of the closest OHLC price of the candle.
|
|
60
59
|
* @returns {void}
|
|
61
60
|
*/
|
|
62
|
-
|
|
61
|
+
updateCrossTool(hover: Hover, magnetTarget?: import("./cross-tool.component").MagnetTarget): void;
|
|
62
|
+
private updateCrossToolMobile;
|
|
63
63
|
}
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { BehaviorSubject } from 'rxjs';
|
|
7
7
|
import { ChartBaseElement } from '../../model/chart-base-element';
|
|
8
|
-
import { CHART_UUID } from '../../canvas/canvas-bounds-container';
|
|
8
|
+
import { CanvasElement, CHART_UUID } from '../../canvas/canvas-bounds-container';
|
|
9
|
+
import { isMobile } from '../../utils/device/browser.utils';
|
|
9
10
|
export class CrossToolModel extends ChartBaseElement {
|
|
10
11
|
get currentHover() {
|
|
11
12
|
return this.currentHoverSubject.getValue();
|
|
@@ -13,16 +14,15 @@ export class CrossToolModel extends ChartBaseElement {
|
|
|
13
14
|
set currentHover(value) {
|
|
14
15
|
this.currentHoverSubject.next(value);
|
|
15
16
|
}
|
|
16
|
-
constructor(config, crossToolCanvasModel, crossEventProducer, hoverProducer) {
|
|
17
|
+
constructor(config, crossToolCanvasModel, crossEventProducer, hoverProducer, canvasBoundsContainer) {
|
|
17
18
|
super();
|
|
18
19
|
this.config = config;
|
|
19
20
|
this.crossToolCanvasModel = crossToolCanvasModel;
|
|
20
21
|
this.crossEventProducer = crossEventProducer;
|
|
21
22
|
this.hoverProducer = hoverProducer;
|
|
23
|
+
this.canvasBoundsContainer = canvasBoundsContainer;
|
|
22
24
|
// the main hover object which will be presented on UI
|
|
23
25
|
this.currentHoverSubject = new BehaviorSubject(null);
|
|
24
|
-
this.type = 'cross-and-labels';
|
|
25
|
-
this.type = config.type;
|
|
26
26
|
}
|
|
27
27
|
/**
|
|
28
28
|
* Sets the type of the CrossTool object.
|
|
@@ -31,19 +31,17 @@ export class CrossToolModel extends ChartBaseElement {
|
|
|
31
31
|
* @returns {void}
|
|
32
32
|
*/
|
|
33
33
|
setType(type) {
|
|
34
|
-
this.type = type;
|
|
34
|
+
this.config.type = type;
|
|
35
35
|
}
|
|
36
36
|
/**
|
|
37
37
|
* Method to activate the cross tool.
|
|
38
|
-
* It subscribes to the
|
|
39
|
-
* It also subscribes to the eventBus's hover and close hover events and updates the hover and fires the draw event accordingly.
|
|
40
|
-
* It also subscribes to the chartModel's candlesSetSubject and timeZoneModel's observeTimeZoneChanged events and recalculates the cross tool X formatter.
|
|
38
|
+
* It subscribes to the hoverProducer's hover event and updates the crosstool.
|
|
41
39
|
*/
|
|
42
40
|
doActivate() {
|
|
43
41
|
super.doActivate();
|
|
44
42
|
this.addRxSubscription(this.hoverProducer.hoverSubject.subscribe(hover => {
|
|
45
43
|
if (this.crossEventProducer.crossSubject.getValue() !== null && hover !== null) {
|
|
46
|
-
this.
|
|
44
|
+
isMobile() ? this.updateCrossToolMobile(hover) : this.updateCrossTool(hover);
|
|
47
45
|
}
|
|
48
46
|
else {
|
|
49
47
|
this.currentHover = null;
|
|
@@ -56,7 +54,7 @@ export class CrossToolModel extends ChartBaseElement {
|
|
|
56
54
|
* @private
|
|
57
55
|
*/
|
|
58
56
|
fireDraw() {
|
|
59
|
-
if (this.type !== 'none') {
|
|
57
|
+
if (this.config.type !== 'none') {
|
|
60
58
|
this.crossToolCanvasModel.fireDraw();
|
|
61
59
|
}
|
|
62
60
|
}
|
|
@@ -74,7 +72,7 @@ export class CrossToolModel extends ChartBaseElement {
|
|
|
74
72
|
* @param {number} hover.candleHover.closestOHLCY - The y coordinate of the closest OHLC price of the candle.
|
|
75
73
|
* @returns {void}
|
|
76
74
|
*/
|
|
77
|
-
|
|
75
|
+
updateCrossTool(hover, magnetTarget = this.config.magnetTarget) {
|
|
78
76
|
if (this.currentHover === null) {
|
|
79
77
|
this.currentHover = { x: hover.x, y: 0, time: hover.timeFormatted, paneId: hover.paneId };
|
|
80
78
|
}
|
|
@@ -110,4 +108,37 @@ export class CrossToolModel extends ChartBaseElement {
|
|
|
110
108
|
this.currentHover.paneId = hover.paneId;
|
|
111
109
|
this.currentHoverSubject.next(this.currentHover);
|
|
112
110
|
}
|
|
111
|
+
updateCrossToolMobile(hover) {
|
|
112
|
+
var _a;
|
|
113
|
+
// mobile crosstool works only after long touch event
|
|
114
|
+
if (!this.hoverProducer.longTouchActivatedSubject.getValue()) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
const { fixed, temp, isSet } = this.crossEventProducer.crossToolTouchInfo;
|
|
118
|
+
// long touch makes crosstool fixed and the further moving will place crosstool under the current hover coordinates (ordinary logic)
|
|
119
|
+
// if crosstool is already set (long touch end event happened) the moving of chart will move crosstool according to it's initial (fixed position)
|
|
120
|
+
if (!isSet) {
|
|
121
|
+
this.updateCrossTool(hover);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
// additional crosstool move logic
|
|
125
|
+
const paneBounds = this.canvasBoundsContainer.getBounds(CanvasElement.PANE_UUID(hover.paneId));
|
|
126
|
+
const offset = 5;
|
|
127
|
+
// take a difference inbetween current hover and temporary crosstool coordinates
|
|
128
|
+
const xDiff = hover.x - temp.x;
|
|
129
|
+
const yDiff = hover.y - temp.y;
|
|
130
|
+
// apply the difference to the fixed coordinates
|
|
131
|
+
const rawX = fixed.x + xDiff;
|
|
132
|
+
const rawY = fixed.y + yDiff;
|
|
133
|
+
const paneYStart = paneBounds.y + offset;
|
|
134
|
+
const paneYEnd = paneBounds.y + paneBounds.height - offset;
|
|
135
|
+
// check for chart bounds and don't move crosstool outside of it
|
|
136
|
+
const x = rawX < offset ? offset : rawX > paneBounds.width - offset ? paneBounds.width - offset : rawX;
|
|
137
|
+
const y = rawY < paneYStart ? paneYStart : rawY > paneYEnd ? paneYEnd : rawY;
|
|
138
|
+
const crossToolHover = (_a = this.hoverProducer.createHover(x, y, hover.paneId)) !== null && _a !== void 0 ? _a : hover;
|
|
139
|
+
const updatedHover = Object.assign(Object.assign({}, crossToolHover), { x,
|
|
140
|
+
y });
|
|
141
|
+
this.crossEventProducer.crossToolHover = updatedHover;
|
|
142
|
+
this.updateCrossTool(updatedHover);
|
|
143
|
+
}
|
|
113
144
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
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 { CanvasElement } from '../../../canvas/canvas-bounds-container';
|
|
6
|
+
import { CanvasElement, X_AXIS_MOBILE_PADDING } from '../../../canvas/canvas-bounds-container';
|
|
7
7
|
import { avoidAntialiasing, drawRoundedRect } from '../../../utils/canvas/canvas-drawing-functions.utils';
|
|
8
8
|
import { priceLabelDrawersMap } from '../../y_axis/price_labels/price-label.drawer';
|
|
9
9
|
export class CrossAndLabelsDrawerType {
|
|
@@ -98,12 +98,12 @@ export class CrossAndLabelsDrawerType {
|
|
|
98
98
|
const boxWidth = width + xLabelPaddingLeft + xLabelPaddingRight;
|
|
99
99
|
const boxHeight = fontHeight + xLabelPaddingTop + xLabelPaddingBottom;
|
|
100
100
|
const xBoxPos = Math.max(x - boxWidth / 2, 0);
|
|
101
|
-
const yBoxPos = xAxis.y + xLabelMarginTop;
|
|
101
|
+
const yBoxPos = xAxis.y + xLabelMarginTop + X_AXIS_MOBILE_PADDING / 2;
|
|
102
102
|
drawRoundedRect(ctx, xBoxPos, yBoxPos, boxWidth, boxHeight);
|
|
103
103
|
// label
|
|
104
104
|
ctx.fillStyle = crossToolColors.labelTextColor;
|
|
105
105
|
const xTextPos = Math.max(x - width / 2, xLabelPaddingLeft);
|
|
106
|
-
const yTextPos = xAxis.y + xLabelMarginTop + fontHeight + xLabelPaddingTop - 1; // -1 for vertical adjustment
|
|
106
|
+
const yTextPos = xAxis.y + xLabelMarginTop + fontHeight + X_AXIS_MOBILE_PADDING / 2 + xLabelPaddingTop - 1; // -1 for vertical adjustment
|
|
107
107
|
ctx.fillText(labelText, xTextPos, yTextPos);
|
|
108
108
|
ctx.restore();
|
|
109
109
|
}
|
|
@@ -73,7 +73,7 @@ export class HighLowDrawer {
|
|
|
73
73
|
*/
|
|
74
74
|
getMarkerText(yValue, type) {
|
|
75
75
|
const formattedValue = this.chartModel.pane.regularFormatter(yValue);
|
|
76
|
-
const prefix = type === 'high' ?
|
|
76
|
+
const prefix = type === 'high' ? this.config.components.highLow.prefix.high : this.config.components.highLow.prefix.low;
|
|
77
77
|
return `${prefix} ${formattedValue}`;
|
|
78
78
|
}
|
|
79
79
|
/**
|
|
@@ -24,6 +24,7 @@ import { PaneComponent } from './pane.component';
|
|
|
24
24
|
import { DataSeriesModel } from '../../model/data-series.model';
|
|
25
25
|
import { HitTestCanvasModel } from '../../model/hit-test-canvas.model';
|
|
26
26
|
import { ChartResizeHandler } from '../../inputhandlers/chart-resize.handler';
|
|
27
|
+
export type MoveDataSeriesToPaneDirection = 'above' | 'below';
|
|
27
28
|
export declare class PaneManager extends ChartBaseElement {
|
|
28
29
|
private chartBaseModel;
|
|
29
30
|
private dynamicObjectsCanvasModel;
|
|
@@ -107,6 +108,10 @@ export declare class PaneManager extends ChartBaseElement {
|
|
|
107
108
|
* Shows a pane, use if the pane is hidden
|
|
108
109
|
*/
|
|
109
110
|
showPane(paneUUID: string): void;
|
|
111
|
+
/**
|
|
112
|
+
* Move data series to a certain pane, or create a new one if no pane is found
|
|
113
|
+
*/
|
|
114
|
+
moveDataSeriesToPane(dataSeries: DataSeriesModel[], initialPane: PaneComponent, initialExtent: YExtentComponent, paneUUID?: string, extent?: YExtentComponent, direction?: MoveDataSeriesToPaneDirection): void;
|
|
110
115
|
/**
|
|
111
116
|
* Adds cursors to the chart elements based on the provided uuid and cursor type.
|
|
112
117
|
* @private
|
|
@@ -188,6 +188,26 @@ export class PaneManager extends ChartBaseElement {
|
|
|
188
188
|
this.canvasBoundsContainer.showPaneBounds(paneUUID);
|
|
189
189
|
this.recalculateState();
|
|
190
190
|
}
|
|
191
|
+
/**
|
|
192
|
+
* Move data series to a certain pane, or create a new one if no pane is found
|
|
193
|
+
*/
|
|
194
|
+
moveDataSeriesToPane(dataSeries, initialPane, initialExtent, paneUUID, extent, direction) {
|
|
195
|
+
const pane = paneUUID && this.panes[paneUUID];
|
|
196
|
+
if (!pane) {
|
|
197
|
+
const order = direction && direction === 'above' ? 0 : this.panesOrder.length;
|
|
198
|
+
const newPane = this.createPane(undefined, { order });
|
|
199
|
+
newPane.moveDataSeriesToExistingExtentComponent(dataSeries, initialPane, initialExtent, newPane.mainExtent);
|
|
200
|
+
initialPane.yExtentComponents.length === 0 && this.removePane(initialPane.uuid);
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
if (extent) {
|
|
204
|
+
pane.moveDataSeriesToExistingExtentComponent(dataSeries, initialPane, initialExtent, extent);
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
pane.moveDataSeriesToNewExtentComponent(dataSeries, initialPane, initialExtent);
|
|
208
|
+
}
|
|
209
|
+
initialPane.yExtentComponents.length === 0 && this.removePane(initialPane.uuid);
|
|
210
|
+
}
|
|
191
211
|
/**
|
|
192
212
|
* Adds cursors to the chart elements based on the provided uuid and cursor type.
|
|
193
213
|
* @private
|
|
@@ -7,7 +7,7 @@ import { Subject } from 'rxjs';
|
|
|
7
7
|
import { CanvasAnimation } from '../../animation/canvas-animation';
|
|
8
8
|
import { CanvasBoundsContainer, HitBoundsTest } from '../../canvas/canvas-bounds-container';
|
|
9
9
|
import { CursorHandler } from '../../canvas/cursor.handler';
|
|
10
|
-
import { FullChartConfig } from '../../chart.config';
|
|
10
|
+
import { FullChartConfig, YAxisAlign } from '../../chart.config';
|
|
11
11
|
import { DrawingManager } from '../../drawers/drawing-manager';
|
|
12
12
|
import EventBus from '../../events/event-bus';
|
|
13
13
|
import { CanvasInputListenerComponent } from '../../inputlisteners/canvas-input-listener.component';
|
|
@@ -84,6 +84,14 @@ export declare class PaneComponent extends ChartBaseElement {
|
|
|
84
84
|
private addCursors;
|
|
85
85
|
createExtentComponent(options?: AtLeastOne<YExtentCreationOptions>): YExtentComponent;
|
|
86
86
|
removeExtentComponent(extentComponent: YExtentComponent): void;
|
|
87
|
+
/**
|
|
88
|
+
* Create new pane extent and attach data series to it
|
|
89
|
+
*/
|
|
90
|
+
moveDataSeriesToNewExtentComponent(dataSeries: DataSeriesModel[], initialPane: PaneComponent, initialExtent: YExtentComponent, align?: YAxisAlign): void;
|
|
91
|
+
/**
|
|
92
|
+
* Attach data series to existing y axis extent
|
|
93
|
+
*/
|
|
94
|
+
moveDataSeriesToExistingExtentComponent(dataSeries: DataSeriesModel[], initialPane: PaneComponent, initialExtent: YExtentComponent, extentComponent: YExtentComponent): void;
|
|
87
95
|
/**
|
|
88
96
|
* This method updates the view by calling the doAutoScale method of the scaleModel and firing the Draw event using the eventBus.
|
|
89
97
|
* @private
|
|
@@ -149,6 +149,22 @@ export class PaneComponent extends ChartBaseElement {
|
|
|
149
149
|
this.yExtentComponents.forEach((c, idx) => (c.idx = idx));
|
|
150
150
|
this.canvasBoundsContainer.updateYAxisWidths();
|
|
151
151
|
}
|
|
152
|
+
/**
|
|
153
|
+
* Create new pane extent and attach data series to it
|
|
154
|
+
*/
|
|
155
|
+
moveDataSeriesToNewExtentComponent(dataSeries, initialPane, initialExtent, align = 'right') {
|
|
156
|
+
const extent = this.createExtentComponent();
|
|
157
|
+
extent.yAxis.setYAxisAlign(align);
|
|
158
|
+
dataSeries.forEach(series => series.moveToExtent(extent));
|
|
159
|
+
initialExtent.dataSeries.size === 0 && initialPane.removeExtentComponent(initialExtent);
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Attach data series to existing y axis extent
|
|
163
|
+
*/
|
|
164
|
+
moveDataSeriesToExistingExtentComponent(dataSeries, initialPane, initialExtent, extentComponent) {
|
|
165
|
+
dataSeries.forEach(series => series.moveToExtent(extentComponent));
|
|
166
|
+
initialExtent.dataSeries.size === 0 && initialPane.removeExtentComponent(initialExtent);
|
|
167
|
+
}
|
|
152
168
|
/**
|
|
153
169
|
* This method updates the view by calling the doAutoScale method of the scaleModel and firing the Draw event using the eventBus.
|
|
154
170
|
* @private
|
|
@@ -4,7 +4,6 @@
|
|
|
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 { FullChartConfig } from '../../chart.config';
|
|
7
|
-
import { DrawingManager } from '../../drawers/drawing-manager';
|
|
8
7
|
import { ChartBaseElement } from '../../model/chart-base-element';
|
|
9
8
|
import { Pixel, Unit } from '../../model/scaling/viewport.model';
|
|
10
9
|
import { ChartComponent } from '../chart/chart.component';
|
|
@@ -13,13 +12,12 @@ import { PaneComponent } from '../pane/pane.component';
|
|
|
13
12
|
import { VolumesModel } from './volumes.model';
|
|
14
13
|
export declare class SeparateVolumesComponent extends ChartBaseElement {
|
|
15
14
|
private chartComponent;
|
|
16
|
-
private drawingManager;
|
|
17
15
|
config: FullChartConfig;
|
|
18
16
|
private volumesModel;
|
|
19
17
|
private paneManager;
|
|
20
18
|
static UUID: string;
|
|
21
19
|
pane: PaneComponent | undefined;
|
|
22
|
-
constructor(chartComponent: ChartComponent,
|
|
20
|
+
constructor(chartComponent: ChartComponent, config: FullChartConfig, volumesModel: VolumesModel, paneManager: PaneManager);
|
|
23
21
|
protected doActivate(): void;
|
|
24
22
|
/**
|
|
25
23
|
* Activates the separate volumes feature.
|
|
@@ -7,10 +7,9 @@ import { ChartBaseElement } from '../../model/chart-base-element';
|
|
|
7
7
|
import { createCandlesOffsetProvider } from '../chart/data-series.high-low-provider';
|
|
8
8
|
import { volumeFormatter } from './volumes.formatter';
|
|
9
9
|
class SeparateVolumesComponent extends ChartBaseElement {
|
|
10
|
-
constructor(chartComponent,
|
|
10
|
+
constructor(chartComponent, config, volumesModel, paneManager) {
|
|
11
11
|
super();
|
|
12
12
|
this.chartComponent = chartComponent;
|
|
13
|
-
this.drawingManager = drawingManager;
|
|
14
13
|
this.config = config;
|
|
15
14
|
this.volumesModel = volumesModel;
|
|
16
15
|
this.paneManager = paneManager;
|
|
@@ -53,7 +52,6 @@ class SeparateVolumesComponent extends ChartBaseElement {
|
|
|
53
52
|
deactiveSeparateVolumes() {
|
|
54
53
|
this.paneManager.removePane(SeparateVolumesComponent.UUID);
|
|
55
54
|
delete this.pane;
|
|
56
|
-
this.drawingManager.removeDrawerByName('UNDERLAY_VOLUMES_AREA');
|
|
57
55
|
}
|
|
58
56
|
/**
|
|
59
57
|
* Converts a pixel value from the Y-axis of the scale model to the corresponding data value.
|
|
@@ -23,7 +23,7 @@ export class VolumesComponent extends ChartBaseElement {
|
|
|
23
23
|
const volumesModel = new VolumesModel(chartComponent, scale);
|
|
24
24
|
this.volumesModel = volumesModel;
|
|
25
25
|
this.addChildEntity(volumesModel);
|
|
26
|
-
this.separateVolumes = new SeparateVolumesComponent(chartComponent,
|
|
26
|
+
this.separateVolumes = new SeparateVolumesComponent(chartComponent, config, volumesModel, paneManager);
|
|
27
27
|
this.volumesDrawer = new VolumesDrawer(config, this.volumesModel, chartComponent.chartModel, () => { var _a, _b; return (this.config.components.volumes.showSeparately ? (_b = (_a = this.separateVolumes.pane) === null || _a === void 0 ? void 0 : _a.scale) !== null && _b !== void 0 ? _b : scale : scale); }, this.volumesColorByChartTypeMap, () => true);
|
|
28
28
|
config.components.volumes.visible && this.syncVolumesDynamicObject();
|
|
29
29
|
this.addChildEntity(this.separateVolumes);
|
|
@@ -101,12 +101,12 @@ export class VolumesDrawer {
|
|
|
101
101
|
const width = nextX !== undefined ? nextX - x : floorToDPR(unitToPixels(vCandle.width, viewportModel.zoomX));
|
|
102
102
|
if (this.config.components.volumes.showSeparately) {
|
|
103
103
|
const y = floorToDPR(viewportModel.toY(vCandle.candle.volume));
|
|
104
|
-
const height =
|
|
104
|
+
const height = ceilToDPR(viewportModel.toY(0)) - y;
|
|
105
105
|
this.drawVolume(canvasModel, vCandle, x, y, width, height);
|
|
106
106
|
}
|
|
107
107
|
else {
|
|
108
108
|
const zoomY = volumeMax / (fullVHeight / OVERLAY_VOLUME_TOTAL_HEIGHT_DIVISOR);
|
|
109
|
-
const height = Math.max(unitToPixels(vCandle.candle.volume, zoomY), 2);
|
|
109
|
+
const height = Math.max(ceilToDPR(unitToPixels(vCandle.candle.volume, zoomY)), 2);
|
|
110
110
|
const y = floorToDPR(bounds.y + fullVHeight - height);
|
|
111
111
|
this.drawVolume(canvasModel, vCandle, x, y, width, height);
|
|
112
112
|
}
|
|
@@ -139,7 +139,7 @@ export class VolumesDrawer {
|
|
|
139
139
|
ctx.stroke();
|
|
140
140
|
}
|
|
141
141
|
else {
|
|
142
|
-
ctx.fillRect(x, y, width,
|
|
142
|
+
ctx.fillRect(x, y, width, height);
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
145
|
}
|
|
@@ -5,21 +5,12 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { CanvasBoundsContainer } from '../../canvas/canvas-bounds-container';
|
|
7
7
|
import { ChartBaseElement } from '../../model/chart-base-element';
|
|
8
|
-
import { FullChartConfig } from '../../chart.config';
|
|
8
|
+
import { ChartConfigComponentsWaterMark, FullChartConfig } from '../../chart.config';
|
|
9
9
|
import { CanvasModel } from '../../model/canvas.model';
|
|
10
10
|
import { DrawingManager } from '../../drawers/drawing-manager';
|
|
11
11
|
import EventBus from '../../events/event-bus';
|
|
12
12
|
import { ChartModel } from '../chart/chart.model';
|
|
13
13
|
import { PaneManager } from '../pane/pane-manager.component';
|
|
14
|
-
export interface WaterMarkConfig {
|
|
15
|
-
isVisible?: boolean;
|
|
16
|
-
fontFamily?: string;
|
|
17
|
-
firstRowFontSize?: number;
|
|
18
|
-
firstRowBottomPadding?: number;
|
|
19
|
-
secondRowFontSize?: number;
|
|
20
|
-
secondRowBottomPadding?: number;
|
|
21
|
-
thirdRowFontSize?: number;
|
|
22
|
-
}
|
|
23
14
|
export interface WaterMarkData {
|
|
24
15
|
firstRow?: string;
|
|
25
16
|
secondRow?: string;
|
|
@@ -55,11 +46,11 @@ export declare class WaterMarkComponent extends ChartBaseElement {
|
|
|
55
46
|
private getWaterMarkData;
|
|
56
47
|
/**
|
|
57
48
|
* Sets the watermark configuration for the chart.
|
|
58
|
-
* @param {
|
|
49
|
+
* @param {ChartConfigComponentsWaterMark} watermarkConfig - The configuration object for the watermark.
|
|
59
50
|
* @returns {void}
|
|
60
51
|
|
|
61
52
|
*/
|
|
62
|
-
setWaterMarkConfig(watermarkConfig:
|
|
53
|
+
setWaterMarkConfig(watermarkConfig: ChartConfigComponentsWaterMark): void;
|
|
63
54
|
/**
|
|
64
55
|
* Sets the logo image to be used as a watermark.
|
|
65
56
|
* @param {CanvasImageSource} img - The image to be used as a watermark.
|
|
@@ -56,7 +56,7 @@ export class WaterMarkComponent extends ChartBaseElement {
|
|
|
56
56
|
}
|
|
57
57
|
/**
|
|
58
58
|
* Sets the watermark configuration for the chart.
|
|
59
|
-
* @param {
|
|
59
|
+
* @param {ChartConfigComponentsWaterMark} watermarkConfig - The configuration object for the watermark.
|
|
60
60
|
* @returns {void}
|
|
61
61
|
|
|
62
62
|
*/
|
|
@@ -75,7 +75,7 @@ export const parseTimeFormatsFromKey = (format) => {
|
|
|
75
75
|
};
|
|
76
76
|
}
|
|
77
77
|
else {
|
|
78
|
-
console.warn(`${format} is not fit, check the documentation to see available formats
|
|
78
|
+
console.warn(`${format} is not fit, check the documentation to see available formats in dxchart-lite documentation.`);
|
|
79
79
|
return null;
|
|
80
80
|
}
|
|
81
81
|
};
|
|
@@ -3,7 +3,7 @@
|
|
|
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 { CanvasElement } from '../../canvas/canvas-bounds-container';
|
|
6
|
+
import { CanvasElement, X_AXIS_MOBILE_PADDING } from '../../canvas/canvas-bounds-container';
|
|
7
7
|
const DEFAULT_X_LABEL_PADDING = { x: 4, y: 4 };
|
|
8
8
|
/**
|
|
9
9
|
* Draws the label on X axis.
|
|
@@ -50,7 +50,7 @@ export function drawXAxisLabel(ctx, canvasBoundsContainer, config, label) {
|
|
|
50
50
|
}
|
|
51
51
|
ctx.fillStyle = label.color;
|
|
52
52
|
const xTextPos = boxStart + DEFAULT_X_LABEL_PADDING.x;
|
|
53
|
-
const yTextPos = xAxisBounds.y + offsetTop + fontSize
|
|
53
|
+
const yTextPos = xAxisBounds.y + offsetTop + fontSize + X_AXIS_MOBILE_PADDING / 2;
|
|
54
54
|
ctx.fillText(label.text, xTextPos, yTextPos);
|
|
55
55
|
ctx.restore();
|
|
56
56
|
}
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
import { ChartBaseElement } from '../../model/chart-base-element';
|
|
7
7
|
import { CanvasElement } from '../../canvas/canvas-bounds-container';
|
|
8
8
|
import { DragNDropXComponent } from '../dran-n-drop_helper/drag-n-drop-x.component';
|
|
9
|
+
// if you drag full X width from left to right - you will have x3 zoom, and vice-versa
|
|
10
|
+
const FULL_X_WIDTH_ZOOM_FACTOR = 3;
|
|
9
11
|
/**
|
|
10
12
|
* Handles the mouse drag on X axis - to zoom the viewport horizontally.
|
|
11
13
|
* @doc-tags scaling,zoom,viewport
|
|
@@ -21,10 +23,12 @@ export class XAxisScaleHandler extends ChartBaseElement {
|
|
|
21
23
|
this.hitTest = hitTest;
|
|
22
24
|
this.hitTestCanvasModel = hitTestCanvasModel;
|
|
23
25
|
this.lastXStart = 0;
|
|
26
|
+
this.lastXEnd = 0;
|
|
24
27
|
this.lastXWidth = 0;
|
|
25
28
|
this.lastXPxWidth = 0;
|
|
26
29
|
this.onXDragStart = () => {
|
|
27
30
|
this.lastXStart = this.scale.xStart;
|
|
31
|
+
this.lastXEnd = this.scale.xEnd;
|
|
28
32
|
this.lastXWidth = this.scale.xEnd - this.scale.xStart;
|
|
29
33
|
const bounds = this.canvasBoundsContainer.getBounds(CanvasElement.X_AXIS);
|
|
30
34
|
this.lastXPxWidth = bounds.width - this.canvasInputListener.currentPoint.x;
|
|
@@ -32,23 +36,48 @@ export class XAxisScaleHandler extends ChartBaseElement {
|
|
|
32
36
|
this.hitTestCanvasModel.hitTestDrawersPredicateSubject.next(false);
|
|
33
37
|
};
|
|
34
38
|
this.onXDragTick = (dragInfo) => {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
let { delta: absoluteXDelta } = dragInfo;
|
|
40
|
+
// mouse click or single tap drag
|
|
41
|
+
if (!this.touches || this.touches.length === 1) {
|
|
42
|
+
const newPxWidth = this.lastXPxWidth - absoluteXDelta;
|
|
43
|
+
// cursor goes beyond x-axis - maximum scale is reached
|
|
44
|
+
if (newPxWidth < 0) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const xZoomMult = this.lastXPxWidth / newPxWidth;
|
|
48
|
+
const newWidth = this.lastXWidth * xZoomMult;
|
|
49
|
+
const newXStart = this.lastXStart + (this.lastXWidth - newWidth);
|
|
50
|
+
this.scale.setXScale(newXStart, this.scale.xEnd);
|
|
39
51
|
return;
|
|
40
52
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
this.
|
|
53
|
+
// if multitouch - take the first two touch events and apply delta the following way:
|
|
54
|
+
// the touch on the left keeps the initial delta because left => right gesture
|
|
55
|
+
// the touch on the right has the reversed delta because the gesture is right => left
|
|
56
|
+
if (this.touches.length > 1) {
|
|
57
|
+
const left = Math.min(this.touches[0].clientX, this.touches[1].clientX);
|
|
58
|
+
absoluteXDelta = left === this.touches[0].clientX ? absoluteXDelta : -absoluteXDelta;
|
|
59
|
+
let xZoomMult;
|
|
60
|
+
if (absoluteXDelta < 0) {
|
|
61
|
+
xZoomMult = 1 / (1 + (-absoluteXDelta / this.lastXPxWidth) * (FULL_X_WIDTH_ZOOM_FACTOR - 1));
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
xZoomMult = 1 + (absoluteXDelta / this.lastXPxWidth) * (FULL_X_WIDTH_ZOOM_FACTOR - 1);
|
|
65
|
+
}
|
|
66
|
+
const newXWidth = this.lastXWidth * xZoomMult;
|
|
67
|
+
const delta = (newXWidth - this.lastXWidth) / 2;
|
|
68
|
+
const newXStart = this.lastXStart - delta;
|
|
69
|
+
const newXEnd = this.lastXEnd + delta;
|
|
70
|
+
if (this.lastXStart !== newXStart || this.lastXEnd !== newXEnd) {
|
|
71
|
+
this.scale.setXScale(newXStart, newXEnd);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
45
74
|
};
|
|
46
75
|
this.onXDragEnd = () => {
|
|
47
76
|
// Continue redrawing hit test
|
|
48
77
|
this.hitTestCanvasModel.hitTestDrawersPredicateSubject.next(true);
|
|
49
78
|
};
|
|
50
|
-
this.setDblTapCallback = (cb) => this.dblTapCallback = cb;
|
|
51
|
-
this.setDblClickCallback = (cb) => this.dblClickCallback = cb;
|
|
79
|
+
this.setDblTapCallback = (cb) => (this.dblTapCallback = cb);
|
|
80
|
+
this.setDblClickCallback = (cb) => (this.dblClickCallback = cb);
|
|
52
81
|
this.dblClickCallback = () => chartModel.doBasicScale();
|
|
53
82
|
this.dblTapCallback = () => chartModel.doBasicScale();
|
|
54
83
|
const dragNDropXComponent = new DragNDropXComponent(hitTest, {
|