@oanda/labs-order-book-widget 1.0.62 → 1.0.63

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 (65) hide show
  1. package/CHANGELOG.md +240 -0
  2. package/dist/main/OrderBookWidget/OrderBookWidget.js +6 -3
  3. package/dist/main/OrderBookWidget/OrderBookWidget.js.map +1 -1
  4. package/dist/main/OrderBookWidget/Widget.js +12 -14
  5. package/dist/main/OrderBookWidget/Widget.js.map +1 -1
  6. package/dist/main/OrderBookWidget/components/Chart/Chart.js +49 -14
  7. package/dist/main/OrderBookWidget/components/Chart/Chart.js.map +1 -1
  8. package/dist/main/OrderBookWidget/components/Chart/constants.js +7 -3
  9. package/dist/main/OrderBookWidget/components/Chart/constants.js.map +1 -1
  10. package/dist/main/OrderBookWidget/components/Chart/formatters.js +14 -0
  11. package/dist/main/OrderBookWidget/components/Chart/formatters.js.map +1 -0
  12. package/dist/main/OrderBookWidget/components/Chart/getOption.js +274 -0
  13. package/dist/main/OrderBookWidget/components/Chart/getOption.js.map +1 -0
  14. package/dist/main/OrderBookWidget/components/Chart/types.js +6 -0
  15. package/dist/main/OrderBookWidget/components/Chart/types.js.map +1 -0
  16. package/dist/main/OrderBookWidget/config.js +15 -0
  17. package/dist/main/OrderBookWidget/config.js.map +1 -0
  18. package/dist/main/OrderBookWidget/render.js +31 -10
  19. package/dist/main/OrderBookWidget/render.js.map +1 -1
  20. package/dist/main/OrderBookWidget/types.js.map +1 -1
  21. package/dist/module/OrderBookWidget/OrderBookWidget.js +7 -4
  22. package/dist/module/OrderBookWidget/OrderBookWidget.js.map +1 -1
  23. package/dist/module/OrderBookWidget/Widget.js +13 -15
  24. package/dist/module/OrderBookWidget/Widget.js.map +1 -1
  25. package/dist/module/OrderBookWidget/components/Chart/Chart.js +47 -14
  26. package/dist/module/OrderBookWidget/components/Chart/Chart.js.map +1 -1
  27. package/dist/module/OrderBookWidget/components/Chart/constants.js +6 -2
  28. package/dist/module/OrderBookWidget/components/Chart/constants.js.map +1 -1
  29. package/dist/module/OrderBookWidget/components/Chart/formatters.js +8 -0
  30. package/dist/module/OrderBookWidget/components/Chart/formatters.js.map +1 -0
  31. package/dist/module/OrderBookWidget/components/Chart/getOption.js +266 -0
  32. package/dist/module/OrderBookWidget/components/Chart/getOption.js.map +1 -0
  33. package/dist/module/OrderBookWidget/components/Chart/types.js +2 -0
  34. package/dist/module/OrderBookWidget/components/Chart/types.js.map +1 -0
  35. package/dist/module/OrderBookWidget/config.js +10 -0
  36. package/dist/module/OrderBookWidget/config.js.map +1 -0
  37. package/dist/module/OrderBookWidget/render.js +31 -10
  38. package/dist/module/OrderBookWidget/render.js.map +1 -1
  39. package/dist/module/OrderBookWidget/types.js.map +1 -1
  40. package/dist/types/OrderBookWidget/OrderBookWidget.d.ts +1 -1
  41. package/dist/types/OrderBookWidget/components/Chart/Chart.d.ts +2 -6
  42. package/dist/types/OrderBookWidget/components/Chart/constants.d.ts +6 -2
  43. package/dist/types/OrderBookWidget/components/Chart/formatters.d.ts +3 -0
  44. package/dist/types/OrderBookWidget/components/Chart/getOption.d.ts +174 -0
  45. package/dist/types/OrderBookWidget/components/Chart/types.d.ts +18 -0
  46. package/dist/types/OrderBookWidget/config.d.ts +6 -0
  47. package/dist/types/OrderBookWidget/render.d.ts +1 -6
  48. package/dist/types/OrderBookWidget/types.d.ts +2 -0
  49. package/package.json +3 -3
  50. package/src/OrderBookWidget/OrderBookWidget.tsx +9 -6
  51. package/src/OrderBookWidget/Widget.tsx +12 -21
  52. package/src/OrderBookWidget/components/Chart/Chart.tsx +56 -18
  53. package/src/OrderBookWidget/components/Chart/constants.ts +7 -2
  54. package/src/OrderBookWidget/components/Chart/formatters.ts +11 -0
  55. package/src/OrderBookWidget/components/Chart/getOption.ts +296 -0
  56. package/src/OrderBookWidget/components/Chart/types.ts +29 -0
  57. package/src/OrderBookWidget/config.ts +11 -0
  58. package/src/OrderBookWidget/render.tsx +36 -18
  59. package/src/OrderBookWidget/types.ts +2 -0
  60. package/dist/main/OrderBookWidget/components/Chart/getOptions.js +0 -322
  61. package/dist/main/OrderBookWidget/components/Chart/getOptions.js.map +0 -1
  62. package/dist/module/OrderBookWidget/components/Chart/getOptions.js +0 -315
  63. package/dist/module/OrderBookWidget/components/Chart/getOptions.js.map +0 -1
  64. package/dist/types/OrderBookWidget/components/Chart/getOptions.d.ts +0 -6
  65. package/src/OrderBookWidget/components/Chart/getOptions.ts +0 -361
