From 0eed83d2c17f3735d46c338b9f74b63bc1994a84 Mon Sep 17 00:00:00 2001 From: firerum Date: Wed, 18 Sep 2024 22:23:52 +0100 Subject: [PATCH 1/4] switched to pie chart for better staked to earn tvl insights --- components/leaderboards/lands-tvl-chart.tsx | 136 ++++++++++---------- pages/leaderboard.tsx | 2 +- yarn.lock | 29 ++++- 3 files changed, 94 insertions(+), 73 deletions(-) diff --git a/components/leaderboards/lands-tvl-chart.tsx b/components/leaderboards/lands-tvl-chart.tsx index 7e944af7..4ac5ddc5 100644 --- a/components/leaderboards/lands-tvl-chart.tsx +++ b/components/leaderboards/lands-tvl-chart.tsx @@ -1,83 +1,79 @@ -import { TrendingUp } from "lucide-react" -import { Bar, BarChart, CartesianGrid, LabelList, XAxis, YAxis } from "recharts" import { - Card, - CardContent, - CardDescription, - CardFooter, - CardHeader, - CardTitle, -} from "@components/ui/card" -import { - ChartConfig, - ChartContainer, - ChartTooltip, - ChartTooltipContent, -} from "@components/ui/chart" -import numeral from "numeral" + PieChart, + Pie, + Cell, + Tooltip, + Legend, + ResponsiveContainer, +} from "recharts"; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@components/ui/card"; +import numeral from "numeral"; + +// I used a predefined color palette for each token to ensure uniqueness +// i might need to work on more dynamic one later, but it seems to be failing right now +const COLORS = [ + "#0088FE", "#00C49F", "#FFBB28", "#FF8042", "#FF6547", + "#8884D8", "#1D8BF1", "#FF4545", "#FFA500", "#00C49A" +]; -export function LandsTVLChart({ chartData, chartConfig }: { chartData: any[], chartConfig: ChartConfig }) { +export function LandsTVLChart({ chartData }: { chartData: any[] }) { return ( Stake-to-Earn TVL - Value in USD of all tokens staked on Charisma + + Distribution of Total Value Locked (TVL) across staked tokens on Charisma + - - - - - - - - } - - /> - - - + + + numeral(value).format('$0,0.00')} + nameKey="id" + > + {chartData.map((entry, index) => ( + + ))} + + + numeral(value).format("$0,0.00") + } + contentStyle={{ + backgroundColor: "#170202", + borderColor: "#ccc", + borderRadius: "5px", + padding: "5px", + }} + itemStyle={{ color: "#fff" }} /> - - - + + + + {/*
diff --git a/pages/leaderboard.tsx b/pages/leaderboard.tsx index ac7adbab..ed28893f 100644 --- a/pages/leaderboard.tsx +++ b/pages/leaderboard.tsx @@ -148,7 +148,7 @@ export default function LeaderboardPage({ wchaPriceData, holders, expTotalSupply - + diff --git a/yarn.lock b/yarn.lock index 6d4d1772..24540f88 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9419,6 +9419,15 @@ string-width@^3.0.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^5.1.0" +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + string-width@^5.0.1, string-width@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" @@ -9482,7 +9491,7 @@ stringify-entities@^4.0.0: character-entities-html4 "^2.0.0" character-entities-legacy "^3.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -9496,6 +9505,13 @@ strip-ansi@^5.1.0: dependencies: ansi-regex "^4.1.0" +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + strip-ansi@^7.0.1: version "7.1.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" @@ -10681,7 +10697,16 @@ word-wrapper@^1.0.7: resolved "https://registry.yarnpkg.com/word-wrapper/-/word-wrapper-1.0.7.tgz#1f14afebf66dfdf0fef55efd37184efbd08c28b6" integrity sha512-VOPBFCm9b6FyYKQYfn9AVn2dQvdR/YOVFV6IBRA1TBMJWKffvhEX1af6FMGrttILs2Q9ikCRhLqkbY2weW6dOQ== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== From 29983036b61158b1e022ce322088859f34e47da8 Mon Sep 17 00:00:00 2001 From: Ross Ragsdale Date: Thu, 19 Sep 2024 15:18:20 -0500 Subject: [PATCH 2/4] :wrench: Update cron --- pages/api/v0/crons/stimulate.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pages/api/v0/crons/stimulate.ts b/pages/api/v0/crons/stimulate.ts index 373ca1a4..3f1d50e8 100644 --- a/pages/api/v0/crons/stimulate.ts +++ b/pages/api/v0/crons/stimulate.ts @@ -27,9 +27,10 @@ export default async function stimulateSwapAPI( contractAddress: 'SP1Y5YSTAHZ88XYK1VPDH24GY0HPX5J4JECTMY4A1.univ2-path2', functionName: 'do-swap', args: [ - uintCV(6000000), + uintCV(30000000), principalCV('SP1Y5YSTAHZ88XYK1VPDH24GY0HPX5J4JECTMY4A1.wstx'), - principalCV('SP2ZNGJ85ENDY6QRHQ5P2D4FXKGZWCKTB2T0Z55KS.liquid-staked-charisma'), + // principalCV('SP2ZNGJ85ENDY6QRHQ5P2D4FXKGZWCKTB2T0Z55KS.liquid-staked-charisma'), + principalCV('SP3NE50GEXFG9SZGTT51P40X2CKYSZ5CC4ZTZ7A2G.welshcorgicoin-token'), principalCV('SP1Y5YSTAHZ88XYK1VPDH24GY0HPX5J4JECTMY4A1.univ2-share-fee-to'), ], fee: 10000 From d073c0dd8e55e7700bdc8451236840800d1139ec Mon Sep 17 00:00:00 2001 From: Ross Ragsdale Date: Thu, 19 Sep 2024 15:20:07 -0500 Subject: [PATCH 3/4] :wrench: Update cron --- pages/api/v0/crons/stimulate.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/api/v0/crons/stimulate.ts b/pages/api/v0/crons/stimulate.ts index 3f1d50e8..093a74e0 100644 --- a/pages/api/v0/crons/stimulate.ts +++ b/pages/api/v0/crons/stimulate.ts @@ -27,7 +27,7 @@ export default async function stimulateSwapAPI( contractAddress: 'SP1Y5YSTAHZ88XYK1VPDH24GY0HPX5J4JECTMY4A1.univ2-path2', functionName: 'do-swap', args: [ - uintCV(30000000), + uintCV(20000000), principalCV('SP1Y5YSTAHZ88XYK1VPDH24GY0HPX5J4JECTMY4A1.wstx'), // principalCV('SP2ZNGJ85ENDY6QRHQ5P2D4FXKGZWCKTB2T0Z55KS.liquid-staked-charisma'), principalCV('SP3NE50GEXFG9SZGTT51P40X2CKYSZ5CC4ZTZ7A2G.welshcorgicoin-token'), From 6f6e11836ad6d5ab6a14f286a8504d193bc9584b Mon Sep 17 00:00:00 2001 From: firerum Date: Thu, 19 Sep 2024 22:07:42 +0100 Subject: [PATCH 4/4] switched to pie chart for better staked to earn tvl insights with better percentage info --- components/leaderboards/lands-tvl-chart.tsx | 241 +++++++++++++------- next-env.d.ts | 2 +- 2 files changed, 158 insertions(+), 85 deletions(-) diff --git a/components/leaderboards/lands-tvl-chart.tsx b/components/leaderboards/lands-tvl-chart.tsx index 4ac5ddc5..2ab28094 100644 --- a/components/leaderboards/lands-tvl-chart.tsx +++ b/components/leaderboards/lands-tvl-chart.tsx @@ -1,88 +1,161 @@ +import React, { useState, useEffect } from 'react'; import { - PieChart, - Pie, - Cell, - Tooltip, - Legend, - ResponsiveContainer, -} from "recharts"; -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@components/ui/card"; -import numeral from "numeral"; + PieChart, + Pie, + Cell, + Tooltip, + ResponsiveContainer, +} from 'recharts'; +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, +} from '@components/ui/card'; +import numeral from 'numeral'; + +// I switched to dynamic colors incase the number of tokens increases +const generateColors = (numColors: number): string[] => { + const colors: string[] = []; + const saturation = 70; + const lightness = 50; + for (let i = 0; i < numColors; i++) { + const hue = Math.round((360 / numColors) * i); + colors.push(`hsl(${hue}, ${saturation}%, ${lightness}%)`); + } + return colors; +}; + +interface ChartData { + id: string; + score: number; +} + +interface Props { + chartData: ChartData[]; +} + +// Custom hook to get the window width +// the legend was overlapping the piechart on mobile devices so i decided to use the function below +function useWindowWidth() { + const [width, setWidth] = useState(undefined); + + useEffect(() => { + if (typeof window !== 'undefined') { + const handleResize = () => { + setWidth(window.innerWidth); + }; + window.addEventListener('resize', handleResize); + // Set initial width + handleResize(); + return () => window.removeEventListener('resize', handleResize); + } + }, []); + + return width; +} + +export function LandsTVLChart({ chartData }: Props) { + const width = useWindowWidth(); + const isMobile = width !== undefined && width < 600; + + // calculate total TVL and percentage share for each token + const totalTVL = chartData.reduce((sum, entry) => sum + entry.score, 0); + const dataWithPercentages = chartData.map((entry) => ({ + ...entry, + percentage: ((entry.score / totalTVL) * 100).toFixed(2), + })); -// I used a predefined color palette for each token to ensure uniqueness -// i might need to work on more dynamic one later, but it seems to be failing right now -const COLORS = [ - "#0088FE", "#00C49F", "#FFBB28", "#FF8042", "#FF6547", - "#8884D8", "#1D8BF1", "#FF4545", "#FFA500", "#00C49A" -]; + const COLORS = generateColors(chartData.length); -export function LandsTVLChart({ chartData }: { chartData: any[] }) { - return ( - - - Stake-to-Earn TVL - - Distribution of Total Value Locked (TVL) across staked tokens on Charisma - - - -
- - - - {chartData.map((entry, index) => ( - - ))} - - - numeral(value).format("$0,0.00") - } - contentStyle={{ - backgroundColor: "#170202", - borderColor: "#ccc", - borderRadius: "5px", - padding: "5px", - }} - itemStyle={{ color: "#fff" }} - /> - - - -
-
- {/* -
- Trending up by 5.2% this month -
-
- Showing total tokens for the last 6 months -
-
*/} -
- ) + return ( + + + Stake-to-Earn TVL + + Distribution of Total Value Locked (TVL) across staked tokens on Charisma + + + +
+ + + + {dataWithPercentages.map((entry, index) => ( + + ))} + + [ + numeral(value).format('$0,0.00'), + `${props.payload.id}`, + ]} + contentStyle={{ + backgroundColor: '#170202', + borderColor: '#ccc', + borderRadius: '5px', + padding: '5px', + }} + itemStyle={{ color: '#fff' }} + /> + + + {/* Custom Legend */} +
+ {dataWithPercentages.map((item, index) => ( +
+
+ {`${item.id}: ${item.percentage}%`} +
+ ))} +
+
+
+
+ ); } diff --git a/next-env.d.ts b/next-env.d.ts index 4f11a03d..a4a7b3f5 100644 --- a/next-env.d.ts +++ b/next-env.d.ts @@ -2,4 +2,4 @@ /// // NOTE: This file should not be edited -// see https://nextjs.org/docs/basic-features/typescript for more information. +// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information.