import dayjs from 'dayjs' import { useMemo, useState } from 'react' import { FormattedHourlyAccountVolumeData } from 'types' import { formatCurrencyValue } from 'utils/numbers' import { TooltipProps } from 'recharts/types/component/Tooltip' import { Cell, XAxis, YAxis, Tooltip, BarChart, Bar, ReferenceLine, ResponsiveContainer, } from 'recharts' import { COLORS } from 'styles/colors' import { formatDateAxis } from '@components/shared/DetailedAreaOrBarChart' import { formatYAxis } from 'utils/formatting' import ChartRangeButtons from '@components/shared/ChartRangeButtons' import { useTranslation } from 'next-i18next' import { NoSymbolIcon } from '@heroicons/react/20/solid' import { FadeInFadeOut } from '@components/shared/Transitions' import ContentBox from '@components/shared/ContentBox' import SheenLoader from '@components/shared/SheenLoader' import useAccountHourlyVolumeStats from 'hooks/useAccountHourlyVolumeStats' import useMangoAccount from 'hooks/useMangoAccount' import { DAILY_MILLISECONDS } from 'utils/constants' import useThemeWrapper from 'hooks/useThemeWrapper' import FormatNumericValue from '@components/shared/FormatNumericValue' const VolumeChart = () => { const { t } = useTranslation(['account', 'common', 'stats']) const { mangoAccountAddress } = useMangoAccount() const { hourlyVolumeData: chartData, loadingHourlyVolume: loading } = useAccountHourlyVolumeStats() const [daysToShow, setDaysToShow] = useState('30') const { theme } = useThemeWrapper() const CustomTooltip = ({ active, payload, label, }: TooltipProps) => { if (active && payload && payload.length) { const load = payload[0].payload return (

{daysToShow === '30' ? dayjs(label).format('DD MMM YY') : dayjs(label).format('DD MMM YY, h:mma')}

{Object.keys(load.markets) .filter((market) => load.markets[market] >= 0.01) .sort((a, b) => a.localeCompare(b)) .map((mkt) => (

{mkt}

{formatCurrencyValue(load.markets[mkt])}

))}

{t('total')}

{formatCurrencyValue(load['total_volume_usd'])}

) } return null } const chunkDataByDay = (data: FormattedHourlyAccountVolumeData[]) => { const chunkedData: FormattedHourlyAccountVolumeData[] = [] // Iterate over the data array for (const entry of data) { const { time, total_volume_usd, markets } = entry // Extract the date portion from the timestamp const date = time.substr(0, 10) // Find the existing chunk for the date or create a new one let chunk = chunkedData.find((chunk) => chunk.time === date) if (!chunk) { chunk = { time: date, total_volume_usd: 0, markets: {}, } chunkedData.push(chunk) } // Update the total volume for the day chunk.total_volume_usd += total_volume_usd // Update the market values for the day for (const market in markets) { if (Object.prototype.hasOwnProperty.call(markets, market)) { const value = markets[market] // Initialize the market value if it doesn't exist if (!chunk.markets[market]) { chunk.markets[market] = 0 } // Add the value to the market value for the day chunk.markets[market] += value } } } return chunkedData } const filteredData: FormattedHourlyAccountVolumeData[] = useMemo(() => { if (!chartData || !chartData.length) return [] const start = Number(daysToShow) * DAILY_MILLISECONDS const filtered = chartData.filter((d: FormattedHourlyAccountVolumeData) => { const date = new Date() if (daysToShow === '30') { date.setHours(0, 0, 0, 0) } else { date.setMinutes(0, 0, 0) } const dataTime = new Date(d.time).getTime() const now = date.getTime() const limit = now - start return dataTime >= limit }) if (daysToShow === '30') { return chunkDataByDay(filtered).sort((a, b) => a.time.localeCompare(b.time), ) } return filtered }, [chartData, daysToShow]) const totalForTimePeriod = useMemo(() => { if (!filteredData.length) return 0 return filteredData.reduce((a, c) => a + c.total_volume_usd, 0) }, [filteredData]) return ( {loading && mangoAccountAddress ? (
) : ( <>

{t('stats:volume')}

{totalForTimePeriod ? ( ) : null}
setDaysToShow(v)} />
{filteredData.find((d) => d.total_volume_usd > 0) ? (
} /> {filteredData.map((entry, index) => { return ( ) })} formatDateAxis(v, parseInt(daysToShow)) } /> formatYAxis(v)} type="number" />
) : (

{t('account:no-data')}

)} )} ) } export default VolumeChart