Commit ea062c17 authored by tom's avatar tom

add chart for address coin history tab

parent 6c2f65d5
......@@ -80,6 +80,11 @@ export interface AddressCoinBalanceHistoryResponse {
};
}
export type AddressCoinBalanceHistoryChart = Array<{
date: string;
value: string;
}>
export interface AddressBlocksValidatedResponse {
items: Array<Block>;
next_page_params: {
......
......@@ -69,7 +69,7 @@ const AddressCoinBalance = ({ addressQuery }: Props) => {
return (
<>
{ socketAlert && <SocketAlert mb={ 6 }/> }
<AddressCoinBalanceChart/>
<AddressCoinBalanceChart addressQuery={ addressQuery }/>
<AddressCoinBalanceHistory query={ coinBalanceQuery }/>
</>
);
......
import { Box } from '@chakra-ui/react';
import type { UseQueryResult } from '@tanstack/react-query';
import { useQuery } from '@tanstack/react-query';
import BigNumber from 'bignumber.js';
import React from 'react';
const AddressCoinBalanceChart = () => {
// chart will be added after stats feature is finalized
return <Box p={ 4 } borderColor="gray.200" borderRadius="md" borderWidth="1px">Here will be coin balance chart</Box>;
import type { Address, AddressCoinBalanceHistoryChart } from 'types/api/address';
import { QueryKeys } from 'types/client/queries';
import appConfig from 'configs/app/config';
import useFetch from 'lib/hooks/useFetch';
import ChartWidget from 'ui/shared/chart/ChartWidget';
interface Props {
addressQuery: UseQueryResult<Address>;
}
const AddressCoinBalanceChart = ({ addressQuery }: Props) => {
const fetch = useFetch();
const { data, isLoading, isError } = useQuery<unknown, unknown, AddressCoinBalanceHistoryChart>(
[ QueryKeys.addressCoinBalanceHistoryByDay, addressQuery.data?.hash ],
async() => fetch(`/node-api/addresses/${ addressQuery.data?.hash }/coin-balance-history-by-day`,
), {
enabled: Boolean(addressQuery.data?.hash),
});
const items = React.useMemo(() => data?.map(({ date, value }) => ({
date: new Date(date),
value: BigNumber(value).div(10 ** appConfig.network.currency.decimals).toNumber(),
})), [ data ]);
return (
<ChartWidget
title="Balances"
items={ items }
isLoading={ isLoading || isError }
/>
);
};
export default AddressCoinBalanceChart;
export default React.memo(AddressCoinBalanceChart);
......@@ -16,7 +16,7 @@ import FullscreenChartModal from './FullscreenChartModal';
type Props = {
items?: Array<TimeChartItem>;
title: string;
description: string;
description?: string;
isLoading: boolean;
}
......@@ -78,7 +78,7 @@ const ChartWidget = ({ items, title, description, isLoading }: Props) => {
}, [ title ]);
if (isLoading) {
return <ChartWidgetSkeleton/>;
return <ChartWidgetSkeleton hasDescription={ Boolean(description) }/>;
}
if (items) {
......@@ -105,15 +105,17 @@ const ChartWidget = ({ items, title, description, isLoading }: Props) => {
{ title }
</Text>
<Text
mb={ 1 }
gridColumn={ 1 }
as="p"
variant="secondary"
fontSize="xs"
>
{ description }
</Text>
{ description && (
<Text
mb={ 1 }
gridColumn={ 1 }
as="p"
variant="secondary"
fontSize="xs"
>
{ description }
</Text>
) }
<Tooltip label="Reset zoom">
<IconButton
......
......@@ -22,7 +22,7 @@ interface Props {
isZoomResetInitial: boolean;
}
const CHART_MARGIN = { bottom: 20, left: 30, right: 20, top: 10 };
const CHART_MARGIN = { bottom: 20, left: 40, right: 20, top: 10 };
const ChartWidgetGraph = ({ isEnlarged, items, onZoom, isZoomResetInitial, title }: Props) => {
const isMobile = useIsMobile();
......@@ -33,8 +33,7 @@ const ChartWidgetGraph = ({ isEnlarged, items, onZoom, isZoomResetInitial, title
const [ range, setRange ] = React.useState<[ number, number ]>([ 0, Infinity ]);
const { innerWidth, innerHeight } = useChartSize(ref.current, CHART_MARGIN);
const displayedData = useMemo(() => items.slice(range[0], range[1]).map((d) =>
({ ...d, date: new Date(d.date) })), [ items, range ]);
const displayedData = useMemo(() => items.slice(range[0], range[1]), [ items, range ]);
const chartData = [ { items: items, name: 'Value', color } ];
const { yTickFormat, xScale, yScale } = useTimeChartController({
......
import { Box, Skeleton } from '@chakra-ui/react';
import React from 'react';
const ChartWidgetSkeleton = () => {
interface Props {
hasDescription: boolean;
}
const ChartWidgetSkeleton = ({ hasDescription }: Props) => {
return (
<Box
height="235px"
paddingY={{ base: 3, lg: 4 }}
>
<Skeleton w="75%" h="24px" mb={ 1 }/>
<Skeleton w="50%" h="18px" mb={ 5 }/>
<Skeleton w="75%" h="24px"/>
{ hasDescription && <Skeleton w="50%" h="18px" mt={ 1 }/> }
<Skeleton w="100%" h="150px"/>
<Skeleton w="100%" h="150px" mt={ 5 }/>
</Box>
);
};
......
......@@ -10,7 +10,7 @@ import ChartWidgetGraph from './ChartWidgetGraph';
type Props = {
isOpen: boolean;
title: string;
description: string;
description?: string;
items: Array<TimeChartItem>;
onClose: () => void;
}
......@@ -56,14 +56,16 @@ const FullscreenChartModal = ({
{ title }
</Heading>
<Text
gridColumn={ 1 }
as="p"
variant="secondary"
fontSize="xs"
>
{ description }
</Text>
{ description && (
<Text
gridColumn={ 1 }
as="p"
variant="secondary"
fontSize="xs"
>
{ description }
</Text>
) }
{ !isZoomResetInitial && (
<Button
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment