-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Vault performance chart adjustments and readme.
- Loading branch information
1 parent
3c6c405
commit 7285fec
Showing
13 changed files
with
242 additions
and
249 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Vault performance chart component | ||
|
||
The vault performance chart is made up of a series of subcomponents with a single graph query at the top. This query accesses the `pricePerShares` graph data, skipping the first two entries. This is because the first two epochs were used for testing and pre-public launch. | ||
|
||
An effect in the main `VaultPerformance` component handles adjusting each of the epoch nodes by deducting the growth percentage at the third epoch from each subsequent epoch. This allows us to display chart data from the public launch, corrected as if the third epoch were zero percent. |
94 changes: 94 additions & 0 deletions
94
packages/front-end/src/components/VaultPerformance/VaultPerformance.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import type { QueryData, ChartData } from "./VaultPerformance.types"; | ||
|
||
import { gql, useQuery } from "@apollo/client"; | ||
import { captureException } from "@sentry/react"; | ||
import { useState, useEffect } from "react"; | ||
import { AnimatePresence } from "framer-motion"; | ||
|
||
import { toTwoDecimalPlaces } from "src/utils/rounding"; | ||
|
||
import { Chart } from "./subcomponents/Chart"; | ||
import { Disclaimer } from "./subcomponents/Disclaimer"; | ||
import { Error } from "./subcomponents/Error"; | ||
import { Loading } from "./subcomponents/Loading"; | ||
import { FadeWrapper } from "./subcomponents/FadeWrapper"; | ||
import { Stats } from "./subcomponents/Stats"; | ||
|
||
export const VaultPerformance = () => { | ||
const [chartData, setChartData] = useState<ChartData[]>([]); | ||
|
||
const { loading, error, data } = useQuery<QueryData>( | ||
gql` | ||
query { | ||
pricePerShares( | ||
orderBy: "epoch" | ||
orderDirection: "asc" | ||
first: 1000 | ||
skip: 2 | ||
) { | ||
epoch | ||
growthSinceFirstEpoch | ||
timestamp | ||
} | ||
} | ||
`, | ||
{ | ||
onError: (err) => { | ||
captureException(err); | ||
console.error(err); | ||
}, | ||
} | ||
); | ||
|
||
useEffect(() => { | ||
if (data) { | ||
const { pricePerShares } = data; | ||
|
||
const publicLaunchOffset = parseFloat( | ||
pricePerShares[0].growthSinceFirstEpoch | ||
); | ||
|
||
const adjustedChartData = pricePerShares.map((pricePoint) => { | ||
const pricePointGrowth = parseFloat(pricePoint.growthSinceFirstEpoch); | ||
const growthSinceFirstEpoch = toTwoDecimalPlaces( | ||
pricePointGrowth - publicLaunchOffset | ||
); | ||
|
||
return { | ||
...pricePoint, | ||
growthSinceFirstEpoch, | ||
}; | ||
}); | ||
|
||
setChartData(adjustedChartData); | ||
} | ||
}, [data]); | ||
|
||
return ( | ||
<AnimatePresence exitBeforeEnter> | ||
{loading && ( | ||
<FadeWrapper key="loading"> | ||
<Loading /> | ||
</FadeWrapper> | ||
)} | ||
|
||
{error && ( | ||
<FadeWrapper key="error"> | ||
<Error /> | ||
</FadeWrapper> | ||
)} | ||
|
||
{data && ( | ||
<FadeWrapper key="data"> | ||
<Stats | ||
cumulativeYield={ | ||
chartData[chartData.length - 1]?.growthSinceFirstEpoch | ||
} | ||
/> | ||
<Chart chartData={chartData} /> | ||
<Disclaimer /> | ||
</FadeWrapper> | ||
)} | ||
</AnimatePresence> | ||
); | ||
}; |
30 changes: 30 additions & 0 deletions
30
packages/front-end/src/components/VaultPerformance/VaultPerformance.types.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
interface PricePerShareEpoch { | ||
epoch: string; | ||
growthSinceFirstEpoch: string; | ||
timestamp: string; | ||
__typename: string; | ||
} | ||
|
||
export interface QueryData { | ||
pricePerShares: PricePerShareEpoch[]; | ||
} | ||
|
||
export interface ChartData | ||
extends Omit<PricePerShareEpoch, "growthSinceFirstEpoch"> { | ||
growthSinceFirstEpoch: number; | ||
} | ||
|
||
export interface CustomTooltipProps { | ||
active?: boolean; | ||
payload?: [ | ||
{ | ||
value: string; | ||
payload: { epoch: string }; | ||
} | ||
]; | ||
label?: string; | ||
} | ||
|
||
export interface ChartProps { | ||
chartData: ChartData[]; | ||
} |
67 changes: 67 additions & 0 deletions
67
packages/front-end/src/components/VaultPerformance/subcomponents/Chart.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import type { ChartProps, CustomTooltipProps } from "../VaultPerformance.types"; | ||
|
||
import dayjs from "dayjs"; | ||
import { | ||
LineChart, | ||
Line, | ||
CartesianGrid, | ||
XAxis, | ||
YAxis, | ||
Tooltip, | ||
ResponsiveContainer, | ||
Legend, | ||
} from "recharts"; | ||
|
||
const CustomTooltip = ({ active, payload, label }: CustomTooltipProps) => { | ||
if (label && active && payload && payload.length) { | ||
return ( | ||
<div | ||
className="custom-tooltip bg-bone bg-opacity-90 border-black p-4 border-2 rounded-xl" | ||
role="dialog" | ||
> | ||
<p>{dayjs.unix(parseInt(label)).format("DD MMM YY")}</p> | ||
<p className="label">{`Yield: ${payload[0].value}%`}</p> | ||
<p className="label">{`Epoch: ${payload[0].payload.epoch}`}</p> | ||
</div> | ||
); | ||
} | ||
|
||
return null; | ||
}; | ||
|
||
export const Chart = ({ chartData }: ChartProps) => ( | ||
<div | ||
className="p-8 flex flex-col lg:flex-row h-full justify-around" | ||
role="graphics-document" | ||
> | ||
<ResponsiveContainer width={"100%"} height={400} className=""> | ||
<LineChart | ||
data={chartData} | ||
margin={{ top: 5, right: 40, bottom: 5, left: 20 }} | ||
> | ||
<Line | ||
type="natural" | ||
dataKey="growthSinceFirstEpoch" | ||
// TODO access color through Tailwind helpers | ||
stroke="black" | ||
strokeWidth={2} | ||
/> | ||
<CartesianGrid stroke="#ccc" strokeDasharray="5 5" /> | ||
<XAxis | ||
type="number" | ||
scale="time" | ||
domain={["dataMin", "dataMax"]} | ||
dataKey="timestamp" | ||
angle={0} | ||
minTickGap={16} | ||
tickFormatter={(value: string) => | ||
dayjs.unix(parseInt(value)).format("DD MMM") | ||
} | ||
/> | ||
<YAxis tickFormatter={(value: string) => `${value}%`} /> | ||
<Tooltip content={<CustomTooltip />} /> | ||
<Legend verticalAlign="bottom" formatter={() => "Cumulative Yield"} /> | ||
</LineChart> | ||
</ResponsiveContainer> | ||
</div> | ||
); |
11 changes: 11 additions & 0 deletions
11
packages/front-end/src/components/VaultPerformance/subcomponents/Disclaimer.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { DHV_NAME } from "src/config/constants"; | ||
import { DISCORD_LINK } from "src/config/links"; | ||
|
||
export const Disclaimer = () => ( | ||
<small className="pb-8 px-8 block w-400"> | ||
{`This chart shows the ${DHV_NAME} share price change since the third epoch (Alpha public launch). Data before this is the result of testing and is excluded. If you have any questions, feel free to `} | ||
<a href={DISCORD_LINK} target="_blank" rel="noopener noreferrer"> | ||
{`reach out to us via our Discord.`} | ||
</a> | ||
</small> | ||
); |
3 changes: 3 additions & 0 deletions
3
packages/front-end/src/components/VaultPerformance/subcomponents/Error.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export const Error = () => ( | ||
<p className="p-8 pt-12 text-center">{`Sorry but we're having difficult fetching that data right now. Please try again later.`}</p> | ||
); |
16 changes: 16 additions & 0 deletions
16
packages/front-end/src/components/VaultPerformance/subcomponents/FadeWrapper.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import type { PropsWithChildren } from "react"; | ||
|
||
import { motion } from "framer-motion"; | ||
|
||
const FadeInOut = { | ||
initial: { opacity: 0 }, | ||
animate: { | ||
opacity: 1, | ||
transition: { duration: 0.3, ease: [0.0, 0.0, 0.2, 1] }, | ||
}, | ||
exit: { opacity: 0, transition: { duration: 0.25, ease: [0.4, 0.0, 1, 1] } }, | ||
}; | ||
|
||
export const FadeWrapper = ({ children }: PropsWithChildren<unknown>) => ( | ||
<motion.div {...FadeInOut}>{children}</motion.div> | ||
); |
7 changes: 7 additions & 0 deletions
7
packages/front-end/src/components/VaultPerformance/subcomponents/Loading.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { Loader } from "src/components/Loader"; | ||
|
||
export const Loading = () => ( | ||
<div className="p-8 pt-12"> | ||
<Loader className="mx-auto h-16" /> | ||
</div> | ||
); |
Oops, something went wrong.