@oanda/labs-crowd-view-widget 1.0.44 → 1.0.46

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 (131) hide show
  1. package/CHANGELOG.md +372 -0
  2. package/dist/main/CrowdViewWidget/Main.js +20 -7
  3. package/dist/main/CrowdViewWidget/Main.js.map +1 -1
  4. package/dist/main/CrowdViewWidget/components/Chart/Chart.js +6 -10
  5. package/dist/main/CrowdViewWidget/components/Chart/Chart.js.map +1 -1
  6. package/dist/main/CrowdViewWidget/components/Chart/chartOptions.js +46 -20
  7. package/dist/main/CrowdViewWidget/components/Chart/chartOptions.js.map +1 -1
  8. package/dist/main/CrowdViewWidget/components/Chart/index.js +4 -4
  9. package/dist/main/CrowdViewWidget/components/Chart/index.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 +18 -88
  12. package/dist/main/CrowdViewWidget/components/Chart/useCrowdViewData.js.map +1 -1
  13. package/dist/main/CrowdViewWidget/components/Chart/utils/aggregateBuckets.js +37 -0
  14. package/dist/main/CrowdViewWidget/components/Chart/utils/aggregateBuckets.js.map +1 -0
  15. package/dist/main/CrowdViewWidget/components/Chart/utils/chartUtils.js +54 -2
  16. package/dist/main/CrowdViewWidget/components/Chart/utils/chartUtils.js.map +1 -1
  17. package/dist/main/CrowdViewWidget/components/Chart/utils/getTargetBucketWidth.js +14 -0
  18. package/dist/main/CrowdViewWidget/components/Chart/utils/getTargetBucketWidth.js.map +1 -0
  19. package/dist/main/CrowdViewWidget/components/Chart/utils/index.js +83 -0
  20. package/dist/main/CrowdViewWidget/components/Chart/utils/index.js.map +1 -0
  21. package/dist/main/CrowdViewWidget/components/Chart/utils/processBuckets.js +29 -0
  22. package/dist/main/CrowdViewWidget/components/Chart/utils/processBuckets.js.map +1 -0
  23. package/dist/main/CrowdViewWidget/components/Chart/utils/processOrderPositionBooks.js +23 -0
  24. package/dist/main/CrowdViewWidget/components/Chart/utils/processOrderPositionBooks.js.map +1 -0
  25. package/dist/main/CrowdViewWidget/components/Chart/utils/processPriceCandles.js +43 -0
  26. package/dist/main/CrowdViewWidget/components/Chart/utils/processPriceCandles.js.map +1 -0
  27. package/dist/main/CrowdViewWidget/components/Chart/utils/validateData.js +23 -0
  28. package/dist/main/CrowdViewWidget/components/Chart/utils/validateData.js.map +1 -0
  29. package/dist/main/CrowdViewWidget/components/Legend/Legend.js +5 -3
  30. package/dist/main/CrowdViewWidget/components/Legend/Legend.js.map +1 -1
  31. package/dist/main/CrowdViewWidget/constants.js +105 -5
  32. package/dist/main/CrowdViewWidget/constants.js.map +1 -1
  33. package/dist/main/CrowdViewWidget/selectConfig.js +18 -60
  34. package/dist/main/CrowdViewWidget/selectConfig.js.map +1 -1
  35. package/dist/main/CrowdViewWidget/types.js +20 -0
  36. package/dist/main/CrowdViewWidget/types.js.map +1 -1
  37. package/dist/main/translations/sources/en.json +29 -0
  38. package/dist/module/CrowdViewWidget/Main.js +21 -8
  39. package/dist/module/CrowdViewWidget/Main.js.map +1 -1
  40. package/dist/module/CrowdViewWidget/components/Chart/Chart.js +7 -11
  41. package/dist/module/CrowdViewWidget/components/Chart/Chart.js.map +1 -1
  42. package/dist/module/CrowdViewWidget/components/Chart/chartOptions.js +47 -21
  43. package/dist/module/CrowdViewWidget/components/Chart/chartOptions.js.map +1 -1
  44. package/dist/module/CrowdViewWidget/components/Chart/index.js +1 -1
  45. package/dist/module/CrowdViewWidget/components/Chart/index.js.map +1 -1
  46. package/dist/module/CrowdViewWidget/components/Chart/types.js.map +1 -1
  47. package/dist/module/CrowdViewWidget/components/Chart/useCrowdViewData.js +14 -84
  48. package/dist/module/CrowdViewWidget/components/Chart/useCrowdViewData.js.map +1 -1
  49. package/dist/module/CrowdViewWidget/components/Chart/utils/aggregateBuckets.js +29 -0
  50. package/dist/module/CrowdViewWidget/components/Chart/utils/aggregateBuckets.js.map +1 -0
  51. package/dist/module/CrowdViewWidget/components/Chart/utils/chartUtils.js +52 -2
  52. package/dist/module/CrowdViewWidget/components/Chart/utils/chartUtils.js.map +1 -1
  53. package/dist/module/CrowdViewWidget/components/Chart/utils/getTargetBucketWidth.js +7 -0
  54. package/dist/module/CrowdViewWidget/components/Chart/utils/getTargetBucketWidth.js.map +1 -0
  55. package/dist/module/CrowdViewWidget/components/Chart/utils/index.js +8 -0
  56. package/dist/module/CrowdViewWidget/components/Chart/utils/index.js.map +1 -0
  57. package/dist/module/CrowdViewWidget/components/Chart/utils/processBuckets.js +22 -0
  58. package/dist/module/CrowdViewWidget/components/Chart/utils/processBuckets.js.map +1 -0
  59. package/dist/module/CrowdViewWidget/components/Chart/utils/processOrderPositionBooks.js +16 -0
  60. package/dist/module/CrowdViewWidget/components/Chart/utils/processOrderPositionBooks.js.map +1 -0
  61. package/dist/module/CrowdViewWidget/components/Chart/utils/processPriceCandles.js +36 -0
  62. package/dist/module/CrowdViewWidget/components/Chart/utils/processPriceCandles.js.map +1 -0
  63. package/dist/module/CrowdViewWidget/components/Chart/utils/validateData.js +16 -0
  64. package/dist/module/CrowdViewWidget/components/Chart/utils/validateData.js.map +1 -0
  65. package/dist/module/CrowdViewWidget/components/Legend/Legend.js +5 -3
  66. package/dist/module/CrowdViewWidget/components/Legend/Legend.js.map +1 -1
  67. package/dist/module/CrowdViewWidget/constants.js +104 -4
  68. package/dist/module/CrowdViewWidget/constants.js.map +1 -1
  69. package/dist/module/CrowdViewWidget/selectConfig.js +3 -45
  70. package/dist/module/CrowdViewWidget/selectConfig.js.map +1 -1
  71. package/dist/module/CrowdViewWidget/types.js +19 -1
  72. package/dist/module/CrowdViewWidget/types.js.map +1 -1
  73. package/dist/module/translations/sources/en.json +29 -0
  74. package/dist/types/CrowdViewWidget/components/Chart/index.d.ts +1 -1
  75. package/dist/types/CrowdViewWidget/components/Chart/types.d.ts +12 -4
  76. package/dist/types/CrowdViewWidget/components/Chart/utils/aggregateBuckets.d.ts +2 -0
  77. package/dist/types/CrowdViewWidget/components/Chart/utils/chartUtils.d.ts +12 -2
  78. package/dist/types/CrowdViewWidget/components/Chart/utils/getTargetBucketWidth.d.ts +3 -0
  79. package/dist/types/CrowdViewWidget/components/Chart/utils/index.d.ts +7 -0
  80. package/dist/types/CrowdViewWidget/components/Chart/utils/processBuckets.d.ts +3 -0
  81. package/dist/types/CrowdViewWidget/components/Chart/utils/processOrderPositionBooks.d.ts +8 -0
  82. package/dist/types/CrowdViewWidget/components/Chart/utils/processPriceCandles.d.ts +27 -0
  83. package/dist/types/CrowdViewWidget/components/Chart/utils/validateData.d.ts +2 -0
  84. package/dist/types/CrowdViewWidget/components/Legend/Legend.d.ts +3 -1
  85. package/dist/types/CrowdViewWidget/constants.d.ts +11 -3
  86. package/dist/types/CrowdViewWidget/selectConfig.d.ts +2 -2
  87. package/dist/types/CrowdViewWidget/types.d.ts +18 -1
  88. package/dist/types/CrowdViewWidget/utils/instrumentUtils.d.ts +1 -4
  89. package/lokalise.config.json +1 -1
  90. package/package.json +4 -3
  91. package/src/CrowdViewWidget/Main.tsx +25 -10
  92. package/src/CrowdViewWidget/components/Chart/Chart.tsx +6 -12
  93. package/src/CrowdViewWidget/components/Chart/chartOptions.ts +70 -36
  94. package/src/CrowdViewWidget/components/Chart/index.ts +1 -1
  95. package/src/CrowdViewWidget/components/Chart/types.ts +16 -4
  96. package/src/CrowdViewWidget/components/Chart/useCrowdViewData.ts +41 -140
  97. package/src/CrowdViewWidget/components/Chart/utils/aggregateBuckets.ts +44 -0
  98. package/src/CrowdViewWidget/components/Chart/utils/chartUtils.ts +96 -3
  99. package/src/CrowdViewWidget/components/Chart/utils/getTargetBucketWidth.ts +13 -0
  100. package/src/CrowdViewWidget/components/Chart/utils/index.ts +7 -0
  101. package/src/CrowdViewWidget/components/Chart/utils/processBuckets.ts +43 -0
  102. package/src/CrowdViewWidget/components/Chart/utils/processOrderPositionBooks.ts +30 -0
  103. package/src/CrowdViewWidget/components/Chart/utils/processPriceCandles.ts +53 -0
  104. package/src/CrowdViewWidget/components/Chart/utils/validateData.ts +27 -0
  105. package/src/CrowdViewWidget/components/Legend/Legend.tsx +13 -2
  106. package/src/CrowdViewWidget/constants.ts +113 -3
  107. package/src/CrowdViewWidget/selectConfig.ts +5 -60
  108. package/src/CrowdViewWidget/types.ts +18 -1
  109. package/src/translations/sources/en.json +29 -0
  110. package/test/Main.test.tsx +73 -27
  111. package/test/components/Chart/utils/chartUtils.test.ts +158 -0
  112. package/test/components/Legend.test.tsx +6 -1
  113. package/test/utils/aggregateBuckets.test.ts +82 -0
  114. package/test/utils/getTargetBucketWidth.test.ts +37 -0
  115. package/test/utils/instrumentUtils.test.ts +13 -7
  116. package/test/utils/processBuckets.test.ts +153 -0
  117. package/test/utils/processOrderPositionBooks.test.ts +127 -0
  118. package/test/utils/processPriceCandles.test.ts +245 -0
  119. package/test/utils/validateData.test.ts +201 -0
  120. package/dist/main/CrowdViewWidget/types/index.js +0 -17
  121. package/dist/main/CrowdViewWidget/types/index.js.map +0 -1
  122. package/dist/main/CrowdViewWidget/types/instruments.js +0 -45
  123. package/dist/main/CrowdViewWidget/types/instruments.js.map +0 -1
  124. package/dist/module/CrowdViewWidget/types/index.js +0 -2
  125. package/dist/module/CrowdViewWidget/types/index.js.map +0 -1
  126. package/dist/module/CrowdViewWidget/types/instruments.js +0 -39
  127. package/dist/module/CrowdViewWidget/types/instruments.js.map +0 -1
  128. package/dist/types/CrowdViewWidget/types/index.d.ts +0 -1
  129. package/dist/types/CrowdViewWidget/types/instruments.d.ts +0 -36
  130. package/src/CrowdViewWidget/types/index.ts +0 -1
  131. package/src/CrowdViewWidget/types/instruments.ts +0 -37
