@oanda/labs-crowd-view-widget 1.0.54 → 1.0.56

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 (193) hide show
  1. package/CHANGELOG.md +452 -0
  2. package/dist/main/CrowdViewWidget/components/Chart/Chart.js +42 -58
  3. package/dist/main/CrowdViewWidget/components/Chart/Chart.js.map +1 -1
  4. package/dist/main/CrowdViewWidget/components/Chart/ChartWithData.js +33 -8
  5. package/dist/main/CrowdViewWidget/components/Chart/ChartWithData.js.map +1 -1
  6. package/dist/main/CrowdViewWidget/components/Chart/chartOptions/getDataZoomConfig.js +15 -9
  7. package/dist/main/CrowdViewWidget/components/Chart/chartOptions/getDataZoomConfig.js.map +1 -1
  8. package/dist/main/CrowdViewWidget/components/Chart/chartOptions/getGridConfig.js +28 -14
  9. package/dist/main/CrowdViewWidget/components/Chart/chartOptions/getGridConfig.js.map +1 -1
  10. package/dist/main/CrowdViewWidget/components/Chart/chartOptions/getGridLines.js +55 -15
  11. package/dist/main/CrowdViewWidget/components/Chart/chartOptions/getGridLines.js.map +1 -1
  12. package/dist/main/CrowdViewWidget/components/Chart/chartOptions/getLabelsConfig.js +171 -0
  13. package/dist/main/CrowdViewWidget/components/Chart/chartOptions/getLabelsConfig.js.map +1 -0
  14. package/dist/main/CrowdViewWidget/components/Chart/chartOptions/getSeriesCandlestickConfig.js +7 -14
  15. package/dist/main/CrowdViewWidget/components/Chart/chartOptions/getSeriesCandlestickConfig.js.map +1 -1
  16. package/dist/main/CrowdViewWidget/components/Chart/chartOptions/getSeriesHeatmapConfig.js +20 -2
  17. package/dist/main/CrowdViewWidget/components/Chart/chartOptions/getSeriesHeatmapConfig.js.map +1 -1
  18. package/dist/main/CrowdViewWidget/components/Chart/chartOptions/getSeriesSentimentConfig.js +13 -5
  19. package/dist/main/CrowdViewWidget/components/Chart/chartOptions/getSeriesSentimentConfig.js.map +1 -1
  20. package/dist/main/CrowdViewWidget/components/Chart/chartOptions/getTooltipConfig.js +51 -5
  21. package/dist/main/CrowdViewWidget/components/Chart/chartOptions/getTooltipConfig.js.map +1 -1
  22. package/dist/main/CrowdViewWidget/components/Chart/chartOptions/getXAxisConfig.js +30 -7
  23. package/dist/main/CrowdViewWidget/components/Chart/chartOptions/getXAxisConfig.js.map +1 -1
  24. package/dist/main/CrowdViewWidget/components/Chart/chartOptions/getYAxisConfig.js +27 -29
  25. package/dist/main/CrowdViewWidget/components/Chart/chartOptions/getYAxisConfig.js.map +1 -1
  26. package/dist/main/CrowdViewWidget/components/Chart/chartOptions/index.js +11 -0
  27. package/dist/main/CrowdViewWidget/components/Chart/chartOptions/index.js.map +1 -1
  28. package/dist/main/CrowdViewWidget/components/Chart/chartUtils/formatXAxisAdditionalLabel.js +18 -0
  29. package/dist/main/CrowdViewWidget/components/Chart/chartUtils/formatXAxisAdditionalLabel.js.map +1 -0
  30. package/dist/main/CrowdViewWidget/components/Chart/chartUtils/formatXAxisLabel.js +6 -5
  31. package/dist/main/CrowdViewWidget/components/Chart/chartUtils/formatXAxisLabel.js.map +1 -1
  32. package/dist/main/CrowdViewWidget/components/Chart/chartUtils/getLabelData.js +1 -20
  33. package/dist/main/CrowdViewWidget/components/Chart/chartUtils/getLabelData.js.map +1 -1
  34. package/dist/main/CrowdViewWidget/components/Chart/chartUtils/getTooltipFormatter.js +91 -21
  35. package/dist/main/CrowdViewWidget/components/Chart/chartUtils/getTooltipFormatter.js.map +1 -1
  36. package/dist/main/CrowdViewWidget/components/Chart/chartUtils/handleLabelUpdate.js +59 -0
  37. package/dist/main/CrowdViewWidget/components/Chart/chartUtils/handleLabelUpdate.js.map +1 -0
  38. package/dist/main/CrowdViewWidget/components/Chart/chartUtils/handleTooltipUpdate.js +34 -0
  39. package/dist/main/CrowdViewWidget/components/Chart/chartUtils/handleTooltipUpdate.js.map +1 -0
  40. package/dist/main/CrowdViewWidget/components/Chart/chartUtils/index.js +44 -0
  41. package/dist/main/CrowdViewWidget/components/Chart/chartUtils/index.js.map +1 -1
  42. package/dist/main/CrowdViewWidget/components/Chart/chartUtils/normalizeLocale.js +11 -0
  43. package/dist/main/CrowdViewWidget/components/Chart/chartUtils/normalizeLocale.js.map +1 -0
  44. package/dist/main/CrowdViewWidget/components/Chart/dataUtils/getMultiplayerForTimeSpan.js +19 -0
  45. package/dist/main/CrowdViewWidget/components/Chart/dataUtils/getMultiplayerForTimeSpan.js.map +1 -0
  46. package/dist/main/CrowdViewWidget/components/Chart/dataUtils/index.js +11 -0
  47. package/dist/main/CrowdViewWidget/components/Chart/dataUtils/index.js.map +1 -1
  48. package/dist/main/CrowdViewWidget/components/Chart/dataUtils/processPriceCandles.js +1 -1
  49. package/dist/main/CrowdViewWidget/components/Chart/dataUtils/processPriceCandles.js.map +1 -1
  50. package/dist/main/CrowdViewWidget/components/Chart/getOption.js +41 -23
  51. package/dist/main/CrowdViewWidget/components/Chart/getOption.js.map +1 -1
  52. package/dist/main/CrowdViewWidget/components/Chart/types.js.map +1 -1
  53. package/dist/main/CrowdViewWidget/components/Chart/useCrowdViewData.js +7 -4
  54. package/dist/main/CrowdViewWidget/components/Chart/useCrowdViewData.js.map +1 -1
  55. package/dist/main/CrowdViewWidget/components/Chart/useResizeObserver.js +47 -0
  56. package/dist/main/CrowdViewWidget/components/Chart/useResizeObserver.js.map +1 -0
  57. package/dist/main/CrowdViewWidget/components/Legend/Legend.js +1 -1
  58. package/dist/main/CrowdViewWidget/components/Legend/Legend.js.map +1 -1
  59. package/dist/main/CrowdViewWidget/components/Legend/LegendBar.js +11 -1
  60. package/dist/main/CrowdViewWidget/components/Legend/LegendBar.js.map +1 -1
  61. package/dist/main/CrowdViewWidget/constants.js +31 -10
  62. package/dist/main/CrowdViewWidget/constants.js.map +1 -1
  63. package/dist/main/CrowdViewWidget/selectConfig.js +3 -9
  64. package/dist/main/CrowdViewWidget/selectConfig.js.map +1 -1
  65. package/dist/main/translations/sources/en.json +10 -8
  66. package/dist/module/CrowdViewWidget/components/Chart/Chart.js +43 -58
  67. package/dist/module/CrowdViewWidget/components/Chart/Chart.js.map +1 -1
  68. package/dist/module/CrowdViewWidget/components/Chart/ChartWithData.js +32 -7
  69. package/dist/module/CrowdViewWidget/components/Chart/ChartWithData.js.map +1 -1
  70. package/dist/module/CrowdViewWidget/components/Chart/chartOptions/getDataZoomConfig.js +15 -9
  71. package/dist/module/CrowdViewWidget/components/Chart/chartOptions/getDataZoomConfig.js.map +1 -1
  72. package/dist/module/CrowdViewWidget/components/Chart/chartOptions/getGridConfig.js +28 -14
  73. package/dist/module/CrowdViewWidget/components/Chart/chartOptions/getGridConfig.js.map +1 -1
  74. package/dist/module/CrowdViewWidget/components/Chart/chartOptions/getGridLines.js +55 -15
  75. package/dist/module/CrowdViewWidget/components/Chart/chartOptions/getGridLines.js.map +1 -1
  76. package/dist/module/CrowdViewWidget/components/Chart/chartOptions/getLabelsConfig.js +163 -0
  77. package/dist/module/CrowdViewWidget/components/Chart/chartOptions/getLabelsConfig.js.map +1 -0
  78. package/dist/module/CrowdViewWidget/components/Chart/chartOptions/getSeriesCandlestickConfig.js +7 -14
  79. package/dist/module/CrowdViewWidget/components/Chart/chartOptions/getSeriesCandlestickConfig.js.map +1 -1
  80. package/dist/module/CrowdViewWidget/components/Chart/chartOptions/getSeriesHeatmapConfig.js +20 -2
  81. package/dist/module/CrowdViewWidget/components/Chart/chartOptions/getSeriesHeatmapConfig.js.map +1 -1
  82. package/dist/module/CrowdViewWidget/components/Chart/chartOptions/getSeriesSentimentConfig.js +13 -5
  83. package/dist/module/CrowdViewWidget/components/Chart/chartOptions/getSeriesSentimentConfig.js.map +1 -1
  84. package/dist/module/CrowdViewWidget/components/Chart/chartOptions/getTooltipConfig.js +50 -5
  85. package/dist/module/CrowdViewWidget/components/Chart/chartOptions/getTooltipConfig.js.map +1 -1
  86. package/dist/module/CrowdViewWidget/components/Chart/chartOptions/getXAxisConfig.js +31 -8
  87. package/dist/module/CrowdViewWidget/components/Chart/chartOptions/getXAxisConfig.js.map +1 -1
  88. package/dist/module/CrowdViewWidget/components/Chart/chartOptions/getYAxisConfig.js +28 -30
  89. package/dist/module/CrowdViewWidget/components/Chart/chartOptions/getYAxisConfig.js.map +1 -1
  90. package/dist/module/CrowdViewWidget/components/Chart/chartOptions/index.js +1 -0
  91. package/dist/module/CrowdViewWidget/components/Chart/chartOptions/index.js.map +1 -1
  92. package/dist/module/CrowdViewWidget/components/Chart/chartUtils/formatXAxisAdditionalLabel.js +11 -0
  93. package/dist/module/CrowdViewWidget/components/Chart/chartUtils/formatXAxisAdditionalLabel.js.map +1 -0
  94. package/dist/module/CrowdViewWidget/components/Chart/chartUtils/formatXAxisLabel.js +6 -5
  95. package/dist/module/CrowdViewWidget/components/Chart/chartUtils/formatXAxisLabel.js.map +1 -1
  96. package/dist/module/CrowdViewWidget/components/Chart/chartUtils/getLabelData.js +1 -20
  97. package/dist/module/CrowdViewWidget/components/Chart/chartUtils/getLabelData.js.map +1 -1
  98. package/dist/module/CrowdViewWidget/components/Chart/chartUtils/getTooltipFormatter.js +91 -21
  99. package/dist/module/CrowdViewWidget/components/Chart/chartUtils/getTooltipFormatter.js.map +1 -1
  100. package/dist/module/CrowdViewWidget/components/Chart/chartUtils/handleLabelUpdate.js +52 -0
  101. package/dist/module/CrowdViewWidget/components/Chart/chartUtils/handleLabelUpdate.js.map +1 -0
  102. package/dist/module/CrowdViewWidget/components/Chart/chartUtils/handleTooltipUpdate.js +27 -0
  103. package/dist/module/CrowdViewWidget/components/Chart/chartUtils/handleTooltipUpdate.js.map +1 -0
  104. package/dist/module/CrowdViewWidget/components/Chart/chartUtils/index.js +4 -0
  105. package/dist/module/CrowdViewWidget/components/Chart/chartUtils/index.js.map +1 -1
  106. package/dist/module/CrowdViewWidget/components/Chart/chartUtils/normalizeLocale.js +4 -0
  107. package/dist/module/CrowdViewWidget/components/Chart/chartUtils/normalizeLocale.js.map +1 -0
  108. package/dist/module/CrowdViewWidget/components/Chart/dataUtils/getMultiplayerForTimeSpan.js +12 -0
  109. package/dist/module/CrowdViewWidget/components/Chart/dataUtils/getMultiplayerForTimeSpan.js.map +1 -0
  110. package/dist/module/CrowdViewWidget/components/Chart/dataUtils/index.js +1 -0
  111. package/dist/module/CrowdViewWidget/components/Chart/dataUtils/index.js.map +1 -1
  112. package/dist/module/CrowdViewWidget/components/Chart/dataUtils/processPriceCandles.js +1 -1
  113. package/dist/module/CrowdViewWidget/components/Chart/dataUtils/processPriceCandles.js.map +1 -1
  114. package/dist/module/CrowdViewWidget/components/Chart/getOption.js +42 -24
  115. package/dist/module/CrowdViewWidget/components/Chart/getOption.js.map +1 -1
  116. package/dist/module/CrowdViewWidget/components/Chart/types.js.map +1 -1
  117. package/dist/module/CrowdViewWidget/components/Chart/useCrowdViewData.js +8 -5
  118. package/dist/module/CrowdViewWidget/components/Chart/useCrowdViewData.js.map +1 -1
  119. package/dist/module/CrowdViewWidget/components/Chart/useResizeObserver.js +40 -0
  120. package/dist/module/CrowdViewWidget/components/Chart/useResizeObserver.js.map +1 -0
  121. package/dist/module/CrowdViewWidget/components/Legend/Legend.js +1 -1
  122. package/dist/module/CrowdViewWidget/components/Legend/Legend.js.map +1 -1
  123. package/dist/module/CrowdViewWidget/components/Legend/LegendBar.js +11 -1
  124. package/dist/module/CrowdViewWidget/components/Legend/LegendBar.js.map +1 -1
  125. package/dist/module/CrowdViewWidget/constants.js +31 -10
  126. package/dist/module/CrowdViewWidget/constants.js.map +1 -1
  127. package/dist/module/CrowdViewWidget/selectConfig.js +3 -9
  128. package/dist/module/CrowdViewWidget/selectConfig.js.map +1 -1
  129. package/dist/module/translations/sources/en.json +10 -8
  130. package/dist/types/CrowdViewWidget/components/Chart/Chart.d.ts +1 -1
  131. package/dist/types/CrowdViewWidget/components/Chart/chartOptions/getDataZoomConfig.d.ts +5 -1
  132. package/dist/types/CrowdViewWidget/components/Chart/chartOptions/getGridLines.d.ts +2 -1
  133. package/dist/types/CrowdViewWidget/components/Chart/chartOptions/getLabelsConfig.d.ts +8 -0
  134. package/dist/types/CrowdViewWidget/components/Chart/chartOptions/getSeriesCandlestickConfig.d.ts +2 -3
  135. package/dist/types/CrowdViewWidget/components/Chart/chartOptions/getSeriesHeatmapConfig.d.ts +2 -1
  136. package/dist/types/CrowdViewWidget/components/Chart/chartOptions/getSeriesSentimentConfig.d.ts +2 -1
  137. package/dist/types/CrowdViewWidget/components/Chart/chartOptions/getTooltipConfig.d.ts +6 -1
  138. package/dist/types/CrowdViewWidget/components/Chart/chartOptions/getXAxisConfig.d.ts +2 -1
  139. package/dist/types/CrowdViewWidget/components/Chart/chartOptions/getYAxisConfig.d.ts +1 -2
  140. package/dist/types/CrowdViewWidget/components/Chart/chartOptions/index.d.ts +1 -0
  141. package/dist/types/CrowdViewWidget/components/Chart/chartUtils/formatXAxisAdditionalLabel.d.ts +1 -0
  142. package/dist/types/CrowdViewWidget/components/Chart/chartUtils/formatXAxisLabel.d.ts +1 -1
  143. package/dist/types/CrowdViewWidget/components/Chart/chartUtils/getLabelData.d.ts +1 -16
  144. package/dist/types/CrowdViewWidget/components/Chart/chartUtils/getTooltipFormatter.d.ts +6 -1
  145. package/dist/types/CrowdViewWidget/components/Chart/chartUtils/handleLabelUpdate.d.ts +4 -0
  146. package/dist/types/CrowdViewWidget/components/Chart/chartUtils/handleTooltipUpdate.d.ts +3 -0
  147. package/dist/types/CrowdViewWidget/components/Chart/chartUtils/index.d.ts +4 -0
  148. package/dist/types/CrowdViewWidget/components/Chart/chartUtils/normalizeLocale.d.ts +1 -0
  149. package/dist/types/CrowdViewWidget/components/Chart/dataUtils/getMultiplayerForTimeSpan.d.ts +2 -0
  150. package/dist/types/CrowdViewWidget/components/Chart/dataUtils/index.d.ts +1 -0
  151. package/dist/types/CrowdViewWidget/components/Chart/types.d.ts +6 -0
  152. package/dist/types/CrowdViewWidget/components/Chart/useResizeObserver.d.ts +5 -0
  153. package/dist/types/CrowdViewWidget/constants.d.ts +28 -15
  154. package/package.json +3 -3
  155. package/src/CrowdViewWidget/components/Chart/Chart.tsx +78 -80
  156. package/src/CrowdViewWidget/components/Chart/ChartWithData.tsx +51 -14
  157. package/src/CrowdViewWidget/components/Chart/chartOptions/getDataZoomConfig.ts +11 -2
  158. package/src/CrowdViewWidget/components/Chart/chartOptions/getGridConfig.ts +34 -19
  159. package/src/CrowdViewWidget/components/Chart/chartOptions/getGridLines.ts +71 -8
  160. package/src/CrowdViewWidget/components/Chart/chartOptions/getLabelsConfig.ts +207 -0
  161. package/src/CrowdViewWidget/components/Chart/chartOptions/getSeriesCandlestickConfig.ts +7 -15
  162. package/src/CrowdViewWidget/components/Chart/chartOptions/getSeriesHeatmapConfig.ts +22 -1
  163. package/src/CrowdViewWidget/components/Chart/chartOptions/getSeriesSentimentConfig.ts +13 -4
  164. package/src/CrowdViewWidget/components/Chart/chartOptions/getTooltipConfig.ts +91 -37
  165. package/src/CrowdViewWidget/components/Chart/chartOptions/getXAxisConfig.ts +62 -30
  166. package/src/CrowdViewWidget/components/Chart/chartOptions/getYAxisConfig.ts +22 -33
  167. package/src/CrowdViewWidget/components/Chart/chartOptions/index.ts +1 -0
  168. package/src/CrowdViewWidget/components/Chart/chartUtils/formatXAxisAdditionalLabel.ts +14 -0
  169. package/src/CrowdViewWidget/components/Chart/chartUtils/formatXAxisLabel.ts +6 -4
  170. package/src/CrowdViewWidget/components/Chart/chartUtils/getLabelData.ts +11 -35
  171. package/src/CrowdViewWidget/components/Chart/chartUtils/getTooltipFormatter.ts +157 -31
  172. package/src/CrowdViewWidget/components/Chart/chartUtils/handleLabelUpdate.ts +80 -0
  173. package/src/CrowdViewWidget/components/Chart/chartUtils/handleTooltipUpdate.ts +37 -0
  174. package/src/CrowdViewWidget/components/Chart/chartUtils/index.ts +4 -0
  175. package/src/CrowdViewWidget/components/Chart/chartUtils/normalizeLocale.ts +3 -0
  176. package/src/CrowdViewWidget/components/Chart/dataUtils/getMultiplayerForTimeSpan.ts +13 -0
  177. package/src/CrowdViewWidget/components/Chart/dataUtils/index.ts +1 -0
  178. package/src/CrowdViewWidget/components/Chart/dataUtils/processPriceCandles.ts +1 -1
  179. package/src/CrowdViewWidget/components/Chart/getOption.ts +47 -17
  180. package/src/CrowdViewWidget/components/Chart/types.ts +6 -0
  181. package/src/CrowdViewWidget/components/Chart/useCrowdViewData.ts +12 -5
  182. package/src/CrowdViewWidget/components/Chart/useResizeObserver.ts +51 -0
  183. package/src/CrowdViewWidget/components/Legend/Legend.tsx +1 -1
  184. package/src/CrowdViewWidget/components/Legend/LegendBar.tsx +18 -1
  185. package/src/CrowdViewWidget/constants.ts +34 -7
  186. package/src/CrowdViewWidget/selectConfig.ts +4 -12
  187. package/src/translations/sources/en.json +10 -8
  188. package/test/components/Chart/utils/chartUtils.test.ts +29 -6
  189. package/test/components/Chart/utils/handleLabelUpdate.test.ts +435 -0
  190. package/test/components/Chart/utils/handleTooltipUpdate.test.ts +140 -0
  191. package/test/components/Legend.test.tsx +3 -3
  192. package/test/components/LegendBar.test.tsx +22 -20
  193. package/test/utils/processPriceCandles.test.ts +4 -4
