@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.
Files changed (55) hide show
  1. package/dist/chart/bootstrap.js +4 -3
  2. package/dist/chart/canvas/canvas-bounds-container.js +5 -3
  3. package/dist/chart/canvas/cursor.handler.js +2 -2
  4. package/dist/chart/components/chart/chart-area-pan.handler.js +3 -3
  5. package/dist/chart/components/chart/chart.component.d.ts +6 -3
  6. package/dist/chart/components/chart/chart.component.js +18 -7
  7. package/dist/chart/components/chart/chart.model.d.ts +1 -2
  8. package/dist/chart/components/chart/chart.model.js +2 -3
  9. package/dist/chart/components/cross_tool/types/cross-and-labels.drawer.js +4 -2
  10. package/dist/chart/components/high_low/high-low.drawer.js +9 -2
  11. package/dist/chart/components/highlights/highlights.drawer.js +1 -1
  12. package/dist/chart/components/pane/pane.component.js +6 -3
  13. package/dist/chart/components/volumes/volumes.drawer.js +1 -1
  14. package/dist/chart/components/x_axis/time/parser/time-formats-matchers.functions.js +1 -1
  15. package/dist/chart/components/x_axis/time/parser/time-formats.model.d.ts +1 -1
  16. package/dist/chart/components/x_axis/time/x-axis-weights.functions.js +2 -2
  17. package/dist/chart/components/x_axis/time/x-axis-weights.generator.js +6 -7
  18. package/dist/chart/components/x_axis/x-axis-labels.generator.d.ts +11 -3
  19. package/dist/chart/components/x_axis/x-axis-labels.generator.js +47 -19
  20. package/dist/chart/components/x_axis/x-axis-time-labels.drawer.js +0 -4
  21. package/dist/chart/components/x_axis/x-axis.component.js +7 -11
  22. package/dist/chart/components/y_axis/price_labels/last-candle-labels.provider.js +5 -5
  23. package/dist/chart/components/y_axis/price_labels/price-label.drawer.js +21 -22
  24. package/dist/chart/components/y_axis/y-axis-labels.drawer.d.ts +18 -6
  25. package/dist/chart/components/y_axis/y-axis-labels.drawer.js +23 -12
  26. package/dist/chart/components/y_axis/y-axis-scale.handler.d.ts +4 -0
  27. package/dist/chart/components/y_axis/y-axis-scale.handler.js +13 -6
  28. package/dist/chart/components/y_axis/y-axis.drawer.js +1 -1
  29. package/dist/chart/drawers/chart-background.drawer.d.ts +2 -3
  30. package/dist/chart/drawers/chart-background.drawer.js +16 -22
  31. package/dist/chart/drawers/data-series-drawers/candle-series-wrapper.js +1 -1
  32. package/dist/chart/drawers/data-series.drawer.d.ts +0 -2
  33. package/dist/chart/drawers/data-series.drawer.js +1 -6
  34. package/dist/chart/drawers/ht-data-series.drawer.js +1 -1
  35. package/dist/chart/inputhandlers/hover-producer.component.d.ts +1 -1
  36. package/dist/chart/model/compare-series-hover.d.ts +1 -1
  37. package/dist/chart/model/compare-series-hover.js +5 -0
  38. package/dist/chart/model/data-series.model.js +1 -1
  39. package/dist/chart/model/hit-test-canvas.model.js +2 -2
  40. package/dist/chart/model/scale.model.d.ts +3 -1
  41. package/dist/chart/model/scale.model.js +23 -4
  42. package/dist/chart/model/scaling/viewport.model.d.ts +2 -0
  43. package/dist/chart/model/scaling/viewport.model.js +13 -4
  44. package/dist/chart/model/time-zone.model.d.ts +0 -14
  45. package/dist/chart/model/time-zone.model.js +13 -33
  46. package/dist/chart/utils/canvas/canvas-drawing-functions.utils.d.ts +12 -1
  47. package/dist/chart/utils/canvas/canvas-drawing-functions.utils.js +16 -1
  48. package/dist/chart/utils/canvas/canvas-text-functions.utils.d.ts +3 -2
  49. package/dist/chart/utils/canvas/canvas-text-functions.utils.js +8 -3
  50. package/dist/chart/utils/math.utils.d.ts +1 -0
  51. package/dist/chart/utils/math.utils.js +3 -0
  52. package/dist/chart/utils/timezone.utils.d.ts +13 -0
  53. package/dist/chart/utils/timezone.utils.js +48 -0
  54. package/dist/dxchart.min.js +6 -6
  55. 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, undefined, { trailing: true, leading: true }))
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 { getPlainLabelTextColor, getPrimaryLabelTextColor } from '../label-color.functions';
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 getLabelBoxColor = this.resolveLabelColorFn(series.config.type);
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 = getLabelBoxColor(series.lastPriceMovement, series.colors);
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
- ? getPlainLabelTextColor(this.chartConfig.colors, textColor, rectLabelInvertedTextColor, this.yAxisConfig)
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
- ? getPlainLabelTextColor(this.chartConfig.colors, rectLabelTextColor, rectLabelInvertedTextColor, this.yAxisConfig)
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
- switch (mode) {
70
- case 'line':
71
- _drawLine();
72
- _drawDescription();
73
- break;
74
- case 'line-label':
75
- _drawLine();
76
- _drawDescription();
77
- _drawLabel();
78
- break;
79
- case 'label':
80
- _drawDescription();
81
- _drawLabel();
82
- break;
83
- case 'none':
84
- break;
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'], drawOutside?: boolean): void;
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'], drawOutside?: boolean): void;
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'], drawOutside?: boolean, backgroundCtx?: CanvasRenderingContext2D): void;
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, drawOutside = false) {
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 ((centralY < bounds.y + labelBoxHeight / 2 || centralY > bounds.y + bounds.height - labelBoxHeight / 2) &&
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, drawOutside = false) {
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 ((centralY < bounds.y + labelBoxHeight / 2 || centralY > bounds.y + bounds.height - labelBoxHeight / 2) &&
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, drawOutside = false, backgroundCtx) {
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 ((centralY < bounds.y + labelBoxHeight / 2 || centralY > bounds.y + bounds.height - labelBoxHeight / 2) &&
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
- if (config.customScaleDblClick) {
69
- canvasInputListener.observeDbClick(hitTest).subscribe(() => {
70
- autoScaleCallback(true);
71
- this.bus.fireDraw();
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 '../../drawers/data-series.drawer';
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
- constructor(canvasModel: CanvasModel, config: FullChartConfig);
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.prevHeight === this.canvasModel.height &&
21
- this.prevWidth === this.canvasModel.width) {
22
- return;
23
- }
24
- this.canvasModel.clear();
25
- const ctx = this.canvasModel.ctx;
26
- if (this.config.colors.chartAreaTheme.backgroundMode === 'gradient') {
27
- const grd = ctx.createLinearGradient(0, 0, this.canvasModel.width, this.canvasModel.height);
28
- grd.addColorStop(0, this.config.colors.chartAreaTheme.backgroundGradientTopColor);
29
- grd.addColorStop(1, this.config.colors.chartAreaTheme.backgroundGradientBottomColor);
30
- ctx.fillStyle = grd;
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 '../data-series.drawer';
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 './data-series.drawer';
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, undefined, { trailing: true }))
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
- super.setXScale(xStart, xEnd, false);
142
- const state = this.export();
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.apply(constrainedState);
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();