@oanda/labs-crowd-view-widget 1.0.51 → 1.0.53

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 (153) hide show
  1. package/CHANGELOG.md +428 -0
  2. package/dist/main/CrowdViewWidget/Main.js +1 -5
  3. package/dist/main/CrowdViewWidget/Main.js.map +1 -1
  4. package/dist/main/CrowdViewWidget/components/Chart/Chart.js +73 -24
  5. package/dist/main/CrowdViewWidget/components/Chart/Chart.js.map +1 -1
  6. package/dist/main/CrowdViewWidget/components/Chart/ChartWithData.js +18 -9
  7. package/dist/main/CrowdViewWidget/components/Chart/ChartWithData.js.map +1 -1
  8. package/dist/main/CrowdViewWidget/components/Chart/chartOptions.js +265 -59
  9. package/dist/main/CrowdViewWidget/components/Chart/chartOptions.js.map +1 -1
  10. package/dist/main/CrowdViewWidget/components/Chart/types.js.map +1 -1
  11. package/dist/main/CrowdViewWidget/components/Chart/useCrowdViewData.js +68 -26
  12. package/dist/main/CrowdViewWidget/components/Chart/useCrowdViewData.js.map +1 -1
  13. package/dist/main/CrowdViewWidget/components/Chart/utils/chartUtils.js +20 -19
  14. package/dist/main/CrowdViewWidget/components/Chart/utils/chartUtils.js.map +1 -1
  15. package/dist/main/CrowdViewWidget/components/Chart/utils/getChartStyles.js +27 -0
  16. package/dist/main/CrowdViewWidget/components/Chart/utils/getChartStyles.js.map +1 -0
  17. package/dist/main/CrowdViewWidget/components/Chart/utils/getGridLines.js +123 -0
  18. package/dist/main/CrowdViewWidget/components/Chart/utils/getGridLines.js.map +1 -0
  19. package/dist/main/CrowdViewWidget/components/Chart/utils/index.js +15 -26
  20. package/dist/main/CrowdViewWidget/components/Chart/utils/index.js.map +1 -1
  21. package/dist/main/CrowdViewWidget/components/Chart/utils/processOrderPositionBooks.js +54 -12
  22. package/dist/main/CrowdViewWidget/components/Chart/utils/processOrderPositionBooks.js.map +1 -1
  23. package/dist/main/CrowdViewWidget/components/Chart/utils/processPriceCandles.js +49 -27
  24. package/dist/main/CrowdViewWidget/components/Chart/utils/processPriceCandles.js.map +1 -1
  25. package/dist/main/CrowdViewWidget/components/Chart/utils/processSentiments.js +43 -0
  26. package/dist/main/CrowdViewWidget/components/Chart/utils/processSentiments.js.map +1 -0
  27. package/dist/main/CrowdViewWidget/components/Chart/utils/validateData.js +8 -2
  28. package/dist/main/CrowdViewWidget/components/Chart/utils/validateData.js.map +1 -1
  29. package/dist/main/CrowdViewWidget/components/Legend/Legend.js +3 -4
  30. package/dist/main/CrowdViewWidget/components/Legend/Legend.js.map +1 -1
  31. package/dist/main/CrowdViewWidget/components/Legend/LegendBar.js +2 -2
  32. package/dist/main/CrowdViewWidget/components/Legend/LegendBar.js.map +1 -1
  33. package/dist/main/CrowdViewWidget/constants.js +14 -8
  34. package/dist/main/CrowdViewWidget/constants.js.map +1 -1
  35. package/dist/main/gql/getOrderPositionBooks.js +1 -1
  36. package/dist/main/gql/getOrderPositionBooks.js.map +1 -1
  37. package/dist/main/gql/getPriceCandles.js +1 -1
  38. package/dist/main/gql/getPriceCandles.js.map +1 -1
  39. package/dist/main/gql/getSentiments.js +11 -0
  40. package/dist/main/gql/getSentiments.js.map +1 -0
  41. package/dist/main/gql/types/gql.js +3 -2
  42. package/dist/main/gql/types/gql.js.map +1 -1
  43. package/dist/main/gql/types/graphql.js +273 -19
  44. package/dist/main/gql/types/graphql.js.map +1 -1
  45. package/dist/module/CrowdViewWidget/Main.js +2 -6
  46. package/dist/module/CrowdViewWidget/Main.js.map +1 -1
  47. package/dist/module/CrowdViewWidget/components/Chart/Chart.js +76 -27
  48. package/dist/module/CrowdViewWidget/components/Chart/Chart.js.map +1 -1
  49. package/dist/module/CrowdViewWidget/components/Chart/ChartWithData.js +18 -9
  50. package/dist/module/CrowdViewWidget/components/Chart/ChartWithData.js.map +1 -1
  51. package/dist/module/CrowdViewWidget/components/Chart/chartOptions.js +265 -60
  52. package/dist/module/CrowdViewWidget/components/Chart/chartOptions.js.map +1 -1
  53. package/dist/module/CrowdViewWidget/components/Chart/types.js.map +1 -1
  54. package/dist/module/CrowdViewWidget/components/Chart/useCrowdViewData.js +69 -27
  55. package/dist/module/CrowdViewWidget/components/Chart/useCrowdViewData.js.map +1 -1
  56. package/dist/module/CrowdViewWidget/components/Chart/utils/chartUtils.js +21 -20
  57. package/dist/module/CrowdViewWidget/components/Chart/utils/chartUtils.js.map +1 -1
  58. package/dist/module/CrowdViewWidget/components/Chart/utils/getChartStyles.js +20 -0
  59. package/dist/module/CrowdViewWidget/components/Chart/utils/getChartStyles.js.map +1 -0
  60. package/dist/module/CrowdViewWidget/components/Chart/utils/getGridLines.js +116 -0
  61. package/dist/module/CrowdViewWidget/components/Chart/utils/getGridLines.js.map +1 -0
  62. package/dist/module/CrowdViewWidget/components/Chart/utils/index.js +2 -3
  63. package/dist/module/CrowdViewWidget/components/Chart/utils/index.js.map +1 -1
  64. package/dist/module/CrowdViewWidget/components/Chart/utils/processOrderPositionBooks.js +54 -12
  65. package/dist/module/CrowdViewWidget/components/Chart/utils/processOrderPositionBooks.js.map +1 -1
  66. package/dist/module/CrowdViewWidget/components/Chart/utils/processPriceCandles.js +49 -27
  67. package/dist/module/CrowdViewWidget/components/Chart/utils/processPriceCandles.js.map +1 -1
  68. package/dist/module/CrowdViewWidget/components/Chart/utils/processSentiments.js +36 -0
  69. package/dist/module/CrowdViewWidget/components/Chart/utils/processSentiments.js.map +1 -0
  70. package/dist/module/CrowdViewWidget/components/Chart/utils/validateData.js +8 -2
  71. package/dist/module/CrowdViewWidget/components/Chart/utils/validateData.js.map +1 -1
  72. package/dist/module/CrowdViewWidget/components/Legend/Legend.js +3 -4
  73. package/dist/module/CrowdViewWidget/components/Legend/Legend.js.map +1 -1
  74. package/dist/module/CrowdViewWidget/components/Legend/LegendBar.js +2 -2
  75. package/dist/module/CrowdViewWidget/components/Legend/LegendBar.js.map +1 -1
  76. package/dist/module/CrowdViewWidget/constants.js +13 -7
  77. package/dist/module/CrowdViewWidget/constants.js.map +1 -1
  78. package/dist/module/gql/getOrderPositionBooks.js +1 -1
  79. package/dist/module/gql/getOrderPositionBooks.js.map +1 -1
  80. package/dist/module/gql/getPriceCandles.js +1 -1
  81. package/dist/module/gql/getPriceCandles.js.map +1 -1
  82. package/dist/module/gql/getSentiments.js +6 -0
  83. package/dist/module/gql/getSentiments.js.map +1 -0
  84. package/dist/module/gql/types/gql.js +3 -2
  85. package/dist/module/gql/types/gql.js.map +1 -1
  86. package/dist/module/gql/types/graphql.js +272 -18
  87. package/dist/module/gql/types/graphql.js.map +1 -1
  88. package/dist/types/CrowdViewWidget/components/Chart/Chart.d.ts +1 -1
  89. package/dist/types/CrowdViewWidget/components/Chart/types.d.ts +69 -9
  90. package/dist/types/CrowdViewWidget/components/Chart/utils/chartUtils.d.ts +5 -6
  91. package/dist/types/CrowdViewWidget/components/Chart/utils/getChartStyles.d.ts +10 -0
  92. package/dist/types/CrowdViewWidget/components/Chart/utils/getGridLines.d.ts +97 -0
  93. package/dist/types/CrowdViewWidget/components/Chart/utils/index.d.ts +2 -3
  94. package/dist/types/CrowdViewWidget/components/Chart/utils/processOrderPositionBooks.d.ts +10 -7
  95. package/dist/types/CrowdViewWidget/components/Chart/utils/processPriceCandles.d.ts +6 -21
  96. package/dist/types/CrowdViewWidget/components/Chart/utils/processSentiments.d.ts +6 -0
  97. package/dist/types/CrowdViewWidget/components/Chart/utils/validateData.d.ts +1 -1
  98. package/dist/types/CrowdViewWidget/components/Legend/Legend.d.ts +2 -2
  99. package/dist/types/CrowdViewWidget/components/Legend/LegendBar.d.ts +1 -1
  100. package/dist/types/CrowdViewWidget/constants.d.ts +12 -6
  101. package/dist/types/gql/getSentiments.d.ts +2 -0
  102. package/dist/types/gql/types/gql.d.ts +15 -4
  103. package/dist/types/gql/types/graphql.d.ts +66 -11
  104. package/package.json +3 -3
  105. package/src/CrowdViewWidget/Main.tsx +2 -4
  106. package/src/CrowdViewWidget/components/Chart/Chart.tsx +99 -38
  107. package/src/CrowdViewWidget/components/Chart/ChartWithData.tsx +24 -7
  108. package/src/CrowdViewWidget/components/Chart/chartOptions.ts +305 -87
  109. package/src/CrowdViewWidget/components/Chart/types.ts +82 -16
  110. package/src/CrowdViewWidget/components/Chart/useCrowdViewData.ts +105 -56
  111. package/src/CrowdViewWidget/components/Chart/utils/chartUtils.ts +65 -34
  112. package/src/CrowdViewWidget/components/Chart/utils/getChartStyles.ts +42 -0
  113. package/src/CrowdViewWidget/components/Chart/utils/getGridLines.ts +148 -0
  114. package/src/CrowdViewWidget/components/Chart/utils/index.ts +2 -3
  115. package/src/CrowdViewWidget/components/Chart/utils/processOrderPositionBooks.ts +84 -22
  116. package/src/CrowdViewWidget/components/Chart/utils/processPriceCandles.ts +52 -38
  117. package/src/CrowdViewWidget/components/Chart/utils/processSentiments.ts +55 -0
  118. package/src/CrowdViewWidget/components/Chart/utils/validateData.ts +10 -2
  119. package/src/CrowdViewWidget/components/Legend/Legend.tsx +5 -6
  120. package/src/CrowdViewWidget/components/Legend/LegendBar.tsx +3 -3
  121. package/src/CrowdViewWidget/constants.ts +18 -7
  122. package/src/gql/getOrderPositionBooks.ts +13 -5
  123. package/src/gql/getPriceCandles.ts +1 -0
  124. package/src/gql/getSentiments.ts +25 -0
  125. package/src/gql/types/gql.ts +14 -6
  126. package/src/gql/types/graphql.ts +259 -16
  127. package/test/components/Chart/utils/chartUtils.test.ts +105 -13
  128. package/test/components/Chart/utils/getChartStyles.test.ts +64 -0
  129. package/test/components/Chart/utils/processSentiments.test.ts +238 -0
  130. package/test/utils/processOrderPositionBooks.test.ts +201 -84
  131. package/test/utils/processPriceCandles.test.ts +93 -67
  132. package/test/utils/validateData.test.ts +136 -38
  133. package/dist/main/CrowdViewWidget/components/Chart/utils/aggregateBuckets.js +0 -37
  134. package/dist/main/CrowdViewWidget/components/Chart/utils/aggregateBuckets.js.map +0 -1
  135. package/dist/main/CrowdViewWidget/components/Chart/utils/getTargetBucketWidth.js +0 -14
  136. package/dist/main/CrowdViewWidget/components/Chart/utils/getTargetBucketWidth.js.map +0 -1
  137. package/dist/main/CrowdViewWidget/components/Chart/utils/processBuckets.js +0 -29
  138. package/dist/main/CrowdViewWidget/components/Chart/utils/processBuckets.js.map +0 -1
  139. package/dist/module/CrowdViewWidget/components/Chart/utils/aggregateBuckets.js +0 -29
  140. package/dist/module/CrowdViewWidget/components/Chart/utils/aggregateBuckets.js.map +0 -1
  141. package/dist/module/CrowdViewWidget/components/Chart/utils/getTargetBucketWidth.js +0 -7
  142. package/dist/module/CrowdViewWidget/components/Chart/utils/getTargetBucketWidth.js.map +0 -1
  143. package/dist/module/CrowdViewWidget/components/Chart/utils/processBuckets.js +0 -22
  144. package/dist/module/CrowdViewWidget/components/Chart/utils/processBuckets.js.map +0 -1
  145. package/dist/types/CrowdViewWidget/components/Chart/utils/aggregateBuckets.d.ts +0 -2
  146. package/dist/types/CrowdViewWidget/components/Chart/utils/getTargetBucketWidth.d.ts +0 -3
  147. package/dist/types/CrowdViewWidget/components/Chart/utils/processBuckets.d.ts +0 -3
  148. package/src/CrowdViewWidget/components/Chart/utils/aggregateBuckets.ts +0 -44
  149. package/src/CrowdViewWidget/components/Chart/utils/getTargetBucketWidth.ts +0 -13
  150. package/src/CrowdViewWidget/components/Chart/utils/processBuckets.ts +0 -43
  151. package/test/utils/aggregateBuckets.test.ts +0 -82
  152. package/test/utils/getTargetBucketWidth.test.ts +0 -37
  153. package/test/utils/processBuckets.test.ts +0 -153
