@oanda/labs-crowd-view-widget 1.0.55 → 1.0.57

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 (129) hide show
  1. package/CHANGELOG.md +460 -0
  2. package/dist/main/CrowdViewWidget/components/Chart/Chart.js +8 -10
  3. package/dist/main/CrowdViewWidget/components/Chart/Chart.js.map +1 -1
  4. package/dist/main/CrowdViewWidget/components/Chart/ChartWithData.js +15 -3
  5. package/dist/main/CrowdViewWidget/components/Chart/ChartWithData.js.map +1 -1
  6. package/dist/main/CrowdViewWidget/components/Chart/chartOptions/getGridConfig.js +29 -14
  7. package/dist/main/CrowdViewWidget/components/Chart/chartOptions/getGridConfig.js.map +1 -1
  8. package/dist/main/CrowdViewWidget/components/Chart/chartOptions/getGridLines.js +28 -9
  9. package/dist/main/CrowdViewWidget/components/Chart/chartOptions/getGridLines.js.map +1 -1
  10. package/dist/main/CrowdViewWidget/components/Chart/chartOptions/getLabelsConfig.js +20 -8
  11. package/dist/main/CrowdViewWidget/components/Chart/chartOptions/getLabelsConfig.js.map +1 -1
  12. package/dist/main/CrowdViewWidget/components/Chart/chartOptions/getTooltipConfig.js +21 -16
  13. package/dist/main/CrowdViewWidget/components/Chart/chartOptions/getTooltipConfig.js.map +1 -1
  14. package/dist/main/CrowdViewWidget/components/Chart/chartOptions/getXAxisConfig.js +29 -6
  15. package/dist/main/CrowdViewWidget/components/Chart/chartOptions/getXAxisConfig.js.map +1 -1
  16. package/dist/main/CrowdViewWidget/components/Chart/chartOptions/getYAxisConfig.js +24 -4
  17. package/dist/main/CrowdViewWidget/components/Chart/chartOptions/getYAxisConfig.js.map +1 -1
  18. package/dist/main/CrowdViewWidget/components/Chart/chartUtils/formatFullDate.js +27 -0
  19. package/dist/main/CrowdViewWidget/components/Chart/chartUtils/formatFullDate.js.map +1 -0
  20. package/dist/main/CrowdViewWidget/components/Chart/chartUtils/formatXAxisAdditionalLabel.js +2 -2
  21. package/dist/main/CrowdViewWidget/components/Chart/chartUtils/formatXAxisAdditionalLabel.js.map +1 -1
  22. package/dist/main/CrowdViewWidget/components/Chart/chartUtils/formatXAxisLabel.js +6 -5
  23. package/dist/main/CrowdViewWidget/components/Chart/chartUtils/formatXAxisLabel.js.map +1 -1
  24. package/dist/main/CrowdViewWidget/components/Chart/chartUtils/getTooltipFormatter.js +71 -22
  25. package/dist/main/CrowdViewWidget/components/Chart/chartUtils/getTooltipFormatter.js.map +1 -1
  26. package/dist/main/CrowdViewWidget/components/Chart/chartUtils/handleLabelUpdate.js +3 -3
  27. package/dist/main/CrowdViewWidget/components/Chart/chartUtils/handleLabelUpdate.js.map +1 -1
  28. package/dist/main/CrowdViewWidget/components/Chart/chartUtils/index.js +22 -0
  29. package/dist/main/CrowdViewWidget/components/Chart/chartUtils/index.js.map +1 -1
  30. package/dist/main/CrowdViewWidget/components/Chart/chartUtils/normalizeLocale.js +11 -0
  31. package/dist/main/CrowdViewWidget/components/Chart/chartUtils/normalizeLocale.js.map +1 -0
  32. package/dist/main/CrowdViewWidget/components/Chart/dataUtils/processPriceCandles.js +1 -1
  33. package/dist/main/CrowdViewWidget/components/Chart/dataUtils/processPriceCandles.js.map +1 -1
  34. package/dist/main/CrowdViewWidget/components/Chart/getOption.js +11 -5
  35. package/dist/main/CrowdViewWidget/components/Chart/getOption.js.map +1 -1
  36. package/dist/main/CrowdViewWidget/components/Chart/types.js.map +1 -1
  37. package/dist/main/CrowdViewWidget/components/Chart/useResizeObserver.js +47 -0
  38. package/dist/main/CrowdViewWidget/components/Chart/useResizeObserver.js.map +1 -0
  39. package/dist/main/CrowdViewWidget/components/Legend/LegendBar.js +1 -1
  40. package/dist/main/CrowdViewWidget/components/Legend/LegendBar.js.map +1 -1
  41. package/dist/main/CrowdViewWidget/constants.js +22 -8
  42. package/dist/main/CrowdViewWidget/constants.js.map +1 -1
  43. package/dist/main/CrowdViewWidget/selectConfig.js +3 -3
  44. package/dist/main/CrowdViewWidget/selectConfig.js.map +1 -1
  45. package/dist/main/translations/sources/en.json +11 -9
  46. package/dist/module/CrowdViewWidget/components/Chart/Chart.js +9 -11
  47. package/dist/module/CrowdViewWidget/components/Chart/Chart.js.map +1 -1
  48. package/dist/module/CrowdViewWidget/components/Chart/ChartWithData.js +15 -3
  49. package/dist/module/CrowdViewWidget/components/Chart/ChartWithData.js.map +1 -1
  50. package/dist/module/CrowdViewWidget/components/Chart/chartOptions/getGridConfig.js +29 -14
  51. package/dist/module/CrowdViewWidget/components/Chart/chartOptions/getGridConfig.js.map +1 -1
  52. package/dist/module/CrowdViewWidget/components/Chart/chartOptions/getGridLines.js +28 -9
  53. package/dist/module/CrowdViewWidget/components/Chart/chartOptions/getGridLines.js.map +1 -1
  54. package/dist/module/CrowdViewWidget/components/Chart/chartOptions/getLabelsConfig.js +20 -8
  55. package/dist/module/CrowdViewWidget/components/Chart/chartOptions/getLabelsConfig.js.map +1 -1
  56. package/dist/module/CrowdViewWidget/components/Chart/chartOptions/getTooltipConfig.js +21 -16
  57. package/dist/module/CrowdViewWidget/components/Chart/chartOptions/getTooltipConfig.js.map +1 -1
  58. package/dist/module/CrowdViewWidget/components/Chart/chartOptions/getXAxisConfig.js +30 -7
  59. package/dist/module/CrowdViewWidget/components/Chart/chartOptions/getXAxisConfig.js.map +1 -1
  60. package/dist/module/CrowdViewWidget/components/Chart/chartOptions/getYAxisConfig.js +25 -5
  61. package/dist/module/CrowdViewWidget/components/Chart/chartOptions/getYAxisConfig.js.map +1 -1
  62. package/dist/module/CrowdViewWidget/components/Chart/chartUtils/formatFullDate.js +20 -0
  63. package/dist/module/CrowdViewWidget/components/Chart/chartUtils/formatFullDate.js.map +1 -0
  64. package/dist/module/CrowdViewWidget/components/Chart/chartUtils/formatXAxisAdditionalLabel.js +2 -2
  65. package/dist/module/CrowdViewWidget/components/Chart/chartUtils/formatXAxisAdditionalLabel.js.map +1 -1
  66. package/dist/module/CrowdViewWidget/components/Chart/chartUtils/formatXAxisLabel.js +6 -5
  67. package/dist/module/CrowdViewWidget/components/Chart/chartUtils/formatXAxisLabel.js.map +1 -1
  68. package/dist/module/CrowdViewWidget/components/Chart/chartUtils/getTooltipFormatter.js +71 -22
  69. package/dist/module/CrowdViewWidget/components/Chart/chartUtils/getTooltipFormatter.js.map +1 -1
  70. package/dist/module/CrowdViewWidget/components/Chart/chartUtils/handleLabelUpdate.js +3 -3
  71. package/dist/module/CrowdViewWidget/components/Chart/chartUtils/handleLabelUpdate.js.map +1 -1
  72. package/dist/module/CrowdViewWidget/components/Chart/chartUtils/index.js +2 -0
  73. package/dist/module/CrowdViewWidget/components/Chart/chartUtils/index.js.map +1 -1
  74. package/dist/module/CrowdViewWidget/components/Chart/chartUtils/normalizeLocale.js +4 -0
  75. package/dist/module/CrowdViewWidget/components/Chart/chartUtils/normalizeLocale.js.map +1 -0
  76. package/dist/module/CrowdViewWidget/components/Chart/dataUtils/processPriceCandles.js +1 -1
  77. package/dist/module/CrowdViewWidget/components/Chart/dataUtils/processPriceCandles.js.map +1 -1
  78. package/dist/module/CrowdViewWidget/components/Chart/getOption.js +11 -5
  79. package/dist/module/CrowdViewWidget/components/Chart/getOption.js.map +1 -1
  80. package/dist/module/CrowdViewWidget/components/Chart/types.js.map +1 -1
  81. package/dist/module/CrowdViewWidget/components/Chart/useResizeObserver.js +40 -0
  82. package/dist/module/CrowdViewWidget/components/Chart/useResizeObserver.js.map +1 -0
  83. package/dist/module/CrowdViewWidget/components/Legend/LegendBar.js +1 -1
  84. package/dist/module/CrowdViewWidget/components/Legend/LegendBar.js.map +1 -1
  85. package/dist/module/CrowdViewWidget/constants.js +22 -8
  86. package/dist/module/CrowdViewWidget/constants.js.map +1 -1
  87. package/dist/module/CrowdViewWidget/selectConfig.js +3 -3
  88. package/dist/module/CrowdViewWidget/selectConfig.js.map +1 -1
  89. package/dist/module/translations/sources/en.json +11 -9
  90. package/dist/types/CrowdViewWidget/components/Chart/chartOptions/getTooltipConfig.d.ts +4 -2
  91. package/dist/types/CrowdViewWidget/components/Chart/chartOptions/getXAxisConfig.d.ts +3 -1
  92. package/dist/types/CrowdViewWidget/components/Chart/chartOptions/getYAxisConfig.d.ts +4 -1
  93. package/dist/types/CrowdViewWidget/components/Chart/chartUtils/formatFullDate.d.ts +1 -0
  94. package/dist/types/CrowdViewWidget/components/Chart/chartUtils/formatXAxisAdditionalLabel.d.ts +1 -1
  95. package/dist/types/CrowdViewWidget/components/Chart/chartUtils/formatXAxisLabel.d.ts +1 -1
  96. package/dist/types/CrowdViewWidget/components/Chart/chartUtils/getTooltipFormatter.d.ts +4 -1
  97. package/dist/types/CrowdViewWidget/components/Chart/chartUtils/handleLabelUpdate.d.ts +1 -1
  98. package/dist/types/CrowdViewWidget/components/Chart/chartUtils/index.d.ts +2 -0
  99. package/dist/types/CrowdViewWidget/components/Chart/chartUtils/normalizeLocale.d.ts +1 -0
  100. package/dist/types/CrowdViewWidget/components/Chart/types.d.ts +1 -0
  101. package/dist/types/CrowdViewWidget/components/Chart/useResizeObserver.d.ts +5 -0
  102. package/dist/types/CrowdViewWidget/constants.d.ts +25 -19
  103. package/package.json +3 -3
  104. package/src/CrowdViewWidget/components/Chart/Chart.tsx +12 -11
  105. package/src/CrowdViewWidget/components/Chart/ChartWithData.tsx +22 -3
  106. package/src/CrowdViewWidget/components/Chart/chartOptions/getGridConfig.ts +35 -19
  107. package/src/CrowdViewWidget/components/Chart/chartOptions/getGridLines.ts +41 -11
  108. package/src/CrowdViewWidget/components/Chart/chartOptions/getLabelsConfig.ts +31 -11
  109. package/src/CrowdViewWidget/components/Chart/chartOptions/getTooltipConfig.ts +24 -22
  110. package/src/CrowdViewWidget/components/Chart/chartOptions/getXAxisConfig.ts +36 -5
  111. package/src/CrowdViewWidget/components/Chart/chartOptions/getYAxisConfig.ts +29 -6
  112. package/src/CrowdViewWidget/components/Chart/chartUtils/formatFullDate.ts +26 -0
  113. package/src/CrowdViewWidget/components/Chart/chartUtils/formatXAxisAdditionalLabel.ts +3 -2
  114. package/src/CrowdViewWidget/components/Chart/chartUtils/formatXAxisLabel.ts +6 -4
  115. package/src/CrowdViewWidget/components/Chart/chartUtils/getTooltipFormatter.ts +143 -32
  116. package/src/CrowdViewWidget/components/Chart/chartUtils/handleLabelUpdate.ts +8 -3
  117. package/src/CrowdViewWidget/components/Chart/chartUtils/index.ts +2 -0
  118. package/src/CrowdViewWidget/components/Chart/chartUtils/normalizeLocale.ts +3 -0
  119. package/src/CrowdViewWidget/components/Chart/dataUtils/processPriceCandles.ts +1 -1
  120. package/src/CrowdViewWidget/components/Chart/getOption.ts +7 -1
  121. package/src/CrowdViewWidget/components/Chart/types.ts +1 -0
  122. package/src/CrowdViewWidget/components/Chart/useResizeObserver.ts +51 -0
  123. package/src/CrowdViewWidget/components/Legend/LegendBar.tsx +3 -2
  124. package/src/CrowdViewWidget/constants.ts +27 -6
  125. package/src/CrowdViewWidget/selectConfig.ts +4 -4
  126. package/src/translations/sources/en.json +11 -9
  127. package/test/components/Chart/utils/chartUtils.test.ts +16 -4
  128. package/test/components/Chart/utils/handleLabelUpdate.test.ts +32 -16
  129. package/test/utils/processPriceCandles.test.ts +4 -4
