Skip to content

Commit

Permalink
Merge pull request #17 from burrowHQ/token-charts
Browse files Browse the repository at this point in the history
update supply & borrow charts
  • Loading branch information
yuhochu authored Oct 25, 2023
2 parents 4560f7a + ef1c382 commit abde1b5
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 48 deletions.
66 changes: 47 additions & 19 deletions hooks/useTokenDetails.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,39 +10,53 @@ export const useTokenDetails = () => {
const [borrowAnimating, setBorrowAnimating] = useState(false);
const [supplyAnimating, setSupplyAnimating] = useState(false);

const changePeriodDisplay = async (tokenId, borrowPeriod, supplyPeriod) => {
const newBorrowPeriod = borrowPeriod && borrowPeriod?.length > tokenDetailDays?.length;
const newSupplyPeriod = supplyPeriod && supplyPeriod?.length > tokenDetailDays?.length;
if (!tokenDetailDays?.length || newBorrowPeriod || newSupplyPeriod) {
await fetchTokenDetails(tokenId, borrowPeriod || supplyPeriod);
} else {
if (borrowPeriod && borrowPeriod !== tokenBorrowDays?.length) {
const changePeriodDisplay = async ({ tokenId, borrowPeriod, supplyPeriod }) => {
try {
const isBorrowPeriodChange =
borrowPeriod === 0 || (borrowPeriod && borrowPeriod !== tokenBorrowDays?.length);
const isSupplyPeriodChange =
supplyPeriod === 0 || (supplyPeriod && supplyPeriod !== tokenSupplyDays?.length);
let docs = tokenDetailDays;

if (isBorrowPeriodChange) {
setBorrowAnimating(true);
const displayDetails = tokenDetailDays.slice(
tokenDetailDays.length - borrowPeriod,
tokenDetailDays.length,
);
}
if (isSupplyPeriodChange) {
setSupplyAnimating(true);
}

if (!tokenDetailDays?.length || borrowPeriod === 0 || supplyPeriod === 0) {
const { all } = await fetchTokenDetails(tokenId, borrowPeriod ?? supplyPeriod, true);
docs = all;
}

if (isBorrowPeriodChange) {
const displayDetails =
borrowPeriod === 0 ? docs : docs.slice(docs.length - borrowPeriod, docs.length);
setTokenBorrowDays(displayDetails);
setTimeout(() => {
setBorrowAnimating(false);
}, 1500);
}

if (supplyPeriod && supplyPeriod !== tokenSupplyDays?.length) {
setSupplyAnimating(true);
const displayDetails = tokenDetailDays.slice(
tokenDetailDays.length - supplyPeriod,
tokenDetailDays.length,
);
if (isSupplyPeriodChange) {
const displayDetails =
supplyPeriod === 0 ? docs : docs.slice(docs.length - supplyPeriod, docs.length);
setTokenSupplyDays(displayDetails);
setTimeout(() => {
setSupplyAnimating(false);
}, 1500);
}
} catch (e) {
console.error(e);
}
};

const fetchTokenDetails = async (tokenId, period = 365) => {
const fetchTokenDetails = async (tokenId, period, isFetchOnly?: boolean) => {
if (period === undefined || period === null) {
period = 365;
}

try {
const [tokenDetailsRes, interestRateRes] = await Promise.allSettled([
Datasource.shared.getTokenDetails(tokenId, period),
Expand All @@ -57,6 +71,7 @@ export const useTokenDetails = () => {
if (interestRateRes.status !== "rejected") {
interestRate = interestRateRes?.value;
}

const lastTokenDetails = tokenDetails[tokenDetails.length - 1];
const borrows: any[] = [];
const supplies: any[] = [];
Expand All @@ -65,7 +80,7 @@ export const useTokenDetails = () => {
const supplyApyWithNet = Number(d.token_supply_apr) + Number(d.net_liquidity_apr || 0);
d.tokenSupplyApy = Number((supplyApyWithNet * 100).toFixed(2));
d.tokenBorrowApy = Number((d.token_borrow_apr * 100).toFixed(2));
d.dayDate = date.toFormat("dd MMM");
d.dayDate = date.toFormat("dd MMM yyyy");
borrows.push({
tokenBorrowApy: d.tokenBorrowApy,
dayDate: d.dayDate,
Expand Down Expand Up @@ -103,12 +118,25 @@ export const useTokenDetails = () => {
supplyRate2,
};
});

const returnObj = {
borrows,
supplies,
interestRates: interestRatesCal,
all: result,
};
if (isFetchOnly) {
return returnObj;
}

setInterestRates(interestRatesCal);
setTokenDetailDays(result);
setTokenBorrowDays(borrows);
setTokenSupplyDays(supplies);
return returnObj;
} catch (e) {
console.error("fetchTokenDetailsErr", e);
throw e;
}
};

Expand Down
20 changes: 9 additions & 11 deletions screens/TokenDetail/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ import { APYCell } from "../Market/APYCell";
import { RewardsV2 } from "../../components/Rewards";
import getConfig from "../../utils/config";
import InterestRateChart, { LabelText } from "./interestRateChart";
import Datasource from "../../data/datasource";
import TokenSuppliesChart from "./tokenSuppliesChart";
import TokenBorrowSuppliesChart from "./tokenBorrowSuppliesChart";
import { useTokenDetails } from "../../hooks/useTokenDetails";

const DetailData = createContext(null) as any;
Expand Down Expand Up @@ -96,8 +95,9 @@ function TokenDetailView({ tokenRow }: { tokenRow: UIAsset }) {
const borrowed = borrowedRows?.find((row) => {
return row.tokenId === tokenRow.tokenId;
});

useEffect(() => {
fetchTokenDetails(tokenRow.tokenId).catch();
fetchTokenDetails(tokenRow.tokenId, 365).catch();
get_token_detail(tokenRow.tokenId).then((response) => {
const { total_suppliers, total_borrowers } = response[0] || {};
if (!isInvalid(total_suppliers)) {
Expand All @@ -109,9 +109,9 @@ function TokenDetailView({ tokenRow }: { tokenRow: UIAsset }) {
});
}, []);

const handlePeriodClick = async (borrowPeriod, supplyPeriod) => {
const handlePeriodClick = async ({ borrowPeriod, supplyPeriod }) => {
try {
await changePeriodDisplay(tokenRow.tokenId, borrowPeriod, supplyPeriod);
await changePeriodDisplay({ tokenId: tokenRow.tokenId, borrowPeriod, supplyPeriod });
} catch (e) {
console.error("err", e);
}
Expand Down Expand Up @@ -548,13 +548,12 @@ function TokenSupplyChart({ tokenDetails, handlePeriodClick }) {
</div>
<HrLine />
<div className="mt-8 xsm:-ml-5">
<TokenSuppliesChart
defaultPeriod={tokenSupplyDays?.length}
<TokenBorrowSuppliesChart
data={tokenSupplyDays}
xKey="dayDate"
yKey="tokenSupplyApy"
disableControl={supplyAnimating}
onPeriodClick={(v) => handlePeriodClick(null, v)}
onPeriodClick={(v) => handlePeriodClick({ supplyPeriod: v })}
/>
{/* <span className="text-sm text-gray-300 text-opacity-50">Chart is coming soon</span> */}
</div>
Expand Down Expand Up @@ -598,14 +597,13 @@ function TokenBorrowChart({ tokenDetails, handlePeriodClick }) {
</div>
<HrLine />
<div className="mt-8 xsm:-ml-5">
<TokenSuppliesChart
<TokenBorrowSuppliesChart
disableControl={borrowAnimating}
defaultPeriod={tokenBorrowDays?.length}
data={tokenBorrowDays}
xKey="dayDate"
yKey="tokenBorrowApy"
isBorrow
onPeriodClick={(v) => handlePeriodClick(v)}
onPeriodClick={(v) => handlePeriodClick({ borrowPeriod: v })}
/>
</div>
</div>
Expand Down
44 changes: 35 additions & 9 deletions screens/TokenDetail/interestRateChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,20 +80,37 @@ const InterestRateChart = ({ data }) => {
/>
)}

<Line type="monotone" dataKey="borrowRate" stroke="#FF6BA9" dot={<CustomizedDot />} />
<Line type="monotone" dataKey="supplyRate" stroke="#D2FF3A" dot={<CustomizedDot />} />
<Line
type="monotone"
dataKey="borrowRate"
stroke="#FF6BA9"
dot={<CustomizedDot />}
activeDot={<ActiveDot />}
/>
<Line
type="monotone"
dataKey="supplyRate"
stroke="#D2FF3A"
dot={<CustomizedDot />}
activeDot={<ActiveDot />}
/>
</LineChart>
</ResponsiveContainer>
);
};

const ActiveDot = (props) => {
const { cx, cy, stroke, fill, payload, value } = props;
return <circle cx={cx} cy={cy} r={4} stroke={fill} fill={fill} />;
};

const CustomizedDot = (props) => {
const { cx, cy, stroke, payload, value } = props;
const { percent } = payload || {};

if (percent === 100) {
return <circle cx={cx} cy={cy} r={4} stroke={stroke} fill={stroke} />;
}
// if (percent === 100) {
// return <circle cx={cx} cy={cy} r={4} stroke={stroke} fill={stroke} />;
// }

return null;
};
Expand All @@ -108,15 +125,24 @@ const CustomTooltip = ({ active, payload, defaultPayload }: any) => {
return (
<div className="px-3 py-2 rounded-md min-w-max" style={{ backgroundColor: "#32344B" }}>
<LabelText left="Utilization Rate" right={`${percent?.toFixed(2)}%`} />
<LabelText left="Borrow Rate" right={`${borrowRate?.toFixed(2)}%`} />
<LabelText left="Supply Rate" right={`${supplyRate?.toFixed(2)}%`} className="mb-0" />
<LabelText
left="Borrow Rate"
right={`${borrowRate?.toFixed(2)}%`}
style={{ color: "#FF6BA9" }}
/>
<LabelText
left="Supply Rate"
right={`${supplyRate?.toFixed(2)}%`}
style={{ color: "#D2FF3A" }}
className="mb-0"
/>
</div>
);
};

export const LabelText = ({ left, right, className = "" }) => {
export const LabelText = ({ left, right, style, className = "" }: any) => {
return (
<div className={`text-white text-sm mb-1 flex justify-between ${className}`}>
<div className={`text-white text-sm mb-1 flex justify-between ${className}`} style={style}>
<div className="mr-1 text-gray-300">{left}</div>
<div>{right}</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ type chartProps = {
isBorrow?: boolean;
onPeriodClick?: (number) => any;
disableControl?: boolean;
defaultPeriod: number;
defaultPeriod?: number;
};

const TokenSuppliesChart = ({
const TokenBorrowSuppliesChart = ({
data,
xKey,
yKey,
Expand All @@ -30,11 +30,15 @@ const TokenSuppliesChart = ({
disableControl,
defaultPeriod,
}: chartProps) => {
const [period, setPeriod] = useState(30);
const [period, setPeriod] = useState(365);
const [init, setInit] = useState(false);
const isMobile = isMobileDevice();

useEffect(() => {
setPeriod(defaultPeriod);
if (!init && defaultPeriod) {
setPeriod(defaultPeriod);
setInit(true);
}
}, [defaultPeriod]);

const handlePeriodClick = (n: number) => {
Expand All @@ -60,8 +64,8 @@ const TokenSuppliesChart = ({
disable={disableControl}
/>
<TabItem
onClick={() => handlePeriodClick(9999)}
active={period === 9999}
onClick={() => handlePeriodClick(0)}
active={period === 0}
label="ALL"
disable={disableControl}
/>
Expand Down Expand Up @@ -101,7 +105,7 @@ const TokenSuppliesChart = ({
fill: "#00c6a2",
strokeDasharray: "2, 2",
}}
content={<CustomTooltip />}
content={<CustomTooltip isBorrow={isBorrow} />}
/>

<defs>
Expand Down Expand Up @@ -142,7 +146,7 @@ const TabItem = ({ onClick, active, label, disable }) => {
<div
onClick={handleClick}
className={twMerge(
"px-2 rounded-md cursor-pointer",
"px-2 rounded-md cursor-pointer select-none",
active && "active bg-dark-900",
disable && "disable text-dark-800",
)}
Expand Down Expand Up @@ -192,4 +196,4 @@ const CustomTooltip = ({ active, payload, label }: any) => {
);
};

export default TokenSuppliesChart;
export default TokenBorrowSuppliesChart;

0 comments on commit abde1b5

Please sign in to comment.