@@ -1,2 +1,20 @@
1
- export {};
1
+ export let InstrumentId = function (InstrumentId) {
2
+ InstrumentId["EUR_AUD"] = "EURAUD";
3
+ InstrumentId["EUR_GBP"] = "EURGBP";
4
+ InstrumentId["EUR_JPY"] = "EURJPY";
5
+ InstrumentId["EUR_USD"] = "EURUSD";
6
+ InstrumentId["EUR_CHF"] = "EURCHF";
7
+ InstrumentId["USD_CHF"] = "USDCHF";
8
+ InstrumentId["USD_JPY"] = "USDJPY";
9
+ InstrumentId["USD_CAD"] = "USDCAD";
10
+ InstrumentId["GBP_USD"] = "GBPUSD";
11
+ InstrumentId["GBP_JPY"] = "GBPJPY";
12
+ InstrumentId["GBP_CHF"] = "GBPCHF";
13
+ InstrumentId["AUD_JPY"] = "AUDJPY";
14
+ InstrumentId["AUD_USD"] = "AUDUSD";
15
+ InstrumentId["NZD_USD"] = "NZDUSD";
16
+ InstrumentId["XAU_USD"] = "XAUUSD";
17
+ InstrumentId["XAG_USD"] = "XAGUSD";
18
+ return InstrumentId;
19
+ }({});
2
20
  //# sourceMappingURL=types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","names":[],"sources":["../../../src/CrowdViewWidget/types.ts"],"sourcesContent":["import type { WidgetConfig } from '@oanda/labs-widget-common';\n\nimport type { Division } from '../gql/types/graphql';\nimport type { InstrumentId } from './types/instruments';\n\nexport interface CrowdViewConfig extends WidgetConfig {\n division: Division;\n}\n\nexport interface MainProps {\n instrument?: InstrumentId;\n division: Division;\n}\n"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"file":"types.js","names":["InstrumentId"],"sources":["../../../src/CrowdViewWidget/types.ts"],"sourcesContent":["import type { WidgetConfig } from '@oanda/labs-widget-common';\n\nimport type { Division } from '../gql/types/graphql';\n\nexport enum InstrumentId {\n EUR_AUD = 'EURAUD',\n EUR_GBP = 'EURGBP',\n EUR_JPY = 'EURJPY',\n EUR_USD = 'EURUSD',\n EUR_CHF = 'EURCHF',\n USD_CHF = 'USDCHF',\n USD_JPY = 'USDJPY',\n USD_CAD = 'USDCAD',\n GBP_USD = 'GBPUSD',\n GBP_JPY = 'GBPJPY',\n GBP_CHF = 'GBPCHF',\n AUD_JPY = 'AUDJPY',\n AUD_USD = 'AUDUSD',\n NZD_USD = 'NZDUSD',\n XAU_USD = 'XAUUSD',\n XAG_USD = 'XAGUSD',\n}\nexport interface CrowdViewConfig extends WidgetConfig {\n division: Division;\n}\n\nexport interface MainProps {\n instrument?: InstrumentId;\n division: Division;\n}\n"],"mappings":"AAIA,WAAYA,YAAY,aAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAZA,YAAY;EAAA,OAAZA,YAAY;AAAA","ignoreList":[]}
