import { FunctionComponent, useMemo, useState } from 'react' import dayjs from 'dayjs' import relativeTime from 'dayjs/plugin/relativeTime' import { AreaChart, Area, XAxis, YAxis, Tooltip, ResponsiveContainer, } from 'recharts' import FlipNumbers from 'react-flip-numbers' import ContentBox from '../shared/ContentBox' import SheenLoader from '../shared/SheenLoader' import { COLORS } from '../../styles/colors' import { useTheme } from 'next-themes' import { IconButton } from './Button' import { ArrowLeftIcon, NoSymbolIcon } from '@heroicons/react/20/solid' import { FadeInFadeOut } from './Transitions' import ChartRangeButtons from './ChartRangeButtons' import Change from './Change' import useLocalStorageState from 'hooks/useLocalStorageState' import { ANIMATION_SETTINGS_KEY } from 'utils/constants' import { formatFixedDecimals } from 'utils/numbers' import { INITIAL_ANIMATION_SETTINGS } from '@components/settings/AnimationSettings' import { AxisDomain } from 'recharts/types/util/types' import { useTranslation } from 'next-i18next' dayjs.extend(relativeTime) interface DetailedAreaChartProps { data: any[] daysToShow?: string domain?: AxisDomain heightClass?: string hideChange?: boolean hideChart?: () => void loading?: boolean prefix?: string setDaysToShow?: (x: string) => void small?: boolean suffix?: string tickFormat?: (x: number) => string title?: string xKey: string yKey: string } export const formatDateAxis = (date: string, days: number) => { if (days === 1) { return dayjs(date).format('h:mma') } else { return dayjs(date).format('D MMM') } } const DetailedAreaChart: FunctionComponent = ({ data, daysToShow = '1', domain, heightClass, hideChange, hideChart, loading, prefix = '', setDaysToShow, small, suffix = '', tickFormat, title, xKey, yKey, }) => { const { t } = useTranslation('common') const [mouseData, setMouseData] = useState(null) const { theme } = useTheme() const [animationSettings] = useLocalStorageState( ANIMATION_SETTINGS_KEY, INITIAL_ANIMATION_SETTINGS ) const handleMouseMove = (coords: any) => { if (coords.activePayload) { setMouseData(coords.activePayload[0].payload) } } const handleMouseLeave = () => { setMouseData(null) } const calculateChartChange = () => { if (data.length) { if (mouseData) { const index = data.findIndex((d: any) => d[xKey] === mouseData[xKey]) const change = index >= 0 ? data[index][yKey] - data[0][yKey] : 0 return isNaN(change) ? 0 : change } else return data[data.length - 1][yKey] - data[0][yKey] } return 0 } const flipGradientCoords = useMemo(() => { if (!data.length) return return data[0][yKey] <= 0 && data[data.length - 1][yKey] < data[0][yKey] }, [data]) return ( {loading ? (
) : data.length ? (
{hideChart ? ( ) : null}

{title}

{mouseData ? (
{animationSettings['number-scroll'] ? ( ) : ( {prefix + formatFixedDecimals(mouseData[yKey] ?? 0) + suffix} )} {!hideChange ? ( ) : null}

{dayjs(mouseData[xKey]).format('DD MMM YY, h:mma')}

) : (
{animationSettings['number-scroll'] ? ( ) : ( {prefix + formatFixedDecimals(data[data.length - 1][yKey]) + suffix} )} {!hideChange ? ( ) : null}

{dayjs(data[data.length - 1][xKey]).format( 'DD MMM YY, h:mma' )}

)}
{setDaysToShow ? (
setDaysToShow(v)} />
) : null}
} /> = 0 ? COLORS.UP[theme] : COLORS.DOWN[theme] } stopOpacity={0.15} /> = 0 ? COLORS.UP[theme] : COLORS.DOWN[theme] } stopOpacity={0} /> = 0 ? COLORS.UP[theme] : COLORS.DOWN[theme] } strokeWidth={1.5} fill={`url(#gradientArea-${title?.replace(/\s/g, '')})`} /> formatDateAxis(d, parseInt(daysToShow)) } /> tickFormat(v) : undefined } tickLine={false} />
) : (

{t('chart-unavailable')}

)} ) } export default DetailedAreaChart