Skip to content

Commit

Permalink
Vault performance chart adjustments and readme.
Browse files Browse the repository at this point in the history
  • Loading branch information
MeanBoyCousin committed Jan 6, 2023
1 parent 3c6c405 commit 7285fec
Show file tree
Hide file tree
Showing 13 changed files with 242 additions and 249 deletions.
144 changes: 0 additions & 144 deletions packages/front-end/src/components/VaultChart.tsx

This file was deleted.

11 changes: 0 additions & 11 deletions packages/front-end/src/components/VaultPerformance.tsx

This file was deleted.

5 changes: 5 additions & 0 deletions packages/front-end/src/components/VaultPerformance/README.md
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.
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>
);
};
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[];
}
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>
);
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>
);
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>
);
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>
);
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>
);
Loading

0 comments on commit 7285fec

Please sign in to comment.