@oanda/labs-crowd-view-widget 1.0.69 → 1.0.70

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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,290 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## 1.0.70 (2026-01-21)
7
+
8
+
9
+
10
+ ## 1.0.251 (2026-01-20)
11
+
12
+
13
+
14
+ ## 1.0.250 (2026-01-20)
15
+
16
+
17
+
18
+ ## 1.0.249 (2026-01-12)
19
+
20
+
21
+
22
+ ## 1.0.248 (2026-01-09)
23
+
24
+
25
+
26
+ ## 1.0.247 (2026-01-08)
27
+
28
+
29
+
30
+ ## 1.0.246 (2026-01-08)
31
+
32
+
33
+
34
+ ## 1.0.245 (2026-01-07)
35
+
36
+
37
+
38
+ ## 1.0.244 (2026-01-02)
39
+
40
+
41
+
42
+ ## 1.0.243 (2025-12-30)
43
+
44
+
45
+
46
+ ## 1.0.242 (2025-12-16)
47
+
48
+
49
+
50
+ ## 1.0.241 (2025-12-16)
51
+
52
+
53
+
54
+ ## 1.0.240 (2025-12-15)
55
+
56
+
57
+
58
+ ## 1.0.239 (2025-12-12)
59
+
60
+
61
+
62
+ ## 1.0.238 (2025-12-11)
63
+
64
+
65
+
66
+ ## 1.0.237 (2025-12-09)
67
+
68
+
69
+
70
+ ## 1.0.236 (2025-12-05)
71
+
72
+
73
+
74
+ ## 1.0.235 (2025-12-04)
75
+
76
+
77
+
78
+ ## 1.0.234 (2025-11-27)
79
+
80
+
81
+
82
+ ## 1.0.233 (2025-11-27)
83
+
84
+
85
+
86
+ ## 1.0.232 (2025-11-27)
87
+
88
+
89
+
90
+ ## 1.0.231 (2025-11-07)
91
+
92
+
93
+
94
+ ## 1.0.230 (2025-11-05)
95
+
96
+
97
+
98
+ ## 1.0.229 (2025-11-05)
99
+
100
+
101
+
102
+ ## 1.0.228 (2025-11-05)
103
+
104
+
105
+
106
+ ## 1.0.227 (2025-10-31)
107
+
108
+
109
+
110
+ ## 1.0.226 (2025-10-29)
111
+
112
+
113
+
114
+ ## 1.0.225 (2025-10-09)
115
+
116
+
117
+
118
+ ## 1.0.224 (2025-09-29)
119
+
120
+
121
+
122
+ ## 1.0.223 (2025-09-29)
123
+
124
+
125
+
126
+ ## 1.0.222 (2025-09-17)
127
+
128
+
129
+
130
+ ## 1.0.221 (2025-09-11)
131
+
132
+
133
+
134
+ ## 1.0.220 (2025-09-09)
135
+
136
+
137
+
138
+ ## 1.0.219 (2025-09-02)
139
+
140
+
141
+
142
+ ## 1.0.218 (2025-09-01)
143
+
144
+
145
+
146
+ ## 1.0.217 (2025-08-25)
147
+
148
+
149
+
150
+ ## 1.0.216 (2025-08-18)
151
+
152
+
153
+
154
+ ## 1.0.215 (2025-08-18)
155
+
156
+
157
+
158
+ ## 1.0.214 (2025-08-14)
159
+
160
+
161
+
162
+ ## 1.0.213 (2025-08-12)
163
+
164
+
165
+
166
+ ## 1.0.212 (2025-08-05)
167
+
168
+
169
+
170
+ ## 1.0.211 (2025-08-05)
171
+
172
+
173
+
174
+ ## 1.0.210 (2025-07-31)
175
+
176
+
177
+
178
+ ## 1.0.209 (2025-07-31)
179
+
180
+
181
+
182
+ ## 1.0.208 (2025-07-24)
183
+
184
+
185
+
186
+ ## 1.0.207 (2025-07-18)
187
+
188
+
189
+
190
+ ## 1.0.206 (2025-07-18)
191
+
192
+
193
+
194
+ ## 1.0.205 (2025-07-17)
195
+
196
+
197
+
198
+ ## 1.0.204 (2025-07-09)
199
+
200
+
201
+
202
+ ## 1.0.203 (2025-06-16)
203
+
204
+
205
+
206
+ ## 1.0.202 (2025-06-04)
207
+
208
+
209
+
210
+ ## 1.0.201 (2025-06-02)
211
+
212
+
213
+
214
+ ## 1.0.200 (2025-05-30)
215
+
216
+
217
+
218
+ ## 1.0.199 (2025-05-29)
219
+
220
+
221
+
222
+ ## 1.0.198 (2025-05-26)
223
+
224
+
225
+
226
+ ## 1.0.197 (2025-05-23)
227
+
228
+
229
+
230
+ ## 1.0.196 (2025-05-22)
231
+
232
+
233
+
234
+ ## 1.0.195 (2025-05-21)
235
+
236
+
237
+
238
+ ## 1.0.194 (2025-05-21)
239
+
240
+
241
+
242
+ ## 1.0.193 (2025-05-15)
243
+
244
+
245
+
246
+ ## 1.0.192 (2025-05-14)
247
+
248
+
249
+
250
+ ## 1.0.191 (2025-04-30)
251
+
252
+
253
+
254
+ ## 1.0.190 (2025-04-28)
255
+
256
+
257
+
258
+ ## 1.0.189 (2025-04-23)
259
+
260
+
261
+
262
+ ## 1.0.188 (2025-04-22)
263
+
264
+
265
+
266
+ ## 1.0.187 (2025-04-18)
267
+
268
+
269
+
270
+ ## 1.0.186 (2025-04-10)
271
+
272
+
273
+
274
+ ## 1.0.185 (2025-04-09)
275
+
276
+
277
+
278
+ ## 1.0.184 (2025-04-08)
279
+
280
+
281
+
282
+ ## 1.0.183 (2025-04-04)
283
+
284
+ **Note:** Version bump only for package @oanda/labs-crowd-view-widget
285
+
286
+
287
+
288
+
289
+
6
290
  ## 1.0.69 (2026-01-20)
7
291
 
8
292
 
