@devexperts/dxcharts-lite 2.3.0 → 2.4.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.
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
@@ -92,6 +92,8 @@ export declare abstract class ViewportModel extends ChartBaseElement implements
92
92
  start: number;
93
93
  end: number;
94
94
  }>;
95
+ protected doActivate(): void;
96
+ protected doDeactivate(): void;
95
97
  /**
96
98
  * Converts a unit value to pixels based on the current zoom level and xStart value.
97
99
  * @param {Unit} unit - The unit value to be converted to pixels.
@@ -52,6 +52,13 @@ export class ViewportModel extends ChartBaseElement {
52
52
  })), distinctUntilChanged((p, c) => p.start === c.start && p.end === c.end), share());
53
53
  }
54
54
  //endregion
55
+ doActivate() {
56
+ super.doActivate();
57
+ }
58
+ doDeactivate() {
59
+ super.doDeactivate();
60
+ this.changed.complete();
61
+ }
55
62
  //region conversion methods
56
63
  /**
57
64
  * Converts a unit value to pixels based on the current zoom level and xStart value.
@@ -75,12 +82,13 @@ export class ViewportModel extends ChartBaseElement {
75
82
  * @returns {Pixel} - The pixel value of the given unit value in the Y-axis.
76
83
  */
77
84
  toY(unit) {
85
+ const bounds = this.getBounds();
78
86
  if (this.inverseY) {
79
- return this.getBounds().y + unitToPixels(unit - this.yStart, this.zoomY);
87
+ return bounds.y + unitToPixels(unit - this.yStart, this.zoomY);
80
88
  }
81
89
  else {
82
90
  // inverse by default because canvas calculation [0,0] point starts from top-left corner
83
- return this.getBounds().y + this.getBounds().height - unitToPixels(unit - this.yStart, this.zoomY);
91
+ return bounds.y + bounds.height - unitToPixels(unit - this.yStart, this.zoomY);
84
92
  }
85
93
  }
86
94
  /**
@@ -106,13 +114,14 @@ export class ViewportModel extends ChartBaseElement {
106
114
  * @returns {void}
107
115
  */
108
116
  fromY(px) {
109
- const normalizedPx = px - this.getBounds().y;
117
+ const bounds = this.getBounds();
118
+ const normalizedPx = px - bounds.y;
110
119
  if (this.inverseY) {
111
120
  return pixelsToUnits(normalizedPx + unitToPixels(this.yStart, this.zoomY), this.zoomY);
112
121
  }
113
122
  else {
114
123
  // inverse by default because canvas calculation [0,0] point starts from top-left corner
115
- return pixelsToUnits(this.getBounds().height - normalizedPx + unitToPixels(this.yStart, this.zoomY), this.zoomY);
124
+ return pixelsToUnits(bounds.height - normalizedPx + unitToPixels(this.yStart, this.zoomY), this.zoomY);
116
125
  }
117
126
  }
118
127
  //endregion
@@ -3,7 +3,6 @@
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 { getTimezoneOffset as getTimezoneOffsetDateFnsTz } from 'date-fns-tz';
7
6
  import { Observable } from 'rxjs';
8
7
  import { DateFormatter, FullChartConfig } from '../chart.config';
9
8
  import { DateTimeFormatter, DateTimeFormatterFactory } from './date-time.formatter';
@@ -13,8 +12,6 @@ export interface TimeZone {
13
12
  readonly name: string;
14
13
  readonly utcOffset: string;
15
14
  }
