@devexperts/dxcharts-lite 2.3.0 → 2.4.1
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/bootstrap.js +4 -3
- package/dist/chart/canvas/canvas-bounds-container.js +5 -3
- package/dist/chart/canvas/cursor.handler.js +2 -2
- package/dist/chart/components/chart/chart-area-pan.handler.js +3 -3
- package/dist/chart/components/chart/chart.component.d.ts +6 -3
- package/dist/chart/components/chart/chart.component.js +18 -7
- package/dist/chart/components/chart/chart.model.d.ts +1 -2
- package/dist/chart/components/chart/chart.model.js +2 -3
- package/dist/chart/components/cross_tool/types/cross-and-labels.drawer.js +4 -2
- package/dist/chart/components/high_low/high-low.drawer.js +9 -2
- package/dist/chart/components/highlights/highlights.drawer.js +1 -1
- package/dist/chart/components/pane/pane.component.js +6 -3
- package/dist/chart/components/volumes/volumes.drawer.js +1 -1
- package/dist/chart/components/x_axis/time/parser/time-formats-matchers.functions.js +1 -1
- package/dist/chart/components/x_axis/time/parser/time-formats.model.d.ts +1 -1
- package/dist/chart/components/x_axis/time/x-axis-weights.functions.js +2 -2
- package/dist/chart/components/x_axis/time/x-axis-weights.generator.js +6 -7
- package/dist/chart/components/x_axis/x-axis-labels.generator.d.ts +11 -3
- package/dist/chart/components/x_axis/x-axis-labels.generator.js +47 -19
- package/dist/chart/components/x_axis/x-axis-time-labels.drawer.js +0 -4
- package/dist/chart/components/x_axis/x-axis.component.js +7 -11
- package/dist/chart/components/y_axis/price_labels/last-candle-labels.provider.js +5 -5
- package/dist/chart/components/y_axis/price_labels/price-label.drawer.js +21 -22
- package/dist/chart/components/y_axis/y-axis-labels.drawer.d.ts +18 -6
- package/dist/chart/components/y_axis/y-axis-labels.drawer.js +23 -12
- package/dist/chart/components/y_axis/y-axis-scale.handler.d.ts +4 -0
- package/dist/chart/components/y_axis/y-axis-scale.handler.js +13 -6
- package/dist/chart/components/y_axis/y-axis.drawer.js +1 -1
- package/dist/chart/drawers/chart-background.drawer.d.ts +2 -3
- package/dist/chart/drawers/chart-background.drawer.js +16 -22
- package/dist/chart/drawers/data-series-drawers/candle-series-wrapper.js +1 -1
- package/dist/chart/drawers/data-series.drawer.d.ts +0 -2
- package/dist/chart/drawers/data-series.drawer.js +1 -6
- package/dist/chart/drawers/ht-data-series.drawer.js +1 -1
- package/dist/chart/inputhandlers/hover-producer.component.d.ts +1 -1
- package/dist/chart/model/compare-series-hover.d.ts +1 -1
- package/dist/chart/model/compare-series-hover.js +5 -0
- package/dist/chart/model/data-series.model.js +1 -1
- package/dist/chart/model/hit-test-canvas.model.js +2 -2
- package/dist/chart/model/scale.model.d.ts +3 -1
- package/dist/chart/model/scale.model.js +23 -4
- package/dist/chart/model/scaling/viewport.model.d.ts +2 -0
- package/dist/chart/model/scaling/viewport.model.js +13 -4
- package/dist/chart/model/time-zone.model.d.ts +0 -14
- package/dist/chart/model/time-zone.model.js +13 -33
- package/dist/chart/utils/canvas/canvas-drawing-functions.utils.d.ts +12 -1
- package/dist/chart/utils/canvas/canvas-drawing-functions.utils.js +16 -1
- package/dist/chart/utils/canvas/canvas-text-functions.utils.d.ts +3 -2
- package/dist/chart/utils/canvas/canvas-text-functions.utils.js +8 -3
- package/dist/chart/utils/math.utils.d.ts +1 -0
- package/dist/chart/utils/math.utils.js +3 -0
- package/dist/chart/utils/timezone.utils.d.ts +13 -0
- package/dist/chart/utils/timezone.utils.js +48 -0
- package/dist/dxchart.min.js +6 -6
- package/package.json +1 -2
|
@@ -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 { merge } from 'rxjs';
|
|
6
|
+
import { merge, animationFrameScheduler } from 'rxjs';
|
|
7
7
|
import { distinctUntilChanged, map, throttleTime, filter } from 'rxjs/operators';
|
|
8
8
|
import { CanvasElement } from '../../canvas/canvas-bounds-container';
|
|
9
9
|
import { ChartBaseElement } from '../../model/chart-base-element';
|
|
@@ -29,7 +29,7 @@ export class XAxisComponent extends ChartBaseElement {
|
|
|
29
29
|
this.scale = scale;
|
|
30
30
|
this.chartResizeHandler = chartResizeHandler;
|
|
31
31
|
this.timeZoneModel = timeZoneModel;
|
|
32
|
-
const xAxisLabelsGenerator = new XAxisTimeLabelsGenerator(eventBus, config, chartComponent.chartModel, scale, timeZoneModel, this.canvasModel);
|
|
32
|
+
const xAxisLabelsGenerator = new XAxisTimeLabelsGenerator(eventBus, config, chartComponent.chartModel, scale, timeZoneModel, this.canvasModel, canvasBoundsContainer);
|
|
33
33
|
this.xAxisLabelsGenerator = xAxisLabelsGenerator;
|
|
34
34
|
this.xAxisLabelsModel = new XAxisLabelsModel(eventBus, []);
|
|
35
35
|
const xAxisCompositeDrawer = new CompositeDrawer();
|
|
@@ -56,26 +56,22 @@ export class XAxisComponent extends ChartBaseElement {
|
|
|
56
56
|
this.xAxisLabelsGenerator.generateLabels();
|
|
57
57
|
}));
|
|
58
58
|
this.addRxSubscription(this.chartComponent.chartModel.candlesPrependSubject
|
|
59
|
-
.pipe(filter(({ prependedCandles }) => prependedCandles.length !== 0), map(({ prependedCandles }) =>
|
|
60
|
-
return this.chartComponent.chartModel.mainCandleSeries.visualPoints.slice(0, prependedCandles.length);
|
|
61
|
-
}))
|
|
59
|
+
.pipe(filter(({ prependedCandles }) => prependedCandles.length !== 0), map(({ prependedCandles }) => this.chartComponent.chartModel.mainCandleSeries.visualPoints.slice(0, prependedCandles.length)))
|
|
62
60
|
.subscribe(newCandles => {
|
|
61
|
+
var _a, _b;
|
|
63
62
|
//@ts-ignore
|
|
64
63
|
if (availableBarTypes.includes(this.config.components.chart.type)) {
|
|
65
|
-
this.xAxisLabelsGenerator.updateHistoryLabels
|
|
66
|
-
this.xAxisLabelsGenerator.updateHistoryLabels(newCandles);
|
|
64
|
+
(_b = (_a = this.xAxisLabelsGenerator).updateHistoryLabels) === null || _b === void 0 ? void 0 : _b.call(_a, newCandles);
|
|
67
65
|
}
|
|
68
66
|
}));
|
|
69
67
|
this.addRxSubscription(merge(this.scale.xChanged, this.chartResizeHandler.canvasResized)
|
|
70
|
-
.pipe(throttleTime(50,
|
|
68
|
+
.pipe(throttleTime(50, animationFrameScheduler, { trailing: true, leading: true }))
|
|
71
69
|
.subscribe(() => {
|
|
72
70
|
this.xAxisLabelsGenerator.recalculateLabels();
|
|
73
71
|
}));
|
|
74
72
|
this.addRxSubscription(this.chartComponent.chartModel.candlesUpdatedSubject
|
|
75
73
|
.pipe(map(() => lastOf(this.chartComponent.chartModel.mainCandleSeries.visualPoints)), distinctUntilChanged((a, b) => { var _a, _b; return ((_a = a === null || a === void 0 ? void 0 : a.candle) === null || _a === void 0 ? void 0 : _a.timestamp) === ((_b = b === null || b === void 0 ? void 0 : b.candle) === null || _b === void 0 ? void 0 : _b.timestamp); }), filter(notEmpty))
|
|
76
|
-
.subscribe(x => {
|
|
77
|
-
this.xAxisLabelsGenerator.updateLastLabel && this.xAxisLabelsGenerator.updateLastLabel(x);
|
|
78
|
-
}));
|
|
74
|
+
.subscribe(x => { var _a, _b; return (_b = (_a = this.xAxisLabelsGenerator) === null || _a === void 0 ? void 0 : _a.updateLastLabel) === null || _b === void 0 ? void 0 : _b.call(_a, x); }));
|
|
79
75
|
}
|
|
80
76
|
/**
|
|
81
77
|
* Returns the xAxisDrawer object.
|
|
@@ -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 {
|
|
6
|
+
import { getPrimaryLabelTextColor } from '../label-color.functions';
|
|
7
7
|
import { lastOf } from '../../../utils/array.utils';
|
|
8
8
|
import { getLabelTextColorByBackgroundColor } from '../../../utils/canvas/canvas-text-functions.utils';
|
|
9
9
|
export class LastCandleLabelsProvider {
|
|
@@ -87,7 +87,7 @@ export class LastCandleLabelsProvider {
|
|
|
87
87
|
const appearanceType = this.yAxisConfig.labels.settings.lastPrice.type;
|
|
88
88
|
const colors = series.colors.labels;
|
|
89
89
|
const { rectLabelTextColor = 'white', rectLabelInvertedTextColor = 'black' } = this.chartConfig.colors.yAxis;
|
|
90
|
-
const
|
|
90
|
+
const getLabelColorBySeries = this.resolveLabelColorFn(series.config.type);
|
|
91
91
|
if (!colors) {
|
|
92
92
|
return {
|
|
93
93
|
bgColor: '#FFFFFF',
|
|
@@ -95,14 +95,14 @@ export class LastCandleLabelsProvider {
|
|
|
95
95
|
rounded: true,
|
|
96
96
|
};
|
|
97
97
|
}
|
|
98
|
-
const boxColor =
|
|
98
|
+
const boxColor = getLabelColorBySeries(series.lastPriceMovement, series.colors);
|
|
99
99
|
// if the label is for the main candle series
|
|
100
100
|
if (primary) {
|
|
101
101
|
const textColor = getPrimaryLabelTextColor(series.lastPriceMovement, colors);
|
|
102
102
|
return {
|
|
103
103
|
bgColor: boxColor,
|
|
104
104
|
textColor: appearanceType === 'plain'
|
|
105
|
-
?
|
|
105
|
+
? getLabelColorBySeries(series.lastPriceMovement, series.colors)
|
|
106
106
|
: getLabelTextColorByBackgroundColor(boxColor, textColor, rectLabelInvertedTextColor),
|
|
107
107
|
rounded: true,
|
|
108
108
|
};
|
|
@@ -111,7 +111,7 @@ export class LastCandleLabelsProvider {
|
|
|
111
111
|
return {
|
|
112
112
|
bgColor: boxColor,
|
|
113
113
|
textColor: appearanceType === 'plain'
|
|
114
|
-
?
|
|
114
|
+
? getLabelColorBySeries(series.lastPriceMovement, series.colors)
|
|
115
115
|
: getLabelTextColorByBackgroundColor(boxColor, rectLabelTextColor, rectLabelInvertedTextColor),
|
|
116
116
|
rounded: true,
|
|
117
117
|
};
|
|
@@ -9,7 +9,7 @@ import { redrawBackgroundArea } from '../../../drawers/chart-background.drawer';
|
|
|
9
9
|
import { avoidAntialiasing, drawLine } from '../../../utils/canvas/canvas-drawing-functions.utils';
|
|
10
10
|
import { calculateSymbolHeight, calculateTextWidth } from '../../../utils/canvas/canvas-font-measure-tool.utils';
|
|
11
11
|
import { floor } from '../../../utils/math.utils';
|
|
12
|
-
import { drawBadgeLabel, drawPlainLabel, drawRectLabel } from '../y-axis-labels.drawer';
|
|
12
|
+
import { drawBadgeLabel, drawPlainLabel, drawRectLabel, checkLabelInBoundaries } from '../y-axis-labels.drawer';
|
|
13
13
|
export const DEFAULT_LABEL_APPEARANCE_TYPE = 'badge';
|
|
14
14
|
const DEFAULT_PADDING = 4;
|
|
15
15
|
export const priceLabelDrawersMap = {
|
|
@@ -66,22 +66,26 @@ export function drawLabel(ctx, backgroundCtx, bounds, paneBounds, visualLabel, c
|
|
|
66
66
|
const lineY = (_e = visualLabel.lineY) !== null && _e !== void 0 ? _e : visualLabel.y;
|
|
67
67
|
const _drawLine = () => showLine && avoidAntialiasing(ctx, () => drawLine(ctx, lineXStart, lineY, lineXEnd, lineY, 1));
|
|
68
68
|
const _drawLabel = () => drawLabel(ctx, bounds, text, centralY, visualLabel, config, colors, false, backgroundCtx);
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
69
|
+
const drawLineLabel = () => {
|
|
70
|
+
_drawLine();
|
|
71
|
+
_drawDescription();
|
|
72
|
+
};
|
|
73
|
+
const drawLineLabelLabel = () => {
|
|
74
|
+
_drawLine();
|
|
75
|
+
_drawLabel();
|
|
76
|
+
_drawDescription();
|
|
77
|
+
};
|
|
78
|
+
const drawLabelLabel = () => {
|
|
79
|
+
_drawDescription();
|
|
80
|
+
_drawLabel();
|
|
81
|
+
};
|
|
82
|
+
const labelDrawerByMode = {
|
|
83
|
+
'line': drawLineLabel,
|
|
84
|
+
'line-label': drawLineLabelLabel,
|
|
85
|
+
'label': drawLabelLabel,
|
|
86
|
+
};
|
|
87
|
+
if (mode !== 'none' && checkLabelInBoundaries(centralY, bounds, labelBoxHeight)) {
|
|
88
|
+
labelDrawerByMode[mode]();
|
|
85
89
|
}
|
|
86
90
|
ctx.restore();
|
|
87
91
|
}
|
|
@@ -101,11 +105,6 @@ function drawDescription(backgroundCtx, ctx, labelBounds, paneBounds, visualLabe
|
|
|
101
105
|
const labelBoxY = centralY - fontHeight / 2 - paddingTop;
|
|
102
106
|
const labelBoxBottom = centralY + fontHeight / 2 + paddingBottom;
|
|
103
107
|
const labelBoxHeight = labelBoxBottom - labelBoxY;
|
|
104
|
-
// do not draw, if description is out of bounds
|
|
105
|
-
if (centralY < labelBounds.y + labelBoxHeight / 2 ||
|
|
106
|
-
centralY > labelBounds.y + labelBounds.height - labelBoxHeight / 2) {
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
108
|
ctx.save();
|
|
110
109
|
// overlay rect
|
|
111
110
|
const width = descriptionWidth + 5;
|
|
@@ -34,10 +34,11 @@ export declare const DEFAULT_PRICE_LABEL_PADDING = 4;
|
|
|
34
34
|
* @param text - text to draw
|
|
35
35
|
* @param centralY - y
|
|
36
36
|
* @param config - label styles config
|
|
37
|
-
* @param align
|
|
38
37
|
* @param yAxisState
|
|
38
|
+
* @param yAxisColors
|
|
39
|
+
* @param checkBoundaries
|
|
39
40
|
*/
|
|
40
|
-
export declare function drawBadgeLabel(ctx: CanvasRenderingContext2D, bounds: Bounds, text: string, centralY: number, config: YAxisLabelDrawConfig, yAxisState: YAxisConfig, yAxisColors: FullChartColors['yAxis'],
|
|
41
|
+
export declare function drawBadgeLabel(ctx: CanvasRenderingContext2D, bounds: Bounds, text: string, centralY: number, config: YAxisLabelDrawConfig, yAxisState: YAxisConfig, yAxisColors: FullChartColors['yAxis'], checkBoundaries?: boolean): void;
|
|
41
42
|
/**
|
|
42
43
|
* Draws rectangle label on Y axis with provided parameters.
|
|
43
44
|
* @param ctx - canvas 2D context to draw on
|
|
@@ -45,10 +46,11 @@ export declare function drawBadgeLabel(ctx: CanvasRenderingContext2D, bounds: Bo
|
|
|
45
46
|
* @param text - text to draw
|
|
46
47
|
* @param centralY - y
|
|
47
48
|
* @param config - label styles config
|
|
48
|
-
* @param align
|
|
49
49
|
* @param yAxisState
|
|
50
|
+
* @param yAxisColors
|
|
51
|
+
* @param checkBoundaries
|
|
50
52
|
*/
|
|
51
|
-
export declare function drawRectLabel(ctx: CanvasRenderingContext2D, bounds: Bounds, text: string, centralY: number, config: YAxisLabelDrawConfig, yAxisState: YAxisConfig, yAxisColors: FullChartColors['yAxis'],
|
|
53
|
+
export declare function drawRectLabel(ctx: CanvasRenderingContext2D, bounds: Bounds, text: string, centralY: number, config: YAxisLabelDrawConfig, yAxisState: YAxisConfig, yAxisColors: FullChartColors['yAxis'], checkBoundaries?: boolean): void;
|
|
52
54
|
/**
|
|
53
55
|
* Draws rectangle label on Y axis with provided parameters but with transparent background.
|
|
54
56
|
* @param ctx - canvas 2D context to draw on
|
|
@@ -56,10 +58,12 @@ export declare function drawRectLabel(ctx: CanvasRenderingContext2D, bounds: Bou
|
|
|
56
58
|
* @param text - text to draw
|
|
57
59
|
* @param centralY - y
|
|
58
60
|
* @param config - label styles config
|
|
59
|
-
* @param align
|
|
60
61
|
* @param yAxisState
|
|
62
|
+
* @param yAxisColors
|
|
63
|
+
* @param checkBoundaries
|
|
64
|
+
* @param backgroundCtx
|
|
61
65
|
*/
|
|
62
|
-
export declare function drawPlainLabel(ctx: CanvasRenderingContext2D, bounds: Bounds, text: string, centralY: number, config: YAxisLabelDrawConfig, yAxisState: YAxisConfig, yAxisColors: FullChartColors['yAxis'],
|
|
66
|
+
export declare function drawPlainLabel(ctx: CanvasRenderingContext2D, bounds: Bounds, text: string, centralY: number, config: YAxisLabelDrawConfig, yAxisState: YAxisConfig, yAxisColors: FullChartColors['yAxis'], checkBoundaries?: boolean, backgroundCtx?: CanvasRenderingContext2D): void;
|
|
63
67
|
/**
|
|
64
68
|
* Offset from the center of label to the top/bottom.
|
|
65
69
|
*
|
|
@@ -68,3 +72,11 @@ export declare function drawPlainLabel(ctx: CanvasRenderingContext2D, bounds: Bo
|
|
|
68
72
|
* @param paddingTop - extra padding from top
|
|
69
73
|
*/
|
|
70
74
|
export declare function getLabelYOffset(font: string, ctx: CanvasRenderingContext2D, paddingTop?: number): number;
|
|
75
|
+
/**
|
|
76
|
+
* Checks if label fits in chart scale boundaries
|
|
77
|
+
* @param centralY
|
|
78
|
+
* @param bounds
|
|
79
|
+
* @param labelBoxHeight
|
|
80
|
+
* returns true if label fits
|
|
81
|
+
*/
|
|
82
|
+
export declare function checkLabelInBoundaries(centralY: number, bounds: Bounds, labelBoxHeight: number): boolean;
|
|
@@ -17,10 +17,11 @@ export const DEFAULT_PRICE_LABEL_PADDING = 4;
|
|
|
17
17
|
* @param text - text to draw
|
|
18
18
|
* @param centralY - y
|
|
19
19
|
* @param config - label styles config
|
|
20
|
-
* @param align
|
|
21
20
|
* @param yAxisState
|
|
21
|
+
* @param yAxisColors
|
|
22
|
+
* @param checkBoundaries
|
|
22
23
|
*/
|
|
23
|
-
export function drawBadgeLabel(ctx, bounds, text, centralY, config, yAxisState, yAxisColors,
|
|
24
|
+
export function drawBadgeLabel(ctx, bounds, text, centralY, config, yAxisState, yAxisColors, checkBoundaries = true) {
|
|
24
25
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
25
26
|
const align = yAxisState.align;
|
|
26
27
|
const textFont = (_a = config.textFont) !== null && _a !== void 0 ? _a : getFontFromConfig(yAxisState);
|
|
@@ -34,8 +35,7 @@ export function drawBadgeLabel(ctx, bounds, text, centralY, config, yAxisState,
|
|
|
34
35
|
const labelBoxBottomY = centralY + halfFontHeight + paddingBottom;
|
|
35
36
|
const labelBoxHeight = labelBoxBottomY - labelBoxTopY;
|
|
36
37
|
// do not draw, if label is out of bounds
|
|
37
|
-
if (
|
|
38
|
-
!drawOutside) {
|
|
38
|
+
if (checkBoundaries && !checkLabelInBoundaries(centralY, bounds, labelBoxHeight)) {
|
|
39
39
|
return;
|
|
40
40
|
}
|
|
41
41
|
ctx.save();
|
|
@@ -64,10 +64,11 @@ export function drawBadgeLabel(ctx, bounds, text, centralY, config, yAxisState,
|
|
|
64
64
|
* @param text - text to draw
|
|
65
65
|
* @param centralY - y
|
|
66
66
|
* @param config - label styles config
|
|
67
|
-
* @param align
|
|
68
67
|
* @param yAxisState
|
|
68
|
+
* @param yAxisColors
|
|
69
|
+
* @param checkBoundaries
|
|
69
70
|
*/
|
|
70
|
-
export function drawRectLabel(ctx, bounds, text, centralY, config, yAxisState, yAxisColors,
|
|
71
|
+
export function drawRectLabel(ctx, bounds, text, centralY, config, yAxisState, yAxisColors, checkBoundaries = true) {
|
|
71
72
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
72
73
|
const align = yAxisState.align;
|
|
73
74
|
const textFont = (_a = config.textFont) !== null && _a !== void 0 ? _a : getFontFromConfig(yAxisState);
|
|
@@ -84,8 +85,7 @@ export function drawRectLabel(ctx, bounds, text, centralY, config, yAxisState, y
|
|
|
84
85
|
const labelBoxHeight = labelBoxBottomY - labelBoxTopY;
|
|
85
86
|
const rounded = (_k = config.rounded) !== null && _k !== void 0 ? _k : (_l = yAxisState.typeConfig.rectangle) === null || _l === void 0 ? void 0 : _l.rounded;
|
|
86
87
|
// do not draw, if label is out of bounds
|
|
87
|
-
if (
|
|
88
|
-
!drawOutside) {
|
|
88
|
+
if (checkBoundaries && !checkLabelInBoundaries(centralY, bounds, labelBoxHeight)) {
|
|
89
89
|
return;
|
|
90
90
|
}
|
|
91
91
|
ctx.save();
|
|
@@ -115,10 +115,12 @@ export function drawRectLabel(ctx, bounds, text, centralY, config, yAxisState, y
|
|
|
115
115
|
* @param text - text to draw
|
|
116
116
|
* @param centralY - y
|
|
117
117
|
* @param config - label styles config
|
|
118
|
-
* @param align
|
|
119
118
|
* @param yAxisState
|
|
119
|
+
* @param yAxisColors
|
|
120
|
+
* @param checkBoundaries
|
|
121
|
+
* @param backgroundCtx
|
|
120
122
|
*/
|
|
121
|
-
export function drawPlainLabel(ctx, bounds, text, centralY, config, yAxisState, yAxisColors,
|
|
123
|
+
export function drawPlainLabel(ctx, bounds, text, centralY, config, yAxisState, yAxisColors, checkBoundaries = true, backgroundCtx) {
|
|
122
124
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
123
125
|
const align = yAxisState.align;
|
|
124
126
|
const textFont = (_a = config.textFont) !== null && _a !== void 0 ? _a : getFontFromConfig(yAxisState);
|
|
@@ -134,8 +136,7 @@ export function drawPlainLabel(ctx, bounds, text, centralY, config, yAxisState,
|
|
|
134
136
|
const labelBoxBottomY = centralY + fontHeight / 2 + paddingBottom;
|
|
135
137
|
const labelBoxHeight = labelBoxBottomY - labelBoxTopY;
|
|
136
138
|
// do not draw, if label is out of bounds
|
|
137
|
-
if (
|
|
138
|
-
!drawOutside) {
|
|
139
|
+
if (checkBoundaries && !checkLabelInBoundaries(centralY, bounds, labelBoxHeight)) {
|
|
139
140
|
return;
|
|
140
141
|
}
|
|
141
142
|
ctx.save();
|
|
@@ -164,3 +165,13 @@ export function getLabelYOffset(font, ctx, paddingTop = DEFAULT_PRICE_LABEL_PADD
|
|
|
164
165
|
const fontHeight = calculateSymbolHeight(font, ctx);
|
|
165
166
|
return fontHeight / 2 + paddingTop;
|
|
166
167
|
}
|
|
168
|
+
/**
|
|
169
|
+
* Checks if label fits in chart scale boundaries
|
|
170
|
+
* @param centralY
|
|
171
|
+
* @param bounds
|
|
172
|
+
* @param labelBoxHeight
|
|
173
|
+
* returns true if label fits
|
|
174
|
+
*/
|
|
175
|
+
export function checkLabelInBoundaries(centralY, bounds, labelBoxHeight) {
|
|
176
|
+
return !(centralY < bounds.y + labelBoxHeight / 2 || centralY > bounds.y + bounds.height - labelBoxHeight / 2);
|
|
177
|
+
}
|
|
@@ -18,8 +18,11 @@ import { ScaleModel } from '../../model/scale.model';
|
|
|
18
18
|
*/
|
|
19
19
|
export declare class YAxisScaleHandler extends ChartBaseElement {
|
|
20
20
|
private bus;
|
|
21
|
+
private config;
|
|
21
22
|
private scale;
|
|
23
|
+
private canvasInputListener;
|
|
22
24
|
private bounds;
|
|
25
|
+
private hitTest;
|
|
23
26
|
private autoScaleCallback;
|
|
24
27
|
yAxisDragEndSubject: Subject<void>;
|
|
25
28
|
lastYStart: Unit;
|
|
@@ -27,6 +30,7 @@ export declare class YAxisScaleHandler extends ChartBaseElement {
|
|
|
27
30
|
lastYHeight: Unit;
|
|
28
31
|
lastYPxHeight: Pixel;
|
|
29
32
|
constructor(bus: EventBus, config: YAxisConfig, panning: ChartPanComponent, scale: ScaleModel, canvasInputListener: CanvasInputListenerComponent, bounds: CanvasBoundsContainer, hitTest: HitBoundsTest, autoScaleCallback: (auto: boolean) => void);
|
|
33
|
+
protected doActivate(): void;
|
|
30
34
|
private onYDragStart;
|
|
31
35
|
private onYDragTick;
|
|
32
36
|
private onYDragEnd;
|
|
@@ -17,8 +17,11 @@ export class YAxisScaleHandler extends ChartBaseElement {
|
|
|
17
17
|
constructor(bus, config, panning, scale, canvasInputListener, bounds, hitTest, autoScaleCallback) {
|
|
18
18
|
super();
|
|
19
19
|
this.bus = bus;
|
|
20
|
+
this.config = config;
|
|
20
21
|
this.scale = scale;
|
|
22
|
+
this.canvasInputListener = canvasInputListener;
|
|
21
23
|
this.bounds = bounds;
|
|
24
|
+
this.hitTest = hitTest;
|
|
22
25
|
this.autoScaleCallback = autoScaleCallback;
|
|
23
26
|
this.yAxisDragEndSubject = new Subject();
|
|
24
27
|
this.lastYStart = 0;
|
|
@@ -26,6 +29,8 @@ export class YAxisScaleHandler extends ChartBaseElement {
|
|
|
26
29
|
this.lastYHeight = 0;
|
|
27
30
|
this.lastYPxHeight = 0;
|
|
28
31
|
this.onYDragStart = () => {
|
|
32
|
+
// halt previous scale animation if drag is started
|
|
33
|
+
this.scale.haltAnimation();
|
|
29
34
|
this.lastYStart = this.scale.yStart;
|
|
30
35
|
this.lastYEnd = this.scale.yEnd;
|
|
31
36
|
this.lastYHeight = this.scale.yEnd - this.scale.yStart;
|
|
@@ -65,12 +70,14 @@ export class YAxisScaleHandler extends ChartBaseElement {
|
|
|
65
70
|
disableChartPanning: false,
|
|
66
71
|
});
|
|
67
72
|
this.addChildEntity(dragNDropYComponent);
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
doActivate() {
|
|
76
|
+
if (this.config.customScaleDblClick) {
|
|
77
|
+
this.addRxSubscription(this.canvasInputListener.observeDbClick(this.hitTest).subscribe(() => {
|
|
78
|
+
this.autoScaleCallback(true);
|
|
79
|
+
this.bus.fireDraw();
|
|
80
|
+
}));
|
|
74
81
|
}
|
|
75
82
|
}
|
|
76
83
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
5
5
|
*/
|
|
6
6
|
import { getFontFromConfig } from '../../chart.config';
|
|
7
|
-
import { clipToBounds } from '../../
|
|
7
|
+
import { clipToBounds } from '../../utils/canvas/canvas-drawing-functions.utils';
|
|
8
8
|
import { calculateSymbolHeight, calculateTextWidth } from '../../utils/canvas/canvas-font-measure-tool.utils';
|
|
9
9
|
/**
|
|
10
10
|
* Draws the Y_AXIS rectangle + it's base labels.
|
|
@@ -9,10 +9,9 @@ import { FullChartConfig } from '../chart.config';
|
|
|
9
9
|
export declare class BackgroundDrawer implements Drawer {
|
|
10
10
|
private canvasModel;
|
|
11
11
|
private config;
|
|
12
|
-
|
|
12
|
+
private backgroundDrawPredicate;
|
|
13
|
+
constructor(canvasModel: CanvasModel, config: FullChartConfig, backgroundDrawPredicate?: () => boolean);
|
|
13
14
|
private prevState;
|
|
14
|
-
private prevWidth;
|
|
15
|
-
private prevHeight;
|
|
16
15
|
draw(): void;
|
|
17
16
|
getCanvasIds(): Array<string>;
|
|
18
17
|
}
|
|
@@ -4,39 +4,33 @@
|
|
|
4
4
|
* If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
5
5
|
*/
|
|
6
6
|
import { getDPR } from '../utils/device/device-pixel-ratio.utils';
|
|
7
|
-
import { deepEqual } from '../utils/object.utils';
|
|
8
7
|
import { floor } from '../utils/math.utils';
|
|
8
|
+
import { deepEqual } from '../utils/object.utils';
|
|
9
9
|
export class BackgroundDrawer {
|
|
10
|
-
constructor(canvasModel, config) {
|
|
10
|
+
constructor(canvasModel, config, backgroundDrawPredicate = () => true) {
|
|
11
11
|
this.canvasModel = canvasModel;
|
|
12
12
|
this.config = config;
|
|
13
|
+
this.backgroundDrawPredicate = backgroundDrawPredicate;
|
|
13
14
|
// we need to save previous state to avoid unnecessary redraws
|
|
14
15
|
this.prevState = {};
|
|
15
|
-
this.prevWidth = 0;
|
|
16
|
-
this.prevHeight = 0;
|
|
17
16
|
}
|
|
18
17
|
draw() {
|
|
19
|
-
if (deepEqual(this.config.colors.chartAreaTheme, this.prevState)
|
|
20
|
-
this.
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
else {
|
|
33
|
-
ctx.fillStyle = this.config.colors.chartAreaTheme.backgroundColor;
|
|
18
|
+
if (this.backgroundDrawPredicate() || !deepEqual(this.config.colors.chartAreaTheme, this.prevState)) {
|
|
19
|
+
this.canvasModel.clear();
|
|
20
|
+
const ctx = this.canvasModel.ctx;
|
|
21
|
+
if (this.config.colors.chartAreaTheme.backgroundMode === 'gradient') {
|
|
22
|
+
const grd = ctx.createLinearGradient(0, 0, this.canvasModel.width, this.canvasModel.height);
|
|
23
|
+
grd.addColorStop(0, this.config.colors.chartAreaTheme.backgroundGradientTopColor);
|
|
24
|
+
grd.addColorStop(1, this.config.colors.chartAreaTheme.backgroundGradientBottomColor);
|
|
25
|
+
ctx.fillStyle = grd;
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
ctx.fillStyle = this.config.colors.chartAreaTheme.backgroundColor;
|
|
29
|
+
}
|
|
30
|
+
ctx.fillRect(0, 0, this.canvasModel.width, this.canvasModel.height);
|
|
34
31
|
}
|
|
35
|
-
ctx.fillRect(0, 0, this.canvasModel.width, this.canvasModel.height);
|
|
36
32
|
// save prev state
|
|
37
33
|
this.prevState = Object.assign({}, this.config.colors.chartAreaTheme);
|
|
38
|
-
this.prevWidth = this.canvasModel.width;
|
|
39
|
-
this.prevHeight = this.canvasModel.height;
|
|
40
34
|
}
|
|
41
35
|
getCanvasIds() {
|
|
42
36
|
return [this.canvasModel.canvasId];
|
|
@@ -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 { clipToBounds } from '
|
|
6
|
+
import { clipToBounds } from '../../utils/canvas/canvas-drawing-functions.utils';
|
|
7
7
|
export const candleTypesList = [
|
|
8
8
|
'candle',
|
|
9
9
|
'bar',
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { DynamicModelDrawer } from '../components/dynamic-objects/dynamic-objects.drawer';
|
|
7
7
|
import { PaneManager } from '../components/pane/pane-manager.component';
|
|
8
|
-
import { Bounds } from '../model/bounds.model';
|
|
9
8
|
import { CanvasModel } from '../model/canvas.model';
|
|
10
9
|
import { DataSeriesModel, VisualSeriesPoint } from '../model/data-series.model';
|
|
11
10
|
export interface ChartDrawerConfig {
|
|
@@ -33,5 +32,4 @@ export declare class DataSeriesDrawer implements DynamicModelDrawer<DataSeriesMo
|
|
|
33
32
|
draw(canvasModel: CanvasModel, model: DataSeriesModel, paneUUID?: string): void;
|
|
34
33
|
drawSeries(ctx: CanvasRenderingContext2D, series: DataSeriesModel): void;
|
|
35
34
|
}
|
|
36
|
-
export declare const clipToBounds: (ctx: CanvasRenderingContext2D, bounds: Bounds) => void;
|
|
37
35
|
export declare const setLineWidth: (ctx: CanvasRenderingContext2D, lineWidth: number, dataSeries: DataSeriesModel, drawerConfig: ChartDrawerConfig, seriesSelectedWidth?: number) => void;
|
|
@@ -3,6 +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 { clipToBounds } from '../utils/canvas/canvas-drawing-functions.utils';
|
|
6
7
|
export const transformToTwoDimension = (points) => (Array.isArray(points[0]) ? points : [points]);
|
|
7
8
|
/**
|
|
8
9
|
* Basic data series drawer.
|
|
@@ -42,12 +43,6 @@ export class DataSeriesDrawer {
|
|
|
42
43
|
}
|
|
43
44
|
}
|
|
44
45
|
}
|
|
45
|
-
export const clipToBounds = (ctx, bounds) => {
|
|
46
|
-
ctx.beginPath();
|
|
47
|
-
ctx.rect(bounds.x, bounds.y, bounds.width, bounds.height);
|
|
48
|
-
ctx.clip();
|
|
49
|
-
ctx.closePath();
|
|
50
|
-
};
|
|
51
46
|
export const setLineWidth = (ctx, lineWidth, dataSeries, drawerConfig, seriesSelectedWidth = lineWidth) => {
|
|
52
47
|
if (drawerConfig.forceBold) {
|
|
53
48
|
ctx.lineWidth = drawerConfig.forceBold;
|
|
@@ -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 { clipToBounds } from '
|
|
6
|
+
import { clipToBounds } from '../utils/canvas/canvas-drawing-functions.utils';
|
|
7
7
|
/***
|
|
8
8
|
* HitTest Chart drawer. It's used to draw hit test for chart types on the hit-test canvas.
|
|
9
9
|
*/
|
|
@@ -32,7 +32,7 @@ export interface HoverParts {
|
|
|
32
32
|
export interface Hover extends BaseHover, HoverParts {
|
|
33
33
|
}
|
|
34
34
|
export interface HoverProducerPart<T = unknown> {
|
|
35
|
-
getData(hover: BaseHover): T;
|
|
35
|
+
getData(hover: BaseHover): T | undefined;
|
|
36
36
|
}
|
|
37
37
|
export interface HoverProducerParts {
|
|
38
38
|
candleHover: CandleHoverProducerPart;
|
|
@@ -19,5 +19,5 @@ export declare class CompareSeriesHoverProducerPart implements HoverProducerPart
|
|
|
19
19
|
* @param {BaseHover} hover - The hover object containing the x-coordinate.
|
|
20
20
|
* @returns {CompareSeriesHover[]} An array of objects containing the instrument symbol, price and id of each series of candles.
|
|
21
21
|
*/
|
|
22
|
-
getData(hover: BaseHover): CompareSeriesHover[];
|
|
22
|
+
getData(hover: BaseHover): CompareSeriesHover[] | undefined;
|
|
23
23
|
}
|
|
@@ -3,6 +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 { MainCandleSeriesModel } from './main-candle-series.model';
|
|
6
7
|
export class CompareSeriesHoverProducerPart {
|
|
7
8
|
constructor(chartModel) {
|
|
8
9
|
this.chartModel = chartModel;
|
|
@@ -13,6 +14,10 @@ export class CompareSeriesHoverProducerPart {
|
|
|
13
14
|
* @returns {CompareSeriesHover[]} An array of objects containing the instrument symbol, price and id of each series of candles.
|
|
14
15
|
*/
|
|
15
16
|
getData(hover) {
|
|
17
|
+
if (this.chartModel.candleSeries.length === 1 &&
|
|
18
|
+
this.chartModel.candleSeries[0] instanceof MainCandleSeriesModel) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
16
21
|
const { x } = hover;
|
|
17
22
|
const candle = this.chartModel.candleFromX(x);
|
|
18
23
|
const idx = candle.idx || 0;
|
|
@@ -138,7 +138,7 @@ 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(() => this.recalculateVisualPoints()));
|
|
141
|
+
this.addRxSubscription(this.scale.scaleInversedSubject.subscribe(() => { this.recalculateVisualPoints(); }));
|
|
142
142
|
}
|
|
143
143
|
/**
|
|
144
144
|
* Sets the data points and recalculates internal state
|
|
@@ -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 { merge, Subject } from 'rxjs';
|
|
6
|
+
import { merge, Subject, animationFrameScheduler } from 'rxjs';
|
|
7
7
|
import { map, throttleTime } from 'rxjs/operators';
|
|
8
8
|
import { CanvasElement } from '../canvas/canvas-bounds-container';
|
|
9
9
|
import { CanvasModel, initCanvasWithConfig } from './canvas.model';
|
|
@@ -50,7 +50,7 @@ export class HitTestCanvasModel extends CanvasModel {
|
|
|
50
50
|
const bounds = this.canvasBoundsContainer.getBoundsHitTest(CanvasElement.ALL_PANES);
|
|
51
51
|
const hoverSub = this.canvasInputListener
|
|
52
52
|
.observeMouseMove()
|
|
53
|
-
.pipe(throttleTime(100,
|
|
53
|
+
.pipe(throttleTime(100, animationFrameScheduler, { trailing: true }))
|
|
54
54
|
.subscribe(point => this.eventHandler(point, 'hover'));
|
|
55
55
|
const touchStartSub = this.canvasInputListener
|
|
56
56
|
.observeTouchStart()
|
|
@@ -48,6 +48,8 @@ export declare class ScaleModel extends ViewportModel {
|
|
|
48
48
|
xConstraints: Constraints[];
|
|
49
49
|
readonly state: ChartScale;
|
|
50
50
|
constructor(config: FullChartConfig, getBounds: BoundsProvider, canvasAnimation: CanvasAnimation);
|
|
51
|
+
protected doActivate(): void;
|
|
52
|
+
protected doDeactivate(): void;
|
|
51
53
|
/**
|
|
52
54
|
* The method adds a new "constraint" to the existing list of x-axis constraints for charting.
|
|
53
55
|
* The "constraint" is expected to be an object containing information about the constraints, such as the minimum and maximum values for the x-axis.
|
|
@@ -88,7 +90,7 @@ export declare class ScaleModel extends ViewportModel {
|
|
|
88
90
|
* @param fireChanged
|
|
89
91
|
* @param forceNoAutoScale - force NOT apply auto-scaling (for lazy loading)
|
|
90
92
|
*/
|
|
91
|
-
setXScale(xStart: Unit, xEnd: Unit): void;
|
|
93
|
+
setXScale(xStart: Unit, xEnd: Unit, forceNoAnimation?: boolean): void;
|
|
92
94
|
setYScale(yStart: Unit, yEnd: Unit, fire?: boolean): void;
|
|
93
95
|
/**
|
|
94
96
|
* Moves both xStart and xEnd without changing the viewport width (zoom).
|
|
@@ -51,6 +51,19 @@ export class ScaleModel extends ViewportModel {
|
|
|
51
51
|
this.offsets = this.config.components.offsets;
|
|
52
52
|
this.addXConstraint((initialState, state) => zoomConstraint(initialState, state, this.config.components.chart, this.getBounds));
|
|
53
53
|
}
|
|
54
|
+
doActivate() {
|
|
55
|
+
super.doActivate();
|
|
56
|
+
this.scaleInversedSubject = new Subject();
|
|
57
|
+
this.beforeStartAnimationSubject = new Subject();
|
|
58
|
+
this.addRxSubscription(this.scaleInversedSubject.subscribe(() => {
|
|
59
|
+
this.fireChanged();
|
|
60
|
+
}));
|
|
61
|
+
}
|
|
62
|
+
doDeactivate() {
|
|
63
|
+
super.doDeactivate();
|
|
64
|
+
this.scaleInversedSubject.complete();
|
|
65
|
+
this.beforeStartAnimationSubject.complete();
|
|
66
|
+
}
|
|
54
67
|
/**
|
|
55
68
|
* The method adds a new "constraint" to the existing list of x-axis constraints for charting.
|
|
56
69
|
* The "constraint" is expected to be an object containing information about the constraints, such as the minimum and maximum values for the x-axis.
|
|
@@ -136,10 +149,10 @@ export class ScaleModel extends ViewportModel {
|
|
|
136
149
|
* @param fireChanged
|
|
137
150
|
* @param forceNoAutoScale - force NOT apply auto-scaling (for lazy loading)
|
|
138
151
|
*/
|
|
139
|
-
setXScale(xStart, xEnd) {
|
|
152
|
+
setXScale(xStart, xEnd, forceNoAnimation = true) {
|
|
140
153
|
const initialState = this.export();
|
|
141
|
-
|
|
142
|
-
const state =
|
|
154
|
+
const zoomX = this.calculateZoomX(xStart, xEnd);
|
|
155
|
+
const state = Object.assign(Object.assign({}, initialState), { zoomX, xStart, xEnd });
|
|
143
156
|
const constrainedState = this.scalePostProcessor(initialState, state);
|
|
144
157
|
if (this.state.lockPriceToBarRatio) {
|
|
145
158
|
changeYToKeepRatio(constrainedState, this.zoomXYRatio);
|
|
@@ -147,7 +160,13 @@ export class ScaleModel extends ViewportModel {
|
|
|
147
160
|
if (this.state.auto) {
|
|
148
161
|
this.autoScaleModel.doAutoYScale(constrainedState);
|
|
149
162
|
}
|
|
150
|
-
this.
|
|
163
|
+
if (forceNoAnimation || this.config.scale.disableAnimations) {
|
|
164
|
+
this.haltAnimation();
|
|
165
|
+
this.apply(constrainedState);
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
startViewportModelAnimation(this.canvasAnimation, this, constrainedState);
|
|
169
|
+
}
|
|
151
170
|
}
|
|
152
171
|
setYScale(yStart, yEnd, fire = false) {
|
|
153
172
|
const initialState = this.export();
|