@@ -0,0 +1,296 @@
1
+ import { colorPalette, getGridLines, getZoomControls } from '@oanda/labs-widget-common';
2
+ import {
3
+ INITIAL_BARS, CHART_WIDTH, CHART_HEIGHT, X_LABEL_SIZE, Y_LABEL_SIZE_DESKTOP,
4
+ } from './constants';
5
+ import { GetOptionType, GetResponsiveOptionsProps } from './types';
6
+ import { tooltipFormatter } from './formatters';
7
+
8
+ export const getDesktopOption = ({ isDark, isOrderBook }: GetResponsiveOptionsProps) => {
9
+ const desktopGridLines = getGridLines({
10
+ isDark,
11
+ chartWidth: CHART_WIDTH,
12
+ chartHeight: CHART_HEIGHT,
13
+ xLabelsSize: X_LABEL_SIZE,
14
+ yLabelSize: Y_LABEL_SIZE_DESKTOP,
15
+ });
16
+
17
+ return {
18
+ grid: [
19
+ {
20
+ name: 'main-grid',
21
+ top: '48px',
22
+ left: '0px',
23
+ right: `${Y_LABEL_SIZE_DESKTOP}px`,
24
+ bottom: `${X_LABEL_SIZE}px`,
25
+ },
26
+ ],
27
+ graphic: [
28
+ ...desktopGridLines,
29
+ {
30
+ type: 'group',
31
+ left: '8px',
32
+ top: '56px',
33
+ silent: true,
34
+ children: [
35
+ {
36
+ type: 'rect',
37
+ z: 100,
38
+ left: 'center',
39
+ top: 'middle',
40
+ shape: {
41
+ width: 70,
42
+ height: 30,
43
+ },
44
+ style: {
45
+ fill: isDark ? colorPalette.darkGray : colorPalette.white,
46
+ shadowBlur: 8,
47
+ shadowOffsetX: 0,
48
+ shadowOffsetY: 1,
49
+ shadowColor: 'rgba(0,0,0,0.1)',
50
+ },
51
+ },
52
+ {
53
+ type: 'text',
54
+ z: 100,
55
+ left: 'center',
56
+ top: 'middle',
57
+ style: {
58
+ fill: isDark ? colorPalette.white : colorPalette.black,
59
+ width: 70,
60
+ height: 30,
61
+ text: isOrderBook ? 'Sell' : 'Short',
62
+ },
63
+ },
64
+ ],
65
+ },
66
+ {
67
+ type: 'group',
68
+ right: '128px',
69
+ top: '56px',
70
+ silent: true,
71
+ children: [
72
+ {
73
+ type: 'rect',
74
+ z: 100,
75
+ right: 'center',
76
+ top: 'middle',
77
+ shape: {
78
+ width: 70,
79
+ height: 30,
80
+ },
81
+ style: {
82
+ fill: isDark ? colorPalette.darkGray : colorPalette.white,
83
+ shadowBlur: 8,
84
+ shadowOffsetX: 0,
85
+ shadowOffsetY: 1,
86
+ shadowColor: 'rgba(0,0,0,0.1)',
87
+ },
88
+ },
89
+ {
90
+ type: 'text',
91
+ z: 100,
92
+ right: 'center',
93
+ top: 'middle',
94
+ style: {
95
+ fill: isDark ? colorPalette.white : colorPalette.black,
96
+ width: 70,
97
+ height: 30,
98
+ text: isOrderBook ? 'Buy' : 'Long',
99
+ },
100
+ },
101
+ ],
102
+ },
103
+ ],
104
+ };
105
+ };
106
+
107
+ export const getOption: GetOptionType = ({
108
+ data, precision, isDark, isOrderBook,
109
+ }) => {
110
+ const buckets = data.orderPositionBooks[0]?.buckets || [];
111
+ const bucketWidth = data.orderPositionBooks[0]?.bucketWidth!;
112
+ const price = data.orderPositionBooks[0]?.price!;
113
+
114
+ const dataset = buckets.map((item) => ([
115
+ item!.price,
116
+ Number(item!.longCountPercent),
117
+ Number(item!.shortCountPercent) * -1,
118
+ ]));
119
+
120
+ const zoomInitialStartValue = price - (bucketWidth * INITIAL_BARS * 0.5);
121
+ const zoomInitialEndValue = price + (bucketWidth * INITIAL_BARS * 0.5);
122
+
123
+ const max = Math.max(...dataset.map((item) => item[1]));
124
+ const min = Math.abs(Math.min(...dataset.map((item) => item[2])));
125
+
126
+ const range = max > min ? max : min;
127
+
128
+ return (
129
+ {
130
+ animation: false,
131
+ color: [
132
+ colorPalette.bottleGreenLight,
133
+ isDark ? colorPalette.orange : colorPalette.raspberryDark,
134
+ ],
135
+ title: {
136
+ text: isOrderBook ? 'OPEN ORDERS' : 'OPEN POSITIONS',
137
+ padding: 20,
138
+ textStyle: {
139
+ fontSize: 14,
140
+ },
141
+ },
142
+ toolbox: {
143
+ feature: getZoomControls({
144
+ resetStartValue: zoomInitialStartValue,
145
+ resetEndValue: zoomInitialEndValue,
146
+ }),
147
+ },
148
+ dataZoom: [
149
+ {
150
+ type: 'inside',
151
+ realtime: true,
152
+ startValue: zoomInitialStartValue,
153
+ endValue: zoomInitialEndValue,
154
+
155
+ yAxisIndex: 0,
156
+ minValueSpan: 10 * bucketWidth,
157
+ },
158
+ ],
159
+ tooltip: {
160
+ trigger: 'axis',
161
+ axisPointer: {
162
+ axis: 'y',
163
+ },
164
+ formatter: (val) => tooltipFormatter(
165
+ (val as { data: number[] }[])[0].data,
166
+ precision,
167
+ isOrderBook,
168
+ ),
169
+ },
170
+ xAxis: {
171
+ type: 'value',
172
+ min: range * -1.05,
173
+ max: range * 1.05,
174
+ axisTick: { show: false },
175
+ axisLine: { show: false },
176
+ axisLabel: {
177
+ padding: [7, 0, 0, 0],
178
+ showMinLabel: false,
179
+ showMaxLabel: false,
180
+ formatter: (value) => (value === 0 ? '%' : `${Math.abs(value)}%`),
181
+ },
182
+ },
183
+ yAxis: {
184
+ type: 'value',
185
+ position: 'right',
186
+ axisLine: { show: false },
187
+ axisTick: { show: false },
188
+ axisLabel: {
189
+ showMaxLabel: false,
190
+ showMinLabel: false,
191
+ padding: [0, 0, 0, 10],
192
+ formatter: (value) => value.toFixed(precision),
193
+ },
194
+ },
195
+ dataset: {
196
+ source: dataset,
197
+ },
198
+ series: [
199
+ {
200
+ type: 'custom',
201
+ clip: true,
202
+ encode: {
203
+ x: 1,
204
+ y: 0,
205
+ tooltip: 1,
206
+ },
207
+ renderItem: (params, api) => {
208
+ const yValue = api.value(0);
209
+ const xStart = api.coord([api.value(1), yValue]);
210
+ const xEnd = api.coord([0, yValue]);
211
+ const bucketWidthHeight = api.size ? (api.size([0, bucketWidth]) as number[])[1] : 0;
212
+ const height = bucketWidthHeight > 4 ? bucketWidthHeight * 0.8 : bucketWidthHeight;
213
+
214
+ const rectShape = {
215
+ x: xStart[0] + 0.5,
216
+ y: xStart[1] - height / 2,
217
+ width: xEnd[0] - xStart[0],
218
+ height,
219
+ };
220
+
221
+ return {
222
+ type: 'rect',
223
+ shape: rectShape,
224
+ emphasis: {
225
+ style: {
226
+ fill: colorPalette.bottleGreenLight,
227
+ },
228
+ },
229
+ style: {
230
+ fill: api.visual('color'),
231
+ },
232
+ };
233
+ },
234
+ },
235
+ {
236
+ type: 'custom',
237
+ clip: true,
238
+ encode: {
239
+ x: 1,
240
+ y: 0,
241
+ tooltip: 2,
242
+ },
243
+ markLine: {
244
+ animation: false,
245
+ silent: true,
246
+ precision: 4,
247
+ symbol: ['none', 'triangle'],
248
+ symbolRotate: 90,
249
+ symbolSize: [20, 10],
250
+ lineStyle: {
251
+ color: isDark ? colorPalette.orange : colorPalette.bottleGreenDark,
252
+ width: 1,
253
+ },
254
+ label: {
255
+ padding: [5, 15, 5, 15],
256
+ color: isDark ? colorPalette.black : colorPalette.white,
257
+ backgroundColor: isDark ? colorPalette.orange : colorPalette.bottleGreenDark,
258
+ },
259
+ data: [
260
+ {
261
+ yAxis: price,
262
+ },
263
+ ],
264
+ },
265
+ renderItem: (params, api) => {
266
+ const yValue = api.value(0);
267
+ const xStart = api.coord([api.value(2), yValue]);
268
+ const xEnd = api.coord([0, yValue]);
269
+ const bucketWidthHeight = api.size ? (api.size([0, bucketWidth]) as number[])[1] : 0;
270
+ const height = bucketWidthHeight > 4 ? bucketWidthHeight * 0.8 : bucketWidthHeight;
271
+
272
+ const rectShape = {
273
+ x: xStart[0] - 0.5,
274
+ y: xStart[1] - height / 2,
275
+ width: xEnd[0] - xStart[0],
276
+ height,
277
+ };
278
+
279
+ return {
280
+ type: 'rect',
281
+ shape: rectShape,
282
+ emphasis: {
283
+ style: {
284
+ fill: isDark ? colorPalette.orange : colorPalette.raspberryDark,
285
+ },
286
+ },
287
+ style: {
288
+ fill: api.visual('color'),
289
+ },
290
+ };
291
+ },
292
+ },
293
+ ],
294
+ }
295
+ );
296
+ };
@@ -0,0 +1,29 @@
1
+ import { EChartsOption } from 'echarts';
2
+ import { GetOrderPositionBooksQuery } from '../../../gql/types/graphql';
3
+
4
+ export interface ChartProps {
5
+ data: GetOrderPositionBooksQuery;
6
+ isOrderBook: boolean;
7
+ }
8
+
9
+ export interface GetResponsiveOptionsProps {
10
+ isDark: boolean;
11
+ isOrderBook: boolean;
12
+ }
13
+
14
+ export interface GetOptionProps {
15
+ data: GetOrderPositionBooksQuery;
16
+ precision: number;
17
+ isDark: boolean;
18
+ isOrderBook: boolean;
19
+ }
20
+
21
+ export type GetOptionType = (
22
+ props: GetOptionProps,
23
+ ) => EChartsOption;
24
+
25
+ export type TooltipFormatterType = (
26
+ data: number[],
27
+ precision: number,
28
+ isOrderBook: boolean,
29
+ ) => string;
@@ -0,0 +1,11 @@
1
+ import { BookType } from '../gql/types/graphql';
2
+
3
+ const navigationConfig = [{
4
+ id: BookType.Order,
5
+ label: 'order_book',
6
+ }, {
7
+ id: BookType.Position,
8
+ label: 'position_book',
9
+ }];
10
+
11
+ export { navigationConfig };
@@ -1,26 +1,44 @@
1
1
  import React from 'react';
