@devexperts/dxcharts-lite 2.5.3 → 2.5.5
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/components/chart/candle.functions.d.ts +2 -1
- package/dist/chart/components/chart/candle.functions.js +27 -20
- package/dist/chart/components/chart/chart.component.js +1 -0
- package/dist/chart/components/chart/chart.model.js +9 -8
- package/dist/chart/components/dynamic-objects/dynamic-objects.model.d.ts +7 -1
- package/dist/chart/components/dynamic-objects/dynamic-objects.model.js +16 -1
- package/dist/chart/model/data-series.config.d.ts +1 -0
- package/dist/chart/model/data-series.config.js +1 -0
- package/dist/chart/model/data-series.model.d.ts +2 -1
- package/dist/chart/model/data-series.model.js +2 -1
- package/dist/chart/model/hit-test-canvas.model.js +5 -5
- package/dist/dxchart.min.js +4 -4
- package/package.json +1 -1
|
@@ -10,10 +10,11 @@ import { PartialCandle } from './chart.component';
|
|
|
10
10
|
* so there is not enough information to build a candle: only Open/Close value available.
|
|
11
11
|
* In this case Daily candle, which we receive, must be completed to full OHLC with equal values.
|
|
12
12
|
*/
|
|
13
|
-
export declare const prepareCandle: (candle: PartialCandle) => Candle;
|
|
13
|
+
export declare const prepareCandle: (candle: PartialCandle) => Candle | undefined;
|
|
14
14
|
/**
|
|
15
15
|
* Adds index to candles according to their array index.
|
|
16
16
|
* @param candles
|
|
17
17
|
*/
|
|
18
18
|
export declare const reindexCandles: (candles: Array<Candle>) => void;
|
|
19
19
|
export declare const deleteCandlesIndex: (candles: Array<Candle>) => void;
|
|
20
|
+
export declare const isCandle: (value: Candle | undefined) => value is Candle;
|
|
@@ -11,27 +11,33 @@ import { finite } from '../../utils/math.utils';
|
|
|
11
11
|
*/
|
|
12
12
|
export const prepareCandle = (candle) => {
|
|
13
13
|
var _a;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
try {
|
|
15
|
+
const settlementPrice = finite(candle.close, candle.open, candle.hi, candle.lo);
|
|
16
|
+
if (!isFinite(settlementPrice)) {
|
|
17
|
+
throw new Error('Received candle without any price');
|
|
18
|
+
}
|
|
19
|
+
// @ts-ignore
|
|
20
|
+
const preparedCandleHi = finite(candle.hi, Math.max(candle.open, candle.close), settlementPrice);
|
|
21
|
+
// @ts-ignore
|
|
22
|
+
const preparedCandleLo = finite(candle.lo, Math.min(candle.open, candle.close), settlementPrice);
|
|
23
|
+
const preparedCandleOpen = finite(candle.open, candle.lo, settlementPrice);
|
|
24
|
+
const preparedCandleClose = finite(candle.close, candle.hi, settlementPrice);
|
|
25
|
+
return {
|
|
26
|
+
hi: preparedCandleHi,
|
|
27
|
+
lo: preparedCandleLo,
|
|
28
|
+
open: preparedCandleOpen,
|
|
29
|
+
close: preparedCandleClose,
|
|
30
|
+
timestamp: candle.timestamp,
|
|
31
|
+
volume: (_a = candle.volume) !== null && _a !== void 0 ? _a : 0,
|
|
32
|
+
expansion: candle.expansion,
|
|
33
|
+
idx: candle.idx,
|
|
34
|
+
impVolatility: candle.impVolatility,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
catch (e) {
|
|
38
|
+
console.warn(e);
|
|
39
|
+
return;
|
|
17
40
|
}
|
|
18
|
-
// @ts-ignore
|
|
19
|
-
const preparedCandleHi = finite(candle.hi, Math.max(candle.open, candle.close), settlementPrice);
|
|
20
|
-
// @ts-ignore
|
|
21
|
-
const preparedCandleLo = finite(candle.lo, Math.min(candle.open, candle.close), settlementPrice);
|
|
22
|
-
const preparedCandleOpen = finite(candle.open, candle.lo, settlementPrice);
|
|
23
|
-
const preparedCandleClose = finite(candle.close, candle.hi, settlementPrice);
|
|
24
|
-
return {
|
|
25
|
-
hi: preparedCandleHi,
|
|
26
|
-
lo: preparedCandleLo,
|
|
27
|
-
open: preparedCandleOpen,
|
|
28
|
-
close: preparedCandleClose,
|
|
29
|
-
timestamp: candle.timestamp,
|
|
30
|
-
volume: (_a = candle.volume) !== null && _a !== void 0 ? _a : 0,
|
|
31
|
-
expansion: candle.expansion,
|
|
32
|
-
idx: candle.idx,
|
|
33
|
-
impVolatility: candle.impVolatility,
|
|
34
|
-
};
|
|
35
41
|
};
|
|
36
42
|
/**
|
|
37
43
|
* Adds index to candles according to their array index.
|
|
@@ -47,3 +53,4 @@ export const deleteCandlesIndex = (candles) => {
|
|
|
47
53
|
candle.idx = undefined;
|
|
48
54
|
});
|
|
49
55
|
};
|
|
56
|
+
export const isCandle = (value) => value !== undefined;
|
|
@@ -20,7 +20,7 @@ import { floor, round } from '../../utils/math.utils';
|
|
|
20
20
|
import { merge as mergeObj } from '../../utils/merge.utils';
|
|
21
21
|
import { createBasicScaleViewportTransformer, createTimeFrameViewportTransformer } from './basic-scale';
|
|
22
22
|
import { calculateCandleWidth } from './candle-width-calculator.functions';
|
|
23
|
-
import { deleteCandlesIndex, prepareCandle, reindexCandles } from './candle.functions';
|
|
23
|
+
import { deleteCandlesIndex, isCandle, prepareCandle, reindexCandles } from './candle.functions';
|
|
24
24
|
import { ChartInstrument } from './chart.component';
|
|
25
25
|
import { fakeCandle } from './fake-candles';
|
|
26
26
|
import { SecondaryChartColorsPool } from './secondary-chart-colors-pool';
|
|
@@ -162,9 +162,9 @@ export class ChartModel extends ChartBaseElement {
|
|
|
162
162
|
* @returns {CandleSeriesModel | undefined} - The newly created secondary candle series model or undefined if it could not be created.
|
|
163
163
|
*/
|
|
164
164
|
setSecondaryCandleSeries(candles, instrument = this.mainCandleSeries.instrument, recalculateAndUpdate = true) {
|
|
165
|
-
const
|
|
165
|
+
const preparedCandles = prepareCandles(candles);
|
|
166
166
|
// set correct indexes based on main candles timestamp
|
|
167
|
-
const reindexCandles = this.reindexCandlesBasedOnSeries(this.mainCandleSeries.dataPoints,
|
|
167
|
+
const reindexCandles = this.reindexCandlesBasedOnSeries(this.mainCandleSeries.dataPoints, preparedCandles);
|
|
168
168
|
// ensure there are no gaps in new candles
|
|
169
169
|
const secondaryCandles = this.secondarySeriesAdjustments(this.mainCandleSeries.dataPoints, reindexCandles);
|
|
170
170
|
// create a new secondary series model if it doesn't already exist
|
|
@@ -198,10 +198,10 @@ export class ChartModel extends ChartBaseElement {
|
|
|
198
198
|
this.mainInstrumentChangedSubject.next(mainSeries.instrument);
|
|
199
199
|
}
|
|
200
200
|
this.rememberCurrentTimeframe();
|
|
201
|
-
const
|
|
201
|
+
const preparedCandles = prepareCandles(mainSeries.candles);
|
|
202
202
|
this.mainCandleSeries.clearData();
|
|
203
|
-
reindexCandles(
|
|
204
|
-
this.mainCandleSeries.dataPoints =
|
|
203
|
+
reindexCandles(preparedCandles);
|
|
204
|
+
this.mainCandleSeries.dataPoints = preparedCandles;
|
|
205
205
|
// deactivate deleted series
|
|
206
206
|
this.secondaryCandleSeries
|
|
207
207
|
.filter(series => {
|
|
@@ -282,7 +282,7 @@ export class ChartModel extends ChartBaseElement {
|
|
|
282
282
|
console.error('All series update failed. Instruments for series are different.');
|
|
283
283
|
return;
|
|
284
284
|
}
|
|
285
|
-
const preparedCandles =
|
|
285
|
+
const preparedCandles = prepareCandles(mainSeries.candles);
|
|
286
286
|
const updateResult = updateCandles(this.mainCandleSeries.dataPoints, preparedCandles);
|
|
287
287
|
const updatedCandles = updateResult.candles;
|
|
288
288
|
reindexCandles(updatedCandles);
|
|
@@ -290,7 +290,7 @@ export class ChartModel extends ChartBaseElement {
|
|
|
290
290
|
// re-create series
|
|
291
291
|
secondarySeries.map(series => {
|
|
292
292
|
var _a, _b, _c, _d;
|
|
293
|
-
const preparedCandles =
|
|
293
|
+
const preparedCandles = prepareCandles(series.candles);
|
|
294
294
|
const updatedCandles = updateCandles((_d = (_c = this.findSecondarySeriesBySymbol((_b = (_a = series.instrument) === null || _a === void 0 ? void 0 : _a.symbol) !== null && _b !== void 0 ? _b : '')) === null || _c === void 0 ? void 0 : _c.dataPoints) !== null && _d !== void 0 ? _d : [], preparedCandles).candles;
|
|
295
295
|
return this.setSecondaryCandleSeries(updatedCandles, series.instrument, false);
|
|
296
296
|
});
|
|
@@ -932,6 +932,7 @@ export class ChartModel extends ChartBaseElement {
|
|
|
932
932
|
}
|
|
933
933
|
}
|
|
934
934
|
const sortCandles = (candles) => candles.slice().sort((a, b) => (a.timestamp === b.timestamp ? 0 : a.timestamp > b.timestamp ? 1 : -1));
|
|
935
|
+
const prepareCandles = (candles) => sortCandles(candles.map(prepareCandle).filter(isCandle));
|
|
935
936
|
const findFirstNotEmptyCandle = (candles, startIdx, iterateStep) => {
|
|
936
937
|
if (startIdx >= candles.length) {
|
|
937
938
|
return candles[candles.length - 1];
|
|
@@ -14,17 +14,19 @@ export interface DynamicObject<T = unknown> {
|
|
|
14
14
|
readonly drawer: DynamicModelDrawer<T>;
|
|
15
15
|
readonly paneId: PaneId;
|
|
16
16
|
readonly model?: T;
|
|
17
|
+
readonly parentId?: DynamicObjectId;
|
|
17
18
|
}
|
|
18
19
|
export declare class DynamicObjectsModel extends ChartBaseElement {
|
|
19
20
|
private canvasModel;
|
|
20
21
|
private _objects;
|
|
21
22
|
private modelIdToObjectMap;
|
|
23
|
+
private _uniqueObjects;
|
|
22
24
|
constructor(canvasModel: CanvasModel);
|
|
23
25
|
/**
|
|
24
26
|
* @returns the `DynamicObject` itself and pane `LinkedList` where the object is stored.
|
|
25
27
|
*
|
|
26
28
|
*/
|
|
27
|
-
|
|
29
|
+
getObjectInfoById(id: DynamicObjectId): [DynamicObject, LinkedList<DynamicObject>] | undefined;
|
|
28
30
|
/**
|
|
29
31
|
* @returns `DynamicObject` position in associated pane `LinkedList`
|
|
30
32
|
* @returns `-1` if an object was not found
|
|
@@ -78,6 +80,10 @@ export declare class DynamicObjectsModel extends ChartBaseElement {
|
|
|
78
80
|
* Getter for the objects
|
|
79
81
|
*/
|
|
80
82
|
get objects(): Record<string, LinkedList<DynamicObject<unknown>>>;
|
|
83
|
+
/**
|
|
84
|
+
* Getter for the unique objects, unique object is an entity which is either dynamic object itself, or its parent
|
|
85
|
+
*/
|
|
86
|
+
get uniqueObjects(): Record<string, Set<DynamicObjectId>>;
|
|
81
87
|
/**
|
|
82
88
|
* Sets the objects
|
|
83
89
|
* @param objects
|
|
@@ -11,6 +11,7 @@ export class DynamicObjectsModel extends ChartBaseElement {
|
|
|
11
11
|
super();
|
|
12
12
|
this.canvasModel = canvasModel;
|
|
13
13
|
this.modelIdToObjectMap = new Map();
|
|
14
|
+
this._uniqueObjects = {};
|
|
14
15
|
this._objects = new BehaviorSubject({});
|
|
15
16
|
}
|
|
16
17
|
/**
|
|
@@ -49,7 +50,7 @@ export class DynamicObjectsModel extends ChartBaseElement {
|
|
|
49
50
|
* @param obj
|
|
50
51
|
*/
|
|
51
52
|
addObject(obj) {
|
|
52
|
-
var _a;
|
|
53
|
+
var _a, _b;
|
|
53
54
|
const paneId = obj.paneId;
|
|
54
55
|
const objects = this.objects;
|
|
55
56
|
const paneList = (_a = objects[paneId]) !== null && _a !== void 0 ? _a : new LinkedList();
|
|
@@ -58,6 +59,10 @@ export class DynamicObjectsModel extends ChartBaseElement {
|
|
|
58
59
|
}
|
|
59
60
|
paneList.insertAtEnd(obj);
|
|
60
61
|
this.modelIdToObjectMap.set(obj.id, obj);
|
|
62
|
+
if (!this.uniqueObjects[paneId]) {
|
|
63
|
+
this.uniqueObjects[paneId] = new Set();
|
|
64
|
+
}
|
|
65
|
+
this.uniqueObjects[paneId].add((_b = obj.parentId) !== null && _b !== void 0 ? _b : obj.id);
|
|
61
66
|
this.setDynamicObjects(objects);
|
|
62
67
|
}
|
|
63
68
|
/**
|
|
@@ -65,6 +70,7 @@ export class DynamicObjectsModel extends ChartBaseElement {
|
|
|
65
70
|
* @param id
|
|
66
71
|
*/
|
|
67
72
|
removeObject(id) {
|
|
73
|
+
var _a;
|
|
68
74
|
const objInfo = this.getObjectInfoById(id);
|
|
69
75
|
if (!objInfo) {
|
|
70
76
|
return;
|
|
@@ -74,6 +80,9 @@ export class DynamicObjectsModel extends ChartBaseElement {
|
|
|
74
80
|
const targetPos = paneList.getNodePosition(targetNode);
|
|
75
81
|
paneList.removeAt(targetPos);
|
|
76
82
|
this.modelIdToObjectMap.delete(id);
|
|
83
|
+
if (this.uniqueObjects[obj.paneId]) {
|
|
84
|
+
this.uniqueObjects[obj.paneId].delete((_a = obj.parentId) !== null && _a !== void 0 ? _a : obj.id);
|
|
85
|
+
}
|
|
77
86
|
if (paneList.size() === 0) {
|
|
78
87
|
delete this.objects[obj.paneId];
|
|
79
88
|
}
|
|
@@ -198,6 +207,12 @@ export class DynamicObjectsModel extends ChartBaseElement {
|
|
|
198
207
|
get objects() {
|
|
199
208
|
return this._objects.getValue();
|
|
200
209
|
}
|
|
210
|
+
/**
|
|
211
|
+
* Getter for the unique objects, unique object is an entity which is either dynamic object itself, or its parent
|
|
212
|
+
*/
|
|
213
|
+
get uniqueObjects() {
|
|
214
|
+
return this._uniqueObjects;
|
|
215
|
+
}
|
|
201
216
|
/**
|
|
202
217
|
* Sets the objects
|
|
203
218
|
* @param objects
|
|
@@ -31,6 +31,7 @@ export interface DataSeriesPaintConfig {
|
|
|
31
31
|
color: string;
|
|
32
32
|
lineWidth: number;
|
|
33
33
|
hoveredLineWidth: number;
|
|
34
|
+
offset: number;
|
|
34
35
|
multiplyColors?: [NegativeColor, PositiveColor] | [NegativeAndDownColor, NegativeAndUpColor, PositiveAndDownColor, PositiveAndUpColor];
|
|
35
36
|
}
|
|
36
37
|
export declare const DEFAULT_DATA_SERIES_PAINT_CONFIG: DataSeriesPaintConfig;
|
|
@@ -47,6 +47,7 @@ export declare class DataSeriesModel<D extends DataSeriesPoint = DataSeriesPoint
|
|
|
47
47
|
extentComponent: YExtentComponent;
|
|
48
48
|
id: string;
|
|
49
49
|
htId: number;
|
|
50
|
+
parentId?: string | number | undefined;
|
|
50
51
|
name: string;
|
|
51
52
|
highlighted: boolean;
|
|
52
53
|
yAxisLabelProvider: DataSeriesYAxisLabelsProvider;
|
|
@@ -71,7 +72,7 @@ export declare class DataSeriesModel<D extends DataSeriesPoint = DataSeriesPoint
|
|
|
71
72
|
get visualPoints(): V[];
|
|
72
73
|
get visualPoints2D(): V[][];
|
|
73
74
|
set visualPoints(points: V[][] | V[]);
|
|
74
|
-
constructor(extentComponent: YExtentComponent, id: string, htId: number, _config?: AtLeastOne<DataSeriesConfig>);
|
|
75
|
+
constructor(extentComponent: YExtentComponent, id: string, htId: number, parentId?: string | number | undefined, _config?: AtLeastOne<DataSeriesConfig>);
|
|
75
76
|
protected doActivate(): void;
|
|
76
77
|
/**
|
|
77
78
|
* Sets the data points and recalculates internal state
|
|
@@ -65,12 +65,13 @@ export class DataSeriesModel extends ChartBaseElement {
|
|
|
65
65
|
this._visualPoints = create2DArray(points);
|
|
66
66
|
this._visualPointsFlat = this._visualPoints.flat();
|
|
67
67
|
}
|
|
68
|
-
constructor(extentComponent, id, htId, _config = cloneUnsafe(DEFAULT_DATA_SERIES_CONFIG)) {
|
|
68
|
+
constructor(extentComponent, id, htId, parentId, _config = cloneUnsafe(DEFAULT_DATA_SERIES_CONFIG)) {
|
|
69
69
|
var _a;
|
|
70
70
|
super();
|
|
71
71
|
this.extentComponent = extentComponent;
|
|
72
72
|
this.id = id;
|
|
73
73
|
this.htId = htId;
|
|
74
|
+
this.parentId = parentId;
|
|
74
75
|
this.name = '';
|
|
75
76
|
this.highlighted = false;
|
|
76
77
|
this._dataPoints = [];
|
|
@@ -10,11 +10,11 @@ import { CanvasModel, initCanvasWithConfig } from './canvas.model';
|
|
|
10
10
|
import { animationFrameId } from '../utils/performance/request-animation-frame-throttle.utils';
|
|
11
11
|
const bigPrimeNumber = 317;
|
|
12
12
|
export const HIT_TEST_ID_RANGE = {
|
|
13
|
-
DRAWINGS: [1,
|
|
14
|
-
NEWS: [
|
|
15
|
-
DATA_SERIES: [
|
|
16
|
-
EVENTS: [
|
|
17
|
-
EXECUTED_ORDERS: [
|
|
13
|
+
DRAWINGS: [1, 4999],
|
|
14
|
+
NEWS: [5000, 5999],
|
|
15
|
+
DATA_SERIES: [6000, 9999],
|
|
16
|
+
EVENTS: [10000, 12999],
|
|
17
|
+
EXECUTED_ORDERS: [13000, 15999],
|
|
18
18
|
};
|
|
19
19
|
/** HitTestCanvasModel
|
|
20
20
|
* Canvas layer for testing mouse events over the models such as Charts, Drawings, Volumes and etc.
|