@@ -1,2 +1,31 @@
1
1
  {
2
+ "1_hour": "1 hour",
3
+ "15_minutes": "15 minutes",
4
+ "4_hours": "4 hours",
5
+ "5_minutes": "5 minutes",
6
+ "buy_advantage": "Buy advantage",
7
+ "buy": "Buy",
8
+ "candle": "Candle",
9
+ "close_price": "Close price",
10
+ "data_unavailable": "Data unavailable",
11
+ "granularity": "Granularity",
12
+ "high": "High",
13
+ "instrument": "Instrument",
14
+ "long_advantage": "Sell advantage",
15
+ "long": "Long",
16
+ "low": "Low",
17
+ "no_matching_results": "No matching results",
18
+ "open_price": "Open price",
19
+ "order_book": "Order book",
20
+ "orders": "Orders",
21
+ "pagination_entries_range": "{{firstItemOnPage}}-{{lastItemOnPage}} of {{itemCount}} entries",
22
+ "position_book": "Position book",
23
+ "positions": "Positions",
24
+ "price_range": "Price range",
25
+ "search": "Search",
26
+ "sell_advantage": "Sell advantage",
27
+ "sell": "Sell",
28
+ "sentiment": "Sentiment",
29
+ "short_advantage": "Buy advantage",
30
+ "short": "Short"
2
31
  }
