@devexperts/dxcharts-lite 2.4.5 → 2.5.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/dist/chart/__tests__/model/date-time.formatter.test.d.ts +6 -0
- package/dist/chart/__tests__/model/date-time.formatter.test.js +30 -0
- package/dist/chart/bootstrap.js +1 -1
- package/dist/chart/canvas/canvas-bounds-container.d.ts +7 -3
- package/dist/chart/canvas/canvas-bounds-container.js +149 -105
- package/dist/chart/canvas/y-axis-bounds.container.js +4 -0
- package/dist/chart/chart.config.d.ts +4 -10
- package/dist/chart/chart.config.js +4 -6
- package/dist/chart/components/chart/chart-area-pan.handler.d.ts +9 -6
- package/dist/chart/components/chart/chart-area-pan.handler.js +41 -38
- package/dist/chart/components/chart/chart.model.d.ts +0 -1
- package/dist/chart/components/chart/chart.model.js +0 -1
- package/dist/chart/components/dran-n-drop_helper/drag-n-drop-x.component.d.ts +0 -6
- package/dist/chart/components/dran-n-drop_helper/drag-n-drop-x.component.js +0 -8
- package/dist/chart/components/dran-n-drop_helper/drag-n-drop-y.component.d.ts +0 -5
- package/dist/chart/components/dran-n-drop_helper/drag-n-drop-y.component.js +0 -7
- package/dist/chart/components/dran-n-drop_helper/drag-n-drop.component.d.ts +1 -12
- package/dist/chart/components/dran-n-drop_helper/drag-n-drop.component.js +19 -30
- package/dist/chart/components/dynamic-objects/dynamic-objects.model.d.ts +6 -3
- package/dist/chart/components/dynamic-objects/dynamic-objects.model.js +14 -3
- package/dist/chart/components/hit-test/hit-test.component.d.ts +3 -1
- package/dist/chart/components/hit-test/hit-test.component.js +6 -1
- package/dist/chart/components/pan/chart-pan.component.d.ts +4 -14
- package/dist/chart/components/pan/chart-pan.component.js +10 -21
- package/dist/chart/components/pane/extent/y-extent-component.d.ts +2 -0
- package/dist/chart/components/pane/pane-manager.component.d.ts +29 -0
- package/dist/chart/components/pane/pane-manager.component.js +71 -8
- package/dist/chart/components/pane/pane.component.d.ts +5 -17
- package/dist/chart/components/pane/pane.component.js +13 -29
- package/dist/chart/components/resizer/bar-resizer.component.d.ts +1 -1
- package/dist/chart/components/resizer/bar-resizer.component.js +8 -5
- package/dist/chart/components/x_axis/x-axis-scale.handler.js +1 -1
- package/dist/chart/components/y_axis/price_labels/y-axis-labels.model.d.ts +1 -3
- package/dist/chart/components/y_axis/price_labels/y-axis-labels.model.js +1 -3
- package/dist/chart/components/y_axis/y-axis-scale.handler.js +6 -8
- package/dist/chart/components/y_axis/y-axis.component.d.ts +1 -1
- package/dist/chart/components/y_axis/y-axis.component.js +7 -4
- package/dist/chart/inputhandlers/hover-producer.component.d.ts +1 -1
- package/dist/chart/inputhandlers/main-canvas-touch.handler.d.ts +11 -7
- package/dist/chart/inputhandlers/main-canvas-touch.handler.js +34 -7
- package/dist/chart/inputlisteners/canvas-input-listener.component.d.ts +0 -14
- package/dist/chart/inputlisteners/canvas-input-listener.component.js +1 -35
- package/dist/chart/model/baseline.model.d.ts +3 -0
- package/dist/chart/model/baseline.model.js +5 -0
- package/dist/chart/model/candle-series.model.d.ts +10 -1
- package/dist/chart/model/candle-series.model.js +20 -2
- package/dist/chart/model/chart-base-element.d.ts +2 -0
- package/dist/chart/model/chart-base-element.js +2 -0
- package/dist/chart/model/data-series.model.js +5 -3
- package/dist/chart/model/date-time.formatter.d.ts +20 -3
- package/dist/chart/model/date-time.formatter.js +62 -14
- package/dist/chart/model/scale.model.d.ts +5 -0
- package/dist/chart/model/scale.model.js +9 -1
- package/dist/chart/model/scaling/constrait.functions.d.ts +5 -7
- package/dist/chart/model/scaling/constrait.functions.js +3 -3
- package/dist/chart/model/time-zone.model.js +3 -1
- package/dist/chart/utils/timezone.utils.js +3 -3
- package/dist/dxchart.min.js +4 -4
- package/package.json +1 -1
|
@@ -8,7 +8,6 @@ import { merge, Subject } from 'rxjs';
|
|
|
8
8
|
import { ChartBaseElement } from '../model/chart-base-element';
|
|
9
9
|
import { distinctUntilChanged, filter, map, tap } from 'rxjs/operators';
|
|
10
10
|
import { EVENT_RESIZED } from '../events/events';
|
|
11
|
-
import { touchpadDetector } from '../utils/device/touchpad.utils';
|
|
12
11
|
import { deviceDetector } from '../utils/device/device-detector.utils';
|
|
13
12
|
/**
|
|
14
13
|
* Gathers user input on canvas element:
|
|
@@ -53,8 +52,6 @@ class CanvasInputListenerComponent extends ChartBaseElement {
|
|
|
53
52
|
this.longTouchStartSubject = new Subject();
|
|
54
53
|
this.longTouchEndSubject = new Subject();
|
|
55
54
|
this.contextMenuSubject = new Subject();
|
|
56
|
-
this.pinchSubject = new Subject();
|
|
57
|
-
this.scrollGestureSubject = new Subject();
|
|
58
55
|
this.fastTouchScroll = new Subject();
|
|
59
56
|
this.mouseLeavesCanvasSubject = new Subject();
|
|
60
57
|
// point at which start dragging
|
|
@@ -269,20 +266,7 @@ class CanvasInputListenerComponent extends ChartBaseElement {
|
|
|
269
266
|
this.addSubscription(subscribeListener(this.element, (e) => this.touchEndSubject.next(e), 'touchend'));
|
|
270
267
|
this.addSubscription(subscribeListener(this.element, (e) => this.touchCancelSubject.next(e), 'touchcancel'));
|
|
271
268
|
this.addSubscription(subscribeListener(this.element, (e) => {
|
|
272
|
-
|
|
273
|
-
if (e.ctrlKey) {
|
|
274
|
-
this.pinchSubject.next(e);
|
|
275
|
-
}
|
|
276
|
-
else {
|
|
277
|
-
// mouse wheel or scroll gesture
|
|
278
|
-
const isTouchpad = touchpadDetector(e);
|
|
279
|
-
if (isTouchpad) {
|
|
280
|
-
this.scrollGestureSubject.next(e);
|
|
281
|
-
}
|
|
282
|
-
else {
|
|
283
|
-
this.wheelSubject.next(e);
|
|
284
|
-
}
|
|
285
|
-
}
|
|
269
|
+
this.wheelSubject.next(e);
|
|
286
270
|
e.preventDefault(); // to disable the scroll over the document, if for example chart is used as widget
|
|
287
271
|
}, 'wheel'));
|
|
288
272
|
this.addSubscription(subscribeListener(this.element, (e) => this.contextMenuSubject.next(e), 'contextmenu'));
|
|
@@ -557,24 +541,6 @@ class CanvasInputListenerComponent extends ChartBaseElement {
|
|
|
557
541
|
.asObservable()
|
|
558
542
|
.pipe(filter(() => hitBoundsTest(this.currentPoint.x, this.currentPoint.y)));
|
|
559
543
|
}
|
|
560
|
-
/**
|
|
561
|
-
* Returns an Observable that emits WheelEvent when a pinch event occurs and the hitBoundsTest function returns true for the current point.
|
|
562
|
-
* @param {HitBoundsTest} hitBoundsTest - A function that takes the current point's x and y coordinates as arguments and returns a boolean indicating whether the point is within the desired bounds.
|
|
563
|
-
* @returns {Observable<WheelEvent>} - An Observable that emits WheelEvent when a pinch event occurs and the hitBoundsTest function returns true for the current point.
|
|
564
|
-
*/
|
|
565
|
-
observePinch(hitBoundsTest = () => true) {
|
|
566
|
-
return this.pinchSubject
|
|
567
|
-
.asObservable()
|
|
568
|
-
.pipe(filter(() => hitBoundsTest(this.currentPoint.x, this.currentPoint.y)));
|
|
569
|
-
}
|
|
570
|
-
/**
|
|
571
|
-
* Returns an Observable that emits a WheelEvent whenever a scroll gesture is detected.
|
|
572
|
-
* The Observable is created from a Subject that is subscribed to by the component's template.
|
|
573
|
-
* @returns {Observable<WheelEvent>} An Observable that emits a WheelEvent whenever a scroll gesture is detected.
|
|
574
|
-
*/
|
|
575
|
-
observeScrollGesture() {
|
|
576
|
-
return this.scrollGestureSubject.asObservable();
|
|
577
|
-
}
|
|
578
544
|
/**
|
|
579
545
|
* Returns an Observable that emits TouchEvent when a touchstart event occurs within the bounds of the current point.
|
|
580
546
|
* @param {HitBoundsTest} [hitBoundsTest=() => true] - A function that tests if the touch event occurred within the bounds of the current point.
|
|
@@ -19,6 +19,7 @@ export declare const BASELINE_RESIZER_UUID = "BASELINE_RESIZER";
|
|
|
19
19
|
*/
|
|
20
20
|
export declare class BaselineModel extends ChartBaseElement {
|
|
21
21
|
private chartModel;
|
|
22
|
+
private chartPanComponent;
|
|
22
23
|
private canvasModel;
|
|
23
24
|
private canvasInputListener;
|
|
24
25
|
private config;
|
|
@@ -29,6 +30,8 @@ export declare class BaselineModel extends ChartBaseElement {
|
|
|
29
30
|
ht: HitBoundsTest;
|
|
30
31
|
constructor(chartModel: ChartModel, chartPanComponent: ChartPanComponent, canvasModel: CanvasModel, canvasInputListener: CanvasInputListenerComponent, config: FullChartConfig, canvasBoundContainer: CanvasBoundsContainer, cursorHandler: CursorHandler);
|
|
31
32
|
protected doActivate(): void;
|
|
33
|
+
private dragStartCb;
|
|
34
|
+
private dragEndCb;
|
|
32
35
|
private dragTickCb;
|
|
33
36
|
/**
|
|
34
37
|
* Recalculates the bounds of the baseline resizer based on the current chart and y-axis bounds.
|
|
@@ -15,6 +15,7 @@ export class BaselineModel extends ChartBaseElement {
|
|
|
15
15
|
constructor(chartModel, chartPanComponent, canvasModel, canvasInputListener, config, canvasBoundContainer, cursorHandler) {
|
|
16
16
|
super();
|
|
17
17
|
this.chartModel = chartModel;
|
|
18
|
+
this.chartPanComponent = chartPanComponent;
|
|
18
19
|
this.canvasModel = canvasModel;
|
|
19
20
|
this.canvasInputListener = canvasInputListener;
|
|
20
21
|
this.config = config;
|
|
@@ -26,6 +27,8 @@ export class BaselineModel extends ChartBaseElement {
|
|
|
26
27
|
this.ht = CanvasBoundsContainer.hitTestOf(this.resizerBounds, {
|
|
27
28
|
extensionY: this.config.components.paneResizer.dragZone,
|
|
28
29
|
});
|
|
30
|
+
this.dragStartCb = () => this.chartPanComponent.deactivatePanHandlers();
|
|
31
|
+
this.dragEndCb = () => this.chartPanComponent.activateChartPanHandlers();
|
|
29
32
|
this.dragTickCb = (dragInfo) => {
|
|
30
33
|
const { delta: yDelta } = dragInfo;
|
|
31
34
|
const chart = this.canvasBoundContainer.getBounds(CanvasElement.CHART);
|
|
@@ -37,6 +40,8 @@ export class BaselineModel extends ChartBaseElement {
|
|
|
37
40
|
};
|
|
38
41
|
const dndHelper = new DragNDropYComponent(this.ht, {
|
|
39
42
|
onDragTick: this.dragTickCb,
|
|
43
|
+
onDragStart: this.dragStartCb,
|
|
44
|
+
onDragEnd: this.dragEndCb,
|
|
40
45
|
}, canvasInputListener, chartPanComponent);
|
|
41
46
|
this.addChildEntity(dndHelper);
|
|
42
47
|
}
|
|
@@ -12,7 +12,7 @@ import EventBus from '../events/event-bus';
|
|
|
12
12
|
import { DeepPartial } from '../utils/object.utils';
|
|
13
13
|
import { Candle } from './candle.model';
|
|
14
14
|
import { DataSeriesType } from './data-series.config';
|
|
15
|
-
import { DataSeriesModel } from './data-series.model';
|
|
15
|
+
import { DataSeriesModel, DataSeriesViewportIndexes } from './data-series.model';
|
|
16
16
|
import { HighLowWithIndex, ScaleModel } from './scale.model';
|
|
17
17
|
import { Unit } from './scaling/viewport.model';
|
|
18
18
|
import VisualCandle from './visual-candle';
|
|
@@ -44,6 +44,15 @@ export declare class CandleSeriesModel extends DataSeriesModel<Candle, VisualCan
|
|
|
44
44
|
* @returns {void}
|
|
45
45
|
*/
|
|
46
46
|
recalculateDataViewportIndexes(xStart?: number, xEnd?: number): void;
|
|
47
|
+
/**
|
|
48
|
+
* Calculates and returns the indexes of the start and end points of the data viewport,
|
|
49
|
+
* based on the given start and end units on the x-axis.
|
|
50
|
+
*
|
|
51
|
+
* @param {Unit} xStart - The start value of the viewport on the x-axis.
|
|
52
|
+
* @param {Unit} xEnd - The end value of the viewport on the x-axis.
|
|
53
|
+
* @returns {DataSeriesViewportIndexes} An object containing the calculated start and end indexes of the data viewport.
|
|
54
|
+
*/
|
|
55
|
+
calculateDataViewportIndexes(xStart: Unit, xEnd: Unit): DataSeriesViewportIndexes;
|
|
47
56
|
/**
|
|
48
57
|
* Calculates the price movement of the last candle by comparing the open and close prices.
|
|
49
58
|
* Sets the lastPriceMovement property of the instance with the name of the direction of the price movement.
|
|
@@ -7,7 +7,7 @@ import { Subject } from 'rxjs';
|
|
|
7
7
|
import { getDefaultConfig } from '../chart.config';
|
|
8
8
|
import { defaultCandleTransformer } from '../components/chart/candle-transformer.functions';
|
|
9
9
|
import { calculateCandleWidth } from '../components/chart/candle-width-calculator.functions';
|
|
10
|
-
import { lastOf } from '../utils/array.utils';
|
|
10
|
+
import { binarySearch, lastOf } from '../utils/array.utils';
|
|
11
11
|
import { merge } from '../utils/merge.utils';
|
|
12
12
|
import { PriceIncrementsUtils } from '../utils/price-increments.utils';
|
|
13
13
|
import { calculateCandlesHighLow, createCandleSeriesHighLowProvider } from './candle-series-high-low.provider';
|
|
@@ -58,10 +58,28 @@ export class CandleSeriesModel extends DataSeriesModel {
|
|
|
58
58
|
* @returns {void}
|
|
59
59
|
*/
|
|
60
60
|
recalculateDataViewportIndexes(xStart = this.scale.xStart, xEnd = this.scale.xEnd) {
|
|
61
|
-
|
|
61
|
+
const { dataIdxStart, dataIdxEnd } = this.calculateDataViewportIndexes(xStart, xEnd);
|
|
62
|
+
this.dataIdxStart = dataIdxStart;
|
|
63
|
+
this.dataIdxEnd = dataIdxEnd;
|
|
62
64
|
this.recalculateZippedHighLow();
|
|
63
65
|
this.eventBus.fireDraw();
|
|
64
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* Calculates and returns the indexes of the start and end points of the data viewport,
|
|
69
|
+
* based on the given start and end units on the x-axis.
|
|
70
|
+
*
|
|
71
|
+
* @param {Unit} xStart - The start value of the viewport on the x-axis.
|
|
72
|
+
* @param {Unit} xEnd - The end value of the viewport on the x-axis.
|
|
73
|
+
* @returns {DataSeriesViewportIndexes} An object containing the calculated start and end indexes of the data viewport.
|
|
74
|
+
*/
|
|
75
|
+
calculateDataViewportIndexes(xStart, xEnd) {
|
|
76
|
+
const dataIdxStart = binarySearch(this.visualPoints, xStart, (it) => it.startUnit).index;
|
|
77
|
+
const dataIdxEnd = binarySearch(this.visualPoints, xEnd, (it) => it.startUnit).index;
|
|
78
|
+
return {
|
|
79
|
+
dataIdxStart,
|
|
80
|
+
dataIdxEnd,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
65
83
|
/**
|
|
66
84
|
* Calculates the price movement of the last candle by comparing the open and close prices.
|
|
67
85
|
* Sets the lastPriceMovement property of the instance with the name of the direction of the price movement.
|
|
@@ -46,12 +46,14 @@ export declare abstract class ChartBaseElement implements ChartEntity {
|
|
|
46
46
|
* Enables the functionality of an object.
|
|
47
47
|
* If the object is not currently active, it sets the state to 'deactivated' and activates it.
|
|
48
48
|
* @returns {void}
|
|
49
|
+
* @deprecated use `ChartBaseElement.activate()` instead
|
|
49
50
|
*/
|
|
50
51
|
enable(): void;
|
|
51
52
|
/**
|
|
52
53
|
* Disables the current object if it is not already disabled.
|
|
53
54
|
* If the object is not disabled, it will be deactivated and its state will be set to 'disabled'.
|
|
54
55
|
* @returns {void}
|
|
56
|
+
* @deprecated use `ChartBaseElement.deactivate()` instead
|
|
55
57
|
*/
|
|
56
58
|
disable(): void;
|
|
57
59
|
/**
|
|
@@ -34,6 +34,7 @@ export class ChartBaseElement {
|
|
|
34
34
|
* Enables the functionality of an object.
|
|
35
35
|
* If the object is not currently active, it sets the state to 'deactivated' and activates it.
|
|
36
36
|
* @returns {void}
|
|
37
|
+
* @deprecated use `ChartBaseElement.activate()` instead
|
|
37
38
|
*/
|
|
38
39
|
enable() {
|
|
39
40
|
if (this._state !== 'active') {
|
|
@@ -45,6 +46,7 @@ export class ChartBaseElement {
|
|
|
45
46
|
* Disables the current object if it is not already disabled.
|
|
46
47
|
* If the object is not disabled, it will be deactivated and its state will be set to 'disabled'.
|
|
47
48
|
* @returns {void}
|
|
49
|
+
* @deprecated use `ChartBaseElement.deactivate()` instead
|
|
48
50
|
*/
|
|
49
51
|
disable() {
|
|
50
52
|
if (this._state !== 'disabled') {
|
|
@@ -138,7 +138,9 @@ export class DataSeriesModel extends ChartBaseElement {
|
|
|
138
138
|
}
|
|
139
139
|
doActivate() {
|
|
140
140
|
this.addRxSubscription(this.scale.xChanged.subscribe(() => this.recalculateDataViewportIndexes()));
|
|
141
|
-
this.addRxSubscription(this.scale.scaleInversedSubject.subscribe(() => {
|
|
141
|
+
this.addRxSubscription(this.scale.scaleInversedSubject.subscribe(() => {
|
|
142
|
+
this.recalculateVisualPoints();
|
|
143
|
+
}));
|
|
142
144
|
}
|
|
143
145
|
/**
|
|
144
146
|
* Sets the data points and recalculates internal state
|
|
@@ -215,8 +217,8 @@ export class DataSeriesModel extends ChartBaseElement {
|
|
|
215
217
|
* @returns {DataSeriesViewportIndexes} An object containing the calculated start and end indexes of the data viewport.
|
|
216
218
|
*/
|
|
217
219
|
calculateDataViewportIndexes(xStart, xEnd) {
|
|
218
|
-
const dataIdxStart = binarySearch(this.visualPoints, xStart, i => i.centerUnit).index;
|
|
219
|
-
const dataIdxEnd = binarySearch(this.visualPoints, xEnd, i => i.centerUnit).index;
|
|
220
|
+
const dataIdxStart = binarySearch(this.visualPoints, xStart, (i) => i.centerUnit).index;
|
|
221
|
+
const dataIdxEnd = binarySearch(this.visualPoints, xEnd, (i) => i.centerUnit).index;
|
|
220
222
|
return {
|
|
221
223
|
dataIdxStart,
|
|
222
224
|
dataIdxEnd,
|
|
@@ -9,10 +9,10 @@ export interface TimeFormatterConfig {
|
|
|
9
9
|
shortMonths?: string[];
|
|
10
10
|
}
|
|
11
11
|
export interface DateTimeFormatter {
|
|
12
|
-
(date:
|
|
12
|
+
(date: number): string;
|
|
13
13
|
}
|
|
14
14
|
export type DateTimeFormatterFactory = (format: string) => DateTimeFormatter;
|
|
15
|
-
export declare const defaultDateTimeFormatter: () => (date:
|
|
15
|
+
export declare const defaultDateTimeFormatter: () => (date: number) => string;
|
|
16
16
|
/**
|
|
17
17
|
* Default chart-core time formatter.
|
|
18
18
|
* @param config
|
|
@@ -20,4 +20,21 @@ export declare const defaultDateTimeFormatter: () => (date: Date | number) => st
|
|
|
20
20
|
* @doc-tags chart-core,default-config,date-formatter
|
|
21
21
|
*/
|
|
22
22
|
export declare const dateTimeFormatterFactory: (config: FullChartConfig, offsetFunction: (timezone: string) => (time: number) => Date) => DateTimeFormatterFactory;
|
|
23
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Returns an array of short day names based on the provided configuration object.
|
|
25
|
+
* If the configuration object does not contain shortDays property, it returns an array of default short day names.
|
|
26
|
+
*
|
|
27
|
+
* @param {TimeFormatterConfig} config - The configuration object containing shortDays property.
|
|
28
|
+
* @returns {string[]} - An array of short day names.
|
|
29
|
+
*/
|
|
30
|
+
export declare function getShortDays(config: TimeFormatterConfig): string[];
|
|
31
|
+
/**
|
|
32
|
+
* Returns an array of short month names based on the provided configuration object.
|
|
33
|
+
* If the configuration object does not have a 'shortMonths' property, it returns the default array of short month names.
|
|
34
|
+
*
|
|
35
|
+
* @param {TimeFormatterConfig} config - The configuration object that contains the shortMonths property.
|
|
36
|
+
* @returns {string[]} - An array of short month names.
|
|
37
|
+
*/
|
|
38
|
+
export declare function getShortMonths(config: TimeFormatterConfig): string[];
|
|
39
|
+
export declare const recalculateXFormatter: (xAxisLabelFormat: string | Array<DateTimeFormatConfig>, period: number, formatterFactory: (format: string) => (timestamp: number) => string) => DateTimeFormatter;
|
|
40
|
+
export declare const formatDate: (date: Date, patternStr: string, daysOfWeek: string[], months: string[]) => string;
|
|
@@ -31,7 +31,6 @@ export const dateTimeFormatterFactory = (config, offsetFunction) => {
|
|
|
31
31
|
['s', 'm', 'H', 'd', 'M'].forEach(function (k) {
|
|
32
32
|
patterns[k + k] = 'this.' + 'addZero' + '(' + patterns[k] + ')';
|
|
33
33
|
});
|
|
34
|
-
const re = new RegExp(Object.keys(patterns).sort().reverse().join('|'), 'g');
|
|
35
34
|
/**
|
|
36
35
|
* Returns a string that concatenates the result of the function getPrefix with the input string fn and the string '()'.
|
|
37
36
|
* @param {string} fn - The input string to concatenate.
|
|
@@ -58,14 +57,6 @@ export const dateTimeFormatterFactory = (config, offsetFunction) => {
|
|
|
58
57
|
function upperCase(fn) {
|
|
59
58
|
return fn + '.toUpperCase()';
|
|
60
59
|
}
|
|
61
|
-
/**
|
|
62
|
-
* Returns a string that concatenates a pattern from an object with a string
|
|
63
|
-
* @param {string} pattern - The key of the pattern to be concatenated
|
|
64
|
-
* @returns {string} - A string that concatenates a pattern from an object with a string
|
|
65
|
-
*/
|
|
66
|
-
function applyPattern(pattern) {
|
|
67
|
-
return "' + (" + patterns[pattern] + ") + '";
|
|
68
|
-
}
|
|
69
60
|
return function (pattern) {
|
|
70
61
|
var _a;
|
|
71
62
|
const context = {
|
|
@@ -89,11 +80,10 @@ export const dateTimeFormatterFactory = (config, offsetFunction) => {
|
|
|
89
80
|
},
|
|
90
81
|
tzDate: offsetFunction((_a = config.timezone) !== null && _a !== void 0 ? _a : '') ||
|
|
91
82
|
function (date) {
|
|
92
|
-
return
|
|
83
|
+
return new Date(+date);
|
|
93
84
|
},
|
|
94
85
|
};
|
|
95
|
-
|
|
96
|
-
return new Function('date', 'date=this.' + 'tzDate' + "(date); return '" + pattern.replace(re, applyPattern) + "'").bind(context);
|
|
86
|
+
return (date) => formatDate(context.tzDate(date), pattern, context.shortDays, context.shortMonths);
|
|
97
87
|
};
|
|
98
88
|
};
|
|
99
89
|
/**
|
|
@@ -103,7 +93,7 @@ export const dateTimeFormatterFactory = (config, offsetFunction) => {
|
|
|
103
93
|
* @param {TimeFormatterConfig} config - The configuration object containing shortDays property.
|
|
104
94
|
* @returns {string[]} - An array of short day names.
|
|
105
95
|
*/
|
|
106
|
-
function getShortDays(config) {
|
|
96
|
+
export function getShortDays(config) {
|
|
107
97
|
var _a;
|
|
108
98
|
return (_a = config.shortDays) !== null && _a !== void 0 ? _a : ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
|
|
109
99
|
}
|
|
@@ -114,7 +104,7 @@ function getShortDays(config) {
|
|
|
114
104
|
* @param {TimeFormatterConfig} config - The configuration object that contains the shortMonths property.
|
|
115
105
|
* @returns {string[]} - An array of short month names.
|
|
116
106
|
*/
|
|
117
|
-
function getShortMonths(config) {
|
|
107
|
+
export function getShortMonths(config) {
|
|
118
108
|
var _a;
|
|
119
109
|
return (_a = config.shortMonths) !== null && _a !== void 0 ? _a : ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
|
120
110
|
}
|
|
@@ -154,3 +144,61 @@ export const recalculateXFormatter = (xAxisLabelFormat, period, formatterFactory
|
|
|
154
144
|
}
|
|
155
145
|
return defaultDateTimeFormatter();
|
|
156
146
|
};
|
|
147
|
+
//#region Custom date pattern parser, transforms Date object to string by given pattern
|
|
148
|
+
// examples: dd.MM => 15.12, YYYY => 2024, HH:mm => 15:56
|
|
149
|
+
export const formatDate = (date, patternStr, daysOfWeek, months) => {
|
|
150
|
+
if (!patternStr) {
|
|
151
|
+
patternStr = 'M/d/yyyy';
|
|
152
|
+
}
|
|
153
|
+
const day = date.getDate();
|
|
154
|
+
const month = date.getMonth();
|
|
155
|
+
const year = date.getFullYear();
|
|
156
|
+
const hour = date.getHours();
|
|
157
|
+
const minute = date.getMinutes();
|
|
158
|
+
const second = date.getSeconds();
|
|
159
|
+
const miliseconds = date.getMilliseconds();
|
|
160
|
+
const h = hour % 12;
|
|
161
|
+
const hh = twoDigitPad(h);
|
|
162
|
+
const HH = twoDigitPad(hour);
|
|
163
|
+
const mm = twoDigitPad(minute);
|
|
164
|
+
const ss = twoDigitPad(second);
|
|
165
|
+
const aaa = hour < 12 ? 'AM' : 'PM';
|
|
166
|
+
const EEEE = daysOfWeek[date.getDay()];
|
|
167
|
+
const EEE = EEEE.substring(0, 3);
|
|
168
|
+
const dd = twoDigitPad(day);
|
|
169
|
+
const M = month + 1;
|
|
170
|
+
const MM = twoDigitPad(M);
|
|
171
|
+
const MMMM = months[month];
|
|
172
|
+
const MMM = MMMM.substring(0, 3);
|
|
173
|
+
const yyyy = year + '';
|
|
174
|
+
const yy = yyyy.substring(2, 4);
|
|
175
|
+
// checks to see if month name will be used
|
|
176
|
+
patternStr = patternStr
|
|
177
|
+
.replace('hh', hh + '')
|
|
178
|
+
.replace('h', h + '')
|
|
179
|
+
.replace('HH', HH + '')
|
|
180
|
+
.replace('H', hour + '')
|
|
181
|
+
.replace('mm', mm + '')
|
|
182
|
+
.replace('m', minute + '')
|
|
183
|
+
.replace('ss', ss + '')
|
|
184
|
+
.replace('s', second + '')
|
|
185
|
+
.replace('S', miliseconds + '')
|
|
186
|
+
.replace('dd', dd + '')
|
|
187
|
+
.replace('d', day + '')
|
|
188
|
+
.replace('EEEE', EEEE)
|
|
189
|
+
.replace('EEE', EEE)
|
|
190
|
+
.replace('YYYY', yyyy)
|
|
191
|
+
.replace('yyyy', yyyy)
|
|
192
|
+
.replace('YY', yy)
|
|
193
|
+
.replace('yy', yy)
|
|
194
|
+
.replace('aaa', aaa);
|
|
195
|
+
if (patternStr.indexOf('MMM') > -1) {
|
|
196
|
+
patternStr = patternStr.replace('MMMM', MMMM).replace('MMM', MMM);
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
patternStr = patternStr.replace('MM', MM + '').replace('M', M + '');
|
|
200
|
+
}
|
|
201
|
+
return patternStr;
|
|
202
|
+
};
|
|
203
|
+
const twoDigitPad = (num) => (typeof num === 'number' && num < 10 ? '0' + num : num);
|
|
204
|
+
//#endregion
|
|
@@ -46,6 +46,10 @@ export declare class ScaleModel extends ViewportModel {
|
|
|
46
46
|
zoomXYRatio: ZoomXToZoomYRatio;
|
|
47
47
|
offsets: ChartConfigComponentsOffsets;
|
|
48
48
|
xConstraints: Constraints[];
|
|
49
|
+
maxZoomReached: {
|
|
50
|
+
zoomIn: boolean;
|
|
51
|
+
zoomOut: boolean;
|
|
52
|
+
};
|
|
49
53
|
readonly state: ChartScale;
|
|
50
54
|
constructor(config: FullChartConfig, getBounds: BoundsProvider, canvasAnimation: CanvasAnimation);
|
|
51
55
|
protected doActivate(): void;
|
|
@@ -82,6 +86,7 @@ export declare class ScaleModel extends ViewportModel {
|
|
|
82
86
|
zoomXToEnd(zoomIn: boolean, zoomSensitivity: number): void;
|
|
83
87
|
haltAnimation(): void;
|
|
84
88
|
private zoomXTo;
|
|
89
|
+
isMaxZoomXReached(zoomIn: boolean): boolean;
|
|
85
90
|
/**
|
|
86
91
|
* Moves the viewport to exactly xStart..xEnd place.
|
|
87
92
|
* (you need to fire DRAW event after this)
|
|
@@ -41,6 +41,7 @@ export class ScaleModel extends ViewportModel {
|
|
|
41
41
|
this.history = [];
|
|
42
42
|
this.zoomXYRatio = 0;
|
|
43
43
|
this.xConstraints = [];
|
|
44
|
+
this.maxZoomReached = { zoomIn: false, zoomOut: false };
|
|
44
45
|
this.scalePostProcessor = (initialState, state) => {
|
|
45
46
|
// for now <s>reduceRight<s/> reduce bcs ChartModel#getZoomConstrait should be invoked first
|
|
46
47
|
// if we will need more complex order handling -> add some managing
|
|
@@ -49,7 +50,11 @@ export class ScaleModel extends ViewportModel {
|
|
|
49
50
|
this.state = cloneUnsafe(config.scale);
|
|
50
51
|
this.autoScaleModel = new AutoScaleViewportSubModel(this);
|
|
51
52
|
this.offsets = this.config.components.offsets;
|
|
52
|
-
this.addXConstraint((initialState, state) =>
|
|
53
|
+
this.addXConstraint((initialState, state) => {
|
|
54
|
+
const { maxZoomReached, newState } = zoomConstraint(initialState, state, this.config.components.chart, this.getBounds);
|
|
55
|
+
this.maxZoomReached = maxZoomReached;
|
|
56
|
+
return newState;
|
|
57
|
+
});
|
|
53
58
|
}
|
|
54
59
|
doActivate() {
|
|
55
60
|
super.doActivate();
|
|
@@ -141,6 +146,9 @@ export class ScaleModel extends ViewportModel {
|
|
|
141
146
|
startViewportModelAnimation(this.canvasAnimation, this, constrainedState);
|
|
142
147
|
}
|
|
143
148
|
}
|
|
149
|
+
isMaxZoomXReached(zoomIn) {
|
|
150
|
+
return (this.maxZoomReached.zoomIn && zoomIn) || (this.maxZoomReached.zoomOut && !zoomIn);
|
|
151
|
+
}
|
|
144
152
|
/**
|
|
145
153
|
* Moves the viewport to exactly xStart..xEnd place.
|
|
146
154
|
* (you need to fire DRAW event after this)
|
|
@@ -33,11 +33,9 @@ export declare const candleEdgesConstrait: (state: ViewportModelState, visualCan
|
|
|
33
33
|
* @doc-tags viewport,zoom,scaling
|
|
34
34
|
*/
|
|
35
35
|
export declare const zoomConstraint: (_: ViewportModelState, state: ViewportModelState, chartConfig: ChartConfigComponentsChart, boundsProvider: BoundsProvider) => {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
zoomY: number;
|
|
42
|
-
inverseY: boolean;
|
|
36
|
+
newState: ViewportModelState;
|
|
37
|
+
maxZoomReached: {
|
|
38
|
+
zoomIn: boolean;
|
|
39
|
+
zoomOut: boolean;
|
|
40
|
+
};
|
|
43
41
|
};
|
|
@@ -53,13 +53,13 @@ export const zoomConstraint = (_, state, chartConfig, boundsProvider) => {
|
|
|
53
53
|
if (maxViewportReached) {
|
|
54
54
|
newState.xStart = newState.xEnd - maxCandlesInViewport;
|
|
55
55
|
newState.zoomX = calculateZoom(newState.xEnd - newState.xStart, bounds.width);
|
|
56
|
-
return newState;
|
|
56
|
+
return { newState, maxZoomReached: { zoomOut: true, zoomIn: false } };
|
|
57
57
|
}
|
|
58
58
|
if (minViewportReached) {
|
|
59
59
|
newState.xStart = newState.xEnd - chartConfig.minCandles;
|
|
60
60
|
newState.zoomX = calculateZoom(newState.xEnd - newState.xStart, bounds.width);
|
|
61
|
-
return newState;
|
|
61
|
+
return { newState, maxZoomReached: { zoomOut: false, zoomIn: true } };
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
|
-
return newState;
|
|
64
|
+
return { newState, maxZoomReached: { zoomOut: false, zoomIn: false } };
|
|
65
65
|
};
|
|
@@ -87,7 +87,9 @@ export class TimeZoneModel {
|
|
|
87
87
|
// In JS Date object is created with local tz offset,
|
|
88
88
|
// so we have to subtract localOffset from current time
|
|
89
89
|
return time => {
|
|
90
|
-
return new Date(time +
|
|
90
|
+
return new Date(time +
|
|
91
|
+
getTimezoneOffset(timezone, time) +
|
|
92
|
+
new Date(time).getTimezoneOffset() * timeMultiplier);
|
|
91
93
|
};
|
|
92
94
|
}
|
|
93
95
|
}
|
|
@@ -35,10 +35,10 @@ export function getDateTimeFormat(timeZone) {
|
|
|
35
35
|
export const getTimezoneOffset = (timeZone, timestamp = Date.now()) => {
|
|
36
36
|
const formatter = getDateTimeFormat(timeZone);
|
|
37
37
|
const dateString = formatter.format(timestamp);
|
|
38
|
-
// exec() returns [, fMonth, fDay, fYear, fHour, fMinute]
|
|
39
|
-
const tokens = /(\d+)\/(\d+)\/(\d+),? (\d+):(\d+)/.exec(dateString);
|
|
38
|
+
// exec() returns [, fMonth, fDay, fYear, fHour, fMinute, fSeconds]
|
|
39
|
+
const tokens = /(\d+)\/(\d+)\/(\d+),? (\d+):(\d+):(\d+)/.exec(dateString);
|
|
40
40
|
if (tokens) {
|
|
41
|
-
const asUTC = Date.UTC(+tokens[3], +tokens[1] - 1, +tokens[2], +tokens[4] % 24, +tokens[5],
|
|
41
|
+
const asUTC = Date.UTC(+tokens[3], +tokens[1] - 1, +tokens[2], +tokens[4] % 24, +tokens[5], +tokens[6]);
|
|
42
42
|
let asTimezone = timestamp;
|
|
43
43
|
const over = asTimezone % 1000;
|
|
44
44
|
asTimezone -= over >= 0 ? over : 1000 + over;
|