@devexperts/dxcharts-lite 2.0.1 → 2.1.0
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 +28 -29
- package/dist/chart/__tests__/chart.test.d.ts +6 -0
- package/dist/chart/__tests__/chart.test.js +51 -0
- package/dist/chart/{chart-container.js → __tests__/env.d.ts} +0 -1
- package/dist/chart/__tests__/env.js +28 -0
- package/dist/chart/bootstrap.d.ts +7 -2
- package/dist/chart/bootstrap.js +2 -2
- package/dist/chart/chart.config.d.ts +4 -1
- package/dist/chart/chart.config.js +1 -1
- package/dist/chart/chart.d.ts +2 -0
- package/dist/chart/chart.js +3 -1
- package/dist/chart/components/chart/candle-transformer.functions.d.ts +1 -0
- package/dist/chart/components/chart/candle-transformer.functions.js +1 -0
- package/dist/chart/components/chart/chart-base.model.d.ts +2 -2
- package/dist/chart/components/chart/chart-base.model.js +2 -2
- package/dist/chart/components/chart/chart.component.d.ts +6 -0
- package/dist/chart/components/chart/chart.component.js +23 -4
- package/dist/chart/components/chart/chart.model.d.ts +9 -3
- package/dist/chart/components/chart/chart.model.js +35 -13
- package/dist/chart/components/cross_tool/cross-tool.component.d.ts +2 -1
- package/dist/chart/components/cross_tool/cross-tool.component.js +4 -3
- package/dist/chart/components/cross_tool/cross-tool.model.js +1 -0
- package/dist/chart/components/cross_tool/types/cross-and-labels.drawer.d.ts +3 -1
- package/dist/chart/components/cross_tool/types/cross-and-labels.drawer.js +3 -2
- package/dist/chart/components/dynamic-objects/dynamic-objects.component.js +1 -1
- package/dist/chart/components/dynamic-objects/dynamic-objects.model.d.ts +30 -10
- package/dist/chart/components/dynamic-objects/dynamic-objects.model.js +119 -57
- package/dist/chart/components/grid/grid.drawer.js +3 -1
- package/dist/chart/components/pane/extent/y-extent-component.js +2 -1
- package/dist/chart/components/pane/pane-hit-test.controller.js +2 -2
- package/dist/chart/components/volumes/volumes.component.d.ts +3 -0
- package/dist/chart/components/volumes/volumes.component.js +21 -4
- package/dist/chart/components/volumes/volumes.model.d.ts +2 -0
- package/dist/chart/components/volumes/volumes.model.js +2 -0
- package/dist/chart/components/x_axis/x-axis.component.js +2 -2
- package/dist/chart/components/y_axis/label-color.functions.d.ts +2 -1
- package/dist/chart/components/y_axis/label-color.functions.js +17 -0
- package/dist/chart/components/y_axis/price_labels/data-series-y-axis-labels.provider.d.ts +2 -2
- package/dist/chart/components/y_axis/price_labels/data-series-y-axis-labels.provider.js +27 -25
- package/dist/chart/components/y_axis/price_labels/labels-positions-calculator.js +24 -13
- package/dist/chart/components/y_axis/price_labels/last-candle-labels.provider.d.ts +3 -3
- package/dist/chart/components/y_axis/price_labels/last-candle-labels.provider.js +58 -40
- package/dist/chart/components/y_axis/price_labels/y-axis-price-labels.drawer.d.ts +3 -3
- package/dist/chart/components/y_axis/price_labels/y-axis-price-labels.drawer.js +15 -13
- package/dist/chart/components/y_axis/y-axis-scale.handler.js +1 -1
- package/dist/chart/components/y_axis/y-axis.component.d.ts +2 -1
- package/dist/chart/components/y_axis/y-axis.component.js +6 -2
- package/dist/chart/drawers/ht-data-series.drawer.js +1 -1
- package/dist/chart/inputhandlers/hover-producer.component.d.ts +1 -1
- package/dist/chart/inputhandlers/hover-producer.component.js +7 -7
- package/dist/chart/inputlisteners/canvas-input-listener.component.d.ts +9 -2
- package/dist/chart/inputlisteners/canvas-input-listener.component.js +21 -19
- package/dist/chart/model/candle-series.model.d.ts +1 -1
- package/dist/chart/model/candle-series.model.js +2 -2
- package/dist/chart/model/compare-series-hover.d.ts +2 -1
- package/dist/chart/model/compare-series-hover.js +1 -0
- package/dist/chart/model/data-series.model.d.ts +3 -2
- package/dist/chart/model/data-series.model.js +2 -1
- package/dist/chart/model/main-candle-series.model.d.ts +1 -1
- package/dist/chart/model/main-candle-series.model.js +2 -2
- package/dist/chart/model/scale.model.d.ts +2 -0
- package/dist/chart/model/scale.model.js +11 -2
- package/dist/chart/utils/dom.utils.d.ts +7 -0
- package/dist/chart/utils/dom.utils.js +12 -0
- package/dist/chart/utils/linkedList.utils.d.ts +3 -3
- package/dist/chart/utils/linkedList.utils.js +55 -57
- package/dist/dxchart.min.js +4 -4
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -8
- package/package.json +18 -4
- package/dist/chart/chart-container.d.ts +0 -18
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { CanvasBoundsContainer } from '../../../canvas/canvas-bounds-container';
|
|
7
7
|
import { FullChartConfig } from '../../../chart.config';
|
|
8
|
+
import { CanvasModel } from '../../../model/canvas.model';
|
|
8
9
|
import { PaneManager } from '../../pane/pane-manager.component';
|
|
9
10
|
import { CrossToolTypeDrawer } from '../cross-tool.drawer';
|
|
10
11
|
import { CrossToolHover } from '../cross-tool.model';
|
|
@@ -12,9 +13,10 @@ export declare class CrossAndLabelsDrawerType implements CrossToolTypeDrawer {
|
|
|
12
13
|
private config;
|
|
13
14
|
private canvasBoundsContainer;
|
|
14
15
|
private paneManager;
|
|
16
|
+
private backgroundCanvasModel;
|
|
15
17
|
private crossDrawPredicate;
|
|
16
18
|
private noLines?;
|
|
17
|
-
constructor(config: FullChartConfig, canvasBoundsContainer: CanvasBoundsContainer, paneManager: PaneManager, crossDrawPredicate?: () => boolean, noLines?: boolean | undefined);
|
|
19
|
+
constructor(config: FullChartConfig, canvasBoundsContainer: CanvasBoundsContainer, paneManager: PaneManager, backgroundCanvasModel: CanvasModel, crossDrawPredicate?: () => boolean, noLines?: boolean | undefined);
|
|
18
20
|
/**
|
|
19
21
|
* Draws a cross tool on a canvas context and its labels if the crossDrawPredicate is true.
|
|
20
22
|
* @param {CanvasRenderingContext2D} ctx - The canvas context to draw on.
|
|
@@ -7,10 +7,11 @@ import { CanvasElement } 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 {
|
|
10
|
-
constructor(config, canvasBoundsContainer, paneManager, crossDrawPredicate = () => true, noLines) {
|
|
10
|
+
constructor(config, canvasBoundsContainer, paneManager, backgroundCanvasModel, crossDrawPredicate = () => true, noLines) {
|
|
11
11
|
this.config = config;
|
|
12
12
|
this.canvasBoundsContainer = canvasBoundsContainer;
|
|
13
13
|
this.paneManager = paneManager;
|
|
14
|
+
this.backgroundCanvasModel = backgroundCanvasModel;
|
|
14
15
|
this.crossDrawPredicate = crossDrawPredicate;
|
|
15
16
|
this.noLines = noLines;
|
|
16
17
|
}
|
|
@@ -135,7 +136,7 @@ export class CrossAndLabelsDrawerType {
|
|
|
135
136
|
paddingBottom: yLabelPadding === null || yLabelPadding === void 0 ? void 0 : yLabelPadding.bottom,
|
|
136
137
|
paddingEnd: yLabelPadding === null || yLabelPadding === void 0 ? void 0 : yLabelPadding.end,
|
|
137
138
|
paddingTop: yLabelPadding === null || yLabelPadding === void 0 ? void 0 : yLabelPadding.top,
|
|
138
|
-
}, extent.yAxis.state, this.config.colors.yAxis, true);
|
|
139
|
+
}, extent.yAxis.state, this.config.colors.yAxis, true, this.backgroundCanvasModel.ctx);
|
|
139
140
|
}
|
|
140
141
|
}
|
|
141
142
|
}
|
|
@@ -10,7 +10,7 @@ export class DynamicObjectsComponent extends ChartBaseElement {
|
|
|
10
10
|
constructor(canvasModel, drawingManager) {
|
|
11
11
|
super();
|
|
12
12
|
// model
|
|
13
|
-
const dynamicObjectsModel = new DynamicObjectsModel();
|
|
13
|
+
const dynamicObjectsModel = new DynamicObjectsModel(canvasModel);
|
|
14
14
|
this.model = dynamicObjectsModel;
|
|
15
15
|
this.addChildEntity(dynamicObjectsModel);
|
|
16
16
|
// drawer
|
|
@@ -4,53 +4,73 @@
|
|
|
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
|
-
import { LinkedList
|
|
7
|
+
import { LinkedList } from '../../utils/linkedList.utils';
|
|
8
8
|
import { DynamicModelDrawer } from './dynamic-objects.drawer';
|
|
9
|
+
import { CanvasModel } from '../../model/canvas.model';
|
|
9
10
|
export type PaneId = string;
|
|
11
|
+
export type DynamicObjectId = string | number;
|
|
10
12
|
export interface DynamicObject<T = unknown> {
|
|
13
|
+
readonly id: DynamicObjectId;
|
|
11
14
|
readonly drawer: DynamicModelDrawer<T>;
|
|
12
|
-
readonly
|
|
15
|
+
readonly paneId: PaneId;
|
|
16
|
+
readonly model?: T;
|
|
13
17
|
}
|
|
14
18
|
export declare class DynamicObjectsModel extends ChartBaseElement {
|
|
19
|
+
private canvasModel;
|
|
15
20
|
private _objects;
|
|
16
|
-
private
|
|
17
|
-
constructor();
|
|
21
|
+
private modelIdToObjectMap;
|
|
22
|
+
constructor(canvasModel: CanvasModel);
|
|
23
|
+
/**
|
|
24
|
+
* @returns the `DynamicObject` itself and pane `LinkedList` where the object is stored.
|
|
25
|
+
*
|
|
26
|
+
*/
|
|
27
|
+
private getObjectInfoById;
|
|
28
|
+
/**
|
|
29
|
+
* @returns `DynamicObject` position in associated pane `LinkedList`
|
|
30
|
+
* @returns `-1` if an object was not found
|
|
31
|
+
*
|
|
32
|
+
*/
|
|
33
|
+
getObjectPosition(id: DynamicObjectId): number;
|
|
18
34
|
/**
|
|
19
35
|
* Adds an object from outside chart-core into model
|
|
20
36
|
* @param obj
|
|
21
37
|
* @param paneId
|
|
22
38
|
*/
|
|
23
|
-
addObject(obj: DynamicObject
|
|
39
|
+
addObject(obj: DynamicObject): void;
|
|
24
40
|
/**
|
|
25
41
|
* Removes an object from model
|
|
26
42
|
* @param model
|
|
27
43
|
* @param paneId
|
|
28
44
|
*/
|
|
29
|
-
removeObject(
|
|
45
|
+
removeObject(id: DynamicObjectId): void;
|
|
46
|
+
/**
|
|
47
|
+
* Moves the object inside the associated LinkedList to the specified position
|
|
48
|
+
*/
|
|
49
|
+
moveToPosition(id: DynamicObjectId, position: number): void;
|
|
30
50
|
/**
|
|
31
51
|
* Moves the object inside the drawing order so it's being drawn before the other elements
|
|
32
52
|
* @param paneId
|
|
33
53
|
* @param listNode
|
|
34
54
|
*/
|
|
35
|
-
bringToFront(
|
|
55
|
+
bringToFront(id: DynamicObjectId): void;
|
|
36
56
|
/**
|
|
37
57
|
* Moves the object inside the drawing order so it's being drawn after the other elements
|
|
38
58
|
* @param paneId
|
|
39
59
|
* @param listNode
|
|
40
60
|
*/
|
|
41
|
-
bringToBack(
|
|
61
|
+
bringToBack(id: DynamicObjectId): void;
|
|
42
62
|
/**
|
|
43
63
|
* Moves the object inside the drawing order so it's being drawn one layer ahead
|
|
44
64
|
* @param obj
|
|
45
65
|
* @param paneId
|
|
46
66
|
*/
|
|
47
|
-
moveForward(
|
|
67
|
+
moveForward(id: DynamicObjectId): void;
|
|
48
68
|
/**
|
|
49
69
|
* Moves the object inside the drawing order so it's being drawn one layer closer to the back
|
|
50
70
|
* @param obj
|
|
51
71
|
* @param paneId
|
|
52
72
|
*/
|
|
53
|
-
moveBackwards(
|
|
73
|
+
moveBackwards(id: DynamicObjectId): void;
|
|
54
74
|
/**
|
|
55
75
|
* Getter for the objects
|
|
56
76
|
*/
|
|
@@ -7,25 +7,58 @@ import { BehaviorSubject } from 'rxjs';
|
|
|
7
7
|
import { ChartBaseElement } from '../../model/chart-base-element';
|
|
8
8
|
import { LinkedList, ListNode } from '../../utils/linkedList.utils';
|
|
9
9
|
export class DynamicObjectsModel extends ChartBaseElement {
|
|
10
|
-
constructor() {
|
|
10
|
+
constructor(canvasModel) {
|
|
11
11
|
super();
|
|
12
|
-
this.
|
|
12
|
+
this.canvasModel = canvasModel;
|
|
13
|
+
this.modelIdToObjectMap = new Map();
|
|
13
14
|
this._objects = new BehaviorSubject({});
|
|
14
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* @returns the `DynamicObject` itself and pane `LinkedList` where the object is stored.
|
|
18
|
+
*
|
|
19
|
+
*/
|
|
20
|
+
getObjectInfoById(id) {
|
|
21
|
+
const obj = this.modelIdToObjectMap.get(id);
|
|
22
|
+
if (!obj) {
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
const paneId = obj.paneId;
|
|
26
|
+
const objects = this.objects;
|
|
27
|
+
const paneList = objects[paneId];
|
|
28
|
+
if (!paneList) {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
return [obj, paneList];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* @returns `DynamicObject` position in associated pane `LinkedList`
|
|
35
|
+
* @returns `-1` if an object was not found
|
|
36
|
+
*
|
|
37
|
+
*/
|
|
38
|
+
getObjectPosition(id) {
|
|
39
|
+
const objInfo = this.getObjectInfoById(id);
|
|
40
|
+
if (!objInfo) {
|
|
41
|
+
return -1;
|
|
42
|
+
}
|
|
43
|
+
const [obj, paneList] = objInfo;
|
|
44
|
+
const targetNode = new ListNode(obj);
|
|
45
|
+
return paneList.getNodePosition(targetNode);
|
|
46
|
+
}
|
|
15
47
|
/**
|
|
16
48
|
* Adds an object from outside chart-core into model
|
|
17
49
|
* @param obj
|
|
18
50
|
* @param paneId
|
|
19
51
|
*/
|
|
20
|
-
addObject(obj
|
|
52
|
+
addObject(obj) {
|
|
21
53
|
var _a;
|
|
54
|
+
const paneId = obj.paneId;
|
|
22
55
|
const objects = this.objects;
|
|
23
56
|
const paneList = (_a = objects[paneId]) !== null && _a !== void 0 ? _a : new LinkedList();
|
|
24
57
|
if (!Object.keys(objects).find(pane => pane === paneId)) {
|
|
25
58
|
objects[paneId] = paneList;
|
|
26
59
|
}
|
|
27
60
|
paneList.insertAtEnd(obj);
|
|
28
|
-
this.
|
|
61
|
+
this.modelIdToObjectMap.set(obj.id, obj);
|
|
29
62
|
this.setDynamicObjects(objects);
|
|
30
63
|
}
|
|
31
64
|
/**
|
|
@@ -33,36 +66,61 @@ export class DynamicObjectsModel extends ChartBaseElement {
|
|
|
33
66
|
* @param model
|
|
34
67
|
* @param paneId
|
|
35
68
|
*/
|
|
36
|
-
removeObject(
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
this.setDynamicObjects(objects);
|
|
69
|
+
removeObject(id) {
|
|
70
|
+
const objInfo = this.getObjectInfoById(id);
|
|
71
|
+
if (!objInfo) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const [obj, paneList] = objInfo;
|
|
75
|
+
const targetNode = new ListNode(obj);
|
|
76
|
+
const targetPos = paneList.getNodePosition(targetNode);
|
|
77
|
+
paneList.removeAt(targetPos);
|
|
78
|
+
this.modelIdToObjectMap.delete(id);
|
|
79
|
+
if (paneList.size() === 0) {
|
|
80
|
+
delete this.objects[obj.paneId];
|
|
49
81
|
}
|
|
82
|
+
this.setDynamicObjects(this.objects);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Moves the object inside the associated LinkedList to the specified position
|
|
86
|
+
*/
|
|
87
|
+
moveToPosition(id, position) {
|
|
88
|
+
const objInfo = this.getObjectInfoById(id);
|
|
89
|
+
if (!objInfo) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const [obj, paneList] = objInfo;
|
|
93
|
+
const node = new ListNode(obj);
|
|
94
|
+
const currentPos = paneList.getNodePosition(node);
|
|
95
|
+
if (currentPos === position) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
if (currentPos < position) {
|
|
99
|
+
paneList.insertAt(position, obj);
|
|
100
|
+
paneList.removeAt(currentPos);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
paneList.removeAt(currentPos);
|
|
104
|
+
paneList.insertAt(position, obj);
|
|
105
|
+
}
|
|
106
|
+
this.setDynamicObjects(this.objects);
|
|
50
107
|
}
|
|
51
108
|
/**
|
|
52
109
|
* Moves the object inside the drawing order so it's being drawn before the other elements
|
|
53
110
|
* @param paneId
|
|
54
111
|
* @param listNode
|
|
55
112
|
*/
|
|
56
|
-
bringToFront(
|
|
57
|
-
const
|
|
58
|
-
if (
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
113
|
+
bringToFront(id) {
|
|
114
|
+
const objInfo = this.getObjectInfoById(id);
|
|
115
|
+
if (!objInfo) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const [obj, paneList] = objInfo;
|
|
119
|
+
const targetNode = new ListNode(obj);
|
|
120
|
+
const targetPos = paneList.getNodePosition(targetNode);
|
|
121
|
+
if (targetPos >= 0 && targetPos < paneList.size()) {
|
|
122
|
+
paneList.removeAt(targetPos);
|
|
123
|
+
paneList.insertAtEnd(obj);
|
|
66
124
|
this.setDynamicObjects(this.objects);
|
|
67
125
|
}
|
|
68
126
|
}
|
|
@@ -71,16 +129,17 @@ export class DynamicObjectsModel extends ChartBaseElement {
|
|
|
71
129
|
* @param paneId
|
|
72
130
|
* @param listNode
|
|
73
131
|
*/
|
|
74
|
-
bringToBack(
|
|
75
|
-
const
|
|
76
|
-
if (
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
132
|
+
bringToBack(id) {
|
|
133
|
+
const objInfo = this.getObjectInfoById(id);
|
|
134
|
+
if (!objInfo) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const [obj, paneList] = objInfo;
|
|
138
|
+
const targetNode = new ListNode(obj);
|
|
139
|
+
const targetPos = paneList.getNodePosition(targetNode);
|
|
140
|
+
if (targetPos > 0 && targetPos <= paneList.size()) {
|
|
141
|
+
paneList.removeAt(targetPos);
|
|
142
|
+
paneList.insertAt(0, obj);
|
|
84
143
|
this.setDynamicObjects(this.objects);
|
|
85
144
|
}
|
|
86
145
|
}
|
|
@@ -89,16 +148,17 @@ export class DynamicObjectsModel extends ChartBaseElement {
|
|
|
89
148
|
* @param obj
|
|
90
149
|
* @param paneId
|
|
91
150
|
*/
|
|
92
|
-
moveForward(
|
|
93
|
-
const
|
|
94
|
-
if (
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
151
|
+
moveForward(id) {
|
|
152
|
+
const objInfo = this.getObjectInfoById(id);
|
|
153
|
+
if (!objInfo) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
const [obj, paneList] = objInfo;
|
|
157
|
+
const targetNode = new ListNode(obj);
|
|
158
|
+
const targetPos = paneList.getNodePosition(targetNode);
|
|
159
|
+
if (targetPos >= 0 && targetPos + 1 < paneList.size()) {
|
|
160
|
+
paneList.removeAt(targetPos);
|
|
161
|
+
paneList.insertAt(targetPos + 1, obj);
|
|
102
162
|
this.setDynamicObjects(this.objects);
|
|
103
163
|
}
|
|
104
164
|
}
|
|
@@ -107,16 +167,17 @@ export class DynamicObjectsModel extends ChartBaseElement {
|
|
|
107
167
|
* @param obj
|
|
108
168
|
* @param paneId
|
|
109
169
|
*/
|
|
110
|
-
moveBackwards(
|
|
111
|
-
const
|
|
112
|
-
if (
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
170
|
+
moveBackwards(id) {
|
|
171
|
+
const objInfo = this.getObjectInfoById(id);
|
|
172
|
+
if (!objInfo) {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
const [obj, paneList] = objInfo;
|
|
176
|
+
const targetNode = new ListNode(obj);
|
|
177
|
+
const targetPos = paneList.getNodePosition(targetNode);
|
|
178
|
+
if (targetPos > 0 && targetPos < paneList.size()) {
|
|
179
|
+
paneList.removeAt(targetPos);
|
|
180
|
+
paneList.insertAt(targetPos - 1, obj);
|
|
120
181
|
this.setDynamicObjects(this.objects);
|
|
121
182
|
}
|
|
122
183
|
}
|
|
@@ -132,5 +193,6 @@ export class DynamicObjectsModel extends ChartBaseElement {
|
|
|
132
193
|
*/
|
|
133
194
|
setDynamicObjects(objects) {
|
|
134
195
|
this._objects.next(objects);
|
|
196
|
+
this.canvasModel.fireDraw();
|
|
135
197
|
}
|
|
136
198
|
}
|
|
@@ -40,9 +40,11 @@ export class GridDrawer {
|
|
|
40
40
|
* @param {CanvasRenderingContext2D} ctx - The 2D rendering context of the canvas element.
|
|
41
41
|
*/
|
|
42
42
|
drawZeroLine(ctx) {
|
|
43
|
+
const yAxisLabels = this.yLabelsProvider();
|
|
43
44
|
if (this.getBaseline &&
|
|
44
45
|
this.yAxisState.type === 'percent' &&
|
|
45
|
-
this.yAxisState.zeroPercentLine
|
|
46
|
+
this.yAxisState.zeroPercentLine &&
|
|
47
|
+
yAxisLabels.length) {
|
|
46
48
|
const bounds = this.xBoundsProvider();
|
|
47
49
|
const y = floor(this.getBaseline());
|
|
48
50
|
ctx.beginPath();
|
|
@@ -7,6 +7,7 @@ import { CanvasElement } from '../../../canvas/canvas-bounds-container';
|
|
|
7
7
|
import { ChartBaseElement } from '../../../model/chart-base-element';
|
|
8
8
|
import { DataSeriesModel, VisualSeriesPoint, defaultValueFormatter, } from '../../../model/data-series.model';
|
|
9
9
|
import { mergeHighLow } from '../../../model/scaling/auto-scale.model';
|
|
10
|
+
import { uuid } from '../../../utils/uuid.utils';
|
|
10
11
|
import { createYExtentFormatters } from '../../chart/price.formatter';
|
|
11
12
|
export class YExtentComponent extends ChartBaseElement {
|
|
12
13
|
constructor(paneUUID, idx, paneComponent, chartBaseModel, canvasBoundsContainer, hitTestController, dynamicObjectsCanvasModel, scale, createYAxisComponent, dragNDrop, dataSeries = new Set(), formatters = {
|
|
@@ -66,7 +67,7 @@ export class YExtentComponent extends ChartBaseElement {
|
|
|
66
67
|
* @returns {DataSeriesModel} - The newly created DataSeriesModel object.
|
|
67
68
|
*/
|
|
68
69
|
createDataSeries() {
|
|
69
|
-
const series = new DataSeriesModel(this, this.hitTestController.getNewDataSeriesHitTestId());
|
|
70
|
+
const series = new DataSeriesModel(this, uuid(), this.hitTestController.getNewDataSeriesHitTestId());
|
|
70
71
|
series.toVisualPoints = this.toVisualPoints;
|
|
71
72
|
return series;
|
|
72
73
|
}
|
|
@@ -32,7 +32,7 @@ export class PaneHitTestController {
|
|
|
32
32
|
* @returns {DataSeriesModel | undefined} - The data series with the given ID, or undefined if it does not exist.
|
|
33
33
|
*/
|
|
34
34
|
lookup(id) {
|
|
35
|
-
const result = this.allDataSeries.find(d => d.
|
|
35
|
+
const result = this.allDataSeries.find(d => d.htId === id);
|
|
36
36
|
return result;
|
|
37
37
|
}
|
|
38
38
|
/**
|
|
@@ -41,7 +41,7 @@ export class PaneHitTestController {
|
|
|
41
41
|
* @returns {void}
|
|
42
42
|
*/
|
|
43
43
|
onHover(model) {
|
|
44
|
-
this.allDataSeries.forEach(d => (d.hovered = d.
|
|
44
|
+
this.allDataSeries.forEach(d => (d.hovered = d.htId === (model === null || model === void 0 ? void 0 : model.htId)));
|
|
45
45
|
this.canvasModel.fireDraw();
|
|
46
46
|
}
|
|
47
47
|
onMouseDown(model) {
|
|
@@ -21,9 +21,11 @@ export declare class VolumesComponent extends ChartBaseElement {
|
|
|
21
21
|
private canvasModel;
|
|
22
22
|
private canvasBoundsContainer;
|
|
23
23
|
private config;
|
|
24
|
+
private dynamicObjectsComponent;
|
|
24
25
|
separateVolumes: SeparateVolumesComponent;
|
|
25
26
|
volumesColorByChartTypeMap: Partial<Record<BarType, VolumeColorResolver>>;
|
|
26
27
|
volumesModel: VolumesModel;
|
|
28
|
+
private readonly volumesDrawer;
|
|
27
29
|
volumeVisibilityChangedSubject: BehaviorSubject<boolean>;
|
|
28
30
|
volumeIsSeparateModeChangedSubject: BehaviorSubject<boolean>;
|
|
29
31
|
constructor(canvasModel: CanvasModel, chartComponent: ChartComponent, scale: ScaleModel, canvasBoundsContainer: CanvasBoundsContainer, drawingManager: DrawingManager, config: FullChartConfig, paneManager: PaneManager, dynamicObjectsComponent: DynamicObjectsComponent);
|
|
@@ -56,4 +58,5 @@ export declare class VolumesComponent extends ChartBaseElement {
|
|
|
56
58
|
* @returns {void}
|
|
57
59
|
*/
|
|
58
60
|
setVisible(visible?: boolean): void;
|
|
61
|
+
private addVolumesToDynamicObjects;
|
|
59
62
|
}
|
|
@@ -9,13 +9,14 @@ import { ChartBaseElement } from '../../model/chart-base-element';
|
|
|
9
9
|
import { SeparateVolumesComponent } from './separate-volumes.component';
|
|
10
10
|
import { resolveColorForBar, resolveColorForCandle, resolveColorForLine } from './volume-color-resolvers.functions';
|
|
11
11
|
import { VolumesDrawer } from './volumes.drawer';
|
|
12
|
-
import { VolumesModel } from './volumes.model';
|
|
12
|
+
import { VOLUMES_UUID, VolumesModel } from './volumes.model';
|
|
13
13
|
export class VolumesComponent extends ChartBaseElement {
|
|
14
14
|
constructor(canvasModel, chartComponent, scale, canvasBoundsContainer, drawingManager, config, paneManager, dynamicObjectsComponent) {
|
|
15
15
|
super();
|
|
16
16
|
this.canvasModel = canvasModel;
|
|
17
17
|
this.canvasBoundsContainer = canvasBoundsContainer;
|
|
18
18
|
this.config = config;
|
|
19
|
+
this.dynamicObjectsComponent = dynamicObjectsComponent;
|
|
19
20
|
this.volumesColorByChartTypeMap = {};
|
|
20
21
|
this.volumeVisibilityChangedSubject = new BehaviorSubject(false);
|
|
21
22
|
this.volumeIsSeparateModeChangedSubject = new BehaviorSubject(false);
|
|
@@ -23,8 +24,8 @@ export class VolumesComponent extends ChartBaseElement {
|
|
|
23
24
|
this.volumesModel = volumesModel;
|
|
24
25
|
this.addChildEntity(volumesModel);
|
|
25
26
|
this.separateVolumes = new SeparateVolumesComponent(chartComponent, drawingManager, config, volumesModel, paneManager);
|
|
26
|
-
|
|
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
|
+
config.components.volumes.visible && this.addVolumesToDynamicObjects();
|
|
28
29
|
this.addChildEntity(this.separateVolumes);
|
|
29
30
|
this.registerDefaultVolumeColorResolvers();
|
|
30
31
|
this.volumeVisibilityChangedSubject.next(config.components.volumes.visible);
|
|
@@ -83,7 +84,10 @@ export class VolumesComponent extends ChartBaseElement {
|
|
|
83
84
|
setVisible(visible = true) {
|
|
84
85
|
this.config.components.volumes.visible = visible;
|
|
85
86
|
this.volumeVisibilityChangedSubject.next(visible);
|
|
86
|
-
|
|
87
|
+
visible
|
|
88
|
+
? this.addVolumesToDynamicObjects()
|
|
89
|
+
: this.dynamicObjectsComponent.model.removeObject(this.volumesModel.id);
|
|
90
|
+
if (this.config.components.volumes.showSeparately) {
|
|
87
91
|
if (visible) {
|
|
88
92
|
this.separateVolumes.activateSeparateVolumes();
|
|
89
93
|
this.volumeIsSeparateModeChangedSubject.next(true);
|
|
@@ -96,4 +100,17 @@ export class VolumesComponent extends ChartBaseElement {
|
|
|
96
100
|
this.canvasBoundsContainer.recalculatePanesHeightRatios();
|
|
97
101
|
this.canvasModel.fireDraw();
|
|
98
102
|
}
|
|
103
|
+
addVolumesToDynamicObjects() {
|
|
104
|
+
// check if the volumes dynamic object is already added
|
|
105
|
+
const position = this.dynamicObjectsComponent.model.getObjectPosition(this.volumesModel.id);
|
|
106
|
+
if (position !== -1) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
this.dynamicObjectsComponent.model.addObject({
|
|
110
|
+
id: this.volumesModel.id,
|
|
111
|
+
paneId: this.config.components.volumes.showSeparately ? VOLUMES_UUID : CHART_UUID,
|
|
112
|
+
drawer: this.volumesDrawer,
|
|
113
|
+
model: this.volumesModel,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
99
116
|
}
|
|
@@ -8,9 +8,11 @@ import { ChartBaseElement } from '../../model/chart-base-element';
|
|
|
8
8
|
import { ScaleModel } from '../../model/scale.model';
|
|
9
9
|
import { HighLowProvider } from '../../model/scaling/auto-scale.model';
|
|
10
10
|
import { ChartComponent } from '../chart/chart.component';
|
|
11
|
+
export declare const VOLUMES_UUID = "volumes";
|
|
11
12
|
export declare class VolumesModel extends ChartBaseElement {
|
|
12
13
|
private chartComponent;
|
|
13
14
|
private scale;
|
|
15
|
+
readonly id = "volumes";
|
|
14
16
|
volumeMax: BehaviorSubject<number>;
|
|
15
17
|
highLowProvider: HighLowProvider;
|
|
16
18
|
constructor(chartComponent: ChartComponent, scale: ScaleModel);
|
|
@@ -7,11 +7,13 @@ import { BehaviorSubject, merge } from 'rxjs';
|
|
|
7
7
|
import { ChartBaseElement } from '../../model/chart-base-element';
|
|
8
8
|
import { firstOf, maxMin } from '../../utils/array.utils';
|
|
9
9
|
const volumeMaxMinFn = maxMin(candle => candle.candle.volume);
|
|
10
|
+
export const VOLUMES_UUID = 'volumes';
|
|
10
11
|
export class VolumesModel extends ChartBaseElement {
|
|
11
12
|
constructor(chartComponent, scale) {
|
|
12
13
|
super();
|
|
13
14
|
this.chartComponent = chartComponent;
|
|
14
15
|
this.scale = scale;
|
|
16
|
+
this.id = VOLUMES_UUID;
|
|
15
17
|
// max volume in all data series
|
|
16
18
|
this.volumeMax = new BehaviorSubject(0);
|
|
17
19
|
this.highLowProvider = {
|
|
@@ -56,8 +56,8 @@ export class XAxisComponent extends ChartBaseElement {
|
|
|
56
56
|
this.xAxisLabelsGenerator.generateLabels();
|
|
57
57
|
}));
|
|
58
58
|
this.addRxSubscription(this.chartComponent.chartModel.candlesPrependSubject
|
|
59
|
-
.pipe(filter(({
|
|
60
|
-
return this.chartComponent.chartModel.mainCandleSeries.visualPoints.slice(0,
|
|
59
|
+
.pipe(filter(({ prependedCandles }) => prependedCandles.length !== 0), map(({ prependedCandles }) => {
|
|
60
|
+
return this.chartComponent.chartModel.mainCandleSeries.visualPoints.slice(0, prependedCandles.length);
|
|
61
61
|
}))
|
|
62
62
|
.subscribe(newCandles => {
|
|
63
63
|
//@ts-ignore
|
|
@@ -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
|
import { PriceMovement } from '../../model/candle-series.model';
|
|
7
|
-
import { FullChartColors, YAxisLabelsColors } from '../../chart.config';
|
|
7
|
+
import { FullChartColors, YAxisConfig, YAxisLabelsColors } from '../../chart.config';
|
|
8
8
|
export declare const DEFAULT_LABEL_COLOR = "#FF00FF";
|
|
9
|
+
export declare function getPlainLabelTextColor(colorsConfig: FullChartColors, textColor: string, invertedTextColor: string, yAxisState: YAxisConfig): string;
|
|
9
10
|
export declare const getPrimaryLabelTextColor: (lastPriceMovement: PriceMovement, colors: YAxisLabelsColors) => string;
|
|
10
11
|
export declare const resolveColorForBar: (priceMovement: PriceMovement, colors: FullChartColors) => string;
|
|
11
12
|
export declare const resolveColorForLine: (priceMovement: PriceMovement, colors: FullChartColors) => string;
|
|
@@ -3,7 +3,24 @@
|
|
|
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 { getLabelTextColorByBackgroundColor } from '../../utils/canvas/canvas-text-functions.utils';
|
|
6
7
|
export const DEFAULT_LABEL_COLOR = '#FF00FF';
|
|
8
|
+
export function getPlainLabelTextColor(colorsConfig, textColor, invertedTextColor, yAxisState) {
|
|
9
|
+
// `plain` label is transparent, so to calculate text color
|
|
10
|
+
// we need to go down to draw hierarchy
|
|
11
|
+
// the next is YAxis bg color
|
|
12
|
+
const yAxisBGColor = colorsConfig.yAxis.backgroundColor;
|
|
13
|
+
// if yAxis bg color is transparent, then we need to check chart area background color
|
|
14
|
+
const plainChartBGColor = colorsConfig.chartAreaTheme.backgroundColor;
|
|
15
|
+
// when chart area bg color is gradient, then we need to check which side yAxis is drawn
|
|
16
|
+
// because color on the right side and left side is different
|
|
17
|
+
const leftChartBGColor = colorsConfig.chartAreaTheme.backgroundGradientTopColor;
|
|
18
|
+
const rightChartBGColor = colorsConfig.chartAreaTheme.backgroundGradientBottomColor;
|
|
19
|
+
const gradientChartBGColor = yAxisState.align === 'left' ? leftChartBGColor : rightChartBGColor;
|
|
20
|
+
const chartBGColor = colorsConfig.chartAreaTheme.backgroundMode === 'gradient' ? gradientChartBGColor : plainChartBGColor;
|
|
21
|
+
const bgColor = yAxisBGColor === 'transparent' ? chartBGColor : yAxisBGColor;
|
|
22
|
+
return getLabelTextColorByBackgroundColor(bgColor, textColor, invertedTextColor);
|
|
23
|
+
}
|
|
7
24
|
export const getPrimaryLabelTextColor = (lastPriceMovement, colors) => {
|
|
8
25
|
if (lastPriceMovement === 'down') {
|
|
9
26
|
return colors.lastPrice.textNegative;
|
|
@@ -12,8 +12,8 @@ export declare class DataSeriesYAxisLabelsProvider implements YAxisLabelsProvide
|
|
|
12
12
|
private series;
|
|
13
13
|
private config;
|
|
14
14
|
yAxisBoundsProvider: BoundsProvider;
|
|
15
|
-
axisState
|
|
16
|
-
constructor(series: DataSeriesModel, config: DataSeriesConfig, yAxisBoundsProvider: BoundsProvider, axisState
|
|
15
|
+
axisState: YAxisConfig;
|
|
16
|
+
constructor(series: DataSeriesModel, config: DataSeriesConfig, yAxisBoundsProvider: BoundsProvider, axisState: YAxisConfig);
|
|
17
17
|
/**
|
|
18
18
|
* Returns an array of LabelGroup objects that contain VisualYAxisLabel objects.
|
|
19
19
|
* The labels are unordered and are based on the last data series point or the last visual series point, depending on the configuration.
|