@@ -3,4 +3,4 @@ export * from './chartOptions';
3
3
  export * from './ChartWithData';
4
4
  export * from './types';
5
5
  export * from './useCrowdViewData';
6
- export * from './utils/chartUtils';
6
+ export * from './utils';
@@ -1,7 +1,12 @@
1
1
  import type { EChartsOption } from 'echarts';
2
2
  import type { BookType, Division, Granularity } from '../../../gql/types/graphql';
3
+ import type { InstrumentId } from '../../types';
4
+ export interface Bucket {
5
+ price: number;
6
+ sentiment: number;
7
+ }
3
8
  export interface UseCrowdViewDataProps {
4
- instrument: string;
9
+ instrument: InstrumentId;
5
10
  bookType: BookType;
6
11
  division: Division;
7
12
  granularity: Granularity;
@@ -9,22 +14,25 @@ export interface UseCrowdViewDataProps {
9
14
  interface CrowdViewData {
10
15
  xAxisData: string[];
11
16
  candlesSeriesData: [number, number, number, number][];
12
- orderPositionBooks: ([string, number, string] | null)[];
17
+ orderPositionBooks: [string, number | null, number][];
13
18
  bucketWidth: number;
19
+ buckets: Bucket[][];
20
+ precision: number;
21
+ bookType: BookType;
14
22
  }
15
23
  export interface UseCrowdViewDataReturn {
16
24
  data: CrowdViewData | null;
17
25
  loading: boolean;
18
26
  error: boolean;
19
27
  }
20
- export type GetOptionType = (props: CrowdViewData, isDark: boolean) => EChartsOption;
28
+ export type GetOptionType = (props: CrowdViewData, isDark: boolean, labelCallback: (key: string, params?: Record<string, unknown>) => string) => EChartsOption;
21
29
  export interface ChartProps {
22
30
  data: CrowdViewData;
23
31
  }
24
32
  export interface ChartWithDataProps {
25
33
  bookType: BookType;
26
34
  division: Division;
27
- instrument: string;
35
+ instrument: InstrumentId;
28
36
  granularity: Granularity;
29
37
  }
30
38
  export interface GetLabelsDataProps {
@@ -0,0 +1,2 @@
1
+ import type { Bucket } from '../types';
2
+ export declare const aggregateBuckets: (buckets: Bucket[], newBucketWidth: number) => Bucket[];
@@ -1,5 +1,5 @@
1
- import { Granularity, TimeSpan } from '../../../../gql/types/graphql';
2
- import type { GetLabelsDataProps } from '../types';
1
+ import { BookType, Granularity, TimeSpan } from '../../../../gql/types/graphql';
2
+ import type { Bucket, GetLabelsDataProps } from '../types';
3
3
  export declare const getLabelData: ({ xAxisData, isGreaterThanTwoWeeks, }: GetLabelsDataProps) => {
4
4
  name: string;
5
5
  xAxis: string;
@@ -19,3 +19,13 @@ export declare const getLabelData: ({ xAxisData, isGreaterThanTwoWeeks, }: GetLa
19
19
  export declare const isDifferenceGreaterThanTwoWeeks: (startDate: string, endDate: string) => boolean;
20
20
  export declare const getTimeSpanForGranularity: (granularity: Granularity) => TimeSpan;
21
21
  export declare const getRectColor: (sentiment: number) => string;
22
+ export declare const getTooltipFormatter: ({ params, buckets, bucketWidth, selectedPrice, precision, bookType, labelCallback, }: {
23
+ params: unknown;
24
+ buckets: Bucket[][];
25
+ bucketWidth: number;
26
+ selectedPrice: number;
27
+ precision: number;
28
+ bookType: BookType;
29
+ labelCallback: (key: string) => string;
30
+ }) => string | undefined;
31
+ export declare const formatXAxisLabel: (value: unknown, isGreaterThanTwoWeeks: boolean) => string;
@@ -0,0 +1,3 @@
1
+ import { Granularity } from '../../../../gql/types/graphql';
2
+ import type { InstrumentId } from '../../../types';
3
+ export declare const getTargetBucketWidth: (granularity: Granularity, instrument: InstrumentId) => number;
@@ -0,0 +1,7 @@
1
+ export * from './aggregateBuckets';
2
+ export * from './chartUtils';
3
+ export * from './getTargetBucketWidth';
4
+ export * from './processBuckets';
5
+ export * from './processOrderPositionBooks';
6
+ export * from './processPriceCandles';
7
+ export * from './validateData';
@@ -0,0 +1,3 @@
1
+ import type { GetOrderPositionBooksQuery } from '../../../../gql/types/graphql';
2
+ import type { Bucket } from '../types';
3
+ export declare const processBuckets: (orderPositionData: GetOrderPositionBooksQuery | undefined, targetBucketWidth: number) => Bucket[][];
@@ -0,0 +1,8 @@
1
+ import type { GetOrderPositionBooksQuery } from '../../../../gql/types/graphql';
2
+ export declare const processOrderPositionBooks: (orderPositionData: GetOrderPositionBooksQuery | undefined, candleMap: Map<string, {
3
+ point?: string;
4
+ high?: number;
5
+ low?: number;
6
+ open?: number;
7
+ close?: number;
8
+ }>) => [string, number | null, number][];
@@ -0,0 +1,27 @@
1
+ import type { GetPriceCandlesQuery } from '../../../../gql/types/graphql';
2
+ export declare const processPriceCandles: (priceCandlesData: GetPriceCandlesQuery | undefined) => {
3
+ minPrice: number;
4
+ maxPrice: number;
5
+ hasValidCandles: boolean;
6
+ candleMap: Map<any, any>;
7
+ candles: never[];
8
+ } | {
9
+ minPrice: number;
10
+ maxPrice: number;
11
+ hasValidCandles: boolean;
12
+ candleMap: Map<string, {
13
+ point?: string;
14
+ high?: number;
15
+ low?: number;
16
+ open?: number;
17
+ close?: number;
18
+ }>;
19
+ candles: ({
20
+ __typename?: "Candle";
21
+ point: string;
22
+ high: number;
23
+ low: number;
24
+ open: number;
25
+ close: number;
26
+ } | null)[];
27
+ };
@@ -0,0 +1,2 @@
1
+ import type { GetOrderPositionBooksQuery, GetPriceCandlesQuery } from '../../../../gql/types/graphql';
2
+ export declare const validateData: (priceCandlesData: GetPriceCandlesQuery | undefined, orderPositionData: GetOrderPositionBooksQuery | undefined, hasValidCandles: boolean) => Error | null;
@@ -1,7 +1,9 @@
1
1
  import React from 'react';
2
+ import { BookType } from '../../../gql/types/graphql';
2
3
  interface LegendProps {
3
4
  longValues?: [number, number];
4
5
  shortValues?: [number, number];
6
+ bookType: BookType;
5
7
  }
6
- export declare const Legend: ({ longValues, shortValues, }: LegendProps) => React.JSX.Element;
8
+ export declare const Legend: ({ longValues, shortValues, bookType, }: LegendProps) => React.JSX.Element;
7
9
  export {};
@@ -1,9 +1,10 @@
1
+ import { InstrumentId } from './types';
1
2
  export declare const BOOKS_THRESHOLDS: {
2
3
  readonly MIN: 0.15;
3
4
  readonly MAX: 0.55;
4
5
  };
5
6
  export declare const BUCKET_CONFIG: {
6
- readonly DEFAULT_WIDTH: 0.0005;
7
+ readonly MULTIPLIER: 4;
7
8
  readonly PRICE_PADDING_MULTIPLIER: 2;
8
9
  };
9
10
  export declare const TIME_THRESHOLDS: {
@@ -16,8 +17,15 @@ export declare const CHART_CONFIG: {
16
17
  readonly Y_LABEL_SIZE_DESKTOP: 60;
17
18
  readonly INITIAL_START_ZOOM: 80;
18
19
  readonly INITIAL_END_ZOOM: 100;
20
+ readonly X_AXIS_DATE_PADDING: " ";
19
21
  };
20
22
  export declare const COLOR_MAP: {
21
- readonly long: readonly ["#ffffff", "#fdb833"];
22
- readonly short: readonly ["#ffffff", "#0096c7"];
23
+ readonly long: readonly ["#eaf5fa", "#83c4e0"];
24
+ readonly short: readonly ["#fef7e7", "#fcd171"];
23
25
  };
26
+ export declare const INSTRUMENTS_CONFIG: Record<InstrumentId, {
27
+ precision: number;
28
+ defaultBucketWidth: number;
29
+ v20name: string;
30
+ mt5name: string;
31
+ }>;
@@ -1,11 +1,11 @@
1
1
  import { BookType, Granularity } from '../gql/types/graphql';
2
- import { InstrumentId, InstrumentIdOC } from './types/instruments';
2
+ import { InstrumentId } from './types';
3
3
  declare const navigationConfig: {
4
4
  id: BookType;
5
5
  label: string;
6
6
  }[];
7
7
  declare const instrumentSelectConfigOC: {
8
- id: InstrumentIdOC;
8
+ id: InstrumentId;
9
9
  label: string;
10
10
  }[];
11
11
  declare const instrumentSelectConfig: {
@@ -1,6 +1,23 @@
1
1
  import type { WidgetConfig } from '@oanda/labs-widget-common';
2
2
  import type { Division } from '../gql/types/graphql';
3
- import type { InstrumentId } from './types/instruments';
3
+ export declare enum InstrumentId {
4
+ EUR_AUD = "EURAUD",
5
+ EUR_GBP = "EURGBP",
6
+ EUR_JPY = "EURJPY",
7
+ EUR_USD = "EURUSD",
8
+ EUR_CHF = "EURCHF",
9
+ USD_CHF = "USDCHF",
10
+ USD_JPY = "USDJPY",
11
+ USD_CAD = "USDCAD",
12
+ GBP_USD = "GBPUSD",
13
+ GBP_JPY = "GBPJPY",
14
+ GBP_CHF = "GBPCHF",
15
+ AUD_JPY = "AUDJPY",
16
+ AUD_USD = "AUDUSD",
17
+ NZD_USD = "NZDUSD",
18
+ XAU_USD = "XAUUSD",
19
+ XAG_USD = "XAGUSD"
20
+ }
4
21
  export interface CrowdViewConfig extends WidgetConfig {
5
22
  division: Division;
6
23
  }
@@ -1,8 +1,5 @@
1
1
  import { Division } from '../../gql/types/graphql';
2
2
  export declare const getInstrumentConfigForDivision: (division: Division) => {
3
- id: import("../types").InstrumentIdOC;
4
- label: string;
5
- }[] | {
6
- id: import("../types").InstrumentId;
3
+ id: import("..").InstrumentId;
7
4
  label: string;
8
5
  }[];
@@ -13,6 +13,6 @@
13
13
  "plural_format": "i18next",
14
14
  "export_empty_as": "skip",
15
15
  "include_tags": ["common_widgets"],
16
- "filter_langs": ["en", "zh_TW", "es", "th"]
16
+ "filter_langs": ["en"]
17
17
  }
18
18
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oanda/labs-crowd-view-widget",
3
- "version": "1.0.44",
3
+ "version": "1.0.46",
4
4
  "description": "Labs Crowd View Widget",
5
5
  "main": "dist/main/index.js",
6
6
  "module": "dist/module/index.js",
@@ -13,9 +13,10 @@
13
13
  "author": "OANDA",
14
14
  "license": "UNLICENSED",
15
15
  "dependencies": {
16
- "@oanda/labs-widget-common": "^1.0.226",
16
+ "@oanda/labs-widget-common": "^1.0.228",
17
17
  "@oanda/mono-i18n": "10.0.1",
18
18
  "chroma-js": "^3.1.2",
19
+ "decimal.js": "^10.6.0",
19
20
  "graphql": "16.8.1"
20
21
  },
21
22
  "devDependencies": {
@@ -23,5 +24,5 @@
23
24
  "@graphql-codegen/client-preset": "4.1.0",
24
25
  "@types/chroma-js": "^3.1.2"
25
26
  },
26
- "gitHead": "4709e181ae37de87e1c5d5569391c5f6cfeeca33"
27
+ "gitHead": "8e6597b98667ce51cc5610dddc94f020a2a82908"
27
28
  }
@@ -6,29 +6,44 @@ import {
6
6
  useLayoutProvider,
7
7
  } from '@oanda/labs-widget-common';
8
8
  import { useLocale } from '@oanda/mono-i18n';
9
- import React, { useState } from 'react';
9
+ import React, { useEffect, useMemo, useState } from 'react';
10
10
 
11
11
  import type { Granularity } from '../gql/types/graphql';
12
12
  import { BookType } from '../gql/types/graphql';
13
13
  import { ChartWithData, Legend } from './components';
14
14
  import { granularitySelectConfig, navigationConfig } from './selectConfig';
15
- import type { MainProps } from './types';
16
- import type { InstrumentId } from './types/instruments';
15
+ import type { InstrumentId, MainProps } from './types';
17
16
  import { getInstrumentConfigForDivision } from './utils/instrumentUtils';
18
17
 
19
18
  const Main = ({ division }: MainProps) => {
20
- const instrumentSelectConfigWithDivision =
21
- getInstrumentConfigForDivision(division);
22
-
19
+ const { lang } = useLocale();
23
20
  const { size } = useLayoutProvider();
24
21
  const isDesktop = size === Size.DESKTOP;
22
+
25
23
  const [bookType, setBookType] = useState(BookType.Order);
24
+
25
+ const granularitySelectConfigWithLang = useMemo(
26
+ () =>
27
+ granularitySelectConfig.map((opt) => ({
28
+ ...opt,
29
+ label: lang(opt.label),
30
+ })),
31
+ [lang]
32
+ );
33
+
34
+ const instrumentSelectConfigWithDivision =
35
+ getInstrumentConfigForDivision(division);
26
36
  const [instrument, setInstrument] = useState(
27
37
  instrumentSelectConfigWithDivision[0]
28
38
  );
29
39
 
30
- const [granularity, setGranularity] = useState(granularitySelectConfig[0]);
31
- const { lang } = useLocale();
40
+ const [granularity, setGranularity] = useState(
41
+ granularitySelectConfigWithLang[0]
42
+ );
43
+
44
+ useEffect(() => {
45
+ setGranularity(granularitySelectConfigWithLang[0]);
46
+ }, [granularitySelectConfigWithLang]);
32
47
 
33
48
  return (
34
49
  <>
@@ -68,7 +83,7 @@ const Main = ({ division }: MainProps) => {
68
83
  })}
69
84
  >
70
85
  <Select
71
- options={granularitySelectConfig}
86
+ options={granularitySelectConfigWithLang}
72
87
  searchPlaceholder={lang('search')}
73
88
  selectLabel={lang('granularity')}
74
89
  selectedOption={granularity}
@@ -86,7 +101,7 @@ const Main = ({ division }: MainProps) => {
86
101
  instrument={instrument.id}
87
102
  />
88
103
 
89
- <Legend />
104
+ <Legend bookType={bookType} />
90
105
  </div>
91
106
  )}
92
107
  </>
@@ -4,6 +4,7 @@ import {
4
4
  Theme,
5
5
  useLayoutProvider,
6
6
  } from '@oanda/labs-widget-common';
7
+ import { useLocale } from '@oanda/mono-i18n';
7
8
  import type { EChartsType } from 'echarts';
8
9
  import {
9
10
  BarChart,
@@ -26,6 +27,7 @@ import { CHART_CONFIG } from '../../constants';
26
27
  import { getOption } from './chartOptions';
27
28
  import type { ChartProps } from './types';
28
29
  import {
30
+ formatXAxisLabel,
29
31
  getLabelData,
30
32
  isDifferenceGreaterThanTwoWeeks,
31
33
  } from './utils/chartUtils';
@@ -48,6 +50,7 @@ echarts.registerTheme('light_theme', getChartTheme(Theme.Light));
48
50
 
49
51
  const Chart = ({ data }: ChartProps) => {
50
52
  const { isDark } = useLayoutProvider();
53
+ const { lang } = useLocale();
51
54
 
52
55
  return (
53
56
  <BaseChart
@@ -55,7 +58,7 @@ const Chart = ({ data }: ChartProps) => {
55
58
  echarts={echarts}
56
59
  isDark={isDark}
57
60
  lazyUpdate={true}
58
- option={getOption(data, isDark)}
61
+ option={getOption(data, isDark, lang)}
59
62
  opts={{ renderer: 'canvas' }}
60
63
  onEvents={{
61
64
  datazoom: (_params: unknown, instance: EChartsType) => {
@@ -78,17 +81,8 @@ const Chart = ({ data }: ChartProps) => {
78
81
  instance.setOption({
79
82
  xAxis: {
80
83
  axisLabel: {
81
- formatter: (value: string) => {
82
- const date = new Date(value);
83
- return isGreaterThanTwoWeeks
84
- ? `${date.toLocaleTimeString(undefined, {
85
- hour: '2-digit',
86
- minute: '2-digit',
87
- })}`
88
- : `${date.toLocaleDateString(undefined, {
89
- day: 'numeric',
90
- })}`;
91
- },
84
+ formatter: (value: string) =>
85
+ formatXAxisLabel(value, isGreaterThanTwoWeeks),
92
86
  },
93
87
  },
94
88
  series: [
@@ -5,18 +5,30 @@ import {
5
5
  } from '@oanda/labs-widget-common';
6
6
 
7
7
  import { CHART_CONFIG } from '../../constants';
8
- import type { GetOptionType } from './types';
8
+ import type { Bucket, GetOptionType } from './types';
9
9
  import {
10
+ formatXAxisLabel,
10
11
  getLabelData,
11
12
  getRectColor,
13
+ getTooltipFormatter,
12
14
  isDifferenceGreaterThanTwoWeeks,
13
15
  } from './utils/chartUtils';
14
16
 
15
17
  // @ts-expect-error
16
18
  export const getOption: GetOptionType = (
17
- { xAxisData, candlesSeriesData, orderPositionBooks, bucketWidth },
18
- isDark
19
+ {
20
+ xAxisData,
21
+ candlesSeriesData,
22
+ orderPositionBooks,
23
+ bucketWidth,
24
+ buckets,
25
+ precision,
26
+ bookType,
27
+ },
28
+ isDark,
29
+ labelCallback
19
30
  ) => {
31
+ let selectedPrice: number;
20
32
  const visibleXAxisData = xAxisData.slice(
21
33
  (xAxisData.length * CHART_CONFIG.INITIAL_START_ZOOM) / 100,
22
34
  (xAxisData.length * CHART_CONFIG.INITIAL_END_ZOOM) / 100
@@ -55,29 +67,51 @@ export const getOption: GetOptionType = (
55
67
  trigger: 'axis',
56
68
  axisPointer: {
57
69
  type: 'cross',
70
+ axis: 'x',
71
+ label: {
72
+ formatter: (params) => {
73
+ if (params.axisDimension === 'y') {
74
+ selectedPrice = Number(params.value);
75
+ return Number(params.value).toFixed(precision);
76
+ }
77
+
78
+ if (params.axisDimension === 'x') {
79
+ const date = new Date(params.value as string);
80
+ return date.toLocaleString(undefined, {
81
+ hour: '2-digit',
82
+ minute: '2-digit',
83
+ day: 'numeric',
84
+ month: 'short',
85
+ });
86
+ }
87
+
88
+ return null;
89
+ },
90
+ },
58
91
  },
92
+ confine: true,
93
+ formatter: (params) =>
94
+ getTooltipFormatter({
95
+ params,
96
+ buckets,
97
+ bucketWidth,
98
+ selectedPrice,
99
+ labelCallback,
100
+ precision,
101
+ bookType,
102
+ }),
59
103
  },
60
104
  xAxis: {
61
105
  type: 'category',
62
106
  data: xAxisData,
107
+ splitNumber: 1,
63
108
  axisTick: {
64
109
  show: false,
65
110
  },
66
111
  axisLabel: {
67
112
  padding: [8, 16, 8, 16],
68
113
  margin: 0,
69
- showMinLabel: false,
70
- formatter: (value) => {
71
- const date = new Date(value as string);
72
- return isGreaterThanTwoWeeks
73
- ? `${date.toLocaleTimeString(undefined, {
74
- hour: '2-digit',
75
- minute: '2-digit',
76
- })}`
77
- : `${date.toLocaleDateString(undefined, {
78
- day: 'numeric',
79
- })}`;
80
- },
114
+ formatter: (value) => formatXAxisLabel(value, isGreaterThanTwoWeeks),
81
115
  },
82
116
  },
83
117
  yAxis: {
@@ -90,6 +124,7 @@ export const getOption: GetOptionType = (
90
124
  axisLabel: {
91
125
  showMaxLabel: false,
92
126
  showMinLabel: false,
127
+ formatter: (value: number) => value.toFixed(precision - 1),
93
128
  },
94
129
  },
95
130
  series: [
@@ -101,6 +136,7 @@ export const getOption: GetOptionType = (
101
136
  color: colorPalette.raspberryLight,
102
137
  color0: colorPalette.bottleGreenLight,
103
138
  },
139
+
104
140
  markPoint: {
105
141
  symbol: 'circle',
106
142
  symbolSize: 0,
@@ -115,34 +151,32 @@ export const getOption: GetOptionType = (
115
151
  clip: true,
116
152
  renderItem: (_params, api) => {
117
153
  const xVal = api.value(0);
118
- const metaValues = JSON.parse(api.value(2) as string);
154
+ const bucketIndex = api.value(2) as number;
155
+ const metaValues = buckets[bucketIndex];
119
156
 
120
157
  const [rectWidth, rectHeight] = api.size!([
121
158
  0,
122
159
  bucketWidth,
123
160
  ]) as number[];
124
161
 
125
- const items = metaValues.map(
126
- ({ price, sentiment }: { price: number; sentiment: number }) => {
127
- const start = api.coord([xVal, price]);
162
+ const items = metaValues.map(({ price, sentiment }: Bucket) => {
163
+ const start = api.coord([xVal, price]);
128
164
 
129
- return {
130
- type: 'rect',
131
- shape: {
132
- x: start[0] - rectWidth / 2,
133
- y: start[1],
134
- width: rectWidth,
135
- height: rectHeight,
136
- },
137
- style: {
138
- fill: getRectColor(sentiment),
139
- opacity: 0.7,
140
- },
141
- silent: true,
142
- emphasisDisabled: true,
143
- };
144
- }
145
- );
165
+ return {
166
+ type: 'rect',
167
+ shape: {
168
+ x: start[0] - rectWidth / 2,
169
+ y: start[1] - rectHeight,
170
+ width: rectWidth + 1,
171
+ height: rectHeight,
172
+ },
173
+ style: {
174
+ fill: getRectColor(sentiment),
175
+ },
176
+ silent: true,
177
+ emphasisDisabled: true,
178
+ };
179
+ });
146
180
 
147
181
  return {
148
182
  type: 'group',
@@ -3,4 +3,4 @@ export * from './chartOptions';
3
3
  export * from './ChartWithData';
4
4
  export * from './types';
5
5
  export * from './useCrowdViewData';
6
- export * from './utils/chartUtils';
6
+ export * from './utils';