allow view account charts when no data

This commit is contained in:
saml33 2023-07-06 21:00:47 +10:00
parent 675cc6d274
commit 9b3fd3a454
9 changed files with 285 additions and 261 deletions

View File

@ -5,7 +5,7 @@ import { HourlyFundingChartData, PerformanceDataItem } from 'types'
import { ContentType } from 'recharts/types/component/Tooltip'
import DetailedAreaOrBarChart from '@components/shared/DetailedAreaOrBarChart'
import { ChartToShow } from './AccountPage'
import { ArrowLeftIcon } from '@heroicons/react/20/solid'
import { ArrowLeftIcon, NoSymbolIcon } from '@heroicons/react/20/solid'
const CHART_TABS: ChartToShow[] = [
'account-value',
@ -74,20 +74,27 @@ const AccountChart = ({
</div>
</div>
<div className="px-6 pt-4">
<DetailedAreaOrBarChart
customTooltip={customTooltip}
data={chartData}
daysToShow={daysToShow}
heightClass="h-[calc(100vh-240px)]"
loaderHeightClass="h-[calc(100vh-116px)]"
loading={loading}
prefix="$"
setDaysToShow={setDaysToShow}
tickFormat={(x) => `$${formatYAxis(x)}`}
xKey="time"
yDecimals={yDecimals}
yKey={yKey}
/>
{chartData.length ? (
<DetailedAreaOrBarChart
customTooltip={customTooltip}
data={chartData}
daysToShow={daysToShow}
heightClass="h-[calc(100vh-240px)]"
loaderHeightClass="h-[calc(100vh-166px)]"
loading={loading}
prefix="$"
setDaysToShow={setDaysToShow}
tickFormat={(x) => `$${formatYAxis(x)}`}
xKey="time"
yDecimals={yDecimals}
yKey={yKey}
/>
) : (
<div className="flex flex-col items-center rounded-lg border border-th-bkg-3 p-8">
<NoSymbolIcon className="mb-2 h-6 w-6 text-th-fgd-4" />
<p>{t('account:no-data')}</p>
</div>
)}
</div>
</>
)

View File

@ -404,13 +404,10 @@ const AccountPage = () => {
| 'hourly-funding'
| 'hourly-volume'
) => {
if (
(chartName === 'cumulative-interest-value' && interestTotalValue > 1) ||
interestTotalValue < -1
) {
if (chartName === 'cumulative-interest-value' || interestTotalValue < -1) {
setChartToShow(chartName)
}
if (chartName === 'pnl' && performanceData.length > 4) {
if (chartName === 'pnl') {
setChartToShow(chartName)
}
if (chartName === 'hourly-funding') {
@ -700,21 +697,19 @@ const AccountPage = () => {
</Tooltip>
{mangoAccountAddress ? (
<div className="flex items-center space-x-3">
{performanceData.length > 4 ? (
<Tooltip
className="hidden md:block"
content={t('account:pnl-chart')}
delay={100}
<Tooltip
className="hidden md:block"
content={t('account:pnl-chart')}
delay={100}
>
<IconButton
className="text-th-fgd-3"
hideBg
onClick={() => handleChartToShow('pnl')}
>
<IconButton
className="text-th-fgd-3"
hideBg
onClick={() => handleChartToShow('pnl')}
>
<ChartBarIcon className="h-5 w-5" />
</IconButton>
</Tooltip>
) : null}
<ChartBarIcon className="h-5 w-5" />
</IconButton>
</Tooltip>
<Tooltip
className="hidden md:block"
content={t('account:pnl-history')}
@ -750,12 +745,10 @@ const AccountPage = () => {
<p className="text-sm text-th-fgd-3 xl:text-base">
{t('account:lifetime-volume')}
</p>
{mangoAccountAddress &&
hourlyVolumeData &&
hourlyVolumeData.length ? (
{mangoAccountAddress ? (
<Tooltip
className="hidden md:block"
content="Funding Chart"
content={t('account:volume-chart')}
delay={100}
>
<IconButton
@ -808,10 +801,10 @@ const AccountPage = () => {
{t('total-interest-earned')}
</p>
</Tooltip>
{mangoAccountAddress && Math.abs(interestTotalValue) >= 2 ? (
{mangoAccountAddress ? (
<Tooltip
className="hidden md:block"
content="Cumulative Interest Chart"
content={t('account:cumulative-interest-chart')}
delay={100}
>
<IconButton
@ -851,10 +844,10 @@ const AccountPage = () => {
{t('account:total-funding-earned')}
</p>
</Tooltip>
{mangoAccountAddress && Math.abs(fundingTotalValue) >= 2 ? (
{mangoAccountAddress ? (
<Tooltip
className="hidden md:block"
content="Funding Chart"
content={t('account:funding-chart')}
delay={100}
>
<IconButton

View File

@ -28,7 +28,7 @@ import { formatYAxis } from 'utils/formatting'
import ChartRangeButtons from '@components/shared/ChartRangeButtons'
import { useTranslation } from 'next-i18next'
import { IconButton } from '@components/shared/Button'
import { ArrowLeftIcon } from '@heroicons/react/20/solid'
import { ArrowLeftIcon, NoSymbolIcon } from '@heroicons/react/20/solid'
import { FadeInFadeOut } from '@components/shared/Transitions'
import ContentBox from '@components/shared/ContentBox'
import SheenLoader from '@components/shared/SheenLoader'
@ -133,14 +133,17 @@ const FundingChart = ({ hideChart }: { hideChart: () => void }) => {
: dayjs(label).format('DD MMM YY, h:mma')}
</h3>
<div className="space-y-1">
{data.map((d) => (
<div className="flex items-center justify-between" key={d[0]}>
<p>{d[0]}</p>
<p className="pl-4 font-mono text-th-fgd-2">
{formatCurrencyValue(d[1])}
</p>
</div>
))}
{data
.filter((d) => Math.abs(d[1]) > 0)
.sort((a, b) => a[0].localeCompare(b[0]))
.map((d) => (
<div className="flex items-center justify-between" key={d[0]}>
<p>{d[0]}</p>
<p className="pl-4 font-mono text-th-fgd-2">
{formatCurrencyValue(d[1])}
</p>
</div>
))}
</div>
<div className="mt-3 flex justify-between border-t border-th-bkg-4 pt-3">
<p>{t('total')}</p>
@ -189,7 +192,7 @@ const FundingChart = ({ hideChart }: { hideChart: () => void }) => {
const filteredData: HourlyFundingChartData[] = useMemo(() => {
if (!chartData.length) return []
const start = Number(daysToShow) * 86400000
const filtered = chartData.filter((d: any) => {
const filtered = chartData.filter((d: HourlyFundingChartData) => {
const date = new Date()
if (daysToShow === '30') {
date.setHours(0, 0, 0, 0)
@ -210,125 +213,126 @@ const FundingChart = ({ hideChart }: { hideChart: () => void }) => {
return (
<FadeInFadeOut show={true}>
<ContentBox className="px-6 pt-4" hideBorder hidePadding>
<div className="flex items-center justify-between">
<div className="flex items-center space-x-4 md:space-x-6">
<IconButton onClick={hideChart} size="medium">
<ArrowLeftIcon className="h-5 w-5" />
</IconButton>
<h2 className="text-lg">{t('funding')}</h2>
</div>
<ChartRangeButtons
activeValue={daysToShow}
names={['24H', '7D', '30D']}
values={['1', '7', '30']}
onChange={(v) => setDaysToShow(v)}
/>
</div>
{loadingFunding || fetchingFunding ? (
<SheenLoader className="flex flex-1">
<SheenLoader className="mt-6 flex flex-1">
<div
className={`h-[calc(100vh-116px)] w-full rounded-lg bg-th-bkg-2`}
className={`h-[calc(100vh-166px)] w-full rounded-lg bg-th-bkg-2`}
/>
</SheenLoader>
) : filteredData.length ? (
<div>
<div className="flex items-center justify-between">
<div className="flex items-center space-x-4 md:space-x-6">
<IconButton onClick={hideChart} size="medium">
<ArrowLeftIcon className="h-5 w-5" />
</IconButton>
<h2 className="text-lg">{t('funding')}</h2>
</div>
<ChartRangeButtons
activeValue={daysToShow}
names={['24H', '7D', '30D']}
values={['1', '7', '30']}
onChange={(v) => setDaysToShow(v)}
/>
</div>
<div className="-mx-6 mt-6 h-[calc(100vh-170px)]">
<ResponsiveContainer width="100%" height="100%">
<BarChart data={filteredData}>
<Tooltip
cursor={{
fill: 'var(--bkg-2)',
opacity: 0.5,
}}
content={<CustomTooltip />}
/>
<defs>
<linearGradient
id="greenGradientBar"
x1="0"
y1="0"
x2="0"
y2="1"
>
<stop
offset="0%"
stopColor={COLORS.UP[theme]}
stopOpacity={1}
) : filteredData.find((d) => Math.abs(d.total) > 0) ? (
<div className="-mx-6 mt-6 h-[calc(100vh-170px)]">
<ResponsiveContainer width="100%" height="100%">
<BarChart data={filteredData}>
<Tooltip
cursor={{
fill: 'var(--bkg-2)',
opacity: 0.5,
}}
content={<CustomTooltip />}
/>
<defs>
<linearGradient
id="greenGradientBar"
x1="0"
y1="0"
x2="0"
y2="1"
>
<stop
offset="0%"
stopColor={COLORS.UP[theme]}
stopOpacity={1}
/>
<stop
offset="100%"
stopColor={COLORS.UP[theme]}
stopOpacity={0.7}
/>
</linearGradient>
<linearGradient
id="redGradientBar"
x1="0"
y1="1"
x2="0"
y2="0"
>
<stop
offset="0%"
stopColor={COLORS.DOWN[theme]}
stopOpacity={1}
/>
<stop
offset="100%"
stopColor={COLORS.DOWN[theme]}
stopOpacity={0.7}
/>
</linearGradient>
</defs>
<Bar dataKey="total">
{filteredData.map((entry, index) => {
return (
<Cell
key={`cell-${index}`}
fill={
entry['total'] > 0
? 'url(#greenGradientBar)'
: 'url(#redGradientBar)'
}
/>
<stop
offset="100%"
stopColor={COLORS.UP[theme]}
stopOpacity={0.7}
/>
</linearGradient>
<linearGradient
id="redGradientBar"
x1="0"
y1="1"
x2="0"
y2="0"
>
<stop
offset="0%"
stopColor={COLORS.DOWN[theme]}
stopOpacity={1}
/>
<stop
offset="100%"
stopColor={COLORS.DOWN[theme]}
stopOpacity={0.7}
/>
</linearGradient>
</defs>
<Bar dataKey="total">
{filteredData.map((entry, index) => {
return (
<Cell
key={`cell-${index}`}
fill={
entry['total'] > 0
? 'url(#greenGradientBar)'
: 'url(#redGradientBar)'
}
/>
)
})}
</Bar>
<XAxis
dataKey="time"
axisLine={false}
dy={10}
minTickGap={20}
padding={{ left: 20, right: 20 }}
tick={{
fill: 'var(--fgd-4)',
fontSize: 10,
}}
tickLine={false}
tickFormatter={(v) =>
formatDateAxis(v, parseInt(daysToShow))
}
/>
<YAxis
dataKey="total"
interval="preserveStartEnd"
axisLine={false}
dx={-10}
padding={{ top: 20, bottom: 20 }}
tick={{
fill: 'var(--fgd-4)',
fontSize: 10,
}}
tickLine={false}
tickFormatter={(v) => formatYAxis(v)}
type="number"
/>
<ReferenceLine y={0} stroke={COLORS.BKG4[theme]} />
</BarChart>
</ResponsiveContainer>
</div>
)
})}
</Bar>
<XAxis
dataKey="time"
axisLine={false}
dy={10}
minTickGap={20}
padding={{ left: 20, right: 20 }}
tick={{
fill: 'var(--fgd-4)',
fontSize: 10,
}}
tickLine={false}
tickFormatter={(v) => formatDateAxis(v, parseInt(daysToShow))}
/>
<YAxis
dataKey="total"
interval="preserveStartEnd"
axisLine={false}
dx={-10}
padding={{ top: 20, bottom: 20 }}
tick={{
fill: 'var(--fgd-4)',
fontSize: 10,
}}
tickLine={false}
tickFormatter={(v) => formatYAxis(v)}
type="number"
/>
<ReferenceLine y={0} stroke={COLORS.BKG4[theme]} />
</BarChart>
</ResponsiveContainer>
</div>
) : null}
) : (
<div className="mt-6 flex flex-col items-center rounded-lg border border-th-bkg-3 p-8">
<NoSymbolIcon className="mb-2 h-6 w-6 text-th-fgd-4" />
<p>{t('account:no-data')}</p>
</div>
)}
</ContentBox>
</FadeInFadeOut>
)

View File

@ -1,7 +1,6 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import dayjs from 'dayjs'
import { useMemo, useState } from 'react'
import { FormattedHourlyAccountVolumeData, HourlyFundingChartData } from 'types'
import { FormattedHourlyAccountVolumeData } from 'types'
import { formatCurrencyValue } from 'utils/numbers'
import { TooltipProps } from 'recharts/types/component/Tooltip'
import {
@ -21,7 +20,7 @@ import { formatYAxis } from 'utils/formatting'
import ChartRangeButtons from '@components/shared/ChartRangeButtons'
import { useTranslation } from 'next-i18next'
import { IconButton } from '@components/shared/Button'
import { ArrowLeftIcon } from '@heroicons/react/20/solid'
import { ArrowLeftIcon, NoSymbolIcon } from '@heroicons/react/20/solid'
import { FadeInFadeOut } from '@components/shared/Transitions'
import ContentBox from '@components/shared/ContentBox'
import SheenLoader from '@components/shared/SheenLoader'
@ -35,7 +34,7 @@ const VolumeChart = ({
hideChart: () => void
loading: boolean
}) => {
const { t } = useTranslation(['common', 'stats'])
const { t } = useTranslation(['account', 'common', 'stats'])
const [daysToShow, setDaysToShow] = useState('30')
const { theme } = useTheme()
@ -122,10 +121,10 @@ const VolumeChart = ({
return chunkedData
}
const filteredData: HourlyFundingChartData[] = useMemo(() => {
const filteredData: FormattedHourlyAccountVolumeData[] = useMemo(() => {
if (!chartData || !chartData.length) return []
const start = Number(daysToShow) * 86400000
const filtered = chartData.filter((d: any) => {
const filtered = chartData.filter((d: FormattedHourlyAccountVolumeData) => {
const date = new Date()
if (daysToShow === '30') {
date.setHours(0, 0, 0, 0)
@ -146,103 +145,104 @@ const VolumeChart = ({
return (
<FadeInFadeOut show={true}>
<ContentBox className="px-6 pt-4" hideBorder hidePadding>
<div className="flex items-center justify-between">
<div className="flex items-center space-x-4 md:space-x-6">
<IconButton onClick={hideChart} size="medium">
<ArrowLeftIcon className="h-5 w-5" />
</IconButton>
<h2 className="text-lg">{t('stats:volume')}</h2>
</div>
<ChartRangeButtons
activeValue={daysToShow}
names={['24H', '7D', '30D']}
values={['1', '7', '30']}
onChange={(v) => setDaysToShow(v)}
/>
</div>
{loading ? (
<SheenLoader className="flex flex-1">
<div
className={`h-[calc(100vh-116px)] w-full rounded-lg bg-th-bkg-2`}
className={`h-[calc(100vh-166px)] w-full rounded-lg bg-th-bkg-2`}
/>
</SheenLoader>
) : filteredData.length ? (
<div>
<div className="flex items-center justify-between">
<div className="flex items-center space-x-4 md:space-x-6">
<IconButton onClick={hideChart} size="medium">
<ArrowLeftIcon className="h-5 w-5" />
</IconButton>
<h2 className="text-lg">{t('stats:volume')}</h2>
</div>
<ChartRangeButtons
activeValue={daysToShow}
names={['24H', '7D', '30D']}
values={['1', '7', '30']}
onChange={(v) => setDaysToShow(v)}
/>
</div>
<div className="-mx-6 mt-6 h-[calc(100vh-170px)]">
<ResponsiveContainer width="100%" height="100%">
<BarChart data={filteredData}>
<Tooltip
cursor={{
fill: 'var(--bkg-2)',
opacity: 0.5,
}}
content={<CustomTooltip />}
/>
<defs>
<linearGradient
id="greenGradientBar"
x1="0"
y1="0"
x2="0"
y2="1"
>
<stop
offset="0%"
stopColor={COLORS.UP[theme]}
stopOpacity={1}
) : filteredData.find((d) => d.total_volume_usd > 0) ? (
<div className="-mx-6 mt-6 h-[calc(100vh-170px)]">
<ResponsiveContainer width="100%" height="100%">
<BarChart data={filteredData}>
<Tooltip
cursor={{
fill: 'var(--bkg-2)',
opacity: 0.5,
}}
content={<CustomTooltip />}
/>
<defs>
<linearGradient
id="greenGradientBar"
x1="0"
y1="0"
x2="0"
y2="1"
>
<stop
offset="0%"
stopColor={COLORS.UP[theme]}
stopOpacity={1}
/>
<stop
offset="100%"
stopColor={COLORS.UP[theme]}
stopOpacity={0.7}
/>
</linearGradient>
</defs>
<Bar dataKey="total_volume_usd">
{filteredData.map((entry, index) => {
return (
<Cell
key={`cell-${index}`}
fill="url(#greenGradientBar)"
/>
<stop
offset="100%"
stopColor={COLORS.UP[theme]}
stopOpacity={0.7}
/>
</linearGradient>
</defs>
<Bar dataKey="total_volume_usd">
{filteredData.map((entry, index) => {
return (
<Cell
key={`cell-${index}`}
fill="url(#greenGradientBar)"
/>
)
})}
</Bar>
<XAxis
dataKey="time"
axisLine={false}
dy={10}
minTickGap={20}
padding={{ left: 20, right: 20 }}
tick={{
fill: 'var(--fgd-4)',
fontSize: 10,
}}
tickLine={false}
tickFormatter={(v) =>
formatDateAxis(v, parseInt(daysToShow))
}
/>
<YAxis
dataKey="total_volume_usd"
interval="preserveStartEnd"
axisLine={false}
dx={-10}
padding={{ top: 20, bottom: 20 }}
tick={{
fill: 'var(--fgd-4)',
fontSize: 10,
}}
tickLine={false}
tickFormatter={(v) => formatYAxis(v)}
type="number"
/>
<ReferenceLine y={0} stroke={COLORS.BKG4[theme]} />
</BarChart>
</ResponsiveContainer>
</div>
)
})}
</Bar>
<XAxis
dataKey="time"
axisLine={false}
dy={10}
minTickGap={20}
padding={{ left: 20, right: 20 }}
tick={{
fill: 'var(--fgd-4)',
fontSize: 10,
}}
tickLine={false}
tickFormatter={(v) => formatDateAxis(v, parseInt(daysToShow))}
/>
<YAxis
dataKey="total_volume_usd"
interval="preserveStartEnd"
axisLine={false}
dx={-10}
padding={{ top: 20, bottom: 20 }}
tick={{
fill: 'var(--fgd-4)',
fontSize: 10,
}}
tickLine={false}
tickFormatter={(v) => formatYAxis(v)}
type="number"
/>
<ReferenceLine y={0} stroke={COLORS.BKG4[theme]} />
</BarChart>
</ResponsiveContainer>
</div>
) : null}
) : (
<div className="mt-6 flex flex-col items-center rounded-lg border border-th-bkg-3 p-8">
<NoSymbolIcon className="mb-2 h-6 w-6 text-th-fgd-4" />
<p>{t('account:no-data')}</p>
</div>
)}
</ContentBox>
</FadeInFadeOut>
)

View File

@ -1,10 +1,13 @@
{
"assets": "Assets",
"assets-liabilities": "Assets & Liabilities",
"cumulative-interest-chart": "Cumulative Interst Chart",
"daily-volume": "24h Volume",
"export": "Export {{dataType}}",
"funding-chart": "Funding Chart",
"liabilities": "Liabilities",
"lifetime-volume": "Lifetime Trade Volume",
"no-data": "No data to display",
"no-pnl-history": "No PnL History",
"pnl-chart": "PnL Chart",
"pnl-history": "PnL History",
@ -15,5 +18,6 @@
"tooltip-total-funding": "The sum of perp position funding earned and paid",
"tooltip-total-interest": "The value of interest earned (deposits) minus interest paid (borrows)",
"total-funding-earned": "Total Funding Earned",
"volume-chart": "Volume Chart",
"week-starting": "Week starting {{week}}"
}

View File

@ -1,10 +1,13 @@
{
"assets": "Assets",
"assets-liabilities": "Assets & Liabilities",
"cumulative-interest-chart": "Cumulative Interst Chart",
"daily-volume": "24h Volume",
"export": "Export {{dataType}}",
"funding-chart": "Funding Chart",
"liabilities": "Liabilities",
"lifetime-volume": "Lifetime Trade Volume",
"no-data": "No data to display",
"no-pnl-history": "No PnL History",
"pnl-chart": "PnL Chart",
"pnl-history": "PnL History",
@ -15,5 +18,6 @@
"tooltip-total-funding": "The sum of perp position funding earned and paid",
"tooltip-total-interest": "The value of interest earned (deposits) minus interest paid (borrows)",
"total-funding-earned": "Total Funding Earned",
"volume-chart": "Volume Chart",
"week-starting": "Week starting {{week}}"
}

View File

@ -1,10 +1,13 @@
{
"assets": "Assets",
"assets-liabilities": "Assets & Liabilities",
"cumulative-interest-chart": "Cumulative Interst Chart",
"daily-volume": "24h Volume",
"export": "Export {{dataType}}",
"funding-chart": "Funding Chart",
"liabilities": "Liabilities",
"lifetime-volume": "Lifetime Trade Volume",
"no-data": "No data to display",
"no-pnl-history": "No PnL History",
"pnl-chart": "PnL Chart",
"pnl-history": "PnL History",
@ -15,5 +18,6 @@
"tooltip-total-funding": "The sum of perp position funding earned and paid",
"tooltip-total-interest": "The value of interest earned (deposits) minus interest paid (borrows)",
"total-funding-earned": "Total Funding Earned",
"volume-chart": "Volume Chart",
"week-starting": "Week starting {{week}}"
}

View File

@ -1,10 +1,13 @@
{
"assets": "Assets",
"assets-liabilities": "Assets & Liabilities",
"cumulative-interest-chart": "Cumulative Interst Chart",
"daily-volume": "24h Volume",
"export": "Export {{dataType}}",
"funding-chart": "Funding Chart",
"liabilities": "Liabilities",
"lifetime-volume": "Lifetime Trade Volume",
"no-data": "No data to display",
"no-pnl-history": "No PnL History",
"pnl-chart": "PnL Chart",
"pnl-history": "PnL History",
@ -15,5 +18,6 @@
"tooltip-total-funding": "The sum of perp position funding earned and paid",
"tooltip-total-interest": "The value of interest earned (deposits) minus interest paid (borrows)",
"total-funding-earned": "Total Funding Earned",
"volume-chart": "Volume Chart",
"week-starting": "Week starting {{week}}"
}

View File

@ -1,10 +1,13 @@
{
"assets": "Assets",
"assets-liabilities": "Assets & Liabilities",
"cumulative-interest-chart": "Cumulative Interst Chart",
"daily-volume": "24h Volume",
"export": "Export {{dataType}}",
"funding-chart": "Funding Chart",
"liabilities": "Liabilities",
"lifetime-volume": "Lifetime Trade Volume",
"no-data": "No data to display",
"no-pnl-history": "No PnL History",
"pnl-chart": "PnL Chart",
"pnl-history": "PnL History",
@ -15,5 +18,6 @@
"tooltip-total-funding": "The sum of perp position funding earned and paid",
"tooltip-total-interest": "The value of interest earned (deposits) minus interest paid (borrows)",
"total-funding-earned": "Total Funding Earned",
"volume-chart": "Volume Chart",
"week-starting": "Week starting {{week}}"
}