@@ -1,3 +1,4 @@
1
+ export * from './formatFullDate';
1
2
  export * from './formatXAxisAdditionalLabel';
2
3
  export * from './formatXAxisLabel';
3
4
  export * from './getChartStyles';
@@ -8,3 +9,4 @@ export * from './getTooltipFormatter';
8
9
  export * from './handleLabelUpdate';
9
10
  export * from './handleTooltipUpdate';
10
11
  export * from './isDifferenceGreaterThanTwoWeeks';
12
+ export * from './normalizeLocale';
@@ -0,0 +1,3 @@
1
+ export const normalizeLocale = (locale: string): string => {
2
+ return locale === 'en' ? 'en-GB' : locale;
3
+ };
@@ -60,7 +60,7 @@ export const processPriceCandles = (
60
60
  candlesClose,
61
61
  candlesLow,
62
62
  candlesHigh,
63
- dates,
63
+ dates: [...dates, new Date().toISOString()],
64
64
  hasValidCandles: true,
65
65
  pipsLocation: priceCandlesData.priceCandles.pipsLocation,
66
66
  };
@@ -40,6 +40,7 @@ export const getOption: GetOptionType = ({
40
40
  isDark,
41
41
  isDesktop,
42
42
  labelCallback,
43
+ locale,
43
44
  }) => {
44
45
  const styles = getChartStyles(isDark);
45
46
  const selectedPriceRef = { current: 0 };
@@ -88,21 +89,26 @@ export const getOption: GetOptionType = ({
88
89
  bookType,
89
90
  bucketWidth,
90
91
  buckets,
91
- displayPrecision,
92
92
  labelCallback,
93
93
  selectedPriceRef,
94
94
  tooltipLinesColor: styles.tooltipLinesColor,
95
95
  sentimentLongs,
96
96
  sentimentShorts,
97
+ isDesktop,
98
+ isDark,
99
+ locale,
97
100
  }),
98
101
  grid: getGridConfig({ isDesktop }),
99
102
  xAxis: getXAxisConfig({
100
103
  dates,
101
104
  isGreaterThanTwoWeeks,
105
+ locale,
106
+ isDesktop,
102
107
  }),
103
108
  yAxis: getYAxisConfig({
104
109
  bucketWidth,
105
110
  displayPrecision,
111
+ selectedPriceRef,
106
112
  }),
107
113
  dataZoom: getDataZoomConfig({ isDesktop }),
108
114
  visualMap: getVisualMapConfig({
@@ -57,6 +57,7 @@ interface GetOptionProps {
57
57
  isDesktop: boolean;
58
58
  isLoading: boolean;
59
59
  labelCallback: (key: string, params?: Record<string, unknown>) => string;
60
+ locale: string;
60
61
  }
61
62
 
62
63
  export type GetOptionType = (props: GetOptionProps) => EChartsOption;
@@ -0,0 +1,51 @@
1
+ import { useEffect, useRef, useState } from 'react';
2
+
3
+ interface UseResizeObserverOptions {
4
+ debounceDelay?: number;
5
+ }
6
+
7
+ export const useResizeObserver = (
8
+ options: UseResizeObserverOptions = {}
9
+ ): [React.RefObject<HTMLDivElement>, boolean] => {
10
+ const { debounceDelay = 150 } = options;
11
+ const [isResizing, setIsResizing] = useState(false);
12
+ const containerRef = useRef<HTMLDivElement>(null);
13
+ const resizeTimeoutRef = useRef<NodeJS.Timeout | null>(null);
14
+
15
+ useEffect(() => {
16
+ const container = containerRef.current;
17
+ if (!container) {
18
+ return undefined;
19
+ }
20
+
21
+ if (typeof ResizeObserver === 'undefined') {
22
+ console.warn('ResizeObserver is not supported in this browser');
23
+ return undefined;
24
+ }
25
+
26
+ const resizeObserver = new ResizeObserver(() => {
27
+ setIsResizing(true);
28
+
29
+ if (resizeTimeoutRef.current) {
30
+ clearTimeout(resizeTimeoutRef.current);
31
+ }
32
+
33
+ resizeTimeoutRef.current = setTimeout(() => {
34
+ setIsResizing(false);
35
+ resizeTimeoutRef.current = null;
36
+ }, debounceDelay);
37
+ });
38
+
39
+ resizeObserver.observe(container);
40
+
41
+ return () => {
42
+ resizeObserver.disconnect();
43
+ if (resizeTimeoutRef.current) {
44
+ clearTimeout(resizeTimeoutRef.current);
45
+ resizeTimeoutRef.current = null;
46
+ }
47
+ };
48
+ }, [debounceDelay]);
49
+
50
+ return [containerRef, isResizing];
51
+ };
@@ -12,14 +12,15 @@ interface LegendBarProps {
12
12
 
13
13
  export const LegendBar = ({ type, isDark }: LegendBarProps) => {
14
14
  const colorPalette = isDark ? COLOR_MAP.dark : COLOR_MAP.light;
15
+
15
16
  const startColor =
16
17
  type === 'long' ? colorPalette.long[1] : colorPalette.short[0];
17
18
  const endColor =
18
19
  type === 'long' ? colorPalette.long[0] : colorPalette.short[1];
19
20
  const endGradient =
20
21
  type === 'long'
21
- ? `linear-gradient(90deg,${endColor} 0%, transparent 100%)`
22
- : `linear-gradient(270deg,${startColor} 0%, transparent 100%)`;
22
+ ? `linear-gradient(90deg,${endColor} 0%, ${colorPalette.backgroundColor} 100%)`
23
+ : `linear-gradient(270deg,${startColor} 0%, ${colorPalette.backgroundColor} 100%)`;
23
24
 
24
25
  return (
25
26
  <div
@@ -15,9 +15,9 @@ export const TIME_THRESHOLDS = {
15
15
  TWO_WEEKS_MS: 14 * 24 * 60 * 60 * 1000,
16
16
  } as const;
17
17
 
18
- export const CHART_CONFIG = {
19
- HEIGHT: 440,
20
- MAIN_HEIGHT: 400,
18
+ const CHART_CONFIG_STATIC = {
19
+ MAIN_HEIGHT_DESKTOP: 410,
20
+ MAIN_HEIGHT_MOBILE: 330,
21
21
  MARGIN_BETWEEN: 50,
22
22
  SENTIMENT_HEIGHT: 120,
23
23
  WIDTH: 9999,
@@ -32,9 +32,28 @@ export const CHART_CONFIG = {
32
32
  X_AXIS_DATE_PADDING: ' ',
33
33
  SENTIMENT_MIN: 0,
34
34
  SENTIMENT_MAX: 100,
35
- TOP_MARGIN_DESKTOP: 0,
36
- TOP_MARGIN_MOBILE: 30,
37
- TOOLTIP_OFFSET: 5,
35
+ TOP_LABEL_SPACE_DESKTOP: 0,
36
+ TOP_LABEL_SPACE_MOBILE: 24,
37
+ TOOLTIP_HEIGHT_MOBILE: 85,
38
+ TOOLTIP_HEIGHT_DESKTOP: 46,
39
+ TOOLTIP_OFFSET: 8,
40
+ };
41
+
42
+ const CHART_CONFIG_CALCULATED = {
43
+ HEIGHT_DESKTOP:
44
+ CHART_CONFIG_STATIC.MAIN_HEIGHT_DESKTOP +
45
+ CHART_CONFIG_STATIC.TOP_LABEL_SPACE_DESKTOP +
46
+ CHART_CONFIG_STATIC.X_LABEL_SIZE +
47
+ CHART_CONFIG_STATIC.TOOLTIP_HEIGHT_DESKTOP,
48
+ HEIGHT_MOBILE:
49
+ CHART_CONFIG_STATIC.MAIN_HEIGHT_MOBILE +
50
+ CHART_CONFIG_STATIC.X_LABEL_SIZE +
51
+ CHART_CONFIG_STATIC.TOP_LABEL_SPACE_MOBILE +
52
+ CHART_CONFIG_STATIC.TOOLTIP_HEIGHT_MOBILE,
53
+ };
54
+ export const CHART_CONFIG = {
55
+ ...CHART_CONFIG_STATIC,
56
+ ...CHART_CONFIG_CALCULATED,
38
57
  } as const;
39
58
 
40
59
  export const COLOR_MAP = {
@@ -47,6 +66,7 @@ export const COLOR_MAP = {
47
66
  chroma(colorPalette.darkYellow10).shade(0.5).hex(),
48
67
  chroma(colorPalette.darkYellow90).shade(0.5).hex(),
49
68
  ],
69
+ backgroundColor: colorPalette.black,
50
70
  },
51
71
  light: {
52
72
  long: [
@@ -57,6 +77,7 @@ export const COLOR_MAP = {
57
77
  chroma(colorPalette.lightYellow10).tint(0.5).hex(),
58
78
  chroma(colorPalette.lightYellow90).tint(0.5).hex(),
59
79
  ],
80
+ backgroundColor: colorPalette.white,
60
81
  },
61
82
  } as const;
62
83
 
@@ -13,6 +13,10 @@ const navigationConfig = [
13
13
  ];
14
14
 
15
15
  const instrumentSelectConfigOC = [
16
+ {
17
+ id: InstrumentId.EUR_USD,
18
+ label: 'EUR/USD',
19
+ },
16
20
  {
17
21
  id: InstrumentId.EUR_AUD,
18
22
  label: 'EUR/AUD',
@@ -25,10 +29,6 @@ const instrumentSelectConfigOC = [
25
29
  id: InstrumentId.EUR_JPY,
26
30
  label: 'EUR/JPY',
27
31
  },
28
- {
29
- id: InstrumentId.EUR_USD,
30
- label: 'EUR/USD',
31
- },
32
32
  {
33
33
  id: InstrumentId.EUR_CHF,
34
34
  label: 'EUR/CHF',
@@ -3,31 +3,33 @@
3
3
  "15_minutes": "15 minutes",
4
4
  "4_hours": "4 hours",
5
5
  "5_minutes": "5 minutes",
6
- "buy_overbalance": "Buy overbalance",
7
6
  "buy": "Buy",
7
+ "buy_overbalance": "Buy overbalance",
8
8
  "candle": "Candle",
9
- "close_price": "Close price",
9
+ "close": "Close",
10
10
  "data_unavailable": "Data unavailable",
11
+ "even_market_demand": "Even market demand",
11
12
  "granularity": "Granularity",
12
13
  "high": "High",
13
14
  "instrument": "Instrument",
14
- "long_overbalance": "Long overbalance",
15
15
  "long": "Long",
16
+ "long_overbalance": "Long overbalance",
16
17
  "low": "Low",
17
18
  "no_matching_results": "No matching results",
18
- "open_price": "Open price",
19
+ "open": "Open",
19
20
  "order_book": "Order book",
20
21
  "orders": "Orders",
21
22
  "pagination_entries_range": "{{firstItemOnPage}}-{{lastItemOnPage}} of {{itemCount}} entries",
22
23
  "position_book": "Position book",
23
- "positions": "Positions",
24
+ "price": "Price",
24
25
  "price_range": "Price range",
25
26
  "search": "Search",
26
- "sell_overbalance": "Sell overbalance",
27
27
  "sell": "Sell",
28
+ "sell_overbalance": "Sell overbalance",
28
29
  "sentiment": "Sentiment",
29
- "short_overbalance": "Short overbalance",
30
30
  "short": "Short",
31
- "even_market_demand": "Even market demand",
32
- "price": "Price"
31
+ "short_overbalance": "Short overbalance",
32
+ "tap_chart_to_see_more_details": "Tap the chart to see more details",
33
+ "hover_chart_to_see_more_details": "Hover over the chart to see more details",
34
+ "trades": "Trades"
33
35
  }
@@ -110,13 +110,13 @@ describe('chartUtils', () => {
110
110
  const sampleIso = '2025-03-15T10:30:00Z';
111
111
 
112
112
  it('formats time when flag is true', () => {
113
- const result = formatXAxisLabel(sampleIso, true);
113
+ const result = formatXAxisLabel(sampleIso, true, 'en-US');
114
114
  expect(typeof result).toBe('string');
115
115
  expect(result).toContain(':');
116
116
  });
117
117
 
118
118
  it('formats day when flag is false', () => {
119
- const result = formatXAxisLabel(sampleIso, false);
119
+ const result = formatXAxisLabel(sampleIso, false, 'en-US');
120
120
  expect(typeof result).toBe('string');
121
121
  // Contains day of month (15) with surrounding spaces per implementation
122
122
  expect(result).toMatch(/\s15\s/);
@@ -189,11 +189,14 @@ describe('chartUtils', () => {
189
189
  labelCallback,
190
190
  sentimentLongs: [],
191
191
  sentimentShorts: [],
192
+ isDesktop: true,
193
+ locale: 'en-US',
194
+ isDark: false,
192
195
  });
193
196
  expect(html).toBeDefined();
194
197
  expect(html).toContain('candle');
195
- expect(html).toContain('open_price');
196
- expect(html).toContain('close_price');
198
+ expect(html).toContain('open');
199
+ expect(html).toContain('close');
197
200
  expect(html).toContain('low');
198
201
  expect(html).toContain('high');
199
202
  expect(html).toContain('orders');
@@ -227,6 +230,9 @@ describe('chartUtils', () => {
227
230
  labelCallback,
228
231
  sentimentLongs: [30.5],
229
232
  sentimentShorts: [69.5],
233
+ isDesktop: true,
234
+ locale: 'en-US',
235
+ isDark: false,
230
236
  });
231
237
  expect(html).toBeDefined();
232
238
  expect(html).toContain('candle');
@@ -257,6 +263,9 @@ describe('chartUtils', () => {
257
263
  labelCallback,
258
264
  sentimentLongs: [],
259
265
  sentimentShorts: [],
266
+ isDesktop: true,
267
+ locale: 'en-US',
268
+ isDark: false,
260
269
  });
261
270
  expect(html).toBe('');
262
271
  });
@@ -271,6 +280,9 @@ describe('chartUtils', () => {
271
280
  labelCallback,
272
281
  sentimentLongs: [],
273
282
  sentimentShorts: [],
283
+ isDesktop: true,
284
+ locale: 'en-US',
285
+ isDark: false,
274
286
  });
275
287
  expect(html).toBe('');
276
288
  });
@@ -95,7 +95,8 @@ describe('handleLabelUpdate', () => {
95
95
  mockInstance,
96
96
  mainData,
97
97
  labelTimerRef,
98
- isGreaterThanTwoWeeksRef
98
+ isGreaterThanTwoWeeksRef,
99
+ 'en-US'
99
100
  );
100
101
 
101
102
  jest.advanceTimersByTime(50);
@@ -113,7 +114,8 @@ describe('handleLabelUpdate', () => {
113
114
  mockInstance,
114
115
  mainData,
115
116
  labelTimerRef,
116
- isGreaterThanTwoWeeksRef
117
+ isGreaterThanTwoWeeksRef,
118
+ 'en-US'
117
119
  );
118
120
 
119
121
  jest.advanceTimersByTime(50);
@@ -131,7 +133,8 @@ describe('handleLabelUpdate', () => {
131
133
  mockInstance,
132
134
  mainData,
133
135
  labelTimerRef,
134
- isGreaterThanTwoWeeksRef
136
+ isGreaterThanTwoWeeksRef,
137
+ 'en-US'
135
138
  );
136
139
 
137
140
  jest.advanceTimersByTime(50);
@@ -149,7 +152,8 @@ describe('handleLabelUpdate', () => {
149
152
  mockInstance,
150
153
  mainData,
151
154
  labelTimerRef,
152
- isGreaterThanTwoWeeksRef
155
+ isGreaterThanTwoWeeksRef,
156
+ 'en-US'
153
157
  );
154
158
 
155
159
  jest.advanceTimersByTime(50);
@@ -167,7 +171,8 @@ describe('handleLabelUpdate', () => {
167
171
  mockInstance,
168
172
  mainData,
169
173
  labelTimerRef,
170
- isGreaterThanTwoWeeksRef
174
+ isGreaterThanTwoWeeksRef,
175
+ 'en-US'
171
176
  );
172
177
 
173
178
  jest.advanceTimersByTime(50);
@@ -187,7 +192,8 @@ describe('handleLabelUpdate', () => {
187
192
  mockInstance,
188
193
  mainData,
189
194
  labelTimerRef,
190
- isGreaterThanTwoWeeksRef
195
+ isGreaterThanTwoWeeksRef,
196
+ 'en-US'
191
197
  );
192
198
 
193
199
  jest.advanceTimersByTime(50);
@@ -205,7 +211,8 @@ describe('handleLabelUpdate', () => {
205
211
  mockInstance,
206
212
  mainData,
207
213
  labelTimerRef,
208
- isGreaterThanTwoWeeksRef
214
+ isGreaterThanTwoWeeksRef,
215
+ 'en-US'
209
216
  );
210
217
 
211
218
  jest.advanceTimersByTime(50);
@@ -227,7 +234,8 @@ describe('handleLabelUpdate', () => {
227
234
  mockInstance,
228
235
  mainData,
229
236
  labelTimerRef,
230
- isGreaterThanTwoWeeksRef
237
+ isGreaterThanTwoWeeksRef,
238
+ 'en-US'
231
239
  );
232
240
 
233
241
  jest.advanceTimersByTime(50);
@@ -264,7 +272,8 @@ describe('handleLabelUpdate', () => {
264
272
  mockInstance,
265
273
  mainData,
266
274
  labelTimerRef,
267
- isGreaterThanTwoWeeksRef
275
+ isGreaterThanTwoWeeksRef,
276
+ 'en-US'
268
277
  );
269
278
 
270
279
  jest.advanceTimersByTime(50);
@@ -285,7 +294,8 @@ describe('handleLabelUpdate', () => {
285
294
  mockInstance,
286
295
  mainData,
287
296
  labelTimerRef,
288
- isGreaterThanTwoWeeksRef
297
+ isGreaterThanTwoWeeksRef,
298
+ 'en-US'
289
299
  );
290
300
 
291
301
  jest.advanceTimersByTime(50);
@@ -310,7 +320,8 @@ describe('handleLabelUpdate', () => {
310
320
  mockInstance,
311
321
  mainData,
312
322
  labelTimerRef,
313
- isGreaterThanTwoWeeksRef
323
+ isGreaterThanTwoWeeksRef,
324
+ 'en-US'
314
325
  );
315
326
 
316
327
  expect(clearTimeoutSpy).toHaveBeenCalledWith(existingTimeout);
@@ -329,7 +340,8 @@ describe('handleLabelUpdate', () => {
329
340
  mockInstance,
330
341
  mainData,
331
342
  labelTimerRef,
332
- isGreaterThanTwoWeeksRef
343
+ isGreaterThanTwoWeeksRef,
344
+ 'en-US'
333
345
  );
334
346
 
335
347
  // Should not be called before timeout
@@ -358,7 +370,8 @@ describe('handleLabelUpdate', () => {
358
370
  mockInstance,
359
371
  mainData,
360
372
  labelTimerRef,
361
- isGreaterThanTwoWeeksRef
373
+ isGreaterThanTwoWeeksRef,
374
+ 'en-US'
362
375
  );
363
376
 
364
377
  jest.advanceTimersByTime(50);
@@ -376,7 +389,8 @@ describe('handleLabelUpdate', () => {
376
389
 
377
390
  expect(mockFormatXAxisLabel).toHaveBeenCalledWith(
378
391
  '2025-01-01T00:00:00Z',
379
- true
392
+ true,
393
+ 'en-US'
380
394
  );
381
395
  });
382
396
 
@@ -392,7 +406,8 @@ describe('handleLabelUpdate', () => {
392
406
  mockInstance,
393
407
  mainData,
394
408
  labelTimerRef,
395
- isGreaterThanTwoWeeksRef
409
+ isGreaterThanTwoWeeksRef,
410
+ 'en-US'
396
411
  );
397
412
 
398
413
  jest.advanceTimersByTime(50);
@@ -412,7 +427,8 @@ describe('handleLabelUpdate', () => {
412
427
 
413
428
  expect(mockFormatXAxisAdditionalLabel).toHaveBeenCalledWith(
414
429
  '2025-01-02T00:00:00Z',
415
- true
430
+ true,
431
+ 'en-US'
416
432
  );
417
433
  });
418
434
  });
@@ -90,7 +90,7 @@ describe('processPriceCandles', () => {
90
90
  expect(result.minPrice).toBe(0.9);
91
91
  expect(result.maxPrice).toBe(1.8);
92
92
  expect(result.pipsLocation).toBe(4);
93
- expect(result.dates).toHaveLength(3);
93
+ expect(result.dates).toHaveLength(4);
94
94
  expect(result.candlesOpen).toHaveLength(3);
95
95
  expect(result.candlesClose).toHaveLength(3);
96
96
  expect(result.candlesLow).toHaveLength(3);
@@ -131,7 +131,7 @@ describe('processPriceCandles', () => {
131
131
  expect(result.minPrice).toBe(1.0);
132
132
  expect(result.maxPrice).toBe(1.8);
133
133
  expect(result.pipsLocation).toBe(4);
134
- expect(result.dates).toHaveLength(2);
134
+ expect(result.dates).toHaveLength(3);
135
135
  expect(result.candlesOpen).toHaveLength(2);
136
136
  });
137
137
 
@@ -188,7 +188,7 @@ describe('processPriceCandles', () => {
188
188
  expect(result.minPrice).toBe(1.0);
189
189
  expect(result.maxPrice).toBe(1.5);
190
190
  expect(result.pipsLocation).toBe(4);
191
- expect(result.dates).toHaveLength(1);
191
+ expect(result.dates).toHaveLength(2);
192
192
  expect(result.candlesOpen).toHaveLength(1);
193
193
  });
194
194
 
@@ -263,7 +263,7 @@ describe('processPriceCandles', () => {
263
263
  const result = processPriceCandles(mockData);
264
264
  expect(result.hasValidCandles).toBe(true);
265
265
  expect(result.pipsLocation).toBe(4);
266
- expect(result.dates).toHaveLength(10000);
266
+ expect(result.dates).toHaveLength(10001);
267
267
  // Should calculate min/max without stack overflow
268
268
  expect(result.minPrice).toBeGreaterThan(0);
269
269
  expect(result.maxPrice).toBeGreaterThan(result.minPrice);