chore(market-depth): replace bid and ask columns with a single volume column when i… (#3930)
This commit is contained in:
parent
a9dbc0f6eb
commit
5b0fffc5cb
@ -75,7 +75,56 @@ export const OrderbookRow = React.memo(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
OrderbookRow.displayName = 'OrderbookRow';
|
OrderbookRow.displayName = 'OrderbookRow';
|
||||||
|
|
||||||
export default OrderbookRow;
|
export const OrderbookContinuousRow = React.memo(
|
||||||
|
({
|
||||||
|
ask,
|
||||||
|
bid,
|
||||||
|
cumulativeAsk,
|
||||||
|
cumulativeBid,
|
||||||
|
cumulativeRelativeAsk,
|
||||||
|
cumulativeRelativeBid,
|
||||||
|
decimalPlaces,
|
||||||
|
positionDecimalPlaces,
|
||||||
|
indicativeVolume,
|
||||||
|
price,
|
||||||
|
relativeAsk,
|
||||||
|
relativeBid,
|
||||||
|
onClick,
|
||||||
|
}: OrderbookRowProps) => {
|
||||||
|
const type = bid ? 'bid' : 'ask';
|
||||||
|
const value = bid || ask;
|
||||||
|
const relativeValue = bid ? relativeBid : relativeAsk;
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<VolCell
|
||||||
|
testId={`bid-ask-vol-${price}`}
|
||||||
|
value={value}
|
||||||
|
valueFormatted={addDecimalsFixedFormatNumber(
|
||||||
|
value,
|
||||||
|
positionDecimalPlaces
|
||||||
|
)}
|
||||||
|
relativeValue={relativeValue}
|
||||||
|
type={type}
|
||||||
|
/>
|
||||||
|
<PriceCell
|
||||||
|
testId={`price-${price}`}
|
||||||
|
value={BigInt(price)}
|
||||||
|
onClick={() => onClick && onClick(addDecimal(price, decimalPlaces))}
|
||||||
|
valueFormatted={addDecimalsFixedFormatNumber(price, decimalPlaces)}
|
||||||
|
/>
|
||||||
|
<CumulativeVol
|
||||||
|
testId={`cumulative-vol-${price}`}
|
||||||
|
positionDecimalPlaces={positionDecimalPlaces}
|
||||||
|
bid={cumulativeBid}
|
||||||
|
ask={cumulativeAsk}
|
||||||
|
relativeAsk={cumulativeRelativeAsk}
|
||||||
|
relativeBid={cumulativeRelativeBid}
|
||||||
|
indicativeVolume={indicativeVolume}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
OrderbookContinuousRow.displayName = 'OrderbookContinuousRow';
|
||||||
|
@ -224,4 +224,37 @@ describe('Orderbook', () => {
|
|||||||
expect(onResolutionChange.mock.calls[0][0]).toBe(10);
|
expect(onResolutionChange.mock.calls[0][0]).toBe(10);
|
||||||
expect(onClickSpy).toBeCalledWith('122.99');
|
expect(onClickSpy).toBeCalledWith('122.99');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should have three or four columns', async () => {
|
||||||
|
window.innerHeight = 11 * rowHeight;
|
||||||
|
const { rerender } = render(
|
||||||
|
<Orderbook
|
||||||
|
decimalPlaces={decimalPlaces}
|
||||||
|
positionDecimalPlaces={0}
|
||||||
|
fillGaps
|
||||||
|
{...generateMockData({
|
||||||
|
...params,
|
||||||
|
overlap: 0,
|
||||||
|
})}
|
||||||
|
onResolutionChange={onResolutionChange}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(screen.queryByText('Bid / Ask vol')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
rerender(
|
||||||
|
<Orderbook
|
||||||
|
decimalPlaces={decimalPlaces}
|
||||||
|
positionDecimalPlaces={0}
|
||||||
|
fillGaps
|
||||||
|
{...generateMockData(params)}
|
||||||
|
onResolutionChange={onResolutionChange}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(screen.getByText('Bid vol')).toBeInTheDocument();
|
||||||
|
expect(screen.getByText('Ask vol')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
await expect(screen.queryByText('Bid / Ask vol')).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,12 @@
|
|||||||
import colors from 'tailwindcss/colors';
|
import colors from 'tailwindcss/colors';
|
||||||
import { useEffect, useRef, useState, useCallback, Fragment } from 'react';
|
import {
|
||||||
|
useEffect,
|
||||||
|
useRef,
|
||||||
|
useState,
|
||||||
|
useCallback,
|
||||||
|
Fragment,
|
||||||
|
useMemo,
|
||||||
|
} from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import {
|
import {
|
||||||
addDecimalsFixedFormatNumber,
|
addDecimalsFixedFormatNumber,
|
||||||
@ -11,7 +18,7 @@ import {
|
|||||||
useThemeSwitcher,
|
useThemeSwitcher,
|
||||||
} from '@vegaprotocol/react-helpers';
|
} from '@vegaprotocol/react-helpers';
|
||||||
import * as Schema from '@vegaprotocol/types';
|
import * as Schema from '@vegaprotocol/types';
|
||||||
import { OrderbookRow } from './orderbook-row';
|
import { OrderbookRow, OrderbookContinuousRow } from './orderbook-row';
|
||||||
import { createRow } from './orderbook-data';
|
import { createRow } from './orderbook-data';
|
||||||
import { Checkbox, Icon, Splash, TinyScroll } from '@vegaprotocol/ui-toolkit';
|
import { Checkbox, Icon, Splash, TinyScroll } from '@vegaprotocol/ui-toolkit';
|
||||||
import type { OrderbookData, OrderbookRowData } from './orderbook-data';
|
import type { OrderbookData, OrderbookRowData } from './orderbook-data';
|
||||||
@ -472,39 +479,75 @@ export const Orderbook = ({
|
|||||||
);
|
);
|
||||||
useResizeObserver(gridElement.current, gridResizeHandler);
|
useResizeObserver(gridElement.current, gridResizeHandler);
|
||||||
useResizeObserver(rootElement.current, rootElementResizeHandler);
|
useResizeObserver(rootElement.current, rootElementResizeHandler);
|
||||||
|
const isContinuousMode =
|
||||||
const tableBody =
|
marketTradingMode === Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS;
|
||||||
data && data.length !== 0 ? (
|
const tableHeader = useMemo(() => {
|
||||||
<div className="grid grid-cols-4 gap-1 text-right auto-rows-[17px]">
|
return (
|
||||||
{data.map((data, i) => (
|
<div
|
||||||
<OrderbookRow
|
className={classNames(
|
||||||
key={data.price}
|
'absolute top-0 grid auto-rows-[17px] gap-2 text-right border-b pt-2 bg-white dark:bg-black z-10 border-default w-full',
|
||||||
price={(BigInt(data.price) / BigInt(resolution)).toString()}
|
isContinuousMode ? 'grid-cols-3' : 'grid-cols-4'
|
||||||
onClick={onClick}
|
)}
|
||||||
decimalPlaces={decimalPlaces - Math.log10(resolution)}
|
ref={headerElement}
|
||||||
positionDecimalPlaces={positionDecimalPlaces}
|
>
|
||||||
bid={data.bid}
|
{isContinuousMode ? (
|
||||||
relativeBid={data.relativeBid}
|
<div>{t('Bid / Ask vol')}</div>
|
||||||
cumulativeBid={data.cumulativeVol.bid}
|
) : (
|
||||||
cumulativeRelativeBid={data.cumulativeVol.relativeBid}
|
<>
|
||||||
ask={data.ask}
|
<div>{t('Bid vol')}</div>
|
||||||
relativeAsk={data.relativeAsk}
|
<div>{t('Ask vol')}</div>
|
||||||
cumulativeAsk={data.cumulativeVol.ask}
|
</>
|
||||||
cumulativeRelativeAsk={data.cumulativeVol.relativeAsk}
|
)}
|
||||||
indicativeVolume={
|
<div>{t('Price')}</div>
|
||||||
marketTradingMode !==
|
<div className="pr-1 whitespace-nowrap overflow-hidden text-ellipsis">
|
||||||
Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS &&
|
{t('Cumulative vol')}
|
||||||
indicativePrice === data.price
|
</div>
|
||||||
? indicativeVolume
|
|
||||||
: undefined
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
</div>
|
||||||
) : null;
|
);
|
||||||
|
}, [isContinuousMode]);
|
||||||
|
|
||||||
|
const OrderBookRowComponent = isContinuousMode
|
||||||
|
? OrderbookContinuousRow
|
||||||
|
: OrderbookRow;
|
||||||
|
|
||||||
|
const tableBody = data?.length ? (
|
||||||
|
<div
|
||||||
|
className={classNames(
|
||||||
|
'grid grid-cols-4 gap-1 text-right auto-rows-[17px]',
|
||||||
|
isContinuousMode ? 'grid-cols-3' : 'grid-cols-4'
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{data.map((data, i) => (
|
||||||
|
<OrderBookRowComponent
|
||||||
|
key={data.price}
|
||||||
|
price={(BigInt(data.price) / BigInt(resolution)).toString()}
|
||||||
|
onClick={onClick}
|
||||||
|
decimalPlaces={decimalPlaces - Math.log10(resolution)}
|
||||||
|
positionDecimalPlaces={positionDecimalPlaces}
|
||||||
|
bid={data.bid}
|
||||||
|
relativeBid={data.relativeBid}
|
||||||
|
cumulativeBid={data.cumulativeVol.bid}
|
||||||
|
cumulativeRelativeBid={data.cumulativeVol.relativeBid}
|
||||||
|
ask={data.ask}
|
||||||
|
relativeAsk={data.relativeAsk}
|
||||||
|
cumulativeAsk={data.cumulativeVol.ask}
|
||||||
|
cumulativeRelativeAsk={data.cumulativeVol.relativeAsk}
|
||||||
|
indicativeVolume={
|
||||||
|
marketTradingMode !==
|
||||||
|
Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS &&
|
||||||
|
indicativePrice === data.price
|
||||||
|
? indicativeVolume
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
) : null;
|
||||||
|
|
||||||
const c = theme === 'dark' ? colors.neutral[600] : colors.neutral[300];
|
const c = theme === 'dark' ? colors.neutral[600] : colors.neutral[300];
|
||||||
const gradientStyles = `linear-gradient(${c},${c}) 24.6% 0/1px 100% no-repeat, linear-gradient(${c},${c}) 50% 0/1px 100% no-repeat, linear-gradient(${c},${c}) 75.2% 0/1px 100% no-repeat`;
|
const gradientStyles = isContinuousMode
|
||||||
|
? `linear-gradient(${c},${c}) 33.4% 0/1px 100% no-repeat, linear-gradient(${c},${c}) 66.7% 0/1px 100% no-repeat`
|
||||||
|
: `linear-gradient(${c},${c}) 25% 0/1px 100% no-repeat, linear-gradient(${c},${c}) 50% 0/1px 100% no-repeat, linear-gradient(${c},${c}) 75% 0/1px 100% no-repeat`;
|
||||||
|
|
||||||
const resolutions = new Array(decimalPlaces + 1)
|
const resolutions = new Array(decimalPlaces + 1)
|
||||||
.fill(null)
|
.fill(null)
|
||||||
@ -531,21 +574,11 @@ export const Orderbook = ({
|
|||||||
/* eslint-disable jsx-a11y/no-static-element-interactions */
|
/* eslint-disable jsx-a11y/no-static-element-interactions */
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="h-full relative pl-2 text-xs"
|
className="h-full relative pl-1 text-xs"
|
||||||
ref={rootElement}
|
ref={rootElement}
|
||||||
onDoubleClick={() => setDebug(!debug)}
|
onDoubleClick={() => setDebug(!debug)}
|
||||||
>
|
>
|
||||||
<div
|
{tableHeader}
|
||||||
className="absolute top-0 grid grid-cols-4 auto-rows-[17px] gap-2 text-right border-b pt-2 bg-white dark:bg-black z-10 border-default w-full"
|
|
||||||
ref={headerElement}
|
|
||||||
>
|
|
||||||
<div>{t('Bid vol')}</div>
|
|
||||||
<div>{t('Ask vol')}</div>
|
|
||||||
<div>{t('Price')}</div>
|
|
||||||
<div className="pr-1 whitespace-nowrap overflow-hidden text-ellipsis">
|
|
||||||
{t('Cumulative vol')}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<TinyScroll
|
<TinyScroll
|
||||||
className="h-full overflow-auto relative"
|
className="h-full overflow-auto relative"
|
||||||
onScroll={onScroll}
|
onScroll={onScroll}
|
||||||
|
Loading…
Reference in New Issue
Block a user