2
2
  import { render } from 'react-dom';
3
+ import { Theme } from '@oanda/labs-widget-common';
3
4
  import { OrderBookWidget } from './OrderBookWidget';
4
- import { OrderBookWrapperConfig } from './types';
5
5
 
6
- declare global {
7
- interface Window {
8
- orderBookWidgetConfig: OrderBookWrapperConfig;
9
- }
10
- }
6
+ const {
7
+ graphqlUrl: configGraphQl,
8
+ instrument: configInstrument,
9
+ renderElementId: configRenderElementId,
10
+ locale: configLocale,
11
+ } = window.volatilityChartWidgetConfig || {};
11
12
 
12
13
  const {
13
14
  graphqlUrl,
14
- instrument,
15
- renderElementId,
16
- locale,
17
- } = window.orderBookWidgetConfig;
15
+ } = window.widgetsConfig || {};
16
+
17
+ const orderBookElements = document.querySelectorAll('div[data-order-book-params]');
18
18
 
19
- render(
20
- <OrderBookWidget
21
- locale={locale}
22
- graphqlUrl={graphqlUrl}
23
- instrument={instrument}
24
- />,
25
- document.getElementById(renderElementId),
26
- );
19
+ if (orderBookElements.length > 0) {
20
+ orderBookElements.forEach((element) => {
21
+ const params = element.getAttribute('data-order-book-params');
22
+ const mode = element.getAttribute('data-mode');
23
+ const { instrument, locale } = JSON.parse(params as string);
24
+
25
+ render(
26
+ <OrderBookWidget
27
+ locale={locale}
28
+ graphqlUrl={graphqlUrl}
29
+ instrument={instrument}
30
+ theme={mode as Theme}
31
+ />,
32
+ element,
33
+ );
34
+ });
35
+ } else {
36
+ render(
37
+ <OrderBookWidget
38
+ locale={configLocale}
39
+ graphqlUrl={configGraphQl}
40
+ instrument={configInstrument}
41
+ />,
42
+ document.getElementById(configRenderElementId),
43
+ );
44
+ }
@@ -1,9 +1,11 @@
1
+ import { Theme } from '@oanda/labs-widget-common';
1
2
  import { Locale } from '@oanda/mono-i18n';
2
3
 
3
4
  export interface OrderBookWidgetConfig {
4
5
  graphqlUrl: string;
5
6
  instrument: string;
6
7
  locale: Locale;
8
+ theme?: Theme;
7
9
  }
8
10
 
9
11
  export interface OrderBookWrapperConfig extends OrderBookWidgetConfig {