16
- export declare const memoizedTZOffset: typeof getTimezoneOffsetDateFnsTz;
17
- export declare const getTimezoneOffset: (timezone: string, time: Timestamp) => number;
18
15
  export declare class TimeZoneModel {
19
16
  private config;
20
17
  private timeZoneChangedSubject;
@@ -50,16 +47,5 @@ export declare class TimeZoneModel {
50
47
  getFormatterFactory(): DateTimeFormatterFactory;
51
48
  private formatterCache;
52
49
  getDateTimeFormatter(format: string): DateTimeFormatter;
53
- /**
54
- * Calculates the offset of a given timezone from the local timezone.
55
- * @private
56
- * @param {string} timezone - The timezone to calculate the offset for.
57
- */
58
- private getOffset;
59
- /**
60
- * Gets the timezone offset value in milliseconds
61
- * @param {string} timezone name
62
- * @returns {function(time:Number):Date}
63
- */
64
50
  tzOffset(timezone: string): (time: number) => Date;
65
51
  }
@@ -3,28 +3,20 @@
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 { getTimezoneOffset as getTimezoneOffsetDateFnsTz } from 'date-fns-tz';
7
6
  import { ReplaySubject } from 'rxjs';
8
- import { memoize } from '../utils/performance/memoize.utils';
9
7
  import { dateTimeFormatterFactory } from './date-time.formatter';
10
- export const memoizedTZOffset = memoize(getTimezoneOffsetDateFnsTz);
11
- export const getTimezoneOffset = (timezone, time) => {
12
- // we must pass time here, because we can have daylight saving time, otherwise we will get wrong offset
13
- const localOffset = new Date(time).getTimezoneOffset() * 60 * 1000;
14
- return localOffset + memoizedTZOffset(timezone, time);
15
- };
8
+ import { getTimezoneOffset } from '../utils/timezone.utils';
9
+ // 1 hour in milliseconds
10
+ const timeMultiplier = 60 * 1000;
16
11
  export class TimeZoneModel {
17
12
  constructor(config) {
18
13
  this.config = config;
19
14
  this.timeZoneChangedSubject = new ReplaySubject();
20
- this.currentTzOffset = (time) => this.getOffset(this.config.timezone, time);
15
+ this.currentTzOffset = (time) => {
16
+ // we must pass time here, because we can have daylight saving time, otherwise we will get wrong offset
17
+ return getTimezoneOffset(this.config.timezone, time) + new Date(time).getTimezoneOffset() * timeMultiplier;
18
+ };
21
19
  this.formatterCache = {};
22
- /**
23
- * Calculates the offset of a given timezone from the local timezone.
24
- * @private
25
- * @param {string} timezone - The timezone to calculate the offset for.
26
- */
27
- this.getOffset = (timezone, time) => getTimezoneOffset(timezone, time);
28
20
  this.dateTimeFormatterFactory = this.initFormatterFactory(this.config.dateFormatter);
29
21
  }
30
22
  /**
@@ -87,28 +79,16 @@ export class TimeZoneModel {
87
79
  }
88
80
  return this.formatterCache[format];
89
81
  }
90
- /**
91
- * Gets the timezone offset value in milliseconds
92
- * @param {string} timezone name
93
- * @returns {function(time:Number):Date}
94
- */
95
82
  tzOffset(timezone) {
96
- // we must pass time here, because we can have daylight saving time, otherwise we will get wrong offset
97
- const localOffset = (time) => -new Date(time).getTimezoneOffset() * timeMultiplier;
98
- let offset;
99
83
  if (!timezone) {
100
- offset = localOffset;
84
+ return time => new Date(time);
101
85
  }
102
86
  else {
103
- // we must pass time here, because we can have daylight saving time, otherwise we will get wrong offset
104
- offset = (time) => memoizedTZOffset(timezone, time);
87
+ // In JS Date object is created with local tz offset,
88
+ // so we have to subtract localOffset from current time
89
+ return time => {
90
+ return new Date(time + getTimezoneOffset(timezone, time) + new Date(time).getTimezoneOffset() * timeMultiplier);
91
+ };
105
92
  }
106
- // In JS Date object is created with local tz offset,
107
- // so we have to subtract localOffset from current time
108
- return time => {
109
- return new Date(+time + offset(time) - localOffset(time));
110
- };
111
93
  }
112
94
  }
113
- // 1 hour in milliseconds
114
- const timeMultiplier = 60 * 1000;
@@ -4,6 +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 { YAxisAlign } from '../../chart.config';
7
+ import { Bounds } from '../../model/bounds.model';
7
8
  /**
8
9
  * Draws a rounded rectangle on a canvas context
9
10
  * @param {CanvasRenderingContext2D} ctx - The canvas context to draw on
@@ -57,7 +58,7 @@ export declare function avoidAntialiasing(ctx: CanvasRenderingContext2D, draw: (
57
58
  * @param {{x: number, y: number}} a - The first point of the rectangle.
58
59
  * @param {{x: number, y: number}} b - The second point of the rectangle.
59
60
  * @returns {void}
60
-
61
+
61
62
  */
62
63
  export declare function fillRect(ctx: CanvasRenderingContext2D, a: {
63
64
  x: number;
@@ -66,3 +67,13 @@ export declare function fillRect(ctx: CanvasRenderingContext2D, a: {
66
67
  x: number;
67
68
  y: number;
68
69
  }): void;
70
+ /**
71
+ * Sets clipping region for a Canvas 2D context according to the provided bounds.
72
+ *
73
+ * @param {CanvasRenderingContext2D} ctx - The canvas 2D context which will get the new clip region.
74
+ * @param {object} bounds - The bounds of the clipping region. Object containing x, y, width and height properties.
75
+ *
76
+ * @example
77
+ * clipToBounds(ctx, {x: 50, y: 50, width: 100, height: 100});
78
+ */
79
+ export declare const clipToBounds: (ctx: CanvasRenderingContext2D, bounds: Bounds) => void;
@@ -138,7 +138,7 @@ export function avoidAntialiasing(ctx, draw) {
138
138
  * @param {{x: number, y: number}} a - The first point of the rectangle.
139
139
  * @param {{x: number, y: number}} b - The second point of the rectangle.
140
140
  * @returns {void}
141
-
141
+
142
142
  */
143
143
  export function fillRect(ctx, a, b) {
144
144
  const x = Math.min(a.x, b.x) + 0.5;
@@ -147,3 +147,18 @@ export function fillRect(ctx, a, b) {
147
147
  const h = Math.abs(a.y - b.y);
148
148
  ctx.fillRect(x, y, w, h);
149
149
  }
150
+ /**
151
+ * Sets clipping region for a Canvas 2D context according to the provided bounds.
152
+ *
153
+ * @param {CanvasRenderingContext2D} ctx - The canvas 2D context which will get the new clip region.
154
+ * @param {object} bounds - The bounds of the clipping region. Object containing x, y, width and height properties.
155
+ *
156
+ * @example
157
+ * clipToBounds(ctx, {x: 50, y: 50, width: 100, height: 100});
158
+ */
159
+ export const clipToBounds = (ctx, bounds) => {
160
+ ctx.beginPath();
161
+ ctx.rect(bounds.x, bounds.y, bounds.width, bounds.height);
162
+ ctx.clip();
163
+ ctx.closePath();
164
+ };
@@ -30,9 +30,10 @@ export declare function prepareTextForFill(ctx: CanvasRenderingContext2D, proper
30
30
  /**
31
31
  * Calculates the line height of a text based on the font size of the provided CanvasRenderingContext2D.
32
32
  * @param {CanvasRenderingContext2D} ctx - The CanvasRenderingContext2D object used to draw the text.
33
+ * @param includeBaseLine
33
34
  * @returns {number} The calculated line height of the text.
34
35
  */
35
- export declare function getTextLineHeight(ctx: CanvasRenderingContext2D): number;
36
+ export declare function getTextLineHeight(ctx: CanvasRenderingContext2D, includeBaseLine?: boolean): number;
36
37
  /**
37
38
  * Calculates text bounds [textWidth, textHeight, lineHeight]
38
39
  * @param ctx
@@ -53,7 +54,7 @@ export declare function getTextLines(text: string): string[];
53
54
  * @param {number} y - The y-coordinate of the starting position of the text.
54
55
  * @param {CanvasTextProperties} properties - An object containing properties for the text, such as font size, style, and alignment.
55
56
  * @returns {void}
56
-
57
+
57
58
  */
58
59
  export declare function drawText(ctx: CanvasRenderingContext2D, lines: string[], x: number, y: number, properties: CanvasTextProperties): void;
59
60
  /**
@@ -4,6 +4,10 @@
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 Color from 'color';
7
+ /**
8
+ * Baseline Height in Project
9
+ */
10
+ const BASELINE = 1.33;
7
11
  /**
8
12
  * Sets the font, fill style and text alignment of a canvas context based on the provided properties.
9
13
  * @param {CanvasRenderingContext2D} ctx - The canvas context to modify.
@@ -32,9 +36,10 @@ export function prepareTextForFill(ctx, properties) {
32
36
  /**
33
37
  * Calculates the line height of a text based on the font size of the provided CanvasRenderingContext2D.
34
38
  * @param {CanvasRenderingContext2D} ctx - The CanvasRenderingContext2D object used to draw the text.
39
+ * @param includeBaseLine
35
40
  * @returns {number} The calculated line height of the text.
36
41
  */
37
- export function getTextLineHeight(ctx) {
42
+ export function getTextLineHeight(ctx, includeBaseLine = true) {
38
43
  const textSizeMatch = ctx.font.match(/(\d+.)?\d+(px|pt)/gi);
39
44
  let textSize = '10px';
40
45
  if (textSizeMatch && textSizeMatch.length) {
@@ -46,7 +51,7 @@ export function getTextLineHeight(ctx) {
46
51
  textSize = textSizeMatch[0];
47
52
  }
48
53
  }
49
- return parseInt(textSize, 10) * 1.33; // Base Line Height in Project
54
+ return includeBaseLine ? parseInt(textSize, 10) * BASELINE : parseInt(textSize, 10);
50
55
  }
51
56
  /**
52
57
  * Calculates text bounds [textWidth, textHeight, lineHeight]
@@ -80,7 +85,7 @@ export function getTextLines(text) {
80
85
  * @param {number} y - The y-coordinate of the starting position of the text.
81
86
  * @param {CanvasTextProperties} properties - An object containing properties for the text, such as font size, style, and alignment.
82
87
  * @returns {void}
83
-
88
+
84
89
  */
85
90
  export function drawText(ctx, lines, x, y, properties) {
86
91
  ctx.save();
@@ -12,6 +12,7 @@ export declare class MathUtils {
12
12
  static compare(a: number, b: number, eps: number): number;
13
13
  static isZero(a: number): boolean;
14
14
  static cutNumber(value: number, amountToCut: NumberFormatLabels, zeros?: number): string;
15
+ static isExponential(a: number): boolean;
15
16
  }
16
17
  /**
17
18
  * Checks if first and second number are differs by specified times
@@ -75,6 +75,9 @@ export class MathUtils {
75
75
  };
76
76
  return cutMap[amountToCut](value).toFixed(zeros) + amountToCut;
77
77
  }
78
+ static isExponential(a) {
79
+ return /\de(\-|\+)\d/.test(a.toString());
80
+ }
78
81
  }
79
82
  /**
80
83
  * Checks if first and second number are differs by specified times
@@ -0,0 +1,13 @@
1
+ /*
2
+ * Copyright (C) 2019 - 2023 Devexperts Solutions IE Limited
3
+ * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
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
+ */
6
+ export declare function getDateTimeFormat(timeZone: string): Intl.DateTimeFormat;
7
+ /**
8
+ * Calulates provided timezone offset.
9
+ * @param timeZone - timezone as IANA string ('Asia/Amman', 'Europe/Amsterdam')
10
+ * @param timestamp - timestamp as number (1701251319717)
11
+ * Returns offset from UTC
12
+ */
13
+ export declare const getTimezoneOffset: (timeZone: string, timestamp?: number) => number;
@@ -0,0 +1,48 @@
1
+ /*
2
+ * Copyright (C) 2019 - 2023 Devexperts Solutions IE Limited
3
+ * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
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
+ */
6
+ /**
7
+ * Get a cached Intl.DateTimeFormat instance for the IANA `timeZone`. This can be used
8
+ * to get deterministic local date/time output according to the `en-US` locale which
9
+ * can be used to extract local time parts as necessary.
10
+ * Returns the [year, month, day, hour, minute] tokens of the provided timezone
11
+ */
12
+ const dateTimeFormatCache = {};
13
+ export function getDateTimeFormat(timeZone) {
14
+ if (!dateTimeFormatCache[timeZone]) {
15
+ // New browsers use `hourCycle`, IE and Chrome <73 does not support it and uses `hour12`
16
+ dateTimeFormatCache[timeZone] = new Intl.DateTimeFormat('en-US', {
17
+ hourCycle: 'h23',
18
+ timeZone,
19
+ year: 'numeric',
20
+ month: 'numeric',
21
+ day: '2-digit',
22
+ hour: '2-digit',
23
+ minute: '2-digit',
24
+ second: '2-digit',
25
+ });
26
+ }
27
+ return dateTimeFormatCache[timeZone];
28
+ }
29
+ /**
30
+ * Calulates provided timezone offset.
31
+ * @param timeZone - timezone as IANA string ('Asia/Amman', 'Europe/Amsterdam')
32
+ * @param timestamp - timestamp as number (1701251319717)
33
+ * Returns offset from UTC
34
+ */
35
+ export const getTimezoneOffset = (timeZone, timestamp = Date.now()) => {
36
+ const formatter = getDateTimeFormat(timeZone);
37
+ const dateString = formatter.format(timestamp);
38
+ // exec() returns [, fMonth, fDay, fYear, fHour, fMinute]
39
+ const tokens = /(\d+)\/(\d+)\/(\d+),? (\d+):(\d+)/.exec(dateString);
40
+ if (tokens) {
41
+ const asUTC = Date.UTC(+tokens[3], +tokens[1] - 1, +tokens[2], +tokens[4] % 24, +tokens[5], 0);
42
+ let asTimezone = timestamp;
43
+ const over = asTimezone % 1000;
44
+ asTimezone -= over >= 0 ? over : 1000 + over;
45
+ return asUTC - asTimezone;
46
+ }
47
+ return 0;
48
+ };