@devexperts/dxcharts-lite 2.7.5 → 2.7.7
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 +41 -43
- package/dist/chart/canvas/canvas-bounds-container.d.ts +1 -0
- package/dist/chart/canvas/canvas-bounds-container.js +8 -0
- package/dist/chart/chart.config.d.ts +5 -0
- package/dist/chart/chart.config.js +4 -0
- package/dist/chart/components/chart/candle.functions.js +1 -0
- package/dist/chart/components/highlights/highlights.drawer.js +4 -1
- package/dist/chart/components/pane/extent/y-extent-component.d.ts +3 -1
- package/dist/chart/components/pane/extent/y-extent-component.js +19 -3
- package/dist/chart/components/pane/pane-manager.component.js +7 -2
- package/dist/chart/components/pane/pane.component.d.ts +2 -2
- package/dist/chart/components/pane/pane.component.js +20 -1
- package/dist/chart/components/y_axis/price_labels/last-candle-labels.provider.js +4 -1
- package/dist/chart/components/y_axis/y-axis.component.d.ts +1 -1
- package/dist/chart/components/y_axis/y-axis.component.js +1 -1
- package/dist/chart/drawers/chart-type-drawers/area.drawer.js +9 -2
- package/dist/chart/drawers/data-series-drawers/data-series-drawers.utils.d.ts +1 -0
- package/dist/chart/drawers/data-series-drawers/data-series-drawers.utils.js +12 -9
- package/dist/chart/drawers/data-series-drawers/difference-cloud.drawer.d.ts +5 -2
- package/dist/chart/drawers/data-series-drawers/difference-cloud.drawer.js +12 -11
- package/dist/chart/drawers/data-series-drawers/trend-histogram.drawer.d.ts +1 -1
- package/dist/chart/drawers/data-series-drawers/trend-histogram.drawer.js +14 -15
- package/dist/chart/drawers/data-series.drawer.js +3 -1
- package/dist/chart/drawers/ht-data-series.drawer.d.ts +1 -0
- package/dist/chart/drawers/ht-data-series.drawer.js +2 -1
- package/dist/chart/model/candle.model.d.ts +4 -0
- package/dist/chart/model/candle.model.js +2 -1
- package/dist/chart/model/data-series.config.d.ts +2 -1
- package/dist/chart/model/data-series.model.js +1 -1
- package/dist/chart/model/visual-candle.d.ts +1 -0
- package/dist/chart/model/visual-candle.js +1 -0
- package/dist/chart/utils/math.utils.d.ts +2 -1
- package/dist/chart/utils/math.utils.js +37 -6
- package/dist/dxchart.min.js +4 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
<img src="docs/images/logo.png" alt="devexperts-logo" width="294px" height="100px"/>
|
|
4
4
|
</p>
|
|
5
5
|
|
|
6
|
-
<h1 align="center">DXCharts Lite
|
|
6
|
+
<h1 align="center">DXCharts Lite: Powerful financial charting tool</h1>
|
|
7
7
|
|
|
8
8
|
<p align="center">
|
|
9
9
|
<i>
|
|
10
|
-
DXcharts Lite is a modern solution
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
as a simple widget for
|
|
10
|
+
DXcharts Lite is a modern solution for visualizing financial data with a wide variety of chart types.<br>
|
|
11
|
+
Originally developed as part of large tradings applications used by millions of users,<br>
|
|
12
|
+
DXcharts Lite has matured into an independent product.<br>
|
|
13
|
+
It can be used as a simple widget for blogs or as a component in enterprise trading solutions.<br>
|
|
14
14
|
</i>
|
|
15
15
|
<br>
|
|
16
16
|
</p>
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
|
|
38
38
|
## Overview
|
|
39
39
|
|
|
40
|
-
Get started with DXCharts Lite
|
|
40
|
+
Get started with DXCharts Lite by installing the library and configuring it to your needs.
|
|
41
41
|
|
|
42
42
|
- 🚀 [Quick start](#quick-start)
|
|
43
43
|
- 📦 [Installation](#installation)
|
|
@@ -53,7 +53,7 @@ Get started with DXCharts Lite, install the library and configure it as you want
|
|
|
53
53
|
|
|
54
54
|
### Installation
|
|
55
55
|
|
|
56
|
-
Install library
|
|
56
|
+
Install the library in your project:
|
|
57
57
|
|
|
58
58
|
```js
|
|
59
59
|
npm install @devexperts/dxcharts-lite
|
|
@@ -70,7 +70,7 @@ Your `package.json` after installation:
|
|
|
70
70
|
|
|
71
71
|
### Create chart
|
|
72
72
|
|
|
73
|
-
If you use webpack or
|
|
73
|
+
If you use webpack or another bundler, import the `createChart` method and pass the element where the chart will be rendered as the first argument.
|
|
74
74
|
|
|
75
75
|
```js
|
|
76
76
|
export const createChartInstance = () => {
|
|
@@ -80,23 +80,22 @@ export const createChartInstance = () => {
|
|
|
80
80
|
};
|
|
81
81
|
```
|
|
82
82
|
|
|
83
|
-
`createChart`
|
|
83
|
+
The `createChart` method creates a new chart instance using `ChartBootstrap` class and returns it.
|
|
84
84
|
|
|
85
|
-
|
|
85
|
+
It accepts two parameters:
|
|
86
86
|
|
|
87
|
-
- `element
|
|
88
|
-
- `config` (optional)
|
|
87
|
+
- `element`: The HTML element where the chart will be rendered.
|
|
88
|
+
- `config` (optional): An instance of [ChartConfig](/chart/chart-config/overview).
|
|
89
89
|
|
|
90
|
-
>
|
|
91
|
-
>
|
|
92
|
-
> you can change it by setting `fixedSize` in config
|
|
90
|
+
> Note: Set `width: 100%` and `height: 100%` for the parent container.
|
|
91
|
+
> By default, the chart auto-resizes to the parent, but you can change this by setting `fixedSize` in the config.
|
|
93
92
|
|
|
94
|
-
|
|
93
|
+
You should now see an empty chart on the screen.
|
|
95
94
|
|
|
96
95
|
### Set data
|
|
97
96
|
|
|
98
|
-
|
|
99
|
-
Import `generateCandlesData` and
|
|
97
|
+
To display data (e.g. `Candles`), you can use the bundled function to generate mock data.
|
|
98
|
+
Import `generateCandlesData` and use it to generate candles.
|
|
100
99
|
|
|
101
100
|
```js
|
|
102
101
|
export const generateMockData = () => {
|
|
@@ -105,7 +104,7 @@ export const generateMockData = () => {
|
|
|
105
104
|
};
|
|
106
105
|
```
|
|
107
106
|
|
|
108
|
-
|
|
107
|
+
You should now see a basic chart like the image below:
|
|
109
108
|
|
|
110
109
|
<p align="center">
|
|
111
110
|
<img src="docs/images/basicchart.png" width="1000px" alt="Basic chart"/>
|
|
@@ -113,7 +112,7 @@ Now you should see chart just like image below:
|
|
|
113
112
|
|
|
114
113
|
### HTML-markup
|
|
115
114
|
|
|
116
|
-
Here is
|
|
115
|
+
Here is complete quick-start code example:
|
|
117
116
|
|
|
118
117
|
```html
|
|
119
118
|
<html>
|
|
@@ -145,39 +144,38 @@ Here is full quick-start code example:
|
|
|
145
144
|
|
|
146
145
|
## Configuration
|
|
147
146
|
|
|
148
|
-
You can configure chart
|
|
147
|
+
You can configure the chart using a `ChartConfig` object (optional).
|
|
149
148
|
|
|
150
|
-
`ChartConfig`
|
|
151
|
-
Below
|
|
149
|
+
`ChartConfig` sets the initial properties for the chart instance.
|
|
150
|
+
Below is a table of available options (see documentation for details).
|
|
152
151
|
|
|
153
152
|
- [`FullChartConfig`](docs/generated/FullChartConfig.md)
|
|
154
153
|
|
|
155
154
|
## API
|
|
156
155
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
- [`
|
|
164
|
-
- [`
|
|
165
|
-
- [`
|
|
166
|
-
- [`
|
|
167
|
-
- [`
|
|
168
|
-
- [`
|
|
169
|
-
- [`
|
|
170
|
-
- [`
|
|
171
|
-
- [`
|
|
172
|
-
- [`
|
|
173
|
-
- [`PaneManager`](docs/generated/PaneManager.md) - create and manage panes
|
|
174
|
-
- [`PaneComponent`](docs/generated/PaneComponent.md) - create and manage panes data series
|
|
156
|
+
Each chart component has an API that allows you to change many parameters on the fly, modify appearance at runtime, and subscribe to various chart events (such as hovering over a candle).
|
|
157
|
+
|
|
158
|
+
Main components include:
|
|
159
|
+
|
|
160
|
+
- [`ChartComponent`](docs/generated/ChartComponent.md): Set data, subscribe to data changes
|
|
161
|
+
- [`XAxisComponent`](docs/generated/XAxisComponent.md): Configure x-axis labels
|
|
162
|
+
- [`YAxisComponent`](docs/generated/YAxisComponent.md): Configure y-axis labels and type
|
|
163
|
+
- [`CrossToolComponent`](docs/generated/CrossToolComponent.md): Crosshair type, OHLC magnet
|
|
164
|
+
- [`EventsComponent`](docs/generated/EventsComponent.md): Set events data
|
|
165
|
+
- [`VolumesComponent`](docs/generated/VolumesComponent.md): Set volume data
|
|
166
|
+
- [`WaterMarkComponent`](docs/generated/WaterMarkComponent.md): Create and manage a watermark
|
|
167
|
+
- [`NavigationMapComponent`](docs/generated/NavigationMapComponent.md): Create a navigation map
|
|
168
|
+
- [`SnapshotComponent`](docs/generated/SnapshotComponent.md): Create a snapshot
|
|
169
|
+
- [`HighlightsComponent`](docs/generated/HighlightsComponent.md): Draw highlights on canvas objects such as labels
|
|
170
|
+
- [`PaneManager`](docs/generated/PaneManager.md): Create and manage panes
|
|
171
|
+
- [`PaneComponent`](docs/generated/PaneComponent.md): Create and manage pane data series
|
|
175
172
|
|
|
176
173
|
## Examples
|
|
177
174
|
|
|
178
|
-
We have created
|
|
175
|
+
We have created many examples with different chart configurations.
|
|
179
176
|
You can find them [here](https://github.com/devexperts/dxcharts-lite/tree/master/docs/how-to).
|
|
180
177
|
|
|
181
178
|
## Demo
|
|
182
179
|
|
|
183
|
-
To
|
|
180
|
+
To demonstrate its capabilities, we've created a [Demo version](https://devexperts.com/dxcharts-demo/) based on DXCharts Lite.
|
|
181
|
+
Explore the full power of our library!
|
|
@@ -63,6 +63,7 @@ export declare class CanvasBoundsContainer {
|
|
|
63
63
|
canvasOnPageLocation: Bounds;
|
|
64
64
|
panesOrder: Array<string>;
|
|
65
65
|
panesOrderChangedSubject: Subject<string[]>;
|
|
66
|
+
paneMovedSubject: Subject<void>;
|
|
66
67
|
paneVisibilityChangedSubject: Subject<void>;
|
|
67
68
|
xAxisHeight: number | undefined;
|
|
68
69
|
yAxisWidths: YAxisWidths;
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (C) 2019 - 2025 Devexperts Solutions IE Limited
|
|
3
|
+
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
|
4
|
+
* If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
5
|
+
*/
|
|
1
6
|
/*
|
|
2
7
|
* Copyright (C) 2019 - 2025 Devexperts Solutions IE Limited
|
|
3
8
|
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
|
@@ -74,6 +79,7 @@ export class CanvasBoundsContainer {
|
|
|
74
79
|
// holds ordered "top to bottom" array of panes UUID's (studies in past)
|
|
75
80
|
this.panesOrder = [];
|
|
76
81
|
this.panesOrderChangedSubject = new Subject();
|
|
82
|
+
this.paneMovedSubject = new Subject();
|
|
77
83
|
this.paneVisibilityChangedSubject = new Subject();
|
|
78
84
|
// both will be calculated based on font/content size
|
|
79
85
|
this.xAxisHeight = undefined;
|
|
@@ -147,6 +153,7 @@ export class CanvasBoundsContainer {
|
|
|
147
153
|
this.recalculateBounds();
|
|
148
154
|
this.eventBus.fireDraw();
|
|
149
155
|
this.panesOrderChangedSubject.next(this.panesOrder);
|
|
156
|
+
this.paneMovedSubject.next();
|
|
150
157
|
}
|
|
151
158
|
}
|
|
152
159
|
/**
|
|
@@ -161,6 +168,7 @@ export class CanvasBoundsContainer {
|
|
|
161
168
|
this.recalculateBounds();
|
|
162
169
|
this.eventBus.fireDraw();
|
|
163
170
|
this.panesOrderChangedSubject.next(this.panesOrder);
|
|
171
|
+
this.paneMovedSubject.next();
|
|
164
172
|
}
|
|
165
173
|
}
|
|
166
174
|
/**
|
|
@@ -200,6 +200,7 @@ export interface FullChartConfig extends TimeFormatterConfig {
|
|
|
200
200
|
* Initial visual order of chart drawers. Reorder to put volumes on top of candles for example.
|
|
201
201
|
*/
|
|
202
202
|
drawingOrder: DrawerType[];
|
|
203
|
+
intlFormatter: IntlFormatter;
|
|
203
204
|
useUTCTimeOverride: boolean;
|
|
204
205
|
animation: AnimationConfig;
|
|
205
206
|
devexpertsPromoLink: boolean;
|
|
@@ -265,6 +266,10 @@ export interface AutoScaleDisableOnDrag {
|
|
|
265
266
|
*/
|
|
266
267
|
yDiff: number;
|
|
267
268
|
}
|
|
269
|
+
export interface IntlFormatter {
|
|
270
|
+
decimalSeparator?: string;
|
|
271
|
+
thousandsSeparator?: string;
|
|
272
|
+
}
|
|
268
273
|
export interface ChartComponents {
|
|
269
274
|
chart: ChartConfigComponentsChart;
|
|
270
275
|
xAxis: ChartConfigComponentsXAxis;
|
|
@@ -30,6 +30,10 @@ export const getDefaultConfig = () => ({
|
|
|
30
30
|
shortDays: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
|
|
31
31
|
shortMonths: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
|
|
32
32
|
rtl: false,
|
|
33
|
+
intlFormatter: {
|
|
34
|
+
decimalSeparator: '.',
|
|
35
|
+
thousandsSeparator: '',
|
|
36
|
+
},
|
|
33
37
|
scale: {
|
|
34
38
|
keepZoomXOnYAxisChange: true,
|
|
35
39
|
auto: true,
|
|
@@ -66,7 +66,10 @@ export class HighlightsDrawer {
|
|
|
66
66
|
const fromXCandle = this.chartModel.candleFromTimestamp(item.from);
|
|
67
67
|
const fromXCandleWidth = unitToPixels(fromXCandle.width, this.chartModel.scale.zoomX);
|
|
68
68
|
const fromX = fromXCandle.xStart(this.chartModel.scale);
|
|
69
|
-
|
|
69
|
+
// currently endTime timestamp for PRE_MARKET type includes same timestamp for REGULAR type startTime
|
|
70
|
+
// so we have to take previous timestamp based on current period to exclude PRE_MARKET highlighting
|
|
71
|
+
const xCandleTimestamp = item.to - this.chartModel.chartBaseModel.period;
|
|
72
|
+
const toXCandle = this.chartModel.candleFromTimestamp(xCandleTimestamp);
|
|
70
73
|
const toXCandleWidth = unitToPixels(toXCandle.width, this.chartModel.scale.zoomX);
|
|
71
74
|
const toX = toXCandle.xStart(this.chartModel.scale) + toXCandleWidth;
|
|
72
75
|
// draw highlight' borders
|
|
@@ -25,6 +25,8 @@ export interface YExtentCreationOptions {
|
|
|
25
25
|
paneFormatters: YExtentFormatters;
|
|
26
26
|
increment: number | null;
|
|
27
27
|
initialYAxisState: YAxisConfig;
|
|
28
|
+
inverse: boolean;
|
|
29
|
+
lockToPriceRatio: boolean;
|
|
28
30
|
}
|
|
29
31
|
export declare class YExtentComponent extends ChartBaseElement {
|
|
30
32
|
paneUUID: string;
|
|
@@ -71,7 +73,7 @@ export declare class YExtentComponent extends ChartBaseElement {
|
|
|
71
73
|
*/
|
|
72
74
|
removeDataSeries(series: DataSeriesModel): void;
|
|
73
75
|
valueFormatter: (value: Unit, dataSeries?: DataSeriesModel) => string;
|
|
74
|
-
get regularFormatter(): (value: number) => string;
|
|
76
|
+
get regularFormatter(): (value: number, precision?: number | undefined) => string;
|
|
75
77
|
/**
|
|
76
78
|
* Sets the pane value formatters for the current instance.
|
|
77
79
|
* @param {YExtentFormatters} formatters - The pane value formatters to be set.
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (C) 2019 - 2025 Devexperts Solutions IE Limited
|
|
3
|
+
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
|
4
|
+
* If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
5
|
+
*/
|
|
1
6
|
/*
|
|
2
7
|
* Copyright (C) 2019 - 2025 Devexperts Solutions IE Limited
|
|
3
8
|
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
|
@@ -35,9 +40,20 @@ export class YExtentComponent extends ChartBaseElement {
|
|
|
35
40
|
return (_b = (_a = this.mainDataSeries) === null || _a === void 0 ? void 0 : _a.view.toY(value)) !== null && _b !== void 0 ? _b : 1;
|
|
36
41
|
};
|
|
37
42
|
this.valueFormatter = (value, dataSeries) => {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
43
|
+
if (!this.formatters[this.yAxis.getAxisType()]) {
|
|
44
|
+
return this.formatters.regular(value);
|
|
45
|
+
}
|
|
46
|
+
const { regular, percent, logarithmic } = this.formatters;
|
|
47
|
+
switch (this.yAxis.getAxisType()) {
|
|
48
|
+
case 'regular':
|
|
49
|
+
return this.formatters.regular(value);
|
|
50
|
+
case 'percent':
|
|
51
|
+
return percent ? percent(value, dataSeries) : regular(value);
|
|
52
|
+
case 'logarithmic':
|
|
53
|
+
return logarithmic ? logarithmic(value) : regular(value);
|
|
54
|
+
default:
|
|
55
|
+
return this.regularFormatter(value);
|
|
56
|
+
}
|
|
41
57
|
};
|
|
42
58
|
this.addChildEntity(scale);
|
|
43
59
|
this.setValueFormatters(createYExtentFormatters(this));
|
|
@@ -195,11 +195,16 @@ export class PaneManager extends ChartBaseElement {
|
|
|
195
195
|
moveDataSeriesToPane(dataSeries, initialPane, initialExtent, options) {
|
|
196
196
|
const { paneUUID, extent, direction, align, extentIdx, isForceKeepPane, index = 0 } = options;
|
|
197
197
|
const pane = paneUUID && this.panes[paneUUID];
|
|
198
|
-
const initialYAxisState = align ? Object.assign(Object.assign({},
|
|
198
|
+
const initialYAxisState = align ? Object.assign(Object.assign({}, initialExtent.yAxis.state), { align }) : undefined;
|
|
199
199
|
const onNewScale = extentIdx && extentIdx > 0;
|
|
200
200
|
if (!pane) {
|
|
201
201
|
const order = direction && direction === 'above' ? index : index + 1;
|
|
202
|
-
const newPane = this.createPane(paneUUID, {
|
|
202
|
+
const newPane = this.createPane(paneUUID, {
|
|
203
|
+
order,
|
|
204
|
+
initialYAxisState,
|
|
205
|
+
inverse: initialExtent.scale.state.inverse,
|
|
206
|
+
lockToPriceRatio: initialExtent.scale.state.lockPriceToBarRatio,
|
|
207
|
+
});
|
|
203
208
|
newPane.moveDataSeriesToExistingExtentComponent(dataSeries, initialPane, initialExtent, newPane.mainExtent, isForceKeepPane);
|
|
204
209
|
!isForceKeepPane && initialPane.yExtentComponents.length === 0 && this.removePane(initialPane.uuid);
|
|
205
210
|
return;
|
|
@@ -160,7 +160,7 @@ export declare class PaneComponent extends ChartBaseElement {
|
|
|
160
160
|
*/
|
|
161
161
|
canMoveDown(): boolean;
|
|
162
162
|
valueFormatter: (value: Unit, dataSeries?: DataSeriesModel) => string;
|
|
163
|
-
get regularFormatter(): (value: number) => string;
|
|
163
|
+
get regularFormatter(): (value: number, precision?: number | undefined) => string;
|
|
164
164
|
/**
|
|
165
165
|
* Sets the pane value formatters for the current instance.
|
|
166
166
|
* @param {YExtentFormatters} formatters - The pane value formatters to be set.
|
|
@@ -174,7 +174,7 @@ export declare class PaneComponent extends ChartBaseElement {
|
|
|
174
174
|
regularValueFromY(y: number): number;
|
|
175
175
|
}
|
|
176
176
|
export interface YExtentFormatters {
|
|
177
|
-
regular: (value: number) => string;
|
|
177
|
+
regular: (value: number, precision?: number) => string;
|
|
178
178
|
percent?: (value: number, dataSeries?: DataSeriesModel) => string;
|
|
179
179
|
logarithmic?: (value: number) => string;
|
|
180
180
|
}
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (C) 2019 - 2025 Devexperts Solutions IE Limited
|
|
3
|
+
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
|
4
|
+
* If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
5
|
+
*/
|
|
1
6
|
/*
|
|
2
7
|
* Copyright (C) 2019 - 2025 Devexperts Solutions IE Limited
|
|
3
8
|
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
|
@@ -9,10 +14,12 @@ import { areBoundsChanged, CanvasElement, } from '../../canvas/canvas-bounds-con
|
|
|
9
14
|
import { ChartBaseElement } from '../../model/chart-base-element';
|
|
10
15
|
import { SyncedByXScaleModel } from '../../model/scale.model';
|
|
11
16
|
import { firstOf, flatMap, lastOf } from '../../utils/array.utils';
|
|
17
|
+
import { cloneUnsafe } from '../../utils/object.utils';
|
|
12
18
|
import { createCandlesOffsetProvider } from '../chart/data-series.high-low-provider';
|
|
13
19
|
import { GridComponent } from '../grid/grid.component';
|
|
14
20
|
import { YAxisComponent } from '../y_axis/y-axis.component';
|
|
15
21
|
import { createDefaultYExtentHighLowProvider, YExtentComponent, } from './extent/y-extent-component';
|
|
22
|
+
import { merge } from '../../utils/merge.utils';
|
|
16
23
|
export class PaneComponent extends ChartBaseElement {
|
|
17
24
|
get scale() {
|
|
18
25
|
return this.mainExtent.scale;
|
|
@@ -135,6 +142,8 @@ export class PaneComponent extends ChartBaseElement {
|
|
|
135
142
|
yExtentComponent.addSubscription(unsub);
|
|
136
143
|
yExtentComponent.addSubscription(this.addCursors(extentIdx, yExtentComponent.yAxis));
|
|
137
144
|
(options === null || options === void 0 ? void 0 : options.paneFormatters) && yExtentComponent.setValueFormatters(options.paneFormatters);
|
|
145
|
+
yExtentComponent.yAxis.togglePriceScaleInverse(options === null || options === void 0 ? void 0 : options.inverse);
|
|
146
|
+
yExtentComponent.scale.setLockPriceToBarRatio(options === null || options === void 0 ? void 0 : options.lockToPriceRatio);
|
|
138
147
|
const useDefaultHighLow = (_b = options === null || options === void 0 ? void 0 : options.useDefaultHighLow) !== null && _b !== void 0 ? _b : true;
|
|
139
148
|
if (useDefaultHighLow) {
|
|
140
149
|
scaleModel.autoScaleModel.setHighLowProvider('default', createCandlesOffsetProvider(() => ({ top: 10, bottom: 10, left: 0, right: 0, visible: true }), createDefaultYExtentHighLowProvider(yExtentComponent)));
|
|
@@ -163,7 +172,17 @@ export class PaneComponent extends ChartBaseElement {
|
|
|
163
172
|
* Create new pane extent and attach data series to it
|
|
164
173
|
*/
|
|
165
174
|
moveDataSeriesToNewExtentComponent(dataSeries, initialPane, initialExtent, align = 'right') {
|
|
166
|
-
const
|
|
175
|
+
const yAxisConfigCopy = cloneUnsafe(initialExtent.yAxis.state);
|
|
176
|
+
const scaleConfigCopy = cloneUnsafe(initialExtent.scale.state);
|
|
177
|
+
const initialYAxisState = merge(yAxisConfigCopy, this.config.components.yAxis, {
|
|
178
|
+
overrideExisting: false,
|
|
179
|
+
addIfMissing: true,
|
|
180
|
+
});
|
|
181
|
+
const extent = this.createExtentComponent({
|
|
182
|
+
initialYAxisState,
|
|
183
|
+
inverse: scaleConfigCopy.inverse,
|
|
184
|
+
lockToPriceRatio: scaleConfigCopy.lockPriceToBarRatio,
|
|
185
|
+
});
|
|
167
186
|
extent.yAxis.setYAxisAlign(align);
|
|
168
187
|
dataSeries.forEach(series => series.moveToExtent(extent));
|
|
169
188
|
initialExtent.dataSeries.size === 0 && initialPane.removeExtentComponents([initialExtent]);
|
|
@@ -98,7 +98,10 @@ export class LastCandleLabelsProvider {
|
|
|
98
98
|
const boxColor = getLabelColorBySeries(series.lastPriceMovement, series.colors);
|
|
99
99
|
// if the label is for the main candle series
|
|
100
100
|
if (primary) {
|
|
101
|
-
const
|
|
101
|
+
const isScatterPlot = series.config.type === 'scatterPlot';
|
|
102
|
+
const textColor = isScatterPlot
|
|
103
|
+
? rectLabelTextColor
|
|
104
|
+
: getPrimaryLabelTextColor(series.lastPriceMovement, colors);
|
|
102
105
|
return {
|
|
103
106
|
bgColor: boxColor,
|
|
104
107
|
textColor: appearanceType === 'plain'
|
|
@@ -149,7 +149,7 @@ export declare class YAxisComponent extends ChartBaseElement {
|
|
|
149
149
|
* Inversion also works for candles, drawings and overlay studies.
|
|
150
150
|
* @param inverse - true or false
|
|
151
151
|
*/
|
|
152
|
-
togglePriceScaleInverse(inverse
|
|
152
|
+
togglePriceScaleInverse(inverse?: boolean): void;
|
|
153
153
|
/**
|
|
154
154
|
* Changes the visibility of the labels' descriptions.
|
|
155
155
|
* @param {boolean} descVisibility - A boolean value indicating whether the descriptions should be visible or not.
|
|
@@ -244,7 +244,7 @@ export class YAxisComponent extends ChartBaseElement {
|
|
|
244
244
|
* Inversion also works for candles, drawings and overlay studies.
|
|
245
245
|
* @param inverse - true or false
|
|
246
246
|
*/
|
|
247
|
-
togglePriceScaleInverse(inverse) {
|
|
247
|
+
togglePriceScaleInverse(inverse = false) {
|
|
248
248
|
this.scale.state.inverse = inverse;
|
|
249
249
|
this.scale.inverseY = inverse;
|
|
250
250
|
this.model.fancyLabelsModel.updateLabels();
|
|
@@ -11,6 +11,8 @@ export class AreaDrawer {
|
|
|
11
11
|
this.config = config;
|
|
12
12
|
}
|
|
13
13
|
draw(ctx, points, model, hitTestDrawerConfig) {
|
|
14
|
+
var _a;
|
|
15
|
+
const isHitTestDrawer = !!hitTestDrawerConfig.color;
|
|
14
16
|
if (model instanceof CandleSeriesModel) {
|
|
15
17
|
// @ts-ignore
|
|
16
18
|
const visualCandles = flat(points);
|
|
@@ -23,7 +25,10 @@ export class AreaDrawer {
|
|
|
23
25
|
else {
|
|
24
26
|
ctx.strokeStyle = model.colors.areaTheme.lineColor;
|
|
25
27
|
}
|
|
26
|
-
if (
|
|
28
|
+
if (isHitTestDrawer) {
|
|
29
|
+
ctx.lineWidth = (_a = hitTestDrawerConfig.hoverWidth) !== null && _a !== void 0 ? _a : this.config.selectedWidth * 3;
|
|
30
|
+
}
|
|
31
|
+
else if (model.highlighted) {
|
|
27
32
|
ctx.lineWidth = this.config.selectedWidth;
|
|
28
33
|
}
|
|
29
34
|
else {
|
|
@@ -63,7 +68,9 @@ export class AreaDrawer {
|
|
|
63
68
|
fillColor)
|
|
64
69
|
: '';
|
|
65
70
|
}
|
|
66
|
-
|
|
71
|
+
if (!isHitTestDrawer) {
|
|
72
|
+
ctx.fill();
|
|
73
|
+
}
|
|
67
74
|
}
|
|
68
75
|
else {
|
|
69
76
|
ctx.lineTo(lineX, closeY);
|
|
@@ -5,4 +5,5 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { VisualSeriesPoint } from '../../model/data-series.model';
|
|
7
7
|
import { Viewable } from '../../model/scaling/viewport.model';
|
|
8
|
+
export declare const buildSectionPath: (point: VisualSeriesPoint, ctx: CanvasRenderingContext2D, view: Viewable, idx: number) => void;
|
|
8
9
|
export declare const buildLinePath: (points: VisualSeriesPoint[], ctx: CanvasRenderingContext2D, view: Viewable) => void;
|
|
@@ -3,19 +3,22 @@
|
|
|
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
|
+
export const buildSectionPath = (point, ctx, view, idx) => {
|
|
7
|
+
const { centerUnit, close } = point;
|
|
8
|
+
const x = view.toX(centerUnit);
|
|
9
|
+
const y = view.toY(close);
|
|
10
|
+
if (idx === 0) {
|
|
11
|
+
ctx.moveTo(x, y);
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
ctx.lineTo(x, y);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
6
17
|
export const buildLinePath = (points, ctx, view) => {
|
|
7
18
|
if (points.length !== 0) {
|
|
8
19
|
// Recognizing line gaps by candles idx.
|
|
9
20
|
points.forEach((p, idx) => {
|
|
10
|
-
|
|
11
|
-
const x = view.toX(centerUnit);
|
|
12
|
-
const y = view.toY(close);
|
|
13
|
-
if (idx === 0) {
|
|
14
|
-
ctx.moveTo(x, y);
|
|
15
|
-
}
|
|
16
|
-
else {
|
|
17
|
-
ctx.lineTo(x, y);
|
|
18
|
-
}
|
|
21
|
+
buildSectionPath(p, ctx, view, idx);
|
|
19
22
|
});
|
|
20
23
|
}
|
|
21
24
|
};
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { DataSeriesModel, VisualSeriesPoint } from '../../model/data-series.model';
|
|
7
7
|
import { HTSeriesDrawerConfig, SeriesDrawer } from '../data-series.drawer';
|
|
8
|
+
import { Viewable } from '../../model/scaling/viewport.model';
|
|
9
|
+
import { Point } from '../../inputlisteners/canvas-input-listener.component';
|
|
8
10
|
/**
|
|
9
11
|
* Point used to draw difference type indicator (clouds) (e.g. Ichimoku indicator)
|
|
10
12
|
*/
|
|
@@ -15,7 +17,8 @@ export declare class DifferenceCloudDrawer implements SeriesDrawer {
|
|
|
15
17
|
constructor();
|
|
16
18
|
draw(ctx: CanvasRenderingContext2D, allPoints: VisualSeriesPoint[][], model: DataSeriesModel, hitTestDrawerConfig: HTSeriesDrawerConfig): void;
|
|
17
19
|
private drawLine;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
+
protected drawDifference(ctx: CanvasRenderingContext2D, lineColor: string, nextLineColor: string, diffPoints: DifferencePoint[], curSeries: DataSeriesModel, nextSeries: DataSeriesModel, hitTestDrawerConfig: HTSeriesDrawerConfig): void;
|
|
21
|
+
protected fillCloud(ctx: CanvasRenderingContext2D, color: string, linePoints: Point[], nextLinePoints: Point[], hitTestDrawerConfig: HTSeriesDrawerConfig): void;
|
|
22
|
+
protected mapDataSeriesDiffPointsIntoPoints(points: VisualSeriesPoint[], view: Viewable): Point[];
|
|
20
23
|
}
|
|
21
24
|
export declare const isDifferenceTool: (type: string) => boolean;
|
|
@@ -30,7 +30,8 @@ export class DifferenceCloudDrawer {
|
|
|
30
30
|
const allPointsMain = mainSeries.getSeriesInViewport(mainSeries.scale.xStart - 1, mainSeries.scale.xEnd + 1);
|
|
31
31
|
const allPointsLinked = linkedSeries.getSeriesInViewport(linkedSeries.scale.xStart - 1, linkedSeries.scale.xEnd + 1);
|
|
32
32
|
allPointsMain.forEach((points, idx) => {
|
|
33
|
-
|
|
33
|
+
var _a, _b;
|
|
34
|
+
const to = Math.min(points.length, (_b = (_a = allPointsLinked[idx]) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0);
|
|
34
35
|
for (let k = 0; k < to; k++) {
|
|
35
36
|
const diffPoints = [
|
|
36
37
|
points[k].clone(),
|
|
@@ -60,8 +61,8 @@ export class DifferenceCloudDrawer {
|
|
|
60
61
|
linePoints.push(point);
|
|
61
62
|
nextLinePoints.push(nextPoint);
|
|
62
63
|
});
|
|
63
|
-
const curSeriesPoints = mapDataSeriesDiffPointsIntoPoints(linePoints, curSeries.view);
|
|
64
|
-
const nextSeriesPoints = mapDataSeriesDiffPointsIntoPoints(nextLinePoints, nextSeries.view);
|
|
64
|
+
const curSeriesPoints = this.mapDataSeriesDiffPointsIntoPoints(linePoints, curSeries.view);
|
|
65
|
+
const nextSeriesPoints = this.mapDataSeriesDiffPointsIntoPoints(nextLinePoints, nextSeries.view);
|
|
65
66
|
this.fillCloud(ctx, nextLineColor, curSeriesPoints, nextSeriesPoints, hitTestDrawerConfig);
|
|
66
67
|
this.fillCloud(ctx, lineColor, nextSeriesPoints, curSeriesPoints, hitTestDrawerConfig);
|
|
67
68
|
}
|
|
@@ -99,13 +100,13 @@ export class DifferenceCloudDrawer {
|
|
|
99
100
|
ctx.fill();
|
|
100
101
|
ctx.restore();
|
|
101
102
|
}
|
|
103
|
+
mapDataSeriesDiffPointsIntoPoints(points, view) {
|
|
104
|
+
return points.map(p => {
|
|
105
|
+
const { centerUnit, close } = p;
|
|
106
|
+
const x = view.toX(centerUnit);
|
|
107
|
+
const y = view.toY(close);
|
|
108
|
+
return { x, y };
|
|
109
|
+
});
|
|
110
|
+
}
|
|
102
111
|
}
|
|
103
|
-
const mapDataSeriesDiffPointsIntoPoints = (points, view) => {
|
|
104
|
-
return points.map(p => {
|
|
105
|
-
const { centerUnit, close } = p;
|
|
106
|
-
const x = view.toX(centerUnit);
|
|
107
|
-
const y = view.toY(close);
|
|
108
|
-
return { x, y };
|
|
109
|
-
});
|
|
110
|
-
};
|
|
111
112
|
export const isDifferenceTool = (type) => type === 'DIFFERENCE';
|
|
@@ -8,5 +8,5 @@ import { HTSeriesDrawerConfig, SeriesDrawer } from '../data-series.drawer';
|
|
|
8
8
|
export declare class TrendHistogramDrawer implements SeriesDrawer {
|
|
9
9
|
constructor();
|
|
10
10
|
draw(ctx: CanvasRenderingContext2D, allPoints: VisualSeriesPoint[][], model: DataSeriesModel, hitTestDrawerConfig: HTSeriesDrawerConfig): void;
|
|
11
|
-
private previousValue;
|
|
12
11
|
}
|
|
12
|
+
export declare const previousValue: (arr: VisualSeriesPoint[], idx: number) => number | undefined;
|
|
@@ -17,11 +17,11 @@ export class TrendHistogramDrawer {
|
|
|
17
17
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
18
18
|
// odd width is crucial to draw histogram without antialiasing
|
|
19
19
|
// 2 colors: Negative and Positive
|
|
20
|
+
const previousClose = previousValue(allPointsFlat, idx);
|
|
21
|
+
const isNegativeTrend = previousClose && point.close < previousClose;
|
|
20
22
|
if (((_a = config.multiplyColors) === null || _a === void 0 ? void 0 : _a.length) === 2) {
|
|
21
23
|
ctx.strokeStyle =
|
|
22
|
-
(_b = hitTestDrawerConfig.color) !== null && _b !== void 0 ? _b : ((
|
|
23
|
-
? config.multiplyColors[1]
|
|
24
|
-
: config.multiplyColors[0]) ||
|
|
24
|
+
(_b = hitTestDrawerConfig.color) !== null && _b !== void 0 ? _b : ((isNegativeTrend ? config.multiplyColors[1] : config.multiplyColors[0]) ||
|
|
25
25
|
config.color ||
|
|
26
26
|
'#FF00FF');
|
|
27
27
|
ctx.beginPath();
|
|
@@ -34,20 +34,19 @@ export class TrendHistogramDrawer {
|
|
|
34
34
|
}
|
|
35
35
|
// 4 colors: Negative and Down, Negative and Up, Positive and Down, Positive and Up
|
|
36
36
|
if (((_c = config.multiplyColors) === null || _c === void 0 ? void 0 : _c.length) === 4) {
|
|
37
|
-
|
|
38
|
-
if (point.close < prevPointClose && point.close < 0) {
|
|
37
|
+
if (isNegativeTrend && point.close < 0) {
|
|
39
38
|
ctx.strokeStyle =
|
|
40
39
|
(_d = hitTestDrawerConfig.color) !== null && _d !== void 0 ? _d : (config.multiplyColors[0] || config.color || '#FF00FF');
|
|
41
40
|
}
|
|
42
|
-
if (
|
|
41
|
+
if (!isNegativeTrend && point.close < 0) {
|
|
43
42
|
ctx.strokeStyle =
|
|
44
43
|
(_e = hitTestDrawerConfig.color) !== null && _e !== void 0 ? _e : (config.multiplyColors[1] || config.color || '#FF00FF');
|
|
45
44
|
}
|
|
46
|
-
if (
|
|
45
|
+
if (isNegativeTrend && point.close > 0) {
|
|
47
46
|
ctx.strokeStyle =
|
|
48
47
|
(_f = hitTestDrawerConfig.color) !== null && _f !== void 0 ? _f : (config.multiplyColors[2] || config.color || '#FF00FF');
|
|
49
48
|
}
|
|
50
|
-
if (
|
|
49
|
+
if (!isNegativeTrend && point.close > 0) {
|
|
51
50
|
ctx.strokeStyle =
|
|
52
51
|
(_g = hitTestDrawerConfig.color) !== null && _g !== void 0 ? _g : (config.multiplyColors[3] || config.color || '#FF00FF');
|
|
53
52
|
}
|
|
@@ -69,11 +68,11 @@ export class TrendHistogramDrawer {
|
|
|
69
68
|
ctx.stroke();
|
|
70
69
|
});
|
|
71
70
|
}
|
|
72
|
-
//weird but works
|
|
73
|
-
previousValue(arr, idx) {
|
|
74
|
-
do {
|
|
75
|
-
idx--;
|
|
76
|
-
} while (idx >= 0 && !isFinite(arr[idx] && arr[idx].close));
|
|
77
|
-
return arr[idx] ? arr[idx].close : Number.NaN;
|
|
78
|
-
}
|
|
79
71
|
}
|
|
72
|
+
// weird but works
|
|
73
|
+
export const previousValue = (arr, idx) => {
|
|
74
|
+
do {
|
|
75
|
+
idx--;
|
|
76
|
+
} while (idx >= 0 && !isFinite(arr[idx] && arr[idx].close));
|
|
77
|
+
return arr[idx] ? arr[idx].close : undefined;
|
|
78
|
+
};
|