@@ -1,12 +1,11 @@
1
+ import chroma from 'chroma-js';
2
+
1
3
  import {
2
- colorPalette,
3
- getGridLines,
4
- getLineCommons,
5
- themeColors,
6
- } from '@oanda/labs-widget-common';
7
-
8
- import { CHART_CONFIG } from '../../constants';
9
- import type { Bucket, GetOptionType } from './types';
4
+ BUCKET_CONFIG,
5
+ CHART_CONFIG,
6
+ CHART_CONFIG_CALCULATED,
7
+ } from '../../constants';
8
+ import type { Bucket, GetOptionType, TooltipParam } from './types';
10
9
  import {
11
10
  formatXAxisLabel,
12
11
  getLabelData,
@@ -14,26 +13,48 @@ import {
14
13
  getTooltipFormatter,
15
14
  isDifferenceGreaterThanTwoWeeks,
16
15
  } from './utils/chartUtils';
16
+ import { getChartStyles } from './utils/getChartStyles';
17
+ import { getGridLines } from './utils/getGridLines';
17
18
 
18
19
  // @ts-expect-error
19
- export const getOption: GetOptionType = (
20
- {
21
- xAxisData,
22
- candlesSeriesData,
23
- orderPositionBooks,
20
+ export const getOption: GetOptionType = ({
21
+ mainData: {
22
+ dates,
23
+ candlesOpen,
24
+ candlesClose,
25
+ candlesLow,
26
+ candlesHigh,
27
+ bookPrices,
28
+ bookIndexes,
29
+ sentimentShorts,
30
+ sentimentLongs,
31
+ },
32
+ additionalData: {
24
33
  bucketWidth,
25
34
  buckets,
26
- precision,
35
+ displayPrecision,
27
36
  bookType,
37
+ sentimentThresholdMin,
38
+ sentimentThresholdMax,
28
39
  },
29
40
  isDark,
30
41
  isDesktop,
31
- labelCallback
32
- ) => {
42
+ labelCallback,
43
+ }) => {
33
44
  let selectedPrice: number;
34
- const visibleXAxisData = xAxisData.slice(
35
- (xAxisData.length * CHART_CONFIG.INITIAL_START_ZOOM) / 100,
36
- (xAxisData.length * CHART_CONFIG.INITIAL_END_ZOOM) / 100
45
+ const {
46
+ sentimentLongColor,
47
+ sentimentShortColor,
48
+ candleLongColor,
49
+ candleShortColor,
50
+ sentimentAreaOpacity,
51
+ tooltipLinesColor,
52
+ sentimentLabelColor,
53
+ } = getChartStyles(isDark);
54
+
55
+ const visibleXAxisData = dates.slice(
56
+ (dates.length * CHART_CONFIG.INITIAL_START_ZOOM) / 100,
57
+ (dates.length * CHART_CONFIG.INITIAL_END_ZOOM) / 100
37
58
  );
38
59
 
39
60
  const isGreaterThanTwoWeeks = isDifferenceGreaterThanTwoWeeks(
@@ -42,29 +63,33 @@ export const getOption: GetOptionType = (
42
63
  );
43
64
 
44
65
  const labelsData = getLabelData({
45
- xAxisData,
66
+ dates,
46
67
  isGreaterThanTwoWeeks,
47
68
  });
48
69
 
49
- const gridLines = getGridLines({
70
+ const gridMainLines = getGridLines({
50
71
  isDark,
51
- chartWidth: CHART_CONFIG.WIDTH,
52
- chartHeight: CHART_CONFIG.HEIGHT,
53
- xLabelsSize: CHART_CONFIG.X_LABEL_SIZE,
54
- yLabelSize: isDesktop
55
- ? CHART_CONFIG.Y_LABEL_SIZE_DESKTOP
56
- : CHART_CONFIG.Y_LABEL_SIZE_MOBILE,
57
- bottomLeftBox: false,
72
+ isDesktop,
58
73
  });
59
74
 
60
75
  return {
61
76
  animation: false,
62
77
  dataZoom: [
63
78
  {
79
+ id: 'main',
64
80
  type: 'inside',
65
81
  xAxisIndex: 0,
66
82
  start: CHART_CONFIG.INITIAL_START_ZOOM,
67
83
  end: CHART_CONFIG.INITIAL_END_ZOOM,
84
+ filterMode: 'filter',
85
+ },
86
+ {
87
+ id: 'sentiment',
88
+ type: 'inside',
89
+ xAxisIndex: 1,
90
+ start: CHART_CONFIG.INITIAL_START_ZOOM,
91
+ end: CHART_CONFIG.INITIAL_END_ZOOM,
92
+ filterMode: 'none',
68
93
  },
69
94
  ],
70
95
  tooltip: {
@@ -72,24 +97,19 @@ export const getOption: GetOptionType = (
72
97
  axisPointer: {
73
98
  type: 'cross',
74
99
  axis: 'x',
100
+ lineStyle: {
101
+ color: tooltipLinesColor,
102
+ },
75
103
  crossStyle: {
76
- color: isDark ? colorPalette.orange : themeColors.borderPrimary.light,
104
+ color: tooltipLinesColor,
77
105
  },
78
106
  label: {
107
+ padding: 0,
108
+ lineHeight: 24,
79
109
  formatter: (params) => {
80
- if (params.axisDimension === 'y') {
110
+ if (params.axisDimension === 'y' && params.axisIndex === 0) {
81
111
  selectedPrice = Number(params.value);
82
- return Number(params.value).toFixed(precision);
83
- }
84
-
85
- if (params.axisDimension === 'x') {
86
- const date = new Date(params.value as string);
87
- return date.toLocaleString(undefined, {
88
- hour: '2-digit',
89
- minute: '2-digit',
90
- day: 'numeric',
91
- month: 'short',
92
- });
112
+ return ` ${Number(params.value).toFixed(displayPrecision)} `;
93
113
  }
94
114
 
95
115
  return null;
@@ -97,62 +117,176 @@ export const getOption: GetOptionType = (
97
117
  },
98
118
  },
99
119
  confine: true,
100
- formatter: (params) =>
120
+ formatter: (params: TooltipParam[]) =>
101
121
  getTooltipFormatter({
102
122
  params,
103
123
  buckets,
104
124
  bucketWidth,
105
125
  selectedPrice,
106
126
  labelCallback,
107
- precision,
108
127
  bookType,
109
128
  }),
110
129
  },
111
- xAxis: {
112
- type: 'category',
113
- data: xAxisData,
114
- splitNumber: 1,
115
- axisTick: {
130
+ xAxis: [
131
+ {
132
+ type: 'category',
133
+ name: 'xAxis-less-than-two-weeks',
134
+ nameTextStyle: {
135
+ fontSize: 0,
136
+ },
137
+ id: 'main-xAxis',
138
+ splitNumber: 1,
139
+ axisTick: {
140
+ show: false,
141
+ },
142
+ axisLabel: {
143
+ padding: [8, 16, 8, 16],
144
+ margin: 0,
145
+ formatter: (value) => formatXAxisLabel(value, isGreaterThanTwoWeeks),
146
+ },
147
+ },
148
+ {
149
+ type: 'category',
150
+ gridIndex: 1,
116
151
  show: false,
152
+ data: dates,
153
+ splitNumber: 1,
154
+ axisTick: {
155
+ show: false,
156
+ },
157
+ axisLabel: {
158
+ show: false,
159
+ },
117
160
  },
118
- axisLabel: {
119
- padding: [8, 16, 8, 16],
120
- margin: 0,
121
- formatter: (value) => formatXAxisLabel(value, isGreaterThanTwoWeeks),
161
+ ],
162
+ yAxis: [
163
+ {
164
+ type: 'value',
165
+ gridIndex: 0,
166
+ position: 'right',
167
+ min: (val) =>
168
+ val.min - bucketWidth * BUCKET_CONFIG.PRICE_MARGIN_MULTIPLIER,
169
+ max: (val) =>
170
+ val.max + bucketWidth * BUCKET_CONFIG.PRICE_MARGIN_MULTIPLIER,
171
+ axisLine: { show: false },
172
+ axisTick: { show: false },
173
+ axisLabel: {
174
+ showMaxLabel: false,
175
+ showMinLabel: false,
176
+ formatter: (value: number) => value.toFixed(displayPrecision - 1),
177
+ },
122
178
  },
179
+ {
180
+ type: 'value',
181
+ gridIndex: 1,
182
+ position: 'right',
183
+ min: CHART_CONFIG.SENTIMENT_MIN,
184
+ max: CHART_CONFIG.SENTIMENT_MAX,
185
+ interval: CHART_CONFIG.SENTIMENT_INTERVAL,
186
+ axisLine: { show: false },
187
+ axisTick: { show: false },
188
+ axisLabel: {
189
+ verticalAlignMaxLabel: 'top',
190
+ verticalAlignMinLabel: 'bottom',
191
+ lineHeight: 20,
192
+ margin: isDesktop ? 4 : 2,
193
+ rich: {
194
+ shortRect: {
195
+ backgroundColor: chroma(sentimentShortColor).alpha(0.3).css(),
196
+ borderColor: sentimentShortColor,
197
+ borderWidth: 1,
198
+ width: 8,
199
+ height: 8,
200
+ },
201
+ longRect: {
202
+ backgroundColor: chroma(sentimentLongColor).alpha(0.3).css(),
203
+ borderColor: sentimentLongColor,
204
+ borderWidth: 1,
205
+ width: 8,
206
+ height: 8,
207
+ },
208
+ },
209
+ formatter: (value: number) => {
210
+ if (value === CHART_CONFIG.SENTIMENT_MIN) {
211
+ return `{shortRect| } ${labelCallback('short')}`;
212
+ }
213
+
214
+ if (value === CHART_CONFIG.SENTIMENT_MAX) {
215
+ return `{longRect| } ${labelCallback('long')}`;
216
+ }
217
+
218
+ if (value === CHART_CONFIG.SENTIMENT_MAX / 2) {
219
+ return '50%';
220
+ }
221
+
222
+ return undefined;
223
+ },
224
+ },
225
+ },
226
+ ],
227
+ axisPointer: {
228
+ link: [
229
+ {
230
+ xAxisIndex: 'all',
231
+ },
232
+ ],
233
+ },
234
+ visualMap: {
235
+ show: false,
236
+ seriesId: 'sentiment',
237
+ dimension: 1,
238
+ pieces: [
239
+ {
240
+ lt: CHART_CONFIG.SENTIMENT_MAX / 2,
241
+ color: sentimentShortColor,
242
+ },
243
+ {
244
+ gte: CHART_CONFIG.SENTIMENT_MAX / 2,
245
+ lte: CHART_CONFIG.SENTIMENT_MAX,
246
+ color: sentimentLongColor,
247
+ },
248
+ {
249
+ gt: CHART_CONFIG.SENTIMENT_MAX,
250
+ color: sentimentLongColor,
251
+ },
252
+ ],
123
253
  },
124
- yAxis: {
125
- type: 'value',
126
- position: 'right',
127
- min: (val) => val.min - bucketWidth * 2,
128
- max: (val) => val.max + bucketWidth * 2,
129
- axisLine: { show: false },
130
- axisTick: { show: false },
131
- axisLabel: {
132
- showMaxLabel: false,
133
- showMinLabel: false,
134
- margin: isDesktop ? 4 : 2,
135
- formatter: (value: number) => value.toFixed(precision - 1),
254
+ dataset: {
255
+ source: {
256
+ dates,
257
+ candlesOpen,
258
+ candlesClose,
259
+ candlesLow,
260
+ candlesHigh,
261
+ bookPrices,
262
+ bookIndexes,
263
+ sentimentShorts,
264
+ sentimentLongs,
136
265
  },
137
266
  },
138
267
  series: [
139
268
  {
140
269
  type: 'candlestick',
141
270
  id: 'candlestick',
142
- data: candlesSeriesData,
271
+ gridIndex: 0,
272
+ xAxisIndex: 0,
273
+ yAxisIndex: 0,
274
+ encode: {
275
+ x: 'dates',
276
+ y: ['open', 'close', 'low', 'high'],
277
+ },
143
278
  itemStyle: {
144
- color: isDark ? colorPalette.orange : colorPalette.raspberryLight,
145
- color0: isDark
146
- ? colorPalette.bottleGreenDark
147
- : colorPalette.bottleGreenLight,
148
- borderColor: isDark
149
- ? colorPalette.orange
150
- : colorPalette.raspberryLight,
151
- borderColor0: isDark
152
- ? colorPalette.bottleGreenDark
153
- : colorPalette.bottleGreenLight,
279
+ color: chroma(candleShortColor).desaturate().css(),
280
+ color0: chroma(candleLongColor).desaturate().css(),
281
+ borderColor: candleShortColor,
282
+ borderColor0: candleLongColor,
283
+ },
284
+ emphasis: {
285
+ itemStyle: {
286
+ color: candleShortColor,
287
+ color0: candleLongColor,
288
+ },
154
289
  },
155
-
156
290
  markPoint: {
157
291
  symbol: 'circle',
158
292
  symbolSize: 0,
@@ -161,13 +295,26 @@ export const getOption: GetOptionType = (
161
295
  },
162
296
  {
163
297
  type: 'custom',
298
+ gridIndex: 0,
164
299
  name: 'heatmap',
165
300
  id: 'heatmap',
301
+ xAxisIndex: 0,
302
+ yAxisIndex: 0,
166
303
  silent: true,
167
304
  clip: true,
305
+ encode: {
306
+ x: 'dates',
307
+ y: 'bookPrices',
308
+ },
309
+ dimensions: ['dates', 'bookPrices', 'bookIndexes'],
168
310
  renderItem: (_params, api) => {
169
311
  const xVal = api.value(0);
170
312
  const bucketIndex = api.value(2) as number;
313
+
314
+ if (!bucketIndex) {
315
+ return null;
316
+ }
317
+
171
318
  const metaValues = buckets[bucketIndex];
172
319
 
173
320
  const [rectWidth, rectHeight] = api.size!([
@@ -187,7 +334,12 @@ export const getOption: GetOptionType = (
187
334
  height: rectHeight,
188
335
  },
189
336
  style: {
190
- fill: getRectColor(sentiment, isDark),
337
+ fill: getRectColor(
338
+ sentiment,
339
+ isDark,
340
+ sentimentThresholdMin,
341
+ sentimentThresholdMax
342
+ ),
191
343
  },
192
344
  silent: true,
193
345
  emphasisDisabled: true,
@@ -201,29 +353,95 @@ export const getOption: GetOptionType = (
201
353
  emphasisDisabled: true,
202
354
  };
203
355
  },
204
- data: orderPositionBooks,
356
+ },
357
+ {
358
+ type: 'line',
359
+ name: 'sentiment-short',
360
+ id: 'sentiment',
361
+ xAxisIndex: 1,
362
+ yAxisIndex: 1,
363
+ showSymbol: false,
364
+ symbol: 'none',
365
+ lineStyle: {
366
+ width: 3,
367
+ opacity: 1,
368
+ },
369
+ areaStyle: {
370
+ color: sentimentShortColor,
371
+ opacity: sentimentAreaOpacity,
372
+ },
373
+ emphasis: {
374
+ disabled: true,
375
+ },
376
+ stack: 'sentiment',
377
+ dimensions: ['dates', 'sentimentShorts', 'sentimentLongs'],
378
+ encode: {
379
+ x: 'dates',
380
+ y: 'sentimentShorts',
381
+ },
382
+ },
383
+ {
384
+ type: 'line',
385
+ name: 'sentiment-long',
386
+ id: 'sentiment-long',
387
+ xAxisIndex: 1,
388
+ yAxisIndex: 1,
389
+ symbol: 'none',
390
+ lineStyle: {
391
+ color: 'transparent',
392
+ width: 0,
393
+ },
394
+ areaStyle: {
395
+ color: sentimentLongColor,
396
+ opacity: sentimentAreaOpacity,
397
+ },
398
+ stack: 'sentiment',
399
+ emphasis: {
400
+ disabled: true,
401
+ },
402
+ tooltip: {
403
+ show: false,
404
+ },
405
+ dimensions: ['dates', 'sentimentLongs'],
406
+ encode: {
407
+ x: 'dates',
408
+ y: 'sentimentLongs',
409
+ },
205
410
  },
206
411
  ],
207
412
  grid: [
208
413
  {
209
414
  name: 'main-grid',
415
+ id: 'main-grid',
416
+ height: `${CHART_CONFIG.MAIN_HEIGHT}px`,
210
417
  top: '0px',
211
418
  left: '0px',
212
419
  right: `${isDesktop ? CHART_CONFIG.Y_LABEL_SIZE_DESKTOP : CHART_CONFIG.Y_LABEL_SIZE_MOBILE}px`,
213
420
  bottom: `${CHART_CONFIG.X_LABEL_SIZE}px`,
214
421
  },
422
+ {
423
+ name: 'sentiment-grid',
424
+ id: 'sentiment-grid',
425
+ height: `${CHART_CONFIG.SENTIMENT_HEIGHT}px`,
426
+ bottom: `0px`,
427
+ left: '0px',
428
+ right: `${isDesktop ? CHART_CONFIG.Y_LABEL_SIZE_DESKTOP : CHART_CONFIG.Y_LABEL_SIZE_MOBILE}px`,
429
+ },
215
430
  ],
216
431
  graphic: [
217
- ...gridLines,
432
+ ...gridMainLines,
218
433
  {
219
- ...getLineCommons(isDark as boolean),
220
- top: 0,
221
- right: 0,
222
- shape: {
223
- x1: 0,
224
- y1: 0,
225
- x2: 0,
226
- y2: 0,
434
+ type: 'text',
435
+ silent: true,
436
+ z: 1,
437
+ left: 4,
438
+ bottom: CHART_CONFIG_CALCULATED.SENTIMENT_TEXT_POSITION,
439
+ style: {
440
+ text: `${labelCallback('sentiment')}:`,
441
+ fontFamily: 'Sofia W03',
442
+ fontSize: 14,
443
+ fontWeight: 'bold',
444
+ fill: sentimentLabelColor,
227
445
  },
228
446
  },
229
447
  ],
@@ -19,33 +19,47 @@ export interface UseCrowdViewDataProps {
19
19
  granularity: Granularity;
20
20
  }
21
21
 
22
- interface CrowdViewData {
23
- xAxisData: string[];
24
- // [open, close, low, high]
25
- candlesSeriesData: [number, number, number, number][];
26
- // [time, price, index]
27
- orderPositionBooks: [string, number | null, number][];
22
+ interface CrowdViewMainData {
23
+ dates: string[];
24
+ candlesOpen: number[];
25
+ candlesClose: number[];
26
+ candlesLow: number[];
27
+ candlesHigh: number[];
28
+ bookPrices?: (number | null)[];
29
+ bookIndexes?: (number | null)[];
30
+ sentimentShorts: (number | null)[];
31
+ sentimentLongs: (number | null)[];
32
+ }
33
+
34
+ interface CrowdViewAdditionalData {
28
35
  bucketWidth: number;
29
36
  buckets: Bucket[][];
30
- precision: number;
37
+ displayPrecision: number;
31
38
  bookType: BookType;
39
+ sentimentThresholdMin: number;
40
+ sentimentThresholdMax: number;
32
41
  }
33
42
 
34
43
  export interface UseCrowdViewDataReturn {
35
- data: CrowdViewData | null;
44
+ mainData?: CrowdViewMainData | null;
45
+ additionalData?: CrowdViewAdditionalData | null;
36
46
  loading: boolean;
37
47
  error: boolean;
38
48
  }
39
49
 
40
- export type GetOptionType = (
41
- props: CrowdViewData,
42
- isDark: boolean,
43
- isDesktop: boolean,
44
- labelCallback: (key: string, params?: Record<string, unknown>) => string
45
- ) => EChartsOption;
50
+ interface GetOptionProps {
51
+ mainData: CrowdViewMainData;
52
+ additionalData: CrowdViewAdditionalData;
53
+ isDark: boolean;
54
+ isDesktop: boolean;
55
+ labelCallback: (key: string, params?: Record<string, unknown>) => string;
56
+ }
57
+
58
+ export type GetOptionType = (props: GetOptionProps) => EChartsOption;
46
59
 
47
60
  export interface ChartProps {
48
- data: CrowdViewData;
61
+ mainData: CrowdViewMainData;
62
+ additionalData: CrowdViewAdditionalData;
49
63
  isDesktop: boolean;
50
64
  }
51
65
 
@@ -57,6 +71,58 @@ export interface ChartWithDataProps {
57
71
  }
58
72
 
59
73
  export interface GetLabelsDataProps {
60
- xAxisData: string[];
74
+ dates: string[];
61
75
  isGreaterThanTwoWeeks: boolean;
62
76
  }
77
+
78
+ interface BaseTooltipParam {
79
+ [key: string]: unknown;
80
+ seriesId?: string;
81
+ seriesName?: string;
82
+ seriesType?: string;
83
+ axisValue?: string | number;
84
+ axisValueLabel?: string;
85
+ axisDimension?: string;
86
+ axisIndex?: number;
87
+ value: unknown;
88
+ }
89
+
90
+ export type TooltipParam =
91
+ | (BaseTooltipParam & {
92
+ seriesId: 'candlestick';
93
+ value: [number, number, number, number, number]; // [0, open, close, low, high]
94
+ })
95
+ | (BaseTooltipParam & {
96
+ seriesId: 'heatmap';
97
+ value: [string, number, number]; // [time, price, index]
98
+ })
99
+ | (BaseTooltipParam & {
100
+ seriesId: 'sentiment';
101
+ value: [string, number, number]; // [time, shortPercent, longPercent]
102
+ });
103
+
104
+ export interface DataZoomBatchItem {
105
+ [key: string]: unknown;
106
+ start: number;
107
+ end: number;
108
+ dataZoomId?: string;
109
+ }
110
+
111
+ export interface DataZoomEvent {
112
+ [key: string]: unknown;
113
+ type: 'datazoom';
114
+ batch?: DataZoomBatchItem[];
115
+ }
116
+
117
+ export interface DataZoomItem {
118
+ startValue: number;
119
+ endValue: number;
120
+ }
121
+
122
+ export type DataZoomArray = Array<DataZoomItem>;
123
+
124
+ export interface XAxisItem {
125
+ name?: string;
126
+ }
127
+
128
+ export type XAxisArray = Array<XAxisItem>;