@@ -5,11 +5,14 @@ import {
5
5
  SpinnerSize,
6
6
  useLayoutProvider,
7
7
  } from '@oanda/labs-widget-common';
8
- import React from 'react';
8
+ import React, { useEffect, useState } from 'react';
9
+ import { useDebounceCallback } from 'usehooks-ts';
9
10
 
11
+ import { CHART_CONFIG } from '../../constants';
10
12
  import { Chart } from './Chart';
11
13
  import type { ChartWithDataProps } from './types';
12
14
  import { useCrowdViewData } from './useCrowdViewData';
15
+ import { useResizeObserver } from './useResizeObserver';
13
16
 
14
17
  const ChartWithData = ({
15
18
  instrument,
@@ -18,37 +21,71 @@ const ChartWithData = ({
18
21
  granularity,
19
22
  }: ChartWithDataProps) => {
20
23
  const { size } = useLayoutProvider();
24
+ const [debouncedLoading, setDebouncedLoading] = useState(true);
25
+ const [containerRef, isResizing] = useResizeObserver({ debounceDelay: 150 });
21
26
  const isDesktop = size === Size.DESKTOP;
22
27
 
23
- const { mainData, additionalData, loading, error } = useCrowdViewData({
24
- instrument,
25
- bookType,
26
- division,
27
- granularity,
28
- });
28
+ const { mainData, additionalData, loading, priceCandlesLoading, error } =
29
+ useCrowdViewData({
30
+ instrument,
31
+ bookType,
32
+ division,
33
+ granularity,
34
+ });
35
+
36
+ const hideLoading = useDebounceCallback(
37
+ () => setDebouncedLoading(false),
38
+ 500
39
+ );
40
+
41
+ useEffect(() => {
42
+ if (loading === false) {
43
+ hideLoading();
44
+ }
45
+ if (loading === true) {
46
+ setDebouncedLoading(true);
47
+ }
48
+ }, [loading, hideLoading]);
49
+
50
+ const showChart =
51
+ !priceCandlesLoading &&
52
+ !error &&
53
+ !!mainData &&
54
+ !!additionalData &&
55
+ !isResizing;
56
+ const showLoader = loading || isResizing;
57
+
58
+ const chartHeight = isDesktop
59
+ ? CHART_CONFIG.HEIGHT_DESKTOP
60
+ : CHART_CONFIG.HEIGHT_MOBILE;
29
61
 
30
62
  return (
31
63
  <>
32
- <div className="lw-relative lw-h-[440px] lw-w-full lw-overflow-hidden">
64
+ <div
65
+ ref={containerRef}
66
+ className="lw-relative lw-w-full lw-overflow-hidden"
67
+ style={{ height: chartHeight }}
68
+ >
33
69
  {error && (
34
70
  <div className="lw-absolute lw-left-0 lw-top-0 lw-flex lw-h-full lw-w-full lw-items-center lw-justify-center lw-border lw-border-solid lw-border-border-primary">
35
71
  <ChartError />
36
72
  </div>
37
73
  )}
38
- {loading && (
39
- <div className="lw-absolute lw-left-0 lw-top-0 lw-flex lw-h-full lw-w-full lw-items-center lw-justify-center lw-border lw-border-solid lw-border-border-primary">
40
- <Spinner size={SpinnerSize.lg} />
41
- </div>
42
- )}
43
- {!loading && !error && !!mainData && !!additionalData && (
74
+ {showChart && (
44
75
  <div className="lw-absolute lw-left-0 lw-top-0 lw-flex lw-h-full lw-w-full">
45
76
  <Chart
46
77
  additionalData={additionalData}
47
78
  isDesktop={isDesktop}
79
+ isLoading={debouncedLoading}
48
80
  mainData={mainData}
49
81
  />
50
82
  </div>
51
83
  )}
84
+ {showLoader && (
85
+ <div className="lw-absolute lw-left-0 lw-top-0 lw-flex lw-h-full lw-w-full lw-items-center lw-justify-center lw-border lw-border-solid lw-border-border-primary lw-bg-bg-transparent-50">
86
+ <Spinner size={SpinnerSize.lg} />
87
+ </div>
88
+ )}
52
89
  </div>
53
90
  </>
54
91
  );
@@ -2,12 +2,21 @@ import type { DataZoomComponentOption } from 'echarts';
2
2
 
3
3
  import { CHART_CONFIG } from '../../../constants';
4
4
 
5
- export const getDataZoomConfig = (): DataZoomComponentOption => ({
5
+ interface GetDataZoomConfigParams {
6
+ isDesktop: boolean;
7
+ }
8
+
9
+ export const getDataZoomConfig = ({
10
+ isDesktop,
11
+ }: GetDataZoomConfigParams): DataZoomComponentOption => ({
6
12
  type: 'inside',
7
13
  id: 'main',
8
14
  xAxisIndex: [0, 1],
9
- start: CHART_CONFIG.INITIAL_START_ZOOM,
15
+ start: isDesktop
16
+ ? CHART_CONFIG.INITIAL_START_ZOOM_DESKTOP
17
+ : CHART_CONFIG.INITIAL_START_ZOOM_MOBILE,
10
18
  end: CHART_CONFIG.INITIAL_END_ZOOM,
11
19
  filterMode: 'filter',
12
20
  minSpan: 10,
21
+ preventDefaultMouseMove: true,
13
22
  });
@@ -8,22 +8,37 @@ interface GetGridConfigParams {
8
8
 
9
9
  export const getGridConfig = ({
10
10
  isDesktop,
11
- }: GetGridConfigParams): GridComponentOption[] => [
12
- {
13
- id: 'main-grid',
14
- name: 'main-grid',
15
- left: `${CHART_CONFIG.Y_SENTIMENT_LABEL_SIZE}px`,
16
- right: `${isDesktop ? CHART_CONFIG.Y_LABEL_SIZE_DESKTOP : CHART_CONFIG.Y_LABEL_SIZE_MOBILE}px`,
17
- top: '0px',
18
- bottom: `${CHART_CONFIG.X_LABEL_SIZE}px`,
19
- height: `${CHART_CONFIG.MAIN_HEIGHT}px`,
20
- },
21
- {
22
- id: 'sentiment-grid',
23
- name: 'sentiment-grid',
24
- left: `${CHART_CONFIG.Y_SENTIMENT_LABEL_SIZE}px`,
25
- right: `${isDesktop ? CHART_CONFIG.Y_LABEL_SIZE_DESKTOP : CHART_CONFIG.Y_LABEL_SIZE_MOBILE}px`,
26
- top: `0px`,
27
- height: `${CHART_CONFIG.MAIN_HEIGHT}px`,
28
- },
29
- ];
11
+ }: GetGridConfigParams): GridComponentOption[] => {
12
+ const {
13
+ Y_SENTIMENT_LABEL_DESKTOP_SIZE,
14
+ Y_SENTIMENT_LABEL_MOBILE_SIZE,
15
+ Y_LABEL_SIZE_DESKTOP,
16
+ Y_LABEL_SIZE_MOBILE,
17
+ TOP_MARGIN_DESKTOP,
18
+ TOP_MARGIN_MOBILE,
19
+ MAIN_HEIGHT_DESKTOP,
20
+ MAIN_HEIGHT_MOBILE,
21
+ MOBILE_TOOLTIP_HEIGHT,
22
+ } = CHART_CONFIG;
23
+
24
+ const mainHeight = isDesktop ? MAIN_HEIGHT_DESKTOP : MAIN_HEIGHT_MOBILE;
25
+
26
+ const position = {
27
+ left: `${isDesktop ? Y_SENTIMENT_LABEL_DESKTOP_SIZE : Y_SENTIMENT_LABEL_MOBILE_SIZE}px`,
28
+ right: `${isDesktop ? Y_LABEL_SIZE_DESKTOP : Y_LABEL_SIZE_MOBILE}px`,
29
+ top: `${isDesktop ? TOP_MARGIN_DESKTOP : TOP_MARGIN_MOBILE + MOBILE_TOOLTIP_HEIGHT}px`,
30
+ height: `${mainHeight}px`,
31
+ };
32
+ return [
33
+ {
34
+ id: 'main-grid',
35
+ name: 'main-grid',
36
+ ...position,
37
+ },
38
+ {
39
+ id: 'sentiment-grid',
40
+ name: 'sentiment-grid',
41
+ ...position,
42
+ },
43
+ ];
44
+ };
@@ -5,13 +5,33 @@ import { CHART_CONFIG } from '../../../constants';
5
5
 
6
6
  interface GetGridLinesParams {
7
7
  isDark: boolean;
8
+ isDesktop: boolean;
8
9
  }
9
10
 
10
11
  export const getGridLines = ({
11
12
  isDark,
13
+ isDesktop,
12
14
  }: GetGridLinesParams): GraphicComponentOption[] => {
13
- const { WIDTH, MAIN_HEIGHT, X_LABEL_SIZE, Y_SENTIMENT_LABEL_SIZE } =
14
- CHART_CONFIG;
15
+ const {
16
+ WIDTH,
17
+ MAIN_HEIGHT_DESKTOP,
18
+ MAIN_HEIGHT_MOBILE,
19
+ X_LABEL_SIZE,
20
+ MOBILE_TOOLTIP_HEIGHT,
21
+ } = CHART_CONFIG;
22
+ const mainHeight = isDesktop ? MAIN_HEIGHT_DESKTOP : MAIN_HEIGHT_MOBILE;
23
+ const ySentimentLabelSize = isDesktop
24
+ ? CHART_CONFIG.Y_SENTIMENT_LABEL_DESKTOP_SIZE
25
+ : CHART_CONFIG.Y_SENTIMENT_LABEL_MOBILE_SIZE;
26
+
27
+ const yLabelSize = isDesktop
28
+ ? CHART_CONFIG.Y_LABEL_SIZE_DESKTOP
29
+ : CHART_CONFIG.Y_LABEL_SIZE_MOBILE;
30
+
31
+ const topMargin = isDesktop
32
+ ? CHART_CONFIG.TOP_MARGIN_DESKTOP
33
+ : CHART_CONFIG.TOP_MARGIN_MOBILE + CHART_CONFIG.MOBILE_TOOLTIP_HEIGHT;
34
+
15
35
  return [
16
36
  // Top
17
37
  {
@@ -23,6 +43,7 @@ export const getGridLines = ({
23
43
  x2: WIDTH,
24
44
  y2: 0,
25
45
  },
46
+ z: 30,
26
47
  },
27
48
  // Right
28
49
  {
@@ -32,8 +53,9 @@ export const getGridLines = ({
32
53
  x1: 0,
33
54
  y1: 0,
34
55
  x2: 0,
35
- y2: MAIN_HEIGHT + X_LABEL_SIZE + 2,
56
+ y2: mainHeight + topMargin + X_LABEL_SIZE + 2,
36
57
  },
58
+ z: 30,
37
59
  },
38
60
  // Bottom
39
61
  {
@@ -45,6 +67,7 @@ export const getGridLines = ({
45
67
  x2: WIDTH,
46
68
  y2: 0,
47
69
  },
70
+ z: 30,
48
71
  },
49
72
  // Left
50
73
  {
@@ -54,31 +77,71 @@ export const getGridLines = ({
54
77
  x1: 0,
55
78
  y1: 0,
56
79
  x2: 0,
57
- y2: MAIN_HEIGHT + X_LABEL_SIZE + 2,
80
+ y2: mainHeight + X_LABEL_SIZE + topMargin + 2,
58
81
  },
82
+ z: 30,
83
+ },
84
+ // Y Label
85
+ {
86
+ ...getLineCommons(isDark),
87
+ right: yLabelSize - 3,
88
+ top: topMargin - 2,
89
+ shape: {
90
+ x1: 0,
91
+ y1: 0,
92
+ x2: 0,
93
+ y2: mainHeight,
94
+ },
95
+ z: 30,
59
96
  },
60
97
  // Y Sentiment Label
61
98
  {
62
99
  ...getLineCommons(isDark),
63
- left: Y_SENTIMENT_LABEL_SIZE - 2,
64
- top: -2,
100
+ left: ySentimentLabelSize - 2,
101
+ top: topMargin - 2,
65
102
  shape: {
66
103
  x1: 0,
67
104
  y1: 0,
68
105
  x2: 0,
69
- y2: MAIN_HEIGHT,
106
+ y2: mainHeight,
70
107
  },
108
+ z: 30,
71
109
  },
72
110
  // X Label
73
111
  {
74
112
  ...getLineCommons(isDark),
75
- top: MAIN_HEIGHT - 2,
113
+ bottom: X_LABEL_SIZE - 3,
76
114
  shape: {
77
115
  x1: 0,
78
116
  y1: 0,
79
117
  x2: WIDTH,
80
118
  y2: 0,
81
119
  },
120
+ z: 30,
121
+ },
122
+ // X Mobile Label
123
+ {
124
+ ...getLineCommons(isDark),
125
+ top: topMargin - 3,
126
+ shape: {
127
+ x1: 0,
128
+ y1: 0,
129
+ x2: WIDTH,
130
+ y2: 0,
131
+ },
132
+ z: 30,
133
+ },
134
+ // Mobile tooltip,
135
+ {
136
+ ...getLineCommons(isDark),
137
+ top: MOBILE_TOOLTIP_HEIGHT - 2,
138
+ shape: {
139
+ x1: 0,
140
+ y1: 0,
141
+ x2: isDesktop ? 0 : WIDTH,
142
+ y2: 0,
143
+ },
144
+ z: 30,
82
145
  },
83
146
  ];
84
147
  };
@@ -0,0 +1,207 @@
1
+ import { colorPalette } from '@oanda/labs-widget-common';
2
+ import chroma from 'chroma-js';
3
+ import type { GraphicComponentOption } from 'echarts';
4
+
5
+ import { CHART_CONFIG } from '../../../constants';
6
+
7
+ interface getLabelsConfigParams {
8
+ isDark: boolean;
9
+ isDesktop: boolean;
10
+ labelCallback: (key: string, params?: Record<string, unknown>) => string;
11
+ }
12
+
13
+ export const getLabelsConfig = ({
14
+ isDark,
15
+ isDesktop,
16
+ labelCallback,
17
+ }: getLabelsConfigParams): GraphicComponentOption[] => {
18
+ const ySentimentLabelSize = isDesktop
19
+ ? CHART_CONFIG.Y_SENTIMENT_LABEL_DESKTOP_SIZE
20
+ : CHART_CONFIG.Y_SENTIMENT_LABEL_MOBILE_SIZE;
21
+
22
+ const yMainLabelSize = isDesktop
23
+ ? CHART_CONFIG.Y_LABEL_SIZE_DESKTOP
24
+ : CHART_CONFIG.Y_LABEL_SIZE_MOBILE;
25
+
26
+ const textColor = isDark ? colorPalette.white : colorPalette.black;
27
+ const labelBackgroundColor = isDark
28
+ ? colorPalette.darkGray
29
+ : colorPalette.white;
30
+ const backgroundColor = isDark ? colorPalette.black : colorPalette.white;
31
+ const shadowColor = chroma(colorPalette.black).alpha(0.1).hex();
32
+
33
+ // Estimate text width for centering rotated text
34
+ // Approximate: fontSize * characterCount * 0.65 (typical character width ratio)
35
+ const sentimentText = labelCallback('sentiment').toUpperCase();
36
+ const priceText = labelCallback('price').toUpperCase();
37
+ const sentimentEstimatedWidth = 10 * sentimentText.length * 0.65;
38
+ const priceEstimatedWidth = 10 * priceText.length * 0.65;
39
+ const sentimentVerticalOffset = sentimentEstimatedWidth / 2;
40
+ const priceVerticalOffset = priceEstimatedWidth / 2;
41
+
42
+ const topMargin = isDesktop
43
+ ? CHART_CONFIG.TOP_MARGIN_DESKTOP
44
+ : CHART_CONFIG.TOP_MARGIN_MOBILE + CHART_CONFIG.MOBILE_TOOLTIP_HEIGHT;
45
+
46
+ const mainHeight = isDesktop
47
+ ? CHART_CONFIG.MAIN_HEIGHT_DESKTOP
48
+ : CHART_CONFIG.MAIN_HEIGHT_MOBILE;
49
+
50
+ return [
51
+ {
52
+ type: 'group',
53
+ left: `${ySentimentLabelSize + 5}px'`,
54
+ top: `${topMargin + 5}px`,
55
+ silent: true,
56
+ children: [
57
+ {
58
+ type: 'rect',
59
+ z: 100,
60
+ right: 'center',
61
+ top: 'middle',
62
+ shape: {
63
+ width: 50,
64
+ height: 24,
65
+ },
66
+ style: {
67
+ fill: labelBackgroundColor,
68
+ shadowBlur: 8,
69
+ shadowOffsetX: 0,
70
+ shadowOffsetY: 1,
71
+ shadowColor: shadowColor,
72
+ },
73
+ },
74
+ {
75
+ type: 'text',
76
+ z: 100,
77
+ right: 'center',
78
+ top: 'middle',
79
+ style: {
80
+ fontSize: 11,
81
+ fontFamily: 'Sofia W03',
82
+ fontWeight: 500,
83
+ fill: textColor,
84
+ width: 70,
85
+ height: 30,
86
+ text: labelCallback('short'),
87
+ },
88
+ },
89
+ ],
90
+ },
91
+ {
92
+ type: 'group',
93
+ left: `${ySentimentLabelSize + 5}px'`,
94
+ top: `${topMargin + mainHeight - 24 - 5}px`,
95
+ silent: true,
96
+ children: [
97
+ {
98
+ type: 'rect',
99
+ z: 100,
100
+ right: 'center',
101
+ top: 'middle',
102
+ shape: {
103
+ width: 50,
104
+ height: 24,
105
+ },
106
+ style: {
107
+ fill: labelBackgroundColor,
108
+ shadowBlur: 8,
109
+ shadowOffsetX: 0,
110
+ shadowOffsetY: 1,
111
+ shadowColor: shadowColor,
112
+ },
113
+ },
114
+ {
115
+ type: 'text',
116
+ z: 100,
117
+ right: 'center',
118
+ top: 'middle',
119
+ style: {
120
+ fontSize: 11,
121
+ fontFamily: 'Sofia W03',
122
+ fontWeight: 500,
123
+ fill: textColor,
124
+ width: 70,
125
+ height: 30,
126
+ text: labelCallback('long'),
127
+ },
128
+ },
129
+ ],
130
+ },
131
+
132
+ {
133
+ type: 'text',
134
+ z: 30,
135
+ rotation: isDesktop ? Math.PI / 2 : 0,
136
+ left: `5px`,
137
+ top: isDesktop
138
+ ? `${topMargin + mainHeight / 2 - sentimentVerticalOffset}px`
139
+ : `${topMargin - 16}px`,
140
+ silent: true,
141
+ style: {
142
+ fontSize: 10,
143
+ fontFamily: 'Sofia W03',
144
+ fontWeight: 300,
145
+ fill: textColor,
146
+ text: sentimentText,
147
+ },
148
+ },
149
+ {
150
+ type: 'text',
151
+ z: 30,
152
+ rotation: isDesktop ? -Math.PI / 2 : 0,
153
+ right: `5px`,
154
+ top: isDesktop
155
+ ? `${topMargin + mainHeight / 2 - priceVerticalOffset}px`
156
+ : `${topMargin - 16}px`,
157
+ silent: true,
158
+ style: {
159
+ fontSize: 10,
160
+ fontFamily: 'Sofia W03',
161
+ fontWeight: 300,
162
+ fill: textColor,
163
+ text: priceText,
164
+ },
165
+ },
166
+ {
167
+ type: 'rect',
168
+ z: 20,
169
+ right: '0px',
170
+ top: `${topMargin}px`,
171
+ shape: {
172
+ width: yMainLabelSize,
173
+ height: mainHeight,
174
+ },
175
+ silent: true,
176
+ style: {
177
+ fill: backgroundColor,
178
+ },
179
+ },
180
+ {
181
+ type: 'rect',
182
+ z: 20,
183
+ left: '0px',
184
+ top: `${topMargin}px`,
185
+ shape: {
186
+ width: ySentimentLabelSize,
187
+ height: mainHeight,
188
+ },
189
+ silent: true,
190
+ style: {
191
+ fill: backgroundColor,
192
+ },
193
+ },
194
+ {
195
+ type: 'text',
196
+ z: 20,
197
+ left: 'center',
198
+ top: CHART_CONFIG.MOBILE_TOOLTIP_HEIGHT / 2 - 5,
199
+ silent: true,
200
+ style: {
201
+ fontSize: isDesktop ? 0 : 11,
202
+ fill: textColor,
203
+ text: isDesktop ? '' : labelCallback('tap_chart_to_see_more_details'),
204
+ },
205
+ },
206
+ ];
207
+ };
@@ -1,31 +1,28 @@
1
1
  import chroma from 'chroma-js';
2
2
  import type { CandlestickSeriesOption } from 'echarts';
3
3
 
4
- import { getLabelData } from '../chartUtils';
5
4
  import type { ChartStyles } from '../chartUtils/getChartStyles';
6
5
 
7
6
  interface GetSeriesCandlestickConfigParams {
8
- dates: string[];
9
- isGreaterThanTwoWeeks: boolean;
10
7
  styles: ChartStyles;
8
+ isLoading: boolean;
11
9
  }
12
10
 
13
11
  export const getSeriesCandlestickConfig = ({
14
- dates,
15
- isGreaterThanTwoWeeks,
16
12
  styles,
13
+ isLoading,
17
14
  }: GetSeriesCandlestickConfigParams): CandlestickSeriesOption => {
18
15
  const { candleLongColor, candleShortColor } = styles;
19
- const labelsData = getLabelData({
20
- dates,
21
- isGreaterThanTwoWeeks,
22
- });
23
16
 
24
17
  return {
18
+ animation: isLoading,
25
19
  type: 'candlestick',
26
20
  id: 'candlestick',
27
21
  xAxisIndex: 0,
28
22
  yAxisIndex: 0,
23
+ silent: true,
24
+ clip: true,
25
+ large: true,
29
26
  encode: {
30
27
  x: 'dates',
31
28
  y: ['open', 'close', 'low', 'high'],
@@ -42,11 +39,6 @@ export const getSeriesCandlestickConfig = ({
42
39
  color0: candleShortColor,
43
40
  },
44
41
  },
45
- markPoint: {
46
- data: labelsData,
47
- symbol: 'circle',
48
- symbolSize: 0,
49
- },
50
- z: 2,
42
+ z: 3,
51
43
  };
52
44
  };
@@ -13,6 +13,7 @@ interface GetSeriesHeatmapConfigParams {
13
13
  isDark: boolean;
14
14
  sentimentThresholdMax: number;
15
15
  sentimentThresholdMin: number;
16
+ isLoading: boolean;
16
17
  }
17
18
 
18
19
  export const getSeriesHeatmapConfig = ({
@@ -21,8 +22,10 @@ export const getSeriesHeatmapConfig = ({
21
22
  isDark,
22
23
  sentimentThresholdMax,
23
24
  sentimentThresholdMin,
25
+ isLoading,
24
26
  }: GetSeriesHeatmapConfigParams): CustomSeriesOption => {
25
27
  return {
28
+ animation: isLoading,
26
29
  type: 'custom',
27
30
  id: 'heatmap',
28
31
  name: 'heatmap',
@@ -35,9 +38,11 @@ export const getSeriesHeatmapConfig = ({
35
38
  dimensions: ['dates', 'bookPrices', 'bookIndexes'],
36
39
  clip: true,
37
40
  renderItem: (
38
- _params: CustomSeriesRenderItemParams,
41
+ params: CustomSeriesRenderItemParams,
39
42
  api: CustomSeriesRenderItemAPI
40
43
  ) => {
44
+ const animationDelay =
45
+ (350 * params.dataIndexInside) / params.dataInsideLength;
41
46
  const xVal = api.value(0);
42
47
  const bucketIndex = api.value(2) as number;
43
48
 
@@ -47,12 +52,17 @@ export const getSeriesHeatmapConfig = ({
47
52
 
48
53
  const metaValues = buckets[bucketIndex];
49
54
 
55
+ if (!metaValues) {
56
+ return null;
57
+ }
58
+
50
59
  const [rectWidth, rectHeight] = api.size!([0, bucketWidth]) as number[];
51
60
 
52
61
  const items = metaValues.map(({ price, sentiment }: Bucket) => {
53
62
  const start = api.coord([xVal, price]);
54
63
 
55
64
  return {
65
+ silent: true,
56
66
  shape: {
57
67
  height: rectHeight,
58
68
  width: rectWidth + 1,
@@ -67,6 +77,16 @@ export const getSeriesHeatmapConfig = ({
67
77
  sentimentThresholdMax
68
78
  ),
69
79
  },
80
+ enterFrom: {
81
+ shape: {},
82
+ style: {
83
+ opacity: 0,
84
+ },
85
+ },
86
+ enterAnimation: {
87
+ duration: 150,
88
+ delay: animationDelay,
89
+ },
70
90
  type: 'rect' as const,
71
91
  };
72
92
  });
@@ -74,6 +94,7 @@ export const getSeriesHeatmapConfig = ({
74
94
  return {
75
95
  children: items,
76
96
  emphasisDisabled: true,
97
+ silent: true,
77
98
  type: 'group' as const,
78
99
  };
79
100
  },
@@ -5,12 +5,16 @@ import type { ChartStyles } from '../chartUtils';
5
5
 
6
6
  interface GetSeriesSentimentConfigParams {
7
7
  styles: ChartStyles;
8
+ isLoading: boolean;
8
9
  }
9
10
 
10
11
  export const getSeriesSentimentConfig = ({
11
12
  styles,
13
+ isLoading,
12
14
  }: GetSeriesSentimentConfigParams): LineSeriesOption => {
13
15
  return {
16
+ animation: isLoading,
17
+ animationDelay: 350,
14
18
  type: 'line',
15
19
  id: 'sentiment',
16
20
  name: 'sentiment',
@@ -18,9 +22,9 @@ export const getSeriesSentimentConfig = ({
18
22
  yAxisIndex: 1,
19
23
  encode: {
20
24
  x: 'dates',
21
- y: 'sentimentShorts',
25
+ y: 'sentimentLongs',
22
26
  },
23
- dimensions: ['dates', 'sentimentShorts', 'sentimentLongs'],
27
+ dimensions: ['dates', 'sentimentLongs', 'sentimentShorts'],
24
28
  lineStyle: {
25
29
  width: styles.sentimentOutlineWidth,
26
30
  opacity: 1,
@@ -30,7 +34,11 @@ export const getSeriesSentimentConfig = ({
30
34
  emphasis: {
31
35
  disabled: true,
32
36
  },
37
+ tooltip: {
38
+ show: false,
39
+ },
33
40
  markLine: {
41
+ animation: isLoading,
34
42
  silent: true,
35
43
  symbol: ['none', 'none'],
36
44
  label: {
@@ -55,9 +63,10 @@ export const getSeriesSentimentConfig = ({
55
63
  },
56
64
  ],
57
65
  },
58
- stack: 'sentiment',
59
66
  showSymbol: false,
60
67
  symbol: 'none',
61
- z: 3,
68
+ z: 2,
69
+ connectNulls: true,
70
+ silent: true,
62
71
  };
63
72
  };