@oanda/labs-crowd-view-widget 1.0.46 → 1.0.47
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 +192 -0
- package/dist/main/CrowdViewWidget/Main.js +6 -4
- package/dist/main/CrowdViewWidget/Main.js.map +1 -1
- package/dist/main/CrowdViewWidget/components/Chart/Chart.js +3 -2
- package/dist/main/CrowdViewWidget/components/Chart/Chart.js.map +1 -1
- package/dist/main/CrowdViewWidget/components/Chart/ChartWithData.js +5 -14
- package/dist/main/CrowdViewWidget/components/Chart/ChartWithData.js.map +1 -1
- package/dist/main/CrowdViewWidget/components/Chart/chartOptions.js +4 -3
- package/dist/main/CrowdViewWidget/components/Chart/chartOptions.js.map +1 -1
- package/dist/main/CrowdViewWidget/components/Chart/types.js.map +1 -1
- package/dist/main/CrowdViewWidget/components/Chart/utils/chartUtils.js +1 -1
- package/dist/main/CrowdViewWidget/components/Chart/utils/chartUtils.js.map +1 -1
- package/dist/main/CrowdViewWidget/components/Legend/Legend.js +1 -1
- package/dist/main/CrowdViewWidget/components/Legend/Legend.js.map +1 -1
- package/dist/main/CrowdViewWidget/components/Legend/LegendBar.js +5 -3
- package/dist/main/CrowdViewWidget/components/Legend/LegendBar.js.map +1 -1
- package/dist/main/CrowdViewWidget/constants.js +1 -0
- package/dist/main/CrowdViewWidget/constants.js.map +1 -1
- package/dist/main/translations/sources/en.json +4 -4
- package/dist/module/CrowdViewWidget/Main.js +6 -4
- package/dist/module/CrowdViewWidget/Main.js.map +1 -1
- package/dist/module/CrowdViewWidget/components/Chart/Chart.js +3 -2
- package/dist/module/CrowdViewWidget/components/Chart/Chart.js.map +1 -1
- package/dist/module/CrowdViewWidget/components/Chart/ChartWithData.js +5 -14
- package/dist/module/CrowdViewWidget/components/Chart/ChartWithData.js.map +1 -1
- package/dist/module/CrowdViewWidget/components/Chart/chartOptions.js +4 -3
- package/dist/module/CrowdViewWidget/components/Chart/chartOptions.js.map +1 -1
- package/dist/module/CrowdViewWidget/components/Chart/types.js.map +1 -1
- package/dist/module/CrowdViewWidget/components/Chart/utils/chartUtils.js +1 -1
- package/dist/module/CrowdViewWidget/components/Chart/utils/chartUtils.js.map +1 -1
- package/dist/module/CrowdViewWidget/components/Legend/Legend.js +1 -1
- package/dist/module/CrowdViewWidget/components/Legend/Legend.js.map +1 -1
- package/dist/module/CrowdViewWidget/components/Legend/LegendBar.js +5 -3
- package/dist/module/CrowdViewWidget/components/Legend/LegendBar.js.map +1 -1
- package/dist/module/CrowdViewWidget/constants.js +1 -0
- package/dist/module/CrowdViewWidget/constants.js.map +1 -1
- package/dist/module/translations/sources/en.json +4 -4
- package/dist/types/CrowdViewWidget/components/Chart/Chart.d.ts +1 -1
- package/dist/types/CrowdViewWidget/components/Chart/types.d.ts +2 -1
- package/dist/types/CrowdViewWidget/constants.d.ts +1 -0
- package/package.json +3 -3
- package/src/CrowdViewWidget/Main.tsx +44 -37
- package/src/CrowdViewWidget/components/Chart/Chart.tsx +2 -2
- package/src/CrowdViewWidget/components/Chart/ChartWithData.tsx +4 -26
- package/src/CrowdViewWidget/components/Chart/chartOptions.ts +6 -2
- package/src/CrowdViewWidget/components/Chart/types.ts +2 -0
- package/src/CrowdViewWidget/components/Chart/utils/chartUtils.ts +6 -2
- package/src/CrowdViewWidget/components/Legend/Legend.tsx +1 -1
- package/src/CrowdViewWidget/components/Legend/LegendBar.tsx +5 -2
- package/src/CrowdViewWidget/constants.ts +1 -0
- package/src/translations/sources/en.json +4 -4
- package/test/components/Chart/utils/chartUtils.test.ts +1 -1
- package/test/components/Legend.test.tsx +2 -2
- package/test/components/LegendBar.test.tsx +3 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","names":["InstrumentId","BOOKS_THRESHOLDS","MIN","MAX","BUCKET_CONFIG","MULTIPLIER","PRICE_PADDING_MULTIPLIER","TIME_THRESHOLDS","TWO_WEEKS_MS","CHART_CONFIG","HEIGHT","WIDTH","X_LABEL_SIZE","Y_LABEL_SIZE_DESKTOP","INITIAL_START_ZOOM","INITIAL_END_ZOOM","X_AXIS_DATE_PADDING","COLOR_MAP","long","short","INSTRUMENTS_CONFIG","EUR_AUD","mt5name","v20name","precision","defaultBucketWidth","EUR_GBP","EUR_JPY","EUR_USD","EUR_CHF","USD_CHF","USD_JPY","USD_CAD","GBP_USD","GBP_JPY","GBP_CHF","AUD_JPY","AUD_USD","NZD_USD","XAU_USD","XAG_USD"],"sources":["../../../src/CrowdViewWidget/constants.ts"],"sourcesContent":["import { InstrumentId } from './types';\n\nexport const BOOKS_THRESHOLDS = {\n MIN: 0.15,\n MAX: 0.55,\n} as const;\n\nexport const BUCKET_CONFIG = {\n MULTIPLIER: 4,\n PRICE_PADDING_MULTIPLIER: 2,\n} as const;\n\nexport const TIME_THRESHOLDS = {\n TWO_WEEKS_MS: 14 * 24 * 60 * 60 * 1000,\n} as const;\n\nexport const CHART_CONFIG = {\n HEIGHT: 425,\n WIDTH: 9999,\n X_LABEL_SIZE: 40,\n Y_LABEL_SIZE_DESKTOP: 60,\n INITIAL_START_ZOOM: 80,\n INITIAL_END_ZOOM: 100,\n X_AXIS_DATE_PADDING: ' ',\n} as const;\n\nexport const COLOR_MAP = {\n long: ['#eaf5fa', '#83c4e0'],\n short: ['#fef7e7', '#fcd171'],\n} as const;\n\nexport const INSTRUMENTS_CONFIG: Record<\n InstrumentId,\n {\n precision: number;\n defaultBucketWidth: number;\n v20name: string;\n mt5name: string;\n }\n> = {\n [InstrumentId.EUR_AUD]: {\n mt5name: 'EURAUD',\n v20name: 'EUR_AUD',\n precision: 5,\n defaultBucketWidth: 0.0005,\n },\n [InstrumentId.EUR_GBP]: {\n mt5name: 'EURGBP',\n v20name: 'EUR_GBP',\n precision: 5,\n defaultBucketWidth: 0.0005,\n },\n [InstrumentId.EUR_JPY]: {\n mt5name: 'EURJPY',\n v20name: 'EUR_JPY',\n precision: 3,\n defaultBucketWidth: 0.05,\n },\n [InstrumentId.EUR_USD]: {\n mt5name: 'EURUSD',\n v20name: 'EUR_USD',\n precision: 5,\n defaultBucketWidth: 0.0005,\n },\n [InstrumentId.EUR_CHF]: {\n mt5name: 'EURCHF',\n v20name: 'EUR_CHF',\n precision: 5,\n defaultBucketWidth: 0.0005,\n },\n [InstrumentId.USD_CHF]: {\n mt5name: 'USDCHF',\n v20name: 'USD_CHF',\n precision: 5,\n defaultBucketWidth: 0.0005,\n },\n [InstrumentId.USD_JPY]: {\n mt5name: 'USDJPY',\n v20name: 'USD_JPY',\n precision: 3,\n defaultBucketWidth: 0.05,\n },\n [InstrumentId.USD_CAD]: {\n mt5name: 'USDCAD',\n v20name: 'USD_CAD',\n precision: 5,\n defaultBucketWidth: 0.0005,\n },\n [InstrumentId.GBP_USD]: {\n mt5name: 'GBPUSD',\n v20name: 'GBP_USD',\n precision: 5,\n defaultBucketWidth: 0.0005,\n },\n [InstrumentId.GBP_JPY]: {\n mt5name: 'GBPJPY',\n v20name: 'GBP_JPY',\n precision: 3,\n defaultBucketWidth: 0.05,\n },\n [InstrumentId.GBP_CHF]: {\n mt5name: 'GBPCHF',\n v20name: 'GBP_CHF',\n precision: 5,\n defaultBucketWidth: 0.0005,\n },\n [InstrumentId.AUD_JPY]: {\n mt5name: 'AUDJPY',\n v20name: 'AUD_JPY',\n precision: 3,\n defaultBucketWidth: 0.05,\n },\n [InstrumentId.AUD_USD]: {\n mt5name: 'AUDUSD',\n v20name: 'AUD_USD',\n precision: 5,\n defaultBucketWidth: 0.0005,\n },\n [InstrumentId.NZD_USD]: {\n mt5name: 'NZDUSD',\n v20name: 'NZD_USD',\n precision: 5,\n defaultBucketWidth: 0.0005,\n },\n [InstrumentId.XAU_USD]: {\n mt5name: 'XAUUSD',\n v20name: 'XAU_USD',\n precision: 3,\n defaultBucketWidth: 0.5,\n },\n [InstrumentId.XAG_USD]: {\n mt5name: 'XAGUSD',\n v20name: 'XAG_USD',\n precision: 5,\n defaultBucketWidth: 0.0005,\n },\n};\n"],"mappings":"AAAA,SAASA,YAAY,QAAQ,SAAS;AAEtC,OAAO,MAAMC,gBAAgB,GAAG;EAC9BC,GAAG,EAAE,IAAI;EACTC,GAAG,EAAE;AACP,CAAU;AAEV,OAAO,MAAMC,aAAa,GAAG;EAC3BC,UAAU,EAAE,CAAC;EACbC,wBAAwB,EAAE;AAC5B,CAAU;AAEV,OAAO,MAAMC,eAAe,GAAG;EAC7BC,YAAY,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG;AACpC,CAAU;AAEV,OAAO,MAAMC,YAAY,GAAG;EAC1BC,MAAM,EAAE,GAAG;EACXC,KAAK,EAAE,IAAI;EACXC,YAAY,EAAE,EAAE;EAChBC,oBAAoB,EAAE,EAAE;EACxBC,kBAAkB,EAAE,EAAE;EACtBC,gBAAgB,EAAE,GAAG;EACrBC,mBAAmB,EAAE;AACvB,CAAU;AAEV,OAAO,MAAMC,SAAS,GAAG;EACvBC,IAAI,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC;EAC5BC,KAAK,EAAE,CAAC,SAAS,EAAE,SAAS;AAC9B,CAAU;AAEV,OAAO,MAAMC,kBAQZ,GAAG;EACF,
|
|
1
|
+
{"version":3,"file":"constants.js","names":["InstrumentId","BOOKS_THRESHOLDS","MIN","MAX","BUCKET_CONFIG","MULTIPLIER","PRICE_PADDING_MULTIPLIER","TIME_THRESHOLDS","TWO_WEEKS_MS","CHART_CONFIG","HEIGHT","WIDTH","X_LABEL_SIZE","Y_LABEL_SIZE_DESKTOP","Y_LABEL_SIZE_MOBILE","INITIAL_START_ZOOM","INITIAL_END_ZOOM","X_AXIS_DATE_PADDING","COLOR_MAP","long","short","INSTRUMENTS_CONFIG","EUR_AUD","mt5name","v20name","precision","defaultBucketWidth","EUR_GBP","EUR_JPY","EUR_USD","EUR_CHF","USD_CHF","USD_JPY","USD_CAD","GBP_USD","GBP_JPY","GBP_CHF","AUD_JPY","AUD_USD","NZD_USD","XAU_USD","XAG_USD"],"sources":["../../../src/CrowdViewWidget/constants.ts"],"sourcesContent":["import { InstrumentId } from './types';\n\nexport const BOOKS_THRESHOLDS = {\n MIN: 0.15,\n MAX: 0.55,\n} as const;\n\nexport const BUCKET_CONFIG = {\n MULTIPLIER: 4,\n PRICE_PADDING_MULTIPLIER: 2,\n} as const;\n\nexport const TIME_THRESHOLDS = {\n TWO_WEEKS_MS: 14 * 24 * 60 * 60 * 1000,\n} as const;\n\nexport const CHART_CONFIG = {\n HEIGHT: 425,\n WIDTH: 9999,\n X_LABEL_SIZE: 40,\n Y_LABEL_SIZE_DESKTOP: 60,\n Y_LABEL_SIZE_MOBILE: 40,\n INITIAL_START_ZOOM: 80,\n INITIAL_END_ZOOM: 100,\n X_AXIS_DATE_PADDING: ' ',\n} as const;\n\nexport const COLOR_MAP = {\n long: ['#eaf5fa', '#83c4e0'],\n short: ['#fef7e7', '#fcd171'],\n} as const;\n\nexport const INSTRUMENTS_CONFIG: Record<\n InstrumentId,\n {\n precision: number;\n defaultBucketWidth: number;\n v20name: string;\n mt5name: string;\n }\n> = {\n [InstrumentId.EUR_AUD]: {\n mt5name: 'EURAUD',\n v20name: 'EUR_AUD',\n precision: 5,\n defaultBucketWidth: 0.0005,\n },\n [InstrumentId.EUR_GBP]: {\n mt5name: 'EURGBP',\n v20name: 'EUR_GBP',\n precision: 5,\n defaultBucketWidth: 0.0005,\n },\n [InstrumentId.EUR_JPY]: {\n mt5name: 'EURJPY',\n v20name: 'EUR_JPY',\n precision: 3,\n defaultBucketWidth: 0.05,\n },\n [InstrumentId.EUR_USD]: {\n mt5name: 'EURUSD',\n v20name: 'EUR_USD',\n precision: 5,\n defaultBucketWidth: 0.0005,\n },\n [InstrumentId.EUR_CHF]: {\n mt5name: 'EURCHF',\n v20name: 'EUR_CHF',\n precision: 5,\n defaultBucketWidth: 0.0005,\n },\n [InstrumentId.USD_CHF]: {\n mt5name: 'USDCHF',\n v20name: 'USD_CHF',\n precision: 5,\n defaultBucketWidth: 0.0005,\n },\n [InstrumentId.USD_JPY]: {\n mt5name: 'USDJPY',\n v20name: 'USD_JPY',\n precision: 3,\n defaultBucketWidth: 0.05,\n },\n [InstrumentId.USD_CAD]: {\n mt5name: 'USDCAD',\n v20name: 'USD_CAD',\n precision: 5,\n defaultBucketWidth: 0.0005,\n },\n [InstrumentId.GBP_USD]: {\n mt5name: 'GBPUSD',\n v20name: 'GBP_USD',\n precision: 5,\n defaultBucketWidth: 0.0005,\n },\n [InstrumentId.GBP_JPY]: {\n mt5name: 'GBPJPY',\n v20name: 'GBP_JPY',\n precision: 3,\n defaultBucketWidth: 0.05,\n },\n [InstrumentId.GBP_CHF]: {\n mt5name: 'GBPCHF',\n v20name: 'GBP_CHF',\n precision: 5,\n defaultBucketWidth: 0.0005,\n },\n [InstrumentId.AUD_JPY]: {\n mt5name: 'AUDJPY',\n v20name: 'AUD_JPY',\n precision: 3,\n defaultBucketWidth: 0.05,\n },\n [InstrumentId.AUD_USD]: {\n mt5name: 'AUDUSD',\n v20name: 'AUD_USD',\n precision: 5,\n defaultBucketWidth: 0.0005,\n },\n [InstrumentId.NZD_USD]: {\n mt5name: 'NZDUSD',\n v20name: 'NZD_USD',\n precision: 5,\n defaultBucketWidth: 0.0005,\n },\n [InstrumentId.XAU_USD]: {\n mt5name: 'XAUUSD',\n v20name: 'XAU_USD',\n precision: 3,\n defaultBucketWidth: 0.5,\n },\n [InstrumentId.XAG_USD]: {\n mt5name: 'XAGUSD',\n v20name: 'XAG_USD',\n precision: 5,\n defaultBucketWidth: 0.0005,\n },\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"15_minutes": "15 minutes",
|
|
4
4
|
"4_hours": "4 hours",
|
|
5
5
|
"5_minutes": "5 minutes",
|
|
6
|
-
"
|
|
6
|
+
"buy_overbalance": "Buy overbalance",
|
|
7
7
|
"buy": "Buy",
|
|
8
8
|
"candle": "Candle",
|
|
9
9
|
"close_price": "Close price",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"granularity": "Granularity",
|
|
12
12
|
"high": "High",
|
|
13
13
|
"instrument": "Instrument",
|
|
14
|
-
"
|
|
14
|
+
"long_overbalance": "Long overbalance",
|
|
15
15
|
"long": "Long",
|
|
16
16
|
"low": "Low",
|
|
17
17
|
"no_matching_results": "No matching results",
|
|
@@ -23,9 +23,9 @@
|
|
|
23
23
|
"positions": "Positions",
|
|
24
24
|
"price_range": "Price range",
|
|
25
25
|
"search": "Search",
|
|
26
|
-
"
|
|
26
|
+
"sell_overbalance": "Sell overbalance",
|
|
27
27
|
"sell": "Sell",
|
|
28
28
|
"sentiment": "Sentiment",
|
|
29
|
-
"
|
|
29
|
+
"short_overbalance": "Short overbalance",
|
|
30
30
|
"short": "Short"
|
|
31
31
|
}
|
|
@@ -25,9 +25,10 @@ export interface UseCrowdViewDataReturn {
|
|
|
25
25
|
loading: boolean;
|
|
26
26
|
error: boolean;
|
|
27
27
|
}
|
|
28
|
-
export type GetOptionType = (props: CrowdViewData, isDark: boolean, labelCallback: (key: string, params?: Record<string, unknown>) => string) => EChartsOption;
|
|
28
|
+
export type GetOptionType = (props: CrowdViewData, isDark: boolean, isDesktop: boolean, labelCallback: (key: string, params?: Record<string, unknown>) => string) => EChartsOption;
|
|
29
29
|
export interface ChartProps {
|
|
30
30
|
data: CrowdViewData;
|
|
31
|
+
isDesktop: boolean;
|
|
31
32
|
}
|
|
32
33
|
export interface ChartWithDataProps {
|
|
33
34
|
bookType: BookType;
|
|
@@ -15,6 +15,7 @@ export declare const CHART_CONFIG: {
|
|
|
15
15
|
readonly WIDTH: 9999;
|
|
16
16
|
readonly X_LABEL_SIZE: 40;
|
|
17
17
|
readonly Y_LABEL_SIZE_DESKTOP: 60;
|
|
18
|
+
readonly Y_LABEL_SIZE_MOBILE: 40;
|
|
18
19
|
readonly INITIAL_START_ZOOM: 80;
|
|
19
20
|
readonly INITIAL_END_ZOOM: 100;
|
|
20
21
|
readonly X_AXIS_DATE_PADDING: " ";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oanda/labs-crowd-view-widget",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.47",
|
|
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.
|
|
16
|
+
"@oanda/labs-widget-common": "^1.0.229",
|
|
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": "
|
|
27
|
+
"gitHead": "47f304845284328dc8e0889e41df96af97dd683b"
|
|
28
28
|
}
|
|
@@ -52,48 +52,55 @@ const Main = ({ division }: MainProps) => {
|
|
|
52
52
|
className="lw-text-sm lw-tracking-normal"
|
|
53
53
|
data-testid="crowd-view-widget"
|
|
54
54
|
>
|
|
55
|
-
<
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
'lw-w-full': !isDesktop,
|
|
66
|
-
'lw-w-[280px]': isDesktop,
|
|
67
|
-
})}
|
|
68
|
-
>
|
|
69
|
-
<Select
|
|
70
|
-
options={instrumentSelectConfigWithDivision}
|
|
71
|
-
searchPlaceholder={lang('search')}
|
|
72
|
-
selectLabel={lang('instrument')}
|
|
73
|
-
selectedOption={instrument}
|
|
74
|
-
setSelectedOption={(val) =>
|
|
75
|
-
setInstrument(val as { id: InstrumentId; label: string })
|
|
76
|
-
}
|
|
77
|
-
/>
|
|
78
|
-
</div>
|
|
55
|
+
<div>
|
|
56
|
+
<Tabs
|
|
57
|
+
mobileFullWidth
|
|
58
|
+
activeTab={bookType}
|
|
59
|
+
handleClick={(e) =>
|
|
60
|
+
setBookType(e.currentTarget.value as BookType)
|
|
61
|
+
}
|
|
62
|
+
items={navigationConfig}
|
|
63
|
+
labelCallback={lang}
|
|
64
|
+
/>
|
|
79
65
|
<div
|
|
80
|
-
className={cn({
|
|
81
|
-
'lw-
|
|
82
|
-
'lw-w-[280px]': isDesktop,
|
|
66
|
+
className={cn('lw-mb-6 lw-mt-12', {
|
|
67
|
+
'lw-flex': isDesktop,
|
|
83
68
|
})}
|
|
84
69
|
>
|
|
85
|
-
<
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
70
|
+
<div
|
|
71
|
+
className={cn('lw-mr-2', {
|
|
72
|
+
'lw-w-full lw-mb-2': !isDesktop,
|
|
73
|
+
'lw-w-[280px]': isDesktop,
|
|
74
|
+
})}
|
|
75
|
+
>
|
|
76
|
+
<Select
|
|
77
|
+
options={instrumentSelectConfigWithDivision}
|
|
78
|
+
searchPlaceholder={lang('search')}
|
|
79
|
+
selectLabel={lang('instrument')}
|
|
80
|
+
selectedOption={instrument}
|
|
81
|
+
setSelectedOption={(val) =>
|
|
82
|
+
setInstrument(val as { id: InstrumentId; label: string })
|
|
83
|
+
}
|
|
84
|
+
/>
|
|
85
|
+
</div>
|
|
86
|
+
<div
|
|
87
|
+
className={cn({
|
|
88
|
+
'lw-w-full': !isDesktop,
|
|
89
|
+
'lw-w-[280px]': isDesktop,
|
|
90
|
+
})}
|
|
91
|
+
>
|
|
92
|
+
<Select
|
|
93
|
+
options={granularitySelectConfigWithLang}
|
|
94
|
+
searchPlaceholder={lang('search')}
|
|
95
|
+
selectLabel={lang('granularity')}
|
|
96
|
+
selectedOption={granularity}
|
|
97
|
+
setSelectedOption={(val) =>
|
|
98
|
+
setGranularity(val as { id: Granularity; label: string })
|
|
99
|
+
}
|
|
100
|
+
/>
|
|
101
|
+
</div>
|
|
94
102
|
</div>
|
|
95
103
|
</div>
|
|
96
|
-
|
|
97
104
|
<ChartWithData
|
|
98
105
|
bookType={bookType}
|
|
99
106
|
division={division}
|
|
@@ -48,7 +48,7 @@ echarts.use([
|
|
|
48
48
|
echarts.registerTheme('dark_theme', getChartTheme(Theme.Dark));
|
|
49
49
|
echarts.registerTheme('light_theme', getChartTheme(Theme.Light));
|
|
50
50
|
|
|
51
|
-
const Chart = ({ data }: ChartProps) => {
|
|
51
|
+
const Chart = ({ data, isDesktop }: ChartProps) => {
|
|
52
52
|
const { isDark } = useLayoutProvider();
|
|
53
53
|
const { lang } = useLocale();
|
|
54
54
|
|
|
@@ -58,7 +58,7 @@ const Chart = ({ data }: ChartProps) => {
|
|
|
58
58
|
echarts={echarts}
|
|
59
59
|
isDark={isDark}
|
|
60
60
|
lazyUpdate={true}
|
|
61
|
-
option={getOption(data, isDark, lang)}
|
|
61
|
+
option={getOption(data, isDark, isDesktop, lang)}
|
|
62
62
|
opts={{ renderer: 'canvas' }}
|
|
63
63
|
onEvents={{
|
|
64
64
|
datazoom: (_params: unknown, instance: EChartsType) => {
|
|
@@ -5,7 +5,6 @@ import {
|
|
|
5
5
|
SpinnerSize,
|
|
6
6
|
useLayoutProvider,
|
|
7
7
|
} from '@oanda/labs-widget-common';
|
|
8
|
-
import classnames from 'classnames';
|
|
9
8
|
import React from 'react';
|
|
10
9
|
|
|
11
10
|
import { Chart } from './Chart';
|
|
@@ -30,41 +29,20 @@ const ChartWithData = ({
|
|
|
30
29
|
|
|
31
30
|
return (
|
|
32
31
|
<>
|
|
33
|
-
<div
|
|
34
|
-
className={classnames('lw-relative lw-w-full', {
|
|
35
|
-
'lw-h-[450px]': isDesktop,
|
|
36
|
-
'lw-h-[390px]': !isDesktop,
|
|
37
|
-
})}
|
|
38
|
-
>
|
|
32
|
+
<div className="lw-relative lw-h-[450px] lw-w-full">
|
|
39
33
|
{error && (
|
|
40
|
-
<div
|
|
41
|
-
className={classnames(
|
|
42
|
-
'lw-absolute lw-left-0 lw-top-0 lw-flex lw-w-full lw-items-center lw-justify-center lw-border lw-border-solid lw-border-border-primary',
|
|
43
|
-
{
|
|
44
|
-
'lw-h-full': isDesktop,
|
|
45
|
-
'lw-h-[calc(100%-40px)]': !isDesktop,
|
|
46
|
-
}
|
|
47
|
-
)}
|
|
48
|
-
>
|
|
34
|
+
<div className="lw-absolute lw-left-0 lw-top-0 lw-flex lw-h-[calc(100%-30px)] lw-w-full lw-items-center lw-justify-center lw-border lw-border-solid lw-border-border-primary">
|
|
49
35
|
<ChartError />
|
|
50
36
|
</div>
|
|
51
37
|
)}
|
|
52
38
|
{loading && (
|
|
53
|
-
<div
|
|
54
|
-
className={classnames(
|
|
55
|
-
'lw-absolute lw-left-0 lw-top-0 lw-flex lw-w-full lw-items-center lw-justify-center lw-border lw-border-solid lw-border-border-primary',
|
|
56
|
-
{
|
|
57
|
-
'lw-h-full': isDesktop,
|
|
58
|
-
'lw-h-[calc(100%-40px)]': !isDesktop,
|
|
59
|
-
}
|
|
60
|
-
)}
|
|
61
|
-
>
|
|
39
|
+
<div className="lw-absolute lw-left-0 lw-top-0 lw-flex lw-h-[calc(100%-30px)] lw-w-full lw-items-center lw-justify-center lw-border lw-border-solid lw-border-border-primary">
|
|
62
40
|
<Spinner size={SpinnerSize.lg} />
|
|
63
41
|
</div>
|
|
64
42
|
)}
|
|
65
43
|
{!loading && !error && !!data && (
|
|
66
44
|
<div className="lw-absolute lw-left-0 lw-top-0 lw-flex lw-h-full lw-w-full">
|
|
67
|
-
<Chart data={data} />
|
|
45
|
+
<Chart data={data} isDesktop={isDesktop} />
|
|
68
46
|
</div>
|
|
69
47
|
)}
|
|
70
48
|
</div>
|
|
@@ -26,6 +26,7 @@ export const getOption: GetOptionType = (
|
|
|
26
26
|
bookType,
|
|
27
27
|
},
|
|
28
28
|
isDark,
|
|
29
|
+
isDesktop,
|
|
29
30
|
labelCallback
|
|
30
31
|
) => {
|
|
31
32
|
let selectedPrice: number;
|
|
@@ -49,7 +50,9 @@ export const getOption: GetOptionType = (
|
|
|
49
50
|
chartWidth: CHART_CONFIG.WIDTH,
|
|
50
51
|
chartHeight: CHART_CONFIG.HEIGHT,
|
|
51
52
|
xLabelsSize: CHART_CONFIG.X_LABEL_SIZE,
|
|
52
|
-
yLabelSize:
|
|
53
|
+
yLabelSize: isDesktop
|
|
54
|
+
? CHART_CONFIG.Y_LABEL_SIZE_DESKTOP
|
|
55
|
+
: CHART_CONFIG.Y_LABEL_SIZE_MOBILE,
|
|
53
56
|
bottomLeftBox: false,
|
|
54
57
|
});
|
|
55
58
|
|
|
@@ -124,6 +127,7 @@ export const getOption: GetOptionType = (
|
|
|
124
127
|
axisLabel: {
|
|
125
128
|
showMaxLabel: false,
|
|
126
129
|
showMinLabel: false,
|
|
130
|
+
margin: isDesktop ? 4 : 2,
|
|
127
131
|
formatter: (value: number) => value.toFixed(precision - 1),
|
|
128
132
|
},
|
|
129
133
|
},
|
|
@@ -193,7 +197,7 @@ export const getOption: GetOptionType = (
|
|
|
193
197
|
name: 'main-grid',
|
|
194
198
|
top: '0px',
|
|
195
199
|
left: '0px',
|
|
196
|
-
right: `${CHART_CONFIG.Y_LABEL_SIZE_DESKTOP}px`,
|
|
200
|
+
right: `${isDesktop ? CHART_CONFIG.Y_LABEL_SIZE_DESKTOP : CHART_CONFIG.Y_LABEL_SIZE_MOBILE}px`,
|
|
197
201
|
bottom: `${CHART_CONFIG.X_LABEL_SIZE}px`,
|
|
198
202
|
},
|
|
199
203
|
],
|
|
@@ -40,11 +40,13 @@ export interface UseCrowdViewDataReturn {
|
|
|
40
40
|
export type GetOptionType = (
|
|
41
41
|
props: CrowdViewData,
|
|
42
42
|
isDark: boolean,
|
|
43
|
+
isDesktop: boolean,
|
|
43
44
|
labelCallback: (key: string, params?: Record<string, unknown>) => string
|
|
44
45
|
) => EChartsOption;
|
|
45
46
|
|
|
46
47
|
export interface ChartProps {
|
|
47
48
|
data: CrowdViewData;
|
|
49
|
+
isDesktop: boolean;
|
|
48
50
|
}
|
|
49
51
|
|
|
50
52
|
export interface ChartWithDataProps {
|
|
@@ -160,10 +160,14 @@ ${
|
|
|
160
160
|
<p>${
|
|
161
161
|
matchedBucket.sentiment < 0
|
|
162
162
|
? labelCallback(
|
|
163
|
-
bookType === BookType.Order
|
|
163
|
+
bookType === BookType.Order
|
|
164
|
+
? 'sell_overbalance'
|
|
165
|
+
: 'short_overbalance'
|
|
164
166
|
)
|
|
165
167
|
: labelCallback(
|
|
166
|
-
bookType === BookType.Order
|
|
168
|
+
bookType === BookType.Order
|
|
169
|
+
? 'buy_overbalance'
|
|
170
|
+
: 'long_overbalance'
|
|
167
171
|
)
|
|
168
172
|
}: ${Math.abs(matchedBucket.sentiment)}% </p>`
|
|
169
173
|
: ''
|
|
@@ -19,7 +19,7 @@ export const Legend = ({
|
|
|
19
19
|
const { lang } = useLocale();
|
|
20
20
|
|
|
21
21
|
return (
|
|
22
|
-
<div className="lw-mx-auto lw-flex lw-w-full lw-flex-col lw-items-center lw-space-y-4 lw-
|
|
22
|
+
<div className="lw-mx-auto lw-flex lw-w-full lw-flex-col lw-items-center lw-space-y-4 lw-pb-6 lw-pt-0 sm:lw-max-w-md lg:lw-max-w-xl">
|
|
23
23
|
<LegendBar
|
|
24
24
|
label={lang(bookType === BookType.Order ? 'buy' : 'long')}
|
|
25
25
|
type="long"
|
|
@@ -15,6 +15,9 @@ export const LegendBar = ({ values, type, label }: LegendBarProps) => {
|
|
|
15
15
|
|
|
16
16
|
return (
|
|
17
17
|
<div className="lw-flex lw-w-full lw-flex-col lw-space-y-1 lw-border-border-primary">
|
|
18
|
+
<span className="lw-whitespace-nowrap lw-font-sans lw-text-xs lw-text-text-primary">
|
|
19
|
+
{label}
|
|
20
|
+
</span>
|
|
18
21
|
<div className="lw-flex lw-h-2 lw-w-full lw-overflow-hidden lw-border lw-border-border-primary">
|
|
19
22
|
<div
|
|
20
23
|
className="lw-h-full lw-flex-1"
|
|
@@ -27,10 +30,10 @@ export const LegendBar = ({ values, type, label }: LegendBarProps) => {
|
|
|
27
30
|
|
|
28
31
|
<div className="lw-flex lw-w-full lw-justify-between">
|
|
29
32
|
<span className="lw-whitespace-nowrap lw-font-sans lw-text-xs lw-text-text-primary">
|
|
30
|
-
{values[0].toFixed(2)}%
|
|
33
|
+
{values[0].toFixed(2)}%
|
|
31
34
|
</span>
|
|
32
35
|
<span className="lw-whitespace-nowrap lw-font-sans lw-text-xs lw-text-text-primary">
|
|
33
|
-
{values[1].toFixed(2)}%
|
|
36
|
+
{`≤ ${values[1].toFixed(2)}`}%
|
|
34
37
|
</span>
|
|
35
38
|
</div>
|
|
36
39
|
</div>
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"15_minutes": "15 minutes",
|
|
4
4
|
"4_hours": "4 hours",
|
|
5
5
|
"5_minutes": "5 minutes",
|
|
6
|
-
"
|
|
6
|
+
"buy_overbalance": "Buy overbalance",
|
|
7
7
|
"buy": "Buy",
|
|
8
8
|
"candle": "Candle",
|
|
9
9
|
"close_price": "Close price",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"granularity": "Granularity",
|
|
12
12
|
"high": "High",
|
|
13
13
|
"instrument": "Instrument",
|
|
14
|
-
"
|
|
14
|
+
"long_overbalance": "Long overbalance",
|
|
15
15
|
"long": "Long",
|
|
16
16
|
"low": "Low",
|
|
17
17
|
"no_matching_results": "No matching results",
|
|
@@ -23,9 +23,9 @@
|
|
|
23
23
|
"positions": "Positions",
|
|
24
24
|
"price_range": "Price range",
|
|
25
25
|
"search": "Search",
|
|
26
|
-
"
|
|
26
|
+
"sell_overbalance": "Sell overbalance",
|
|
27
27
|
"sell": "Sell",
|
|
28
28
|
"sentiment": "Sentiment",
|
|
29
|
-
"
|
|
29
|
+
"short_overbalance": "Short overbalance",
|
|
30
30
|
"short": "Short"
|
|
31
31
|
}
|
|
@@ -152,7 +152,7 @@ describe('chartUtils', () => {
|
|
|
152
152
|
expect(html).toContain('orders');
|
|
153
153
|
expect(html).toContain('price_range');
|
|
154
154
|
// Selected price 1.3306 falls into second bucket 1.3305 - 1.3310 which has negative sentiment
|
|
155
|
-
expect(html).toContain('
|
|
155
|
+
expect(html).toContain('sell_overbalance');
|
|
156
156
|
});
|
|
157
157
|
});
|
|
158
158
|
});
|
|
@@ -20,8 +20,8 @@ describe('Crowd View Widget', () => {
|
|
|
20
20
|
/>
|
|
21
21
|
);
|
|
22
22
|
|
|
23
|
-
expect(getAllByText(/long/)).toHaveLength(
|
|
24
|
-
expect(getAllByText(/short/)).toHaveLength(
|
|
23
|
+
expect(getAllByText(/long/)).toHaveLength(1);
|
|
24
|
+
expect(getAllByText(/short/)).toHaveLength(1);
|
|
25
25
|
});
|
|
26
26
|
});
|
|
27
27
|
});
|
|
@@ -17,8 +17,9 @@ describe('Crowd View Widget', () => {
|
|
|
17
17
|
<LegendBar label="long" type="long" values={mockValues} />
|
|
18
18
|
);
|
|
19
19
|
|
|
20
|
-
expect(getByText('
|
|
21
|
-
expect(getByText('0.
|
|
20
|
+
expect(getByText('long')).toBeInTheDocument();
|
|
21
|
+
expect(getByText('0.15%')).toBeInTheDocument();
|
|
22
|
+
expect(getByText('≤ 0.55%')).toBeInTheDocument();
|
|
22
23
|
});
|
|
23
24
|
|
|
24
25
|
it('renders exactly 1 segment', () => {
|