@devexperts/dxcharts-lite 2.7.26 → 2.7.28
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 +24 -24
- package/dist/chart/animation/viewport-model-animation.js +1 -1
- package/dist/chart/canvas/canvas-bounds-container.js +1 -1
- package/dist/chart/components/chart/chart-area-pan.handler.js +2 -1
- package/dist/chart/components/chart/price-formatters/__tests__/treasury-price.formatter.test.js +5 -5
- package/dist/chart/components/chart/price-formatters/price.formatter.js +3 -0
- package/dist/chart/components/chart/price-formatters/treasury-price.formatter.js +1 -1
- package/dist/chart/components/highlights/highlights.model.d.ts +1 -1
- package/dist/chart/components/volumes/volumes.component.js +1 -1
- package/dist/chart/components/x_axis/time/parser/time-formats.model.d.ts +2 -2
- package/dist/chart/drawers/drawing-manager.d.ts +1 -1
- package/dist/chart/inputhandlers/hover-producer.component.d.ts +5 -0
- package/dist/chart/inputhandlers/hover-producer.component.js +10 -0
- package/dist/chart/model/scale.model.js +4 -3
- package/dist/chart/utils/dom.utils.d.ts +1 -1
- package/dist/dxchart.min.js +3 -3
- package/package.json +21 -20
package/README.md
CHANGED
|
@@ -39,15 +39,15 @@
|
|
|
39
39
|
|
|
40
40
|
Get started with DXCharts Lite by installing the library and configuring it to your needs.
|
|
41
41
|
|
|
42
|
-
-
|
|
43
|
-
-
|
|
44
|
-
-
|
|
45
|
-
-
|
|
46
|
-
-
|
|
47
|
-
-
|
|
48
|
-
-
|
|
49
|
-
-
|
|
50
|
-
-
|
|
42
|
+
- 🚀 [Quick start](#quick-start)
|
|
43
|
+
- 📦 [Installation](#installation)
|
|
44
|
+
- 🛠️ [Create Chart](#create-chart)
|
|
45
|
+
- 📈 [Set data](#set-data)
|
|
46
|
+
- 📄 [HTML markup](#html-markup)
|
|
47
|
+
- ⚙️ [Configuration](#configuration)
|
|
48
|
+
- 🔌 [API](#api)
|
|
49
|
+
- 📒 [Examples](#examples)
|
|
50
|
+
- 🧮 [Demo](#demo)
|
|
51
51
|
|
|
52
52
|
## Quick-start
|
|
53
53
|
|
|
@@ -84,8 +84,8 @@ The `createChart` method creates a new chart instance using `ChartBootstrap` cla
|
|
|
84
84
|
|
|
85
85
|
It accepts two parameters:
|
|
86
86
|
|
|
87
|
-
-
|
|
88
|
-
-
|
|
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
90
|
> Note: Set `width: 100%` and `height: 100%` for the parent container.
|
|
91
91
|
> By default, the chart auto-resizes to the parent, but you can change this by setting `fixedSize` in the config.
|
|
@@ -149,7 +149,7 @@ You can configure the chart using a `ChartConfig` object (optional).
|
|
|
149
149
|
`ChartConfig` sets the initial properties for the chart instance.
|
|
150
150
|
Below is a table of available options (see documentation for details).
|
|
151
151
|
|
|
152
|
-
-
|
|
152
|
+
- [`FullChartConfig`](docs/generated/FullChartConfig.md)
|
|
153
153
|
|
|
154
154
|
## API
|
|
155
155
|
|
|
@@ -157,18 +157,18 @@ Each chart component has an API that allows you to change many parameters on the
|
|
|
157
157
|
|
|
158
158
|
Main components include:
|
|
159
159
|
|
|
160
|
-
-
|
|
161
|
-
-
|
|
162
|
-
-
|
|
163
|
-
-
|
|
164
|
-
-
|
|
165
|
-
-
|
|
166
|
-
-
|
|
167
|
-
-
|
|
168
|
-
-
|
|
169
|
-
-
|
|
170
|
-
-
|
|
171
|
-
-
|
|
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
|
|
172
172
|
|
|
173
173
|
## Examples
|
|
174
174
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { DEFAULT_ANIMATION_TIME_MS, VIEWPORT_ANIMATION_ID } from './canvas-animation';
|
|
7
7
|
const VIEWPORT_ANIMATION_DURATION_MS = DEFAULT_ANIMATION_TIME_MS;
|
|
8
|
-
const STUCK_ANIMATION_THRESHOLD = 0.
|
|
8
|
+
const STUCK_ANIMATION_THRESHOLD = 0.9; // Force finish animations stuck at 90%+
|
|
9
9
|
/**
|
|
10
10
|
* Starts the animation for chart viewport movement for safari.
|
|
11
11
|
* @param canvasAnimation
|
|
@@ -545,7 +545,7 @@ export class CanvasBoundsContainer {
|
|
|
545
545
|
const nMap = this.getBounds(CanvasElement.N_MAP);
|
|
546
546
|
const { height, width } = this.config.components.navigationMap.knots;
|
|
547
547
|
const knotHeightFromConfig = height !== null && height !== void 0 ? height : 0;
|
|
548
|
-
const knotWidthFromConfig = isMobile() ? width * KNOTS_W_MOBILE_MULTIPLIER : width !== null && width !== void 0 ? width : 0;
|
|
548
|
+
const knotWidthFromConfig = isMobile() ? width * KNOTS_W_MOBILE_MULTIPLIER : (width !== null && width !== void 0 ? width : 0);
|
|
549
549
|
const knotY = !knotHeightFromConfig ? nMap.y : nMap.y + (nMap.height - knotHeightFromConfig) / 2;
|
|
550
550
|
// time labels
|
|
551
551
|
const timeLabelsVisible = (_b = (_a = this.config.components.navigationMap) === null || _a === void 0 ? void 0 : _a.timeLabels) === null || _b === void 0 ? void 0 : _b.visible;
|
|
@@ -13,6 +13,7 @@ import { deviceDetector } from '../../utils/device/device-detector.utils';
|
|
|
13
13
|
import { getTouchpadSensitivity } from '../../utils/device/touchpad.utils';
|
|
14
14
|
import { DragNDropXComponent } from '../dran-n-drop_helper/drag-n-drop-x.component';
|
|
15
15
|
import { DragNDropYComponent } from '../dran-n-drop_helper/drag-n-drop-y.component';
|
|
16
|
+
import { ONE_FRAME_MS } from '../../utils/numeric-constants.utils';
|
|
16
17
|
/**
|
|
17
18
|
* ChartAreaPanHandler is a class that handles the panning and zooming of the chart area.
|
|
18
19
|
* It extends the ChartBaseElement class and has the following properties:
|
|
@@ -45,7 +46,7 @@ export class ChartAreaPanHandler extends ChartBaseElement {
|
|
|
45
46
|
// number of candles delta changed during X dragging: 1, 5 or -3 for ex.
|
|
46
47
|
this.xDraggedCandlesDelta = 0;
|
|
47
48
|
this.lastXStart = 0;
|
|
48
|
-
this.wheelThrottleTime =
|
|
49
|
+
this.wheelThrottleTime = ONE_FRAME_MS;
|
|
49
50
|
this.chartPanningOptions = {
|
|
50
51
|
horizontal: true,
|
|
51
52
|
vertical: true,
|
package/dist/chart/components/chart/price-formatters/__tests__/treasury-price.formatter.test.js
CHANGED
|
@@ -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 { treasuryPriceFormatter, parseTreasuryPrice, isTreasuryPriceFormat, TREASURY_32ND } from '../treasury-price.formatter';
|
|
6
|
+
import { treasuryPriceFormatter, parseTreasuryPrice, isTreasuryPriceFormat, TREASURY_32ND, } from '../treasury-price.formatter';
|
|
7
7
|
describe('Treasury Price Formatter', () => {
|
|
8
8
|
describe('treasuryPriceFormatter', () => {
|
|
9
9
|
it('should format decimal prices to treasury format', () => {
|
|
@@ -33,12 +33,12 @@ describe('Treasury Price Formatter', () => {
|
|
|
33
33
|
expect(parseTreasuryPrice("1'00")).toBe(1.0);
|
|
34
34
|
});
|
|
35
35
|
it('should return NaN for invalid formats', () => {
|
|
36
|
-
expect(parseTreasuryPrice(
|
|
36
|
+
expect(parseTreasuryPrice('invalid')).toBe(NaN);
|
|
37
37
|
expect(parseTreasuryPrice("132'")).toBe(NaN);
|
|
38
38
|
expect(parseTreasuryPrice("'10")).toBe(NaN);
|
|
39
39
|
expect(parseTreasuryPrice("132'1")).toBe(NaN);
|
|
40
40
|
expect(parseTreasuryPrice("132'100")).toBe(NaN);
|
|
41
|
-
expect(parseTreasuryPrice(
|
|
41
|
+
expect(parseTreasuryPrice('abc123')).toBe(NaN);
|
|
42
42
|
});
|
|
43
43
|
});
|
|
44
44
|
describe('isTreasuryPriceFormat', () => {
|
|
@@ -49,8 +49,8 @@ describe('Treasury Price Formatter', () => {
|
|
|
49
49
|
expect(isTreasuryPriceFormat("1'31")).toBe(true);
|
|
50
50
|
});
|
|
51
51
|
it('should reject invalid formats', () => {
|
|
52
|
-
expect(isTreasuryPriceFormat(
|
|
53
|
-
expect(isTreasuryPriceFormat(
|
|
52
|
+
expect(isTreasuryPriceFormat('invalid')).toBe(false);
|
|
53
|
+
expect(isTreasuryPriceFormat('132')).toBe(false);
|
|
54
54
|
expect(isTreasuryPriceFormat("132'")).toBe(false);
|
|
55
55
|
expect(isTreasuryPriceFormat("'10")).toBe(false);
|
|
56
56
|
expect(isTreasuryPriceFormat("132'1")).toBe(false);
|
|
@@ -31,6 +31,9 @@ export const createRegularPriceFormatter = (extent, config) => (value) => {
|
|
|
31
31
|
return `${checkedValue}`;
|
|
32
32
|
};
|
|
33
33
|
export const createPercentFormatter = (extent) => (value, dataSeries) => {
|
|
34
|
+
if (value === 0) {
|
|
35
|
+
return '0.00 %';
|
|
36
|
+
}
|
|
34
37
|
const [mainDataSeries] = extent.dataSeries;
|
|
35
38
|
let valueUnit = value;
|
|
36
39
|
const series = dataSeries !== null && dataSeries !== void 0 ? dataSeries : mainDataSeries;
|
|
@@ -40,7 +40,7 @@ export const parseTreasuryPrice = (value) => {
|
|
|
40
40
|
const integerPart = parseInt(match[1], 10);
|
|
41
41
|
const thirtySeconds = parseInt(match[2], 10);
|
|
42
42
|
// Convert 32nds to decimal
|
|
43
|
-
const decimalPart =
|
|
43
|
+
const decimalPart = thirtySeconds * TREASURY_32ND;
|
|
44
44
|
return integerPart + decimalPart;
|
|
45
45
|
}
|
|
46
46
|
// Return Number(value) for non-treasury formats (this will be NaN for invalid strings)
|
|
@@ -8,7 +8,7 @@ import { ChartBaseElement } from '../../model/chart-base-element';
|
|
|
8
8
|
import { ChartModel } from '../chart/chart.model';
|
|
9
9
|
export type HighlightTextPlacement = 'left-left' | 'left-right' | 'right-left' | 'right-right';
|
|
10
10
|
export declare const HIGHLIGHTS_TYPES: readonly ["AFTER_MARKET", "PRE_MARKET", "NO_TRADING", "REGULAR"];
|
|
11
|
-
export type HighlightType = typeof HIGHLIGHTS_TYPES[number];
|
|
11
|
+
export type HighlightType = (typeof HIGHLIGHTS_TYPES)[number];
|
|
12
12
|
export type VisualHighlights = Partial<Record<HighlightType, Highlight[]>>;
|
|
13
13
|
export interface Highlight {
|
|
14
14
|
type: HighlightType;
|
|
@@ -29,7 +29,7 @@ export class VolumesComponent extends ChartBaseElement {
|
|
|
29
29
|
this.volumesModel = volumesModel;
|
|
30
30
|
this.addChildEntity(volumesModel);
|
|
31
31
|
this.separateVolumes = new SeparateVolumesComponent(chartComponent, config, volumesModel, paneManager);
|
|
32
|
-
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);
|
|
32
|
+
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);
|
|
33
33
|
config.components.volumes.visible && this.syncVolumesDynamicObject();
|
|
34
34
|
this.addChildEntity(this.separateVolumes);
|
|
35
35
|
this.registerDefaultVolumeColorResolvers();
|
|
@@ -7,8 +7,8 @@ declare const weekWeekday: "week-weekday";
|
|
|
7
7
|
declare const timeFormatsConfirugable: readonly ["second", "minute", "hour", "day", "month", "year"];
|
|
8
8
|
declare const timeFormatsNoNConfirugable: readonly ["lessThanSecond"];
|
|
9
9
|
type TimeFormatWeekWeekdayType = typeof weekWeekday;
|
|
10
|
-
type TimeFormatConfirugableType = typeof timeFormatsConfirugable[number];
|
|
11
|
-
type TimeFormatNonConfirugableType = typeof timeFormatsNoNConfirugable[number];
|
|
10
|
+
type TimeFormatConfirugableType = (typeof timeFormatsConfirugable)[number];
|
|
11
|
+
type TimeFormatNonConfirugableType = (typeof timeFormatsNoNConfirugable)[number];
|
|
12
12
|
export type TimeFormat = TimeFormatConfirugableType | TimeFormatNonConfirugableType | TimeFormatWeekWeekdayType;
|
|
13
13
|
type TimeFormatConfirugableWithDurationType = `${TimeFormatConfirugableType}_${number}` | `${TimeFormatConfirugableType}_${number}!` | `${TimeFormatWeekWeekdayType}_${number | '$'}_${number}`;
|
|
14
14
|
export type TimeFormatWithDuration = TimeFormatConfirugableWithDurationType | TimeFormatNonConfirugableType;
|
|
@@ -7,7 +7,7 @@ import EventBus from '../events/event-bus';
|
|
|
7
7
|
import { ChartResizeHandler } from '../inputhandlers/chart-resize.handler';
|
|
8
8
|
export declare const HIT_TEST_PREFIX = "HIT_TEST_";
|
|
9
9
|
declare const drawerTypes: readonly ["MAIN_BACKGROUND", "MAIN_CLEAR", "HIT_TEST_CLEAR", "YAXIS_CLEAR", "SERIES_CLEAR", "OVER_SERIES_CLEAR", "HIT_TEST_DRAWINGS", "GRID", "X_AXIS", "Y_AXIS", "HIGH_LOW", "DYNAMIC_OBJECTS", "N_MAP_CHART", "PL_CHART", "WATERMARK", "EMPTY_CHART", "OFFLINE_CHART", "LABELS", "EVENTS", "HIT_TEST_EVENTS", "ZERO_LINE", "PL_ZERO_LINE_BACKGROUND", "CROSS_TOOL"];
|
|
10
|
-
export type DrawerType = typeof drawerTypes[number];
|
|
10
|
+
export type DrawerType = (typeof drawerTypes)[number];
|
|
11
11
|
/**
|
|
12
12
|
* Manages the drawing process.
|
|
13
13
|
* Can re-order drawers to make one be on top of the other.
|
|
@@ -58,6 +58,10 @@ export declare class HoverProducerComponent extends ChartBaseElement {
|
|
|
58
58
|
hoverSubject: BehaviorSubject<Hover | null>;
|
|
59
59
|
get hover(): Hover | null;
|
|
60
60
|
longTouchActivatedSubject: BehaviorSubject<boolean>;
|
|
61
|
+
/**
|
|
62
|
+
* When true, mobile long-touch (e.g. 200ms) does not activate crosshair / disable pan.
|
|
63
|
+
*/
|
|
64
|
+
private longTouchCrosshairSuppressed;
|
|
61
65
|
private hoverProducerParts;
|
|
62
66
|
xFormatter: DateTimeFormatter;
|
|
63
67
|
constructor(crossEventProducer: CrossEventProducerComponent, scale: ScaleModel, config: FullChartConfig, chartModel: ChartModel, canvasInputListener: CanvasInputListenerComponent, canvasBoundsContainer: CanvasBoundsContainer, paneManager: PaneManager, timeZoneModel: TimeZoneModel, mainCanvasTouchHandler: MainCanvasTouchHandler, formatterFactory: (format: string) => (timestamp: number) => string);
|
|
@@ -125,6 +129,7 @@ export declare class HoverProducerComponent extends ChartBaseElement {
|
|
|
125
129
|
* Fires the last hover update if there is a last cross.
|
|
126
130
|
*/
|
|
127
131
|
fireLastCross(): void;
|
|
132
|
+
setLongTouchCrosshairSuppressed(value: boolean): void;
|
|
128
133
|
/**
|
|
129
134
|
* Registers a hover producer part with the given id.
|
|
130
135
|
*
|
|
@@ -34,6 +34,10 @@ export class HoverProducerComponent extends ChartBaseElement {
|
|
|
34
34
|
this.formatterFactory = formatterFactory;
|
|
35
35
|
this.hoverSubject = new BehaviorSubject(null);
|
|
36
36
|
this.longTouchActivatedSubject = new BehaviorSubject(false);
|
|
37
|
+
/**
|
|
38
|
+
* When true, mobile long-touch (e.g. 200ms) does not activate crosshair / disable pan.
|
|
39
|
+
*/
|
|
40
|
+
this.longTouchCrosshairSuppressed = false;
|
|
37
41
|
this.xFormatter = () => '';
|
|
38
42
|
const candleHoverProducerPart = new CandleHoverProducerPart(this.chartModel);
|
|
39
43
|
const compareSeriesHoverProducerPart = new CompareSeriesHoverProducerPart(this.chartModel);
|
|
@@ -104,6 +108,9 @@ export class HoverProducerComponent extends ChartBaseElement {
|
|
|
104
108
|
const hitTest = this.canvasBoundsContainer.getBoundsHitTest(CanvasElement.ALL_PANES);
|
|
105
109
|
this.addRxSubscription(this.canvasInputListener.observeLongTouchStart(hitTest).subscribe(event => {
|
|
106
110
|
var _a;
|
|
111
|
+
if (this.longTouchCrosshairSuppressed) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
107
114
|
this.crossEventProducer.crossToolHover = null;
|
|
108
115
|
this.crossEventProducer.crossToolTouchInfo.isCommonTap = false;
|
|
109
116
|
// don't lock chart and show crosshair if chart is being moved, crosstool is not enabled or we do pinch event
|
|
@@ -283,6 +290,9 @@ export class HoverProducerComponent extends ChartBaseElement {
|
|
|
283
290
|
this.createAndFireHover(lastCross);
|
|
284
291
|
}
|
|
285
292
|
}
|
|
293
|
+
setLongTouchCrosshairSuppressed(value) {
|
|
294
|
+
this.longTouchCrosshairSuppressed = value;
|
|
295
|
+
}
|
|
286
296
|
/**
|
|
287
297
|
* Registers a hover producer part with the given id.
|
|
288
298
|
*
|
|
@@ -128,13 +128,14 @@ export class ScaleModel extends ViewportModel {
|
|
|
128
128
|
* @param zoomSensitivity - The sensitivity of the zoom. Default value is taken from the configuration object.
|
|
129
129
|
*/
|
|
130
130
|
zoomXToEnd(zoomIn, zoomSensitivity) {
|
|
131
|
-
|
|
131
|
+
const disableAnimations = this.config.scale.disableAnimations || this.config.components.yAxis.type === 'percent';
|
|
132
|
+
if (disableAnimations) {
|
|
132
133
|
this.haltAnimation();
|
|
133
134
|
}
|
|
134
135
|
this.beforeStartAnimationSubject.next();
|
|
135
136
|
const state = this.export();
|
|
136
137
|
zoomXToEndViewportCalculator(this, state, zoomSensitivity, zoomIn);
|
|
137
|
-
this.zoomXTo(state, zoomIn,
|
|
138
|
+
this.zoomXTo(state, zoomIn, disableAnimations);
|
|
138
139
|
}
|
|
139
140
|
haltAnimation() {
|
|
140
141
|
var _a;
|
|
@@ -232,7 +233,7 @@ export class ScaleModel extends ViewportModel {
|
|
|
232
233
|
const vCandles = visualCandleSource.slice(Math.max(visualCandleSource.length - this.state.defaultViewportItems, 0));
|
|
233
234
|
const endCandle = vCandles[vCandles.length - 1];
|
|
234
235
|
const xEnd = endCandle.startUnit + endCandle.width + this.offsets.right;
|
|
235
|
-
const xStart = xEnd -
|
|
236
|
+
const xStart = xEnd - this.getBounds().width * this.zoomX;
|
|
236
237
|
const state = Object.assign(Object.assign({}, initialStateCopy), { xStart, xEnd });
|
|
237
238
|
const constrainedState = this.scalePostProcessor(initialStateCopy, state);
|
|
238
239
|
if (this.state.auto) {
|
|
@@ -8,7 +8,7 @@ export declare const MouseButton: {
|
|
|
8
8
|
middle: number;
|
|
9
9
|
right: number;
|
|
10
10
|
};
|
|
11
|
-
export type MouseButtonType = typeof MouseButton[keyof typeof MouseButton];
|
|
11
|
+
export type MouseButtonType = (typeof MouseButton)[keyof typeof MouseButton];
|
|
12
12
|
/**
|
|
13
13
|
* @param {Element} element
|
|
14
14
|
* @param {function} listener
|