@@ -177,10 +177,10 @@ const buildDesktopTooltip = _ref4 => {
177
177
  <div style="${isJapanese ? 'width: 45%;' : 'width: 40%;'}">
178
178
  ${candleSection}
179
179
  </div>
180
- <div style="${isJapanese ? 'width: 24%;' : 'width: 22%;'}">
180
+ <div style="${isJapanese ? 'width: 24%;' : 'width: 20%;'}">
181
181
  ${sentimentSection}
182
182
  </div>
183
- <div style="${isJapanese ? 'width: 31%;' : 'width: 38%;'}">
183
+ <div style="${isJapanese ? 'width: 31%;' : 'width: 40%;'}">
184
184
  ${bookSection}
185
185
  </div>
186
186
  </div>
@@ -1 +1 @@
1
- {"version":3,"file":"getTooltipFormatter.js","names":["_labsWidgetCommon","require","_graphql","_formatFullDate","SENTIMENT_DISPLAY_PRECISION","TOOLTIP_STYLES","MOBILE_COLUMN_WIDTH","PADDING_BOTTOM","FULL_WIDTH","calculateBucketDisplayPrecision","bucketWidth","toString","split","length","findSeriesParam","params","seriesId","find","series","findSentimentSeriesParam","sentimentLongs","sentimentShorts","index","dataIndex","sentimentLong","sentimentShort","getSentimentOverbalanceLabel","sentiment","bookType","BookType","Order","formatCandleData","candleData","labelCallback","isDesktop","open","close","low","high","candleLabel","openLabel","closeLabel","lowLabel","highLabel","formatBookData","_ref","matchedBucket","bucketDisplayPrecision","bookLabelKey","priceRangeStart","price","toFixed","priceRangeEnd","sentimentLabel","sentimentValue","Math","abs","formatSentimentData","hasValidCandleData","hasValidSentimentData","findMatchingBucket","buckets","bucketsIndex","selectedPrice","undefined","selectedBuckets","_ref2","getTooltipFormatter","_ref3","locale","isDark","isJapanese","Array","isArray","candleParam","booksParam","time","Date","axisValue","value","showCandles","showSentiment","timeFormatted","formatFullDate","candleSection","bookSection","sentimentSection","buildDesktopTooltip","buildMobileTooltip","exports","_ref4","backgroundColor","colorPalette","black","white","fullWidth","_ref5","columnWidth","padding"],"sources":["../../../../../../src/CrowdViewWidget/components/Chart/chartUtils/getTooltipFormatter.ts"],"sourcesContent":["import { colorPalette } from '@oanda/labs-widget-common';\n\nimport { BookType } from '../../../../gql/types/graphql';\nimport type { Bucket, TooltipParam } from '../types';\nimport { formatFullDate } from './formatFullDate';\n\nconst SENTIMENT_DISPLAY_PRECISION = 2;\n\nconst TOOLTIP_STYLES = {\n MOBILE_COLUMN_WIDTH: '33.3%',\n PADDING_BOTTOM: '4px',\n FULL_WIDTH: '100%',\n} as const;\n\nconst calculateBucketDisplayPrecision = (bucketWidth: number): number => {\n return bucketWidth.toString().split('.')[1]?.length || 0;\n};\n\nconst findSeriesParam = <T extends TooltipParam['seriesId']>(\n params: TooltipParam[],\n seriesId: T\n): Extract<TooltipParam, { seriesId: T }> | undefined => {\n return params.find(\n (series): series is Extract<TooltipParam, { seriesId: T }> =>\n series.seriesId === seriesId\n );\n};\n\nconst findSentimentSeriesParam = (\n params: TooltipParam[],\n sentimentLongs: (number | null)[],\n sentimentShorts: (number | null)[]\n): {\n sentimentLong: number | null;\n sentimentShort: number | null;\n} => {\n const index = params[0].dataIndex as number;\n\n return {\n sentimentLong: sentimentLongs[index] ?? null,\n sentimentShort: sentimentShorts[index] ?? null,\n };\n};\n\nconst getSentimentOverbalanceLabel = (\n sentiment: number,\n bookType: BookType\n): string => {\n if (sentiment < 0) {\n return bookType === BookType.Order\n ? 'sell_overbalance'\n : 'short_overbalance';\n }\n return bookType === BookType.Order ? 'buy_overbalance' : 'long_overbalance';\n};\n\nconst formatCandleData = (\n candleData: [number, number, number, number, number],\n labelCallback: (key: string) => string,\n isDesktop: boolean\n): string => {\n const [, open, close, low, high] = candleData;\n const candleLabel = labelCallback('candle');\n const openLabel = labelCallback('open');\n const closeLabel = labelCallback('close');\n const lowLabel = labelCallback('low');\n const highLabel = labelCallback('high');\n\n return isDesktop\n ? `<div><b>${candleLabel}:</b></div>\n<div style=\"display: flex; gap: 4px; margin-right: 4px;\">\n<div>${openLabel}: ${open} </div>\n<div>${highLabel}: ${high} </div>\n<div>${lowLabel}: ${low} </div>\n<div>${closeLabel}: ${close} </div>\n</div>`\n : `<div><b>${candleLabel}:</b></div>\n<div>${openLabel}: ${open} </div>\n<div>${highLabel}: ${high} </div>\n<div>${lowLabel}: ${low} </div>\n<div>${closeLabel}: ${close} </div>\n`;\n};\n\nconst formatBookData = ({\n matchedBucket,\n bucketWidth,\n bucketDisplayPrecision,\n bookType,\n labelCallback,\n isDesktop,\n}: {\n matchedBucket: Bucket;\n bucketWidth: number;\n bucketDisplayPrecision: number;\n bookType: BookType;\n labelCallback: (key: string) => string;\n isDesktop: boolean;\n}): string => {\n const bookLabelKey = bookType === BookType.Order ? 'orders' : 'trades';\n const priceRangeStart = matchedBucket.price.toFixed(bucketDisplayPrecision);\n const priceRangeEnd = (matchedBucket.price + bucketWidth).toFixed(\n bucketDisplayPrecision\n );\n const sentimentLabel = getSentimentOverbalanceLabel(\n matchedBucket.sentiment,\n bookType\n );\n const sentimentValue = Math.abs(matchedBucket.sentiment);\n\n return isDesktop\n ? `<div><b>${labelCallback(bookLabelKey)}:</b></div>\n<span style=\"margin-right: 4px;\">${labelCallback('price_range')}: ${priceRangeStart} - ${priceRangeEnd} </span>\n<span style=\"margin-right: 4px;\">${labelCallback(sentimentLabel)}: ${sentimentValue}% </span>`\n : `<div><b>${labelCallback(bookLabelKey)}:</b></div>\n<div>${labelCallback('price_range')}:</div>\n<div>${priceRangeStart} - ${priceRangeEnd} </div>\n<div>${labelCallback(sentimentLabel)}:</div>\n<div>${sentimentValue}% </div>`;\n};\n\nconst formatSentimentData = (\n sentimentLong: number,\n sentimentShort: number,\n labelCallback: (key: string) => string,\n isDesktop: boolean\n): string => {\n return isDesktop\n ? `<div><b>${labelCallback('sentiment')}:</b></div>\n <span style=\"margin-right: 4px;\">${labelCallback('long')}: ${sentimentLong.toFixed(SENTIMENT_DISPLAY_PRECISION)}% </span>\n <span style=\"margin-right: 4px;\">${labelCallback('short')}: ${sentimentShort.toFixed(SENTIMENT_DISPLAY_PRECISION)}% </span>`\n : `<div><b>${labelCallback('sentiment')}:</b></div>\n<div>${labelCallback('long')}: ${sentimentLong.toFixed(SENTIMENT_DISPLAY_PRECISION)}% </div>\n<div>${labelCallback('short')}: ${sentimentShort.toFixed(SENTIMENT_DISPLAY_PRECISION)}% </div>`;\n};\n\nconst hasValidCandleData = (\n candleData: [number, number, number, number, number]\n): boolean =>\n !!candleData[1] && !!candleData[2] && !!candleData[3] && !!candleData[4];\n\nconst hasValidSentimentData = (\n sentimentLong: number | null,\n sentimentShort: number | null\n): boolean => sentimentLong !== null && sentimentShort !== null;\n\nconst findMatchingBucket = (\n buckets: Bucket[][],\n bucketsIndex: number | undefined,\n selectedPrice: number,\n bucketWidth: number\n): Bucket | undefined => {\n if (bucketsIndex === undefined) {\n return undefined;\n }\n const selectedBuckets = buckets[bucketsIndex];\n return selectedBuckets?.find(\n ({ price }) => selectedPrice >= price && selectedPrice < price + bucketWidth\n );\n};\n\nexport const getTooltipFormatter = ({\n params,\n buckets,\n bucketWidth,\n selectedPrice,\n bookType,\n labelCallback,\n sentimentLongs,\n sentimentShorts,\n isDesktop,\n locale,\n isDark,\n isJapanese,\n}: {\n params: TooltipParam[];\n buckets: Bucket[][];\n bucketWidth: number;\n selectedPrice: number;\n bookType: BookType;\n labelCallback: (key: string) => string;\n sentimentLongs: (number | null)[];\n sentimentShorts: (number | null)[];\n isDesktop: boolean;\n locale: string;\n isDark: boolean;\n isJapanese: boolean;\n}) => {\n if (!params || !Array.isArray(params) || params.length === 0) {\n return '';\n }\n\n const candleParam = findSeriesParam(params, 'candlestick');\n const booksParam = findSeriesParam(params, 'heatmap');\n const { sentimentLong, sentimentShort } = findSentimentSeriesParam(\n params,\n sentimentLongs,\n sentimentShorts\n );\n\n if (!candleParam) {\n return '';\n }\n\n const bucketDisplayPrecision = calculateBucketDisplayPrecision(bucketWidth);\n const time = new Date(candleParam.axisValue as string);\n const candleData = candleParam.value;\n const bucketsIndex = booksParam?.value[2];\n const matchedBucket = findMatchingBucket(\n buckets,\n bucketsIndex,\n selectedPrice,\n bucketWidth\n );\n const showCandles = hasValidCandleData(candleData);\n const showSentiment = hasValidSentimentData(sentimentLong, sentimentShort);\n\n if (!showCandles && !matchedBucket) {\n return '';\n }\n\n const timeFormatted = formatFullDate(time, locale);\n const candleSection = showCandles\n ? formatCandleData(candleData, labelCallback, isDesktop)\n : '';\n\n const bookSection = matchedBucket\n ? formatBookData({\n matchedBucket,\n bucketWidth,\n bucketDisplayPrecision,\n bookType,\n labelCallback,\n isDesktop,\n })\n : '';\n\n const sentimentSection =\n showSentiment && sentimentLong && sentimentShort\n ? formatSentimentData(\n sentimentLong,\n sentimentShort,\n labelCallback,\n isDesktop\n )\n : '';\n\n if (isDesktop) {\n return buildDesktopTooltip({\n timeFormatted,\n candleSection,\n sentimentSection,\n bookSection,\n isDark,\n isJapanese,\n });\n }\n\n return buildMobileTooltip({\n timeFormatted,\n candleSection,\n sentimentSection,\n bookSection,\n isDark,\n });\n};\n\ninterface TooltipSections {\n timeFormatted: string;\n candleSection: string;\n sentimentSection: string;\n bookSection: string;\n}\n\nconst buildDesktopTooltip = ({\n candleSection,\n sentimentSection,\n bookSection,\n isDark,\n isJapanese,\n}: TooltipSections & {\n isDark: boolean;\n isJapanese: boolean;\n}): string => {\n const backgroundColor = isDark ? colorPalette.black : colorPalette.white;\n const fullWidth = TOOLTIP_STYLES.FULL_WIDTH;\n\n return `<div style=\"width: ${fullWidth}; background-color: ${backgroundColor};\">\n <div style=\"width: ${fullWidth}; display: flex; justify-content: space-between;\">\n <div style=\"${isJapanese ? 'width: 45%;' : 'width: 40%;'}\">\n${candleSection}\n</div>\n<div style=\"${isJapanese ? 'width: 24%;' : 'width: 22%;'}\">\n${sentimentSection}\n</div>\n<div style=\"${isJapanese ? 'width: 31%;' : 'width: 38%;'}\">\n${bookSection}\n</div>\n</div>\n</div>`;\n};\n\nconst buildMobileTooltip = ({\n timeFormatted,\n candleSection,\n sentimentSection,\n bookSection,\n isDark,\n}: TooltipSections & { isDark: boolean }): string => {\n const backgroundColor = isDark ? colorPalette.black : colorPalette.white;\n const columnWidth = TOOLTIP_STYLES.MOBILE_COLUMN_WIDTH;\n const fullWidth = TOOLTIP_STYLES.FULL_WIDTH;\n const padding = TOOLTIP_STYLES.PADDING_BOTTOM;\n\n return `<div style=\"width: ${fullWidth}; background-color: ${backgroundColor};\">\n <div style=\"padding-bottom: ${padding};\">${timeFormatted}</div>\n <div style=\"width: ${fullWidth}; display: flex; justify-content: space-between;\">\n <div style=\"width: ${columnWidth};\">\n${candleSection}\n</div>\n<div style=\"width: ${columnWidth};\">\n${sentimentSection}\n</div>\n<div style=\"width: ${columnWidth};\">\n${bookSection}\n</div>\n</div>\n</div>`;\n};\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"getTooltipFormatter.js","names":["_labsWidgetCommon","require","_graphql","_formatFullDate","SENTIMENT_DISPLAY_PRECISION","TOOLTIP_STYLES","MOBILE_COLUMN_WIDTH","PADDING_BOTTOM","FULL_WIDTH","calculateBucketDisplayPrecision","bucketWidth","toString","split","length","findSeriesParam","params","seriesId","find","series","findSentimentSeriesParam","sentimentLongs","sentimentShorts","index","dataIndex","sentimentLong","sentimentShort","getSentimentOverbalanceLabel","sentiment","bookType","BookType","Order","formatCandleData","candleData","labelCallback","isDesktop","open","close","low","high","candleLabel","openLabel","closeLabel","lowLabel","highLabel","formatBookData","_ref","matchedBucket","bucketDisplayPrecision","bookLabelKey","priceRangeStart","price","toFixed","priceRangeEnd","sentimentLabel","sentimentValue","Math","abs","formatSentimentData","hasValidCandleData","hasValidSentimentData","findMatchingBucket","buckets","bucketsIndex","selectedPrice","undefined","selectedBuckets","_ref2","getTooltipFormatter","_ref3","locale","isDark","isJapanese","Array","isArray","candleParam","booksParam","time","Date","axisValue","value","showCandles","showSentiment","timeFormatted","formatFullDate","candleSection","bookSection","sentimentSection","buildDesktopTooltip","buildMobileTooltip","exports","_ref4","backgroundColor","colorPalette","black","white","fullWidth","_ref5","columnWidth","padding"],"sources":["../../../../../../src/CrowdViewWidget/components/Chart/chartUtils/getTooltipFormatter.ts"],"sourcesContent":["import { colorPalette } from '@oanda/labs-widget-common';\n\nimport { BookType } from '../../../../gql/types/graphql';\nimport type { Bucket, TooltipParam } from '../types';\nimport { formatFullDate } from './formatFullDate';\n\nconst SENTIMENT_DISPLAY_PRECISION = 2;\n\nconst TOOLTIP_STYLES = {\n MOBILE_COLUMN_WIDTH: '33.3%',\n PADDING_BOTTOM: '4px',\n FULL_WIDTH: '100%',\n} as const;\n\nconst calculateBucketDisplayPrecision = (bucketWidth: number): number => {\n return bucketWidth.toString().split('.')[1]?.length || 0;\n};\n\nconst findSeriesParam = <T extends TooltipParam['seriesId']>(\n params: TooltipParam[],\n seriesId: T\n): Extract<TooltipParam, { seriesId: T }> | undefined => {\n return params.find(\n (series): series is Extract<TooltipParam, { seriesId: T }> =>\n series.seriesId === seriesId\n );\n};\n\nconst findSentimentSeriesParam = (\n params: TooltipParam[],\n sentimentLongs: (number | null)[],\n sentimentShorts: (number | null)[]\n): {\n sentimentLong: number | null;\n sentimentShort: number | null;\n} => {\n const index = params[0].dataIndex as number;\n\n return {\n sentimentLong: sentimentLongs[index] ?? null,\n sentimentShort: sentimentShorts[index] ?? null,\n };\n};\n\nconst getSentimentOverbalanceLabel = (\n sentiment: number,\n bookType: BookType\n): string => {\n if (sentiment < 0) {\n return bookType === BookType.Order\n ? 'sell_overbalance'\n : 'short_overbalance';\n }\n return bookType === BookType.Order ? 'buy_overbalance' : 'long_overbalance';\n};\n\nconst formatCandleData = (\n candleData: [number, number, number, number, number],\n labelCallback: (key: string) => string,\n isDesktop: boolean\n): string => {\n const [, open, close, low, high] = candleData;\n const candleLabel = labelCallback('candle');\n const openLabel = labelCallback('open');\n const closeLabel = labelCallback('close');\n const lowLabel = labelCallback('low');\n const highLabel = labelCallback('high');\n\n return isDesktop\n ? `<div><b>${candleLabel}:</b></div>\n<div style=\"display: flex; gap: 4px; margin-right: 4px;\">\n<div>${openLabel}: ${open} </div>\n<div>${highLabel}: ${high} </div>\n<div>${lowLabel}: ${low} </div>\n<div>${closeLabel}: ${close} </div>\n</div>`\n : `<div><b>${candleLabel}:</b></div>\n<div>${openLabel}: ${open} </div>\n<div>${highLabel}: ${high} </div>\n<div>${lowLabel}: ${low} </div>\n<div>${closeLabel}: ${close} </div>\n`;\n};\n\nconst formatBookData = ({\n matchedBucket,\n bucketWidth,\n bucketDisplayPrecision,\n bookType,\n labelCallback,\n isDesktop,\n}: {\n matchedBucket: Bucket;\n bucketWidth: number;\n bucketDisplayPrecision: number;\n bookType: BookType;\n labelCallback: (key: string) => string;\n isDesktop: boolean;\n}): string => {\n const bookLabelKey = bookType === BookType.Order ? 'orders' : 'trades';\n const priceRangeStart = matchedBucket.price.toFixed(bucketDisplayPrecision);\n const priceRangeEnd = (matchedBucket.price + bucketWidth).toFixed(\n bucketDisplayPrecision\n );\n const sentimentLabel = getSentimentOverbalanceLabel(\n matchedBucket.sentiment,\n bookType\n );\n const sentimentValue = Math.abs(matchedBucket.sentiment);\n\n return isDesktop\n ? `<div><b>${labelCallback(bookLabelKey)}:</b></div>\n<span style=\"margin-right: 4px;\">${labelCallback('price_range')}: ${priceRangeStart} - ${priceRangeEnd} </span>\n<span style=\"margin-right: 4px;\">${labelCallback(sentimentLabel)}: ${sentimentValue}% </span>`\n : `<div><b>${labelCallback(bookLabelKey)}:</b></div>\n<div>${labelCallback('price_range')}:</div>\n<div>${priceRangeStart} - ${priceRangeEnd} </div>\n<div>${labelCallback(sentimentLabel)}:</div>\n<div>${sentimentValue}% </div>`;\n};\n\nconst formatSentimentData = (\n sentimentLong: number,\n sentimentShort: number,\n labelCallback: (key: string) => string,\n isDesktop: boolean\n): string => {\n return isDesktop\n ? `<div><b>${labelCallback('sentiment')}:</b></div>\n <span style=\"margin-right: 4px;\">${labelCallback('long')}: ${sentimentLong.toFixed(SENTIMENT_DISPLAY_PRECISION)}% </span>\n <span style=\"margin-right: 4px;\">${labelCallback('short')}: ${sentimentShort.toFixed(SENTIMENT_DISPLAY_PRECISION)}% </span>`\n : `<div><b>${labelCallback('sentiment')}:</b></div>\n<div>${labelCallback('long')}: ${sentimentLong.toFixed(SENTIMENT_DISPLAY_PRECISION)}% </div>\n<div>${labelCallback('short')}: ${sentimentShort.toFixed(SENTIMENT_DISPLAY_PRECISION)}% </div>`;\n};\n\nconst hasValidCandleData = (\n candleData: [number, number, number, number, number]\n): boolean =>\n !!candleData[1] && !!candleData[2] && !!candleData[3] && !!candleData[4];\n\nconst hasValidSentimentData = (\n sentimentLong: number | null,\n sentimentShort: number | null\n): boolean => sentimentLong !== null && sentimentShort !== null;\n\nconst findMatchingBucket = (\n buckets: Bucket[][],\n bucketsIndex: number | undefined,\n selectedPrice: number,\n bucketWidth: number\n): Bucket | undefined => {\n if (bucketsIndex === undefined) {\n return undefined;\n }\n const selectedBuckets = buckets[bucketsIndex];\n return selectedBuckets?.find(\n ({ price }) => selectedPrice >= price && selectedPrice < price + bucketWidth\n );\n};\n\nexport const getTooltipFormatter = ({\n params,\n buckets,\n bucketWidth,\n selectedPrice,\n bookType,\n labelCallback,\n sentimentLongs,\n sentimentShorts,\n isDesktop,\n locale,\n isDark,\n isJapanese,\n}: {\n params: TooltipParam[];\n buckets: Bucket[][];\n bucketWidth: number;\n selectedPrice: number;\n bookType: BookType;\n labelCallback: (key: string) => string;\n sentimentLongs: (number | null)[];\n sentimentShorts: (number | null)[];\n isDesktop: boolean;\n locale: string;\n isDark: boolean;\n isJapanese: boolean;\n}) => {\n if (!params || !Array.isArray(params) || params.length === 0) {\n return '';\n }\n\n const candleParam = findSeriesParam(params, 'candlestick');\n const booksParam = findSeriesParam(params, 'heatmap');\n const { sentimentLong, sentimentShort } = findSentimentSeriesParam(\n params,\n sentimentLongs,\n sentimentShorts\n );\n\n if (!candleParam) {\n return '';\n }\n\n const bucketDisplayPrecision = calculateBucketDisplayPrecision(bucketWidth);\n const time = new Date(candleParam.axisValue as string);\n const candleData = candleParam.value;\n const bucketsIndex = booksParam?.value[2];\n const matchedBucket = findMatchingBucket(\n buckets,\n bucketsIndex,\n selectedPrice,\n bucketWidth\n );\n const showCandles = hasValidCandleData(candleData);\n const showSentiment = hasValidSentimentData(sentimentLong, sentimentShort);\n\n if (!showCandles && !matchedBucket) {\n return '';\n }\n\n const timeFormatted = formatFullDate(time, locale);\n const candleSection = showCandles\n ? formatCandleData(candleData, labelCallback, isDesktop)\n : '';\n\n const bookSection = matchedBucket\n ? formatBookData({\n matchedBucket,\n bucketWidth,\n bucketDisplayPrecision,\n bookType,\n labelCallback,\n isDesktop,\n })\n : '';\n\n const sentimentSection =\n showSentiment && sentimentLong && sentimentShort\n ? formatSentimentData(\n sentimentLong,\n sentimentShort,\n labelCallback,\n isDesktop\n )\n : '';\n\n if (isDesktop) {\n return buildDesktopTooltip({\n timeFormatted,\n candleSection,\n sentimentSection,\n bookSection,\n isDark,\n isJapanese,\n });\n }\n\n return buildMobileTooltip({\n timeFormatted,\n candleSection,\n sentimentSection,\n bookSection,\n isDark,\n });\n};\n\ninterface TooltipSections {\n timeFormatted: string;\n candleSection: string;\n sentimentSection: string;\n bookSection: string;\n}\n\nconst buildDesktopTooltip = ({\n candleSection,\n sentimentSection,\n bookSection,\n isDark,\n isJapanese,\n}: TooltipSections & {\n isDark: boolean;\n isJapanese: boolean;\n}): string => {\n const backgroundColor = isDark ? colorPalette.black : colorPalette.white;\n const fullWidth = TOOLTIP_STYLES.FULL_WIDTH;\n\n return `<div style=\"width: ${fullWidth}; background-color: ${backgroundColor};\">\n <div style=\"width: ${fullWidth}; display: flex; justify-content: space-between;\">\n <div style=\"${isJapanese ? 'width: 45%;' : 'width: 40%;'}\">\n${candleSection}\n</div>\n<div style=\"${isJapanese ? 'width: 24%;' : 'width: 20%;'}\">\n${sentimentSection}\n</div>\n<div style=\"${isJapanese ? 'width: 31%;' : 'width: 40%;'}\">\n${bookSection}\n</div>\n</div>\n</div>`;\n};\n\nconst buildMobileTooltip = ({\n timeFormatted,\n candleSection,\n sentimentSection,\n bookSection,\n isDark,\n}: TooltipSections & { isDark: boolean }): string => {\n const backgroundColor = isDark ? colorPalette.black : colorPalette.white;\n const columnWidth = TOOLTIP_STYLES.MOBILE_COLUMN_WIDTH;\n const fullWidth = TOOLTIP_STYLES.FULL_WIDTH;\n const padding = TOOLTIP_STYLES.PADDING_BOTTOM;\n\n return `<div style=\"width: ${fullWidth}; background-color: ${backgroundColor};\">\n <div style=\"padding-bottom: ${padding};\">${timeFormatted}</div>\n <div style=\"width: ${fullWidth}; display: flex; justify-content: space-between;\">\n <div style=\"width: ${columnWidth};\">\n${candleSection}\n</div>\n<div style=\"width: ${columnWidth};\">\n${sentimentSection}\n</div>\n<div style=\"width: ${columnWidth};\">\n${bookSection}\n</div>\n</div>\n</div>`;\n};\n"],"mappings":"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","ignoreList":[]}
@@ -1,30 +1,31 @@
1
1
  {
2
- "buy": "購入",
2
+ "buy": "買い",
3
3
  "buy_overbalance": "買い超過",
4
- "candle": "ローソク足",
5
- "close": "クローズ",
4
+ "candle": "四本値",
5
+ "close": "終値",
6
6
  "data_unavailable": "データが利用できません",
7
- "even_market_demand": "均衡需要",
8
- "granularity": "粒度",
7
+ "even_market_demand": "売買均衡",
8
+ "granularity": "時間足",
9
9
  "high": "高値",
10
+ "hour_0": "{{count}} 時間",
10
11
  "hour_plural": "{{count}} 時間",
11
- "hover_chart_to_see_more_details": "チャートの上にカーソルを合わせると詳細を確認できます",
12
- "instrument": "金融商品",
13
- "long": "ロング",
14
- "long_overbalance": "ロング超過",
12
+ "hover_chart_to_see_more_details": "チャート上にカーソルを合わせると詳細を確認できます",
13
+ "instrument": "銘柄",
14
+ "long": "買い",
15
+ "long_overbalance": "買い超過",
15
16
  "low": "安値",
16
- "open": "オープン",
17
- "order_book": "オーダーブック",
18
- "orders": "注文",
19
- "position_book": "ポジションブック",
17
+ "open": "始値",
18
+ "order_book": "オープンオーダー",
19
+ "orders": "未約定のオーダー",
20
+ "position_book": "オープンポジション",
20
21
  "price": "価格",
21
- "price_range": "価格範囲",
22
+ "price_range": "価格レンジ",
22
23
  "search": "検索",
23
24
  "sell": "売り",
24
25
  "sell_overbalance": "売り超過",
25
- "sentiment": "センチメント",
26
- "short": "ショート",
27
- "short_overbalance": "ショート超過",
26
+ "sentiment": "売買ポジション比率",
27
+ "short": "売り",
28
+ "short_overbalance": "売り超過",
28
29
  "tap_chart_to_see_more_details": "チャートをタップすると詳細を確認できます",
29
- "trades": "取引"
30
- }
30
+ "trades": "未決済のポジション"
31
+ }
@@ -170,10 +170,10 @@ const buildDesktopTooltip = _ref4 => {
170
170
  <div style="${isJapanese ? 'width: 45%;' : 'width: 40%;'}">
171
171
  ${candleSection}
172
172
  </div>
173
- <div style="${isJapanese ? 'width: 24%;' : 'width: 22%;'}">
173
+ <div style="${isJapanese ? 'width: 24%;' : 'width: 20%;'}">
174
174
  ${sentimentSection}
175
175
  </div>
176
- <div style="${isJapanese ? 'width: 31%;' : 'width: 38%;'}">
176
+ <div style="${isJapanese ? 'width: 31%;' : 'width: 40%;'}">
177
177
  ${bookSection}
178
178
  </div>
179
179
  </div>
@@ -1 +1 @@
1
- {"version":3,"file":"getTooltipFormatter.js","names":["colorPalette","BookType","formatFullDate","SENTIMENT_DISPLAY_PRECISION","TOOLTIP_STYLES","MOBILE_COLUMN_WIDTH","PADDING_BOTTOM","FULL_WIDTH","calculateBucketDisplayPrecision","bucketWidth","toString","split","length","findSeriesParam","params","seriesId","find","series","findSentimentSeriesParam","sentimentLongs","sentimentShorts","index","dataIndex","sentimentLong","sentimentShort","getSentimentOverbalanceLabel","sentiment","bookType","Order","formatCandleData","candleData","labelCallback","isDesktop","open","close","low","high","candleLabel","openLabel","closeLabel","lowLabel","highLabel","formatBookData","_ref","matchedBucket","bucketDisplayPrecision","bookLabelKey","priceRangeStart","price","toFixed","priceRangeEnd","sentimentLabel","sentimentValue","Math","abs","formatSentimentData","hasValidCandleData","hasValidSentimentData","findMatchingBucket","buckets","bucketsIndex","selectedPrice","undefined","selectedBuckets","_ref2","getTooltipFormatter","_ref3","locale","isDark","isJapanese","Array","isArray","candleParam","booksParam","time","Date","axisValue","value","showCandles","showSentiment","timeFormatted","candleSection","bookSection","sentimentSection","buildDesktopTooltip","buildMobileTooltip","_ref4","backgroundColor","black","white","fullWidth","_ref5","columnWidth","padding"],"sources":["../../../../../../src/CrowdViewWidget/components/Chart/chartUtils/getTooltipFormatter.ts"],"sourcesContent":["import { colorPalette } from '@oanda/labs-widget-common';\n\nimport { BookType } from '../../../../gql/types/graphql';\nimport type { Bucket, TooltipParam } from '../types';\nimport { formatFullDate } from './formatFullDate';\n\nconst SENTIMENT_DISPLAY_PRECISION = 2;\n\nconst TOOLTIP_STYLES = {\n MOBILE_COLUMN_WIDTH: '33.3%',\n PADDING_BOTTOM: '4px',\n FULL_WIDTH: '100%',\n} as const;\n\nconst calculateBucketDisplayPrecision = (bucketWidth: number): number => {\n return bucketWidth.toString().split('.')[1]?.length || 0;\n};\n\nconst findSeriesParam = <T extends TooltipParam['seriesId']>(\n params: TooltipParam[],\n seriesId: T\n): Extract<TooltipParam, { seriesId: T }> | undefined => {\n return params.find(\n (series): series is Extract<TooltipParam, { seriesId: T }> =>\n series.seriesId === seriesId\n );\n};\n\nconst findSentimentSeriesParam = (\n params: TooltipParam[],\n sentimentLongs: (number | null)[],\n sentimentShorts: (number | null)[]\n): {\n sentimentLong: number | null;\n sentimentShort: number | null;\n} => {\n const index = params[0].dataIndex as number;\n\n return {\n sentimentLong: sentimentLongs[index] ?? null,\n sentimentShort: sentimentShorts[index] ?? null,\n };\n};\n\nconst getSentimentOverbalanceLabel = (\n sentiment: number,\n bookType: BookType\n): string => {\n if (sentiment < 0) {\n return bookType === BookType.Order\n ? 'sell_overbalance'\n : 'short_overbalance';\n }\n return bookType === BookType.Order ? 'buy_overbalance' : 'long_overbalance';\n};\n\nconst formatCandleData = (\n candleData: [number, number, number, number, number],\n labelCallback: (key: string) => string,\n isDesktop: boolean\n): string => {\n const [, open, close, low, high] = candleData;\n const candleLabel = labelCallback('candle');\n const openLabel = labelCallback('open');\n const closeLabel = labelCallback('close');\n const lowLabel = labelCallback('low');\n const highLabel = labelCallback('high');\n\n return isDesktop\n ? `<div><b>${candleLabel}:</b></div>\n<div style=\"display: flex; gap: 4px; margin-right: 4px;\">\n<div>${openLabel}: ${open} </div>\n<div>${highLabel}: ${high} </div>\n<div>${lowLabel}: ${low} </div>\n<div>${closeLabel}: ${close} </div>\n</div>`\n : `<div><b>${candleLabel}:</b></div>\n<div>${openLabel}: ${open} </div>\n<div>${highLabel}: ${high} </div>\n<div>${lowLabel}: ${low} </div>\n<div>${closeLabel}: ${close} </div>\n`;\n};\n\nconst formatBookData = ({\n matchedBucket,\n bucketWidth,\n bucketDisplayPrecision,\n bookType,\n labelCallback,\n isDesktop,\n}: {\n matchedBucket: Bucket;\n bucketWidth: number;\n bucketDisplayPrecision: number;\n bookType: BookType;\n labelCallback: (key: string) => string;\n isDesktop: boolean;\n}): string => {\n const bookLabelKey = bookType === BookType.Order ? 'orders' : 'trades';\n const priceRangeStart = matchedBucket.price.toFixed(bucketDisplayPrecision);\n const priceRangeEnd = (matchedBucket.price + bucketWidth).toFixed(\n bucketDisplayPrecision\n );\n const sentimentLabel = getSentimentOverbalanceLabel(\n matchedBucket.sentiment,\n bookType\n );\n const sentimentValue = Math.abs(matchedBucket.sentiment);\n\n return isDesktop\n ? `<div><b>${labelCallback(bookLabelKey)}:</b></div>\n<span style=\"margin-right: 4px;\">${labelCallback('price_range')}: ${priceRangeStart} - ${priceRangeEnd} </span>\n<span style=\"margin-right: 4px;\">${labelCallback(sentimentLabel)}: ${sentimentValue}% </span>`\n : `<div><b>${labelCallback(bookLabelKey)}:</b></div>\n<div>${labelCallback('price_range')}:</div>\n<div>${priceRangeStart} - ${priceRangeEnd} </div>\n<div>${labelCallback(sentimentLabel)}:</div>\n<div>${sentimentValue}% </div>`;\n};\n\nconst formatSentimentData = (\n sentimentLong: number,\n sentimentShort: number,\n labelCallback: (key: string) => string,\n isDesktop: boolean\n): string => {\n return isDesktop\n ? `<div><b>${labelCallback('sentiment')}:</b></div>\n <span style=\"margin-right: 4px;\">${labelCallback('long')}: ${sentimentLong.toFixed(SENTIMENT_DISPLAY_PRECISION)}% </span>\n <span style=\"margin-right: 4px;\">${labelCallback('short')}: ${sentimentShort.toFixed(SENTIMENT_DISPLAY_PRECISION)}% </span>`\n : `<div><b>${labelCallback('sentiment')}:</b></div>\n<div>${labelCallback('long')}: ${sentimentLong.toFixed(SENTIMENT_DISPLAY_PRECISION)}% </div>\n<div>${labelCallback('short')}: ${sentimentShort.toFixed(SENTIMENT_DISPLAY_PRECISION)}% </div>`;\n};\n\nconst hasValidCandleData = (\n candleData: [number, number, number, number, number]\n): boolean =>\n !!candleData[1] && !!candleData[2] && !!candleData[3] && !!candleData[4];\n\nconst hasValidSentimentData = (\n sentimentLong: number | null,\n sentimentShort: number | null\n): boolean => sentimentLong !== null && sentimentShort !== null;\n\nconst findMatchingBucket = (\n buckets: Bucket[][],\n bucketsIndex: number | undefined,\n selectedPrice: number,\n bucketWidth: number\n): Bucket | undefined => {\n if (bucketsIndex === undefined) {\n return undefined;\n }\n const selectedBuckets = buckets[bucketsIndex];\n return selectedBuckets?.find(\n ({ price }) => selectedPrice >= price && selectedPrice < price + bucketWidth\n );\n};\n\nexport const getTooltipFormatter = ({\n params,\n buckets,\n bucketWidth,\n selectedPrice,\n bookType,\n labelCallback,\n sentimentLongs,\n sentimentShorts,\n isDesktop,\n locale,\n isDark,\n isJapanese,\n}: {\n params: TooltipParam[];\n buckets: Bucket[][];\n bucketWidth: number;\n selectedPrice: number;\n bookType: BookType;\n labelCallback: (key: string) => string;\n sentimentLongs: (number | null)[];\n sentimentShorts: (number | null)[];\n isDesktop: boolean;\n locale: string;\n isDark: boolean;\n isJapanese: boolean;\n}) => {\n if (!params || !Array.isArray(params) || params.length === 0) {\n return '';\n }\n\n const candleParam = findSeriesParam(params, 'candlestick');\n const booksParam = findSeriesParam(params, 'heatmap');\n const { sentimentLong, sentimentShort } = findSentimentSeriesParam(\n params,\n sentimentLongs,\n sentimentShorts\n );\n\n if (!candleParam) {\n return '';\n }\n\n const bucketDisplayPrecision = calculateBucketDisplayPrecision(bucketWidth);\n const time = new Date(candleParam.axisValue as string);\n const candleData = candleParam.value;\n const bucketsIndex = booksParam?.value[2];\n const matchedBucket = findMatchingBucket(\n buckets,\n bucketsIndex,\n selectedPrice,\n bucketWidth\n );\n const showCandles = hasValidCandleData(candleData);\n const showSentiment = hasValidSentimentData(sentimentLong, sentimentShort);\n\n if (!showCandles && !matchedBucket) {\n return '';\n }\n\n const timeFormatted = formatFullDate(time, locale);\n const candleSection = showCandles\n ? formatCandleData(candleData, labelCallback, isDesktop)\n : '';\n\n const bookSection = matchedBucket\n ? formatBookData({\n matchedBucket,\n bucketWidth,\n bucketDisplayPrecision,\n bookType,\n labelCallback,\n isDesktop,\n })\n : '';\n\n const sentimentSection =\n showSentiment && sentimentLong && sentimentShort\n ? formatSentimentData(\n sentimentLong,\n sentimentShort,\n labelCallback,\n isDesktop\n )\n : '';\n\n if (isDesktop) {\n return buildDesktopTooltip({\n timeFormatted,\n candleSection,\n sentimentSection,\n bookSection,\n isDark,\n isJapanese,\n });\n }\n\n return buildMobileTooltip({\n timeFormatted,\n candleSection,\n sentimentSection,\n bookSection,\n isDark,\n });\n};\n\ninterface TooltipSections {\n timeFormatted: string;\n candleSection: string;\n sentimentSection: string;\n bookSection: string;\n}\n\nconst buildDesktopTooltip = ({\n candleSection,\n sentimentSection,\n bookSection,\n isDark,\n isJapanese,\n}: TooltipSections & {\n isDark: boolean;\n isJapanese: boolean;\n}): string => {\n const backgroundColor = isDark ? colorPalette.black : colorPalette.white;\n const fullWidth = TOOLTIP_STYLES.FULL_WIDTH;\n\n return `<div style=\"width: ${fullWidth}; background-color: ${backgroundColor};\">\n <div style=\"width: ${fullWidth}; display: flex; justify-content: space-between;\">\n <div style=\"${isJapanese ? 'width: 45%;' : 'width: 40%;'}\">\n${candleSection}\n</div>\n<div style=\"${isJapanese ? 'width: 24%;' : 'width: 22%;'}\">\n${sentimentSection}\n</div>\n<div style=\"${isJapanese ? 'width: 31%;' : 'width: 38%;'}\">\n${bookSection}\n</div>\n</div>\n</div>`;\n};\n\nconst buildMobileTooltip = ({\n timeFormatted,\n candleSection,\n sentimentSection,\n bookSection,\n isDark,\n}: TooltipSections & { isDark: boolean }): string => {\n const backgroundColor = isDark ? colorPalette.black : colorPalette.white;\n const columnWidth = TOOLTIP_STYLES.MOBILE_COLUMN_WIDTH;\n const fullWidth = TOOLTIP_STYLES.FULL_WIDTH;\n const padding = TOOLTIP_STYLES.PADDING_BOTTOM;\n\n return `<div style=\"width: ${fullWidth}; background-color: ${backgroundColor};\">\n <div style=\"padding-bottom: ${padding};\">${timeFormatted}</div>\n <div style=\"width: ${fullWidth}; display: flex; justify-content: space-between;\">\n <div style=\"width: ${columnWidth};\">\n${candleSection}\n</div>\n<div style=\"width: ${columnWidth};\">\n${sentimentSection}\n</div>\n<div style=\"width: ${columnWidth};\">\n${bookSection}\n</div>\n</div>\n</div>`;\n};\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"getTooltipFormatter.js","names":["colorPalette","BookType","formatFullDate","SENTIMENT_DISPLAY_PRECISION","TOOLTIP_STYLES","MOBILE_COLUMN_WIDTH","PADDING_BOTTOM","FULL_WIDTH","calculateBucketDisplayPrecision","bucketWidth","toString","split","length","findSeriesParam","params","seriesId","find","series","findSentimentSeriesParam","sentimentLongs","sentimentShorts","index","dataIndex","sentimentLong","sentimentShort","getSentimentOverbalanceLabel","sentiment","bookType","Order","formatCandleData","candleData","labelCallback","isDesktop","open","close","low","high","candleLabel","openLabel","closeLabel","lowLabel","highLabel","formatBookData","_ref","matchedBucket","bucketDisplayPrecision","bookLabelKey","priceRangeStart","price","toFixed","priceRangeEnd","sentimentLabel","sentimentValue","Math","abs","formatSentimentData","hasValidCandleData","hasValidSentimentData","findMatchingBucket","buckets","bucketsIndex","selectedPrice","undefined","selectedBuckets","_ref2","getTooltipFormatter","_ref3","locale","isDark","isJapanese","Array","isArray","candleParam","booksParam","time","Date","axisValue","value","showCandles","showSentiment","timeFormatted","candleSection","bookSection","sentimentSection","buildDesktopTooltip","buildMobileTooltip","_ref4","backgroundColor","black","white","fullWidth","_ref5","columnWidth","padding"],"sources":["../../../../../../src/CrowdViewWidget/components/Chart/chartUtils/getTooltipFormatter.ts"],"sourcesContent":["import { colorPalette } from '@oanda/labs-widget-common';\n\nimport { BookType } from '../../../../gql/types/graphql';\nimport type { Bucket, TooltipParam } from '../types';\nimport { formatFullDate } from './formatFullDate';\n\nconst SENTIMENT_DISPLAY_PRECISION = 2;\n\nconst TOOLTIP_STYLES = {\n MOBILE_COLUMN_WIDTH: '33.3%',\n PADDING_BOTTOM: '4px',\n FULL_WIDTH: '100%',\n} as const;\n\nconst calculateBucketDisplayPrecision = (bucketWidth: number): number => {\n return bucketWidth.toString().split('.')[1]?.length || 0;\n};\n\nconst findSeriesParam = <T extends TooltipParam['seriesId']>(\n params: TooltipParam[],\n seriesId: T\n): Extract<TooltipParam, { seriesId: T }> | undefined => {\n return params.find(\n (series): series is Extract<TooltipParam, { seriesId: T }> =>\n series.seriesId === seriesId\n );\n};\n\nconst findSentimentSeriesParam = (\n params: TooltipParam[],\n sentimentLongs: (number | null)[],\n sentimentShorts: (number | null)[]\n): {\n sentimentLong: number | null;\n sentimentShort: number | null;\n} => {\n const index = params[0].dataIndex as number;\n\n return {\n sentimentLong: sentimentLongs[index] ?? null,\n sentimentShort: sentimentShorts[index] ?? null,\n };\n};\n\nconst getSentimentOverbalanceLabel = (\n sentiment: number,\n bookType: BookType\n): string => {\n if (sentiment < 0) {\n return bookType === BookType.Order\n ? 'sell_overbalance'\n : 'short_overbalance';\n }\n return bookType === BookType.Order ? 'buy_overbalance' : 'long_overbalance';\n};\n\nconst formatCandleData = (\n candleData: [number, number, number, number, number],\n labelCallback: (key: string) => string,\n isDesktop: boolean\n): string => {\n const [, open, close, low, high] = candleData;\n const candleLabel = labelCallback('candle');\n const openLabel = labelCallback('open');\n const closeLabel = labelCallback('close');\n const lowLabel = labelCallback('low');\n const highLabel = labelCallback('high');\n\n return isDesktop\n ? `<div><b>${candleLabel}:</b></div>\n<div style=\"display: flex; gap: 4px; margin-right: 4px;\">\n<div>${openLabel}: ${open} </div>\n<div>${highLabel}: ${high} </div>\n<div>${lowLabel}: ${low} </div>\n<div>${closeLabel}: ${close} </div>\n</div>`\n : `<div><b>${candleLabel}:</b></div>\n<div>${openLabel}: ${open} </div>\n<div>${highLabel}: ${high} </div>\n<div>${lowLabel}: ${low} </div>\n<div>${closeLabel}: ${close} </div>\n`;\n};\n\nconst formatBookData = ({\n matchedBucket,\n bucketWidth,\n bucketDisplayPrecision,\n bookType,\n labelCallback,\n isDesktop,\n}: {\n matchedBucket: Bucket;\n bucketWidth: number;\n bucketDisplayPrecision: number;\n bookType: BookType;\n labelCallback: (key: string) => string;\n isDesktop: boolean;\n}): string => {\n const bookLabelKey = bookType === BookType.Order ? 'orders' : 'trades';\n const priceRangeStart = matchedBucket.price.toFixed(bucketDisplayPrecision);\n const priceRangeEnd = (matchedBucket.price + bucketWidth).toFixed(\n bucketDisplayPrecision\n );\n const sentimentLabel = getSentimentOverbalanceLabel(\n matchedBucket.sentiment,\n bookType\n );\n const sentimentValue = Math.abs(matchedBucket.sentiment);\n\n return isDesktop\n ? `<div><b>${labelCallback(bookLabelKey)}:</b></div>\n<span style=\"margin-right: 4px;\">${labelCallback('price_range')}: ${priceRangeStart} - ${priceRangeEnd} </span>\n<span style=\"margin-right: 4px;\">${labelCallback(sentimentLabel)}: ${sentimentValue}% </span>`\n : `<div><b>${labelCallback(bookLabelKey)}:</b></div>\n<div>${labelCallback('price_range')}:</div>\n<div>${priceRangeStart} - ${priceRangeEnd} </div>\n<div>${labelCallback(sentimentLabel)}:</div>\n<div>${sentimentValue}% </div>`;\n};\n\nconst formatSentimentData = (\n sentimentLong: number,\n sentimentShort: number,\n labelCallback: (key: string) => string,\n isDesktop: boolean\n): string => {\n return isDesktop\n ? `<div><b>${labelCallback('sentiment')}:</b></div>\n <span style=\"margin-right: 4px;\">${labelCallback('long')}: ${sentimentLong.toFixed(SENTIMENT_DISPLAY_PRECISION)}% </span>\n <span style=\"margin-right: 4px;\">${labelCallback('short')}: ${sentimentShort.toFixed(SENTIMENT_DISPLAY_PRECISION)}% </span>`\n : `<div><b>${labelCallback('sentiment')}:</b></div>\n<div>${labelCallback('long')}: ${sentimentLong.toFixed(SENTIMENT_DISPLAY_PRECISION)}% </div>\n<div>${labelCallback('short')}: ${sentimentShort.toFixed(SENTIMENT_DISPLAY_PRECISION)}% </div>`;\n};\n\nconst hasValidCandleData = (\n candleData: [number, number, number, number, number]\n): boolean =>\n !!candleData[1] && !!candleData[2] && !!candleData[3] && !!candleData[4];\n\nconst hasValidSentimentData = (\n sentimentLong: number | null,\n sentimentShort: number | null\n): boolean => sentimentLong !== null && sentimentShort !== null;\n\nconst findMatchingBucket = (\n buckets: Bucket[][],\n bucketsIndex: number | undefined,\n selectedPrice: number,\n bucketWidth: number\n): Bucket | undefined => {\n if (bucketsIndex === undefined) {\n return undefined;\n }\n const selectedBuckets = buckets[bucketsIndex];\n return selectedBuckets?.find(\n ({ price }) => selectedPrice >= price && selectedPrice < price + bucketWidth\n );\n};\n\nexport const getTooltipFormatter = ({\n params,\n buckets,\n bucketWidth,\n selectedPrice,\n bookType,\n labelCallback,\n sentimentLongs,\n sentimentShorts,\n isDesktop,\n locale,\n isDark,\n isJapanese,\n}: {\n params: TooltipParam[];\n buckets: Bucket[][];\n bucketWidth: number;\n selectedPrice: number;\n bookType: BookType;\n labelCallback: (key: string) => string;\n sentimentLongs: (number | null)[];\n sentimentShorts: (number | null)[];\n isDesktop: boolean;\n locale: string;\n isDark: boolean;\n isJapanese: boolean;\n}) => {\n if (!params || !Array.isArray(params) || params.length === 0) {\n return '';\n }\n\n const candleParam = findSeriesParam(params, 'candlestick');\n const booksParam = findSeriesParam(params, 'heatmap');\n const { sentimentLong, sentimentShort } = findSentimentSeriesParam(\n params,\n sentimentLongs,\n sentimentShorts\n );\n\n if (!candleParam) {\n return '';\n }\n\n const bucketDisplayPrecision = calculateBucketDisplayPrecision(bucketWidth);\n const time = new Date(candleParam.axisValue as string);\n const candleData = candleParam.value;\n const bucketsIndex = booksParam?.value[2];\n const matchedBucket = findMatchingBucket(\n buckets,\n bucketsIndex,\n selectedPrice,\n bucketWidth\n );\n const showCandles = hasValidCandleData(candleData);\n const showSentiment = hasValidSentimentData(sentimentLong, sentimentShort);\n\n if (!showCandles && !matchedBucket) {\n return '';\n }\n\n const timeFormatted = formatFullDate(time, locale);\n const candleSection = showCandles\n ? formatCandleData(candleData, labelCallback, isDesktop)\n : '';\n\n const bookSection = matchedBucket\n ? formatBookData({\n matchedBucket,\n bucketWidth,\n bucketDisplayPrecision,\n bookType,\n labelCallback,\n isDesktop,\n })\n : '';\n\n const sentimentSection =\n showSentiment && sentimentLong && sentimentShort\n ? formatSentimentData(\n sentimentLong,\n sentimentShort,\n labelCallback,\n isDesktop\n )\n : '';\n\n if (isDesktop) {\n return buildDesktopTooltip({\n timeFormatted,\n candleSection,\n sentimentSection,\n bookSection,\n isDark,\n isJapanese,\n });\n }\n\n return buildMobileTooltip({\n timeFormatted,\n candleSection,\n sentimentSection,\n bookSection,\n isDark,\n });\n};\n\ninterface TooltipSections {\n timeFormatted: string;\n candleSection: string;\n sentimentSection: string;\n bookSection: string;\n}\n\nconst buildDesktopTooltip = ({\n candleSection,\n sentimentSection,\n bookSection,\n isDark,\n isJapanese,\n}: TooltipSections & {\n isDark: boolean;\n isJapanese: boolean;\n}): string => {\n const backgroundColor = isDark ? colorPalette.black : colorPalette.white;\n const fullWidth = TOOLTIP_STYLES.FULL_WIDTH;\n\n return `<div style=\"width: ${fullWidth}; background-color: ${backgroundColor};\">\n <div style=\"width: ${fullWidth}; display: flex; justify-content: space-between;\">\n <div style=\"${isJapanese ? 'width: 45%;' : 'width: 40%;'}\">\n${candleSection}\n</div>\n<div style=\"${isJapanese ? 'width: 24%;' : 'width: 20%;'}\">\n${sentimentSection}\n</div>\n<div style=\"${isJapanese ? 'width: 31%;' : 'width: 40%;'}\">\n${bookSection}\n</div>\n</div>\n</div>`;\n};\n\nconst buildMobileTooltip = ({\n timeFormatted,\n candleSection,\n sentimentSection,\n bookSection,\n isDark,\n}: TooltipSections & { isDark: boolean }): string => {\n const backgroundColor = isDark ? colorPalette.black : colorPalette.white;\n const columnWidth = TOOLTIP_STYLES.MOBILE_COLUMN_WIDTH;\n const fullWidth = TOOLTIP_STYLES.FULL_WIDTH;\n const padding = TOOLTIP_STYLES.PADDING_BOTTOM;\n\n return `<div style=\"width: ${fullWidth}; background-color: ${backgroundColor};\">\n <div style=\"padding-bottom: ${padding};\">${timeFormatted}</div>\n <div style=\"width: ${fullWidth}; display: flex; justify-content: space-between;\">\n <div style=\"width: ${columnWidth};\">\n${candleSection}\n</div>\n<div style=\"width: ${columnWidth};\">\n${sentimentSection}\n</div>\n<div style=\"width: ${columnWidth};\">\n${bookSection}\n</div>\n</div>\n</div>`;\n};\n"],"mappings":"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","ignoreList":[]}
@@ -1,30 +1,31 @@
1
1
  {
2
- "buy": "購入",
2
+ "buy": "買い",
3
3
  "buy_overbalance": "買い超過",
4
- "candle": "ローソク足",
5
- "close": "クローズ",
4
+ "candle": "四本値",
5
+ "close": "終値",
6
6
  "data_unavailable": "データが利用できません",
7
- "even_market_demand": "均衡需要",
8
- "granularity": "粒度",
7
+ "even_market_demand": "売買均衡",
8
+ "granularity": "時間足",
9
9
  "high": "高値",
10
+ "hour_0": "{{count}} 時間",
10
11
  "hour_plural": "{{count}} 時間",
11
- "hover_chart_to_see_more_details": "チャートの上にカーソルを合わせると詳細を確認できます",
12
- "instrument": "金融商品",
13
- "long": "ロング",
14
- "long_overbalance": "ロング超過",
12
+ "hover_chart_to_see_more_details": "チャート上にカーソルを合わせると詳細を確認できます",
13
+ "instrument": "銘柄",
14
+ "long": "買い",
15
+ "long_overbalance": "買い超過",
15
16
  "low": "安値",
16
- "open": "オープン",
17
- "order_book": "オーダーブック",
18
- "orders": "注文",
19
- "position_book": "ポジションブック",
17
+ "open": "始値",
18
+ "order_book": "オープンオーダー",
19
+ "orders": "未約定のオーダー",
20
+ "position_book": "オープンポジション",
20
21
  "price": "価格",
21
- "price_range": "価格範囲",
22
+ "price_range": "価格レンジ",
22
23
  "search": "検索",
23
24
  "sell": "売り",
24
25
  "sell_overbalance": "売り超過",
25
- "sentiment": "センチメント",
26
- "short": "ショート",
27
- "short_overbalance": "ショート超過",
26
+ "sentiment": "売買ポジション比率",
27
+ "short": "売り",
28
+ "short_overbalance": "売り超過",
28
29
  "tap_chart_to_see_more_details": "チャートをタップすると詳細を確認できます",
29
- "trades": "取引"
30
- }
30
+ "trades": "未決済のポジション"
31
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oanda/labs-crowd-view-widget",
3
- "version": "1.0.69",
3
+ "version": "1.0.70",
4
4
  "description": "Labs Crowd View Widget",
5
5
  "main": "dist/main/index.js",
6
6
  "module": "dist/module/index.js",
@@ -13,7 +13,7 @@
13
13
  "author": "OANDA",
14
14
  "license": "UNLICENSED",
15
15
  "dependencies": {
16
- "@oanda/labs-widget-common": "^1.0.251",
16
+ "@oanda/labs-widget-common": "^1.0.252",
17
17
  "@oanda/mono-i18n": "10.0.1",
18
18
  "chroma-js": "^3.1.2",
19
19
  "decimal.js": "^10.6.0",
@@ -24,5 +24,5 @@
24
24
  "@graphql-codegen/client-preset": "4.1.0",
25
25
  "@types/chroma-js": "^3.1.2"
26
26
  },
27
- "gitHead": "9f0bb69ebb741a06a9fbd53c1b63a32085d0f2f4"
27
+ "gitHead": "ae201544a004425cf83a3ba9356adbda66f7d0fd"
28
28
  }
@@ -290,10 +290,10 @@ const buildDesktopTooltip = ({
290
290
  <div style="${isJapanese ? 'width: 45%;' : 'width: 40%;'}">
291
291
  ${candleSection}
292
292
  </div>
293
- <div style="${isJapanese ? 'width: 24%;' : 'width: 22%;'}">
293
+ <div style="${isJapanese ? 'width: 24%;' : 'width: 20%;'}">
294
294
  ${sentimentSection}
295
295
  </div>
296
- <div style="${isJapanese ? 'width: 31%;' : 'width: 38%;'}">
296
+ <div style="${isJapanese ? 'width: 31%;' : 'width: 40%;'}">
297
297
  ${bookSection}
298
298
  </div>
299
299
  </div>
@@ -1,30 +1,31 @@
1
1
  {
2
- "buy": "購入",
2
+ "buy": "買い",
3
3
  "buy_overbalance": "買い超過",
4
- "candle": "ローソク足",
5
- "close": "クローズ",
4
+ "candle": "四本値",
5
+ "close": "終値",
6
6
  "data_unavailable": "データが利用できません",
7
- "even_market_demand": "均衡需要",
8
- "granularity": "粒度",
7
+ "even_market_demand": "売買均衡",
8
+ "granularity": "時間足",
9
9
  "high": "高値",
10
+ "hour_0": "{{count}} 時間",
10
11
  "hour_plural": "{{count}} 時間",
11
- "hover_chart_to_see_more_details": "チャートの上にカーソルを合わせると詳細を確認できます",
12
- "instrument": "金融商品",
13
- "long": "ロング",
14
- "long_overbalance": "ロング超過",
12
+ "hover_chart_to_see_more_details": "チャート上にカーソルを合わせると詳細を確認できます",
13
+ "instrument": "銘柄",
14
+ "long": "買い",
15
+ "long_overbalance": "買い超過",
15
16
  "low": "安値",
16
- "open": "オープン",
17
- "order_book": "オーダーブック",
18
- "orders": "注文",
19
- "position_book": "ポジションブック",
17
+ "open": "始値",
18
+ "order_book": "オープンオーダー",
19
+ "orders": "未約定のオーダー",
20
+ "position_book": "オープンポジション",
20
21
  "price": "価格",
21
- "price_range": "価格範囲",
22
+ "price_range": "価格レンジ",
22
23
  "search": "検索",
23
24
  "sell": "売り",
24
25
  "sell_overbalance": "売り超過",
25
- "sentiment": "センチメント",
26
- "short": "ショート",
27
- "short_overbalance": "ショート超過",
26
+ "sentiment": "売買ポジション比率",
27
+ "short": "売り",
28
+ "short_overbalance": "売り超過",
28
29
  "tap_chart_to_see_more_details": "チャートをタップすると詳細を確認できます",
29
- "trades": "取引"
30
- }
30
+ "trades": "未決済のポジション"
31
+ }