From afa95a42276dda1ca2f97e6b805a1d9e697bd2b2 Mon Sep 17 00:00:00 2001 From: mokelgit Date: Thu, 31 Aug 2023 15:36:32 -0400 Subject: [PATCH 01/33] somewhat fixed max on overview page and resized chart watermark --- components/charts/chart.tsx | 16 +++++-- components/layout/OverviewMetrics.tsx | 65 +++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 4 deletions(-) diff --git a/components/charts/chart.tsx b/components/charts/chart.tsx index 6f8aa8cf..738d2b39 100644 --- a/components/charts/chart.tsx +++ b/components/charts/chart.tsx @@ -34,6 +34,7 @@ export const Chart = ({ chartHeight, chartWidth, decimals = 2, + maxY, }: { // data: { [chain: string]: number[][] }; chartType: "area" | "line"; @@ -51,6 +52,7 @@ export const Chart = ({ chartHeight: string; chartWidth: string; decimals?: number; + maxY?: number; }) => { const chartComponent = useRef(null); const [highchartsLoaded, setHighchartsLoaded] = useState(false); @@ -281,11 +283,11 @@ export const Chart = ({ }); chartComponent.current?.redraw(); } - }, [chartType, series, theme, types]); + }, [chartType, series, theme, types, maxY]); useEffect(() => { drawChartSeries(); - }, [drawChartSeries, series, types]); + }, [drawChartSeries, series, types, maxY]); const resetXAxisExtremes = useCallback(() => { if (chartComponent.current) { @@ -420,7 +422,7 @@ export const Chart = ({ ...baseOptions.yAxis, type: yScale, min: yScale === "percentage" ? 0 : undefined, - max: yScale === "percentage" ? undefined : undefined, + max: yScale === "percentage" ? maxY : maxY, gridLineColor: theme === "dark" ? "rgba(215, 223, 222, 0.11)" @@ -469,7 +471,13 @@ export const Chart = ({ />
- + 200 + ? "w-[128px] md:w-[163px]" + : "w-[128.67px] md:w-[193px] " + }`} + />
{series.length === 0 && ( diff --git a/components/layout/OverviewMetrics.tsx b/components/layout/OverviewMetrics.tsx index 2efba1cc..9a54da8f 100644 --- a/components/layout/OverviewMetrics.tsx +++ b/components/layout/OverviewMetrics.tsx @@ -454,6 +454,10 @@ export default function OverviewMetrics({ useEffect(() => { if (selectedMode.includes("gas_fees_share")) { setSelectedMode(showUsd ? "gas_fees_share_usd" : "gas_fees_share_eth"); + } else { + setSelectedMode( + showUsd ? "gas_fees_usd_absolute" : "gas_fees_eth_absolute", + ); } }, [selectedMode, showUsd]); @@ -822,6 +826,66 @@ export default function OverviewMetrics({ ], ); + const chartMax = useMemo(() => { + let returnValue = 0; + let typeIndex = data["all_l2s"].daily["types"].indexOf(selectedMode); + + if (selectedChain) { + for ( + let i = 0; + i < + (selectedTimespan === "max" + ? data[selectedChain].daily[selectedCategory].data.length + : timespans[selectedTimespan].value); + i++ + ) { + if ( + data[selectedChain].daily[selectedCategory].data.length - (i + 1) >= + 0 + ) { + if ( + data[selectedChain].daily[selectedCategory].data[ + data[selectedChain].daily[selectedCategory].data.length - (i + 1) + ][typeIndex] > returnValue + ) { + returnValue = + data[selectedChain].daily[selectedCategory].data[ + data[selectedChain].daily[selectedCategory].data.length - + (i + 1) + ][typeIndex]; + } + } + } + } else { + for ( + let i = 0; + i < + (selectedTimespan === "max" + ? data["all_l2s"].daily[selectedCategory].data.length + : timespans[selectedTimespan].value); + i++ + ) { + if ( + data["all_l2s"].daily[selectedCategory].data.length - (i + 1) >= + 0 + ) { + if ( + data["all_l2s"].daily[selectedCategory].data[ + data["all_l2s"].daily[selectedCategory].data.length - (i + 1) + ][typeIndex] > returnValue + ) { + returnValue = + data["all_l2s"].daily[selectedCategory].data[ + data["all_l2s"].daily[selectedCategory].data.length - (i + 1) + ][typeIndex]; + } + } + } + } + return returnValue; + }, [selectedTimespan, selectedCategory, selectedMode, selectedChain]); + + console.log(chartMax); function formatNumber(number: number): string { if (number === 0) { return "0"; @@ -1374,6 +1438,7 @@ export default function OverviewMetrics({ yScale={selectedValue === "share" ? "percentage" : "linear"} chartHeight="196px" chartWidth="100%" + maxY={chartMax} /> From 9ba40f1416f39647a146a3712c93c8b117b25f48 Mon Sep 17 00:00:00 2001 From: mokelgit Date: Thu, 31 Aug 2023 15:42:01 -0400 Subject: [PATCH 02/33] Enabled blockspace on dev --- components/layout/SidebarMenuGroup.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/layout/SidebarMenuGroup.tsx b/components/layout/SidebarMenuGroup.tsx index 23ee1521..cfce59e7 100644 --- a/components/layout/SidebarMenuGroup.tsx +++ b/components/layout/SidebarMenuGroup.tsx @@ -73,7 +73,7 @@ export default function SidebarMenuGroup({ }; // disable Blockspace menu item in production - if (item.name === "Blockspace" && IS_PREVIEW) + if (item.name === "") return (
From 3cd503bf156d427424834fbb858ff31e63cd27da Mon Sep 17 00:00:00 2001 From: mokelgit Date: Sun, 3 Sep 2023 12:22:41 -0400 Subject: [PATCH 03/33] Built components for average tracker on chart --- components/charts/chart.tsx | 74 ++++++++++++++++++- components/layout/OverviewMetrics.tsx | 102 ++++++++++++++++++++++---- 2 files changed, 159 insertions(+), 17 deletions(-) diff --git a/components/charts/chart.tsx b/components/charts/chart.tsx index 738d2b39..9064457a 100644 --- a/components/charts/chart.tsx +++ b/components/charts/chart.tsx @@ -35,6 +35,7 @@ export const Chart = ({ chartWidth, decimals = 2, maxY, + chartAvg, }: { // data: { [chain: string]: number[][] }; chartType: "area" | "line"; @@ -53,6 +54,7 @@ export const Chart = ({ chartWidth: string; decimals?: number; maxY?: number; + chartAvg?: number; }) => { const chartComponent = useRef(null); const [highchartsLoaded, setHighchartsLoaded] = useState(false); @@ -335,6 +337,61 @@ export const Chart = ({ }; }, [chartComponent, timespan, timespans, resituateChart]); + const chartColor = + AllChainsByKeys[series[0].name]?.colors[theme ?? "dark"][0]; + + function useYAxisTicks(maxY, yScale) { + const [yAxisTicks, setYAxisTicks] = useState({ + interval: 0.05, // Default interval for percentages + numIntervals: 1, + }); + + useEffect(() => { + // Determine the tick interval based on maxY + let selectedInterval; + let numIntervals; + + if (yScale === "percentage") { + // For percentages, use a default interval of 0.05 + selectedInterval = 0.05; + numIntervals = maxY / selectedInterval; + } else { + // For other scales, calculate the interval based on maxY + const tickIntervals = [25, 20, 15, 10, 5, 2, 1, 0.5, 0.1, 0.05]; + + for (const interval of tickIntervals) { + if (maxY >= interval) { + selectedInterval = interval; + numIntervals = maxY / interval; + break; + } + } + + if (!selectedInterval) { + // If no suitable interval is found, use a default interval + selectedInterval = 1; + numIntervals = maxY / selectedInterval; + } + } + + // Round up maxY to ensure it's not smaller than the calculated maxY + maxY = Math.ceil(maxY / selectedInterval) * selectedInterval; + + // Set a maximum of 4 intervals + if (numIntervals > 3) { + numIntervals = 3; + selectedInterval = maxY / numIntervals; + } + + // Set the yAxisTicks state + setYAxisTicks({ interval: selectedInterval, numIntervals }); + }, [maxY, yScale]); + + return yAxisTicks; + } + + const yAxisTicks = useYAxisTicks(maxY, yScale); + return ( <> { @@ -422,11 +479,26 @@ export const Chart = ({ ...baseOptions.yAxis, type: yScale, min: yScale === "percentage" ? 0 : undefined, - max: yScale === "percentage" ? maxY : maxY, + max: maxY ? maxY : undefined, + tickPositions: maxY + ? Array.from( + { length: yAxisTicks.numIntervals + 1 }, + (_, i) => i * yAxisTicks.interval, + ) + : undefined, + tickInterval: maxY ? yAxisTicks.interval : undefined, gridLineColor: theme === "dark" ? "rgba(215, 223, 222, 0.11)" : "rgba(41, 51, 50, 0.11)", + plotLines: [ + { + color: chartColor ? chartColor : null, + width: 1, + value: chartAvg ? chartAvg : null, + dashStyle: "Dash", + }, + ], labels: { ...baseOptions.yAxis.labels, formatter: function ( diff --git a/components/layout/OverviewMetrics.tsx b/components/layout/OverviewMetrics.tsx index 9a54da8f..2ece650c 100644 --- a/components/layout/OverviewMetrics.tsx +++ b/components/layout/OverviewMetrics.tsx @@ -882,10 +882,76 @@ export default function OverviewMetrics({ } } } + + let roundingFactor = selectedMode.includes("share") ? 0.05 : 1000; // 0.05 for percentages, 1000 for absolute values + returnValue = returnValue / roundingFactor; + returnValue = Math.ceil(returnValue) * roundingFactor; + + if (!selectedMode.includes("share")) { + returnValue = Math.ceil(returnValue / 10000) * 10000; + } + return returnValue; }, [selectedTimespan, selectedCategory, selectedMode, selectedChain]); - console.log(chartMax); + const chartAvg = useMemo(() => { + let typeIndex = data["all_l2s"].daily["types"].indexOf(selectedMode); + let returnValue = 0; + if (selectedChain) { + let sum = 0; + for ( + let i = 0; + i < + (selectedTimespan === "max" + ? data[selectedChain].daily[selectedCategory].data.length + : timespans[selectedTimespan].value); + i++ + ) { + if ( + data[selectedChain].daily[selectedCategory].data.length - (i + 1) >= + 0 + ) { + sum += + data[selectedChain].daily[selectedCategory].data[ + data[selectedChain].daily[selectedCategory].data.length - (i + 1) + ][typeIndex]; + } + } + returnValue = + sum / + (selectedTimespan === "max" + ? data[selectedChain].daily[selectedCategory].data.length + : timespans[selectedTimespan].value); + } else { + let sum = 0; + for ( + let i = 0; + i < + (selectedTimespan === "max" + ? data["all_l2s"].daily[selectedCategory].data.length + : timespans[selectedTimespan].value); + i++ + ) { + if ( + data["all_l2s"].daily[selectedCategory].data.length - (i + 1) >= + 0 + ) { + sum += + data["all_l2s"].daily[selectedCategory].data[ + data["all_l2s"].daily[selectedCategory].data.length - (i + 1) + ][typeIndex]; + } + } + returnValue = + sum / + (selectedTimespan === "max" + ? data["all_l2s"].daily[selectedCategory].data.length + : timespans[selectedTimespan].value); + } + + return returnValue; + }, [selectedTimespan, selectedMode, selectedCategory, selectedChain]); + function formatNumber(number: number): string { if (number === 0) { return "0"; @@ -1425,21 +1491,25 @@ export default function OverviewMetrics({ : {categories[selectedCategory]}
- +
+ +
+
From a81d5fe94bf61633a5f75afd8609774e0a30a918 Mon Sep 17 00:00:00 2001 From: mokelgit Date: Sun, 3 Sep 2023 13:25:23 -0400 Subject: [PATCH 04/33] added bar to show values for average --- components/charts/chart.tsx | 32 +++++++++---------------- components/layout/OverviewMetrics.tsx | 34 +++++++++++++++++++++++---- 2 files changed, 41 insertions(+), 25 deletions(-) diff --git a/components/charts/chart.tsx b/components/charts/chart.tsx index 9064457a..f0857313 100644 --- a/components/charts/chart.tsx +++ b/components/charts/chart.tsx @@ -352,30 +352,20 @@ export const Chart = ({ let numIntervals; if (yScale === "percentage") { - // For percentages, use a default interval of 0.05 - selectedInterval = 0.05; - numIntervals = maxY / selectedInterval; + selectedInterval = 0.05; // Default interval for percentages } else { - // For other scales, calculate the interval based on maxY - const tickIntervals = [25, 20, 15, 10, 5, 2, 1, 0.5, 0.1, 0.05]; - - for (const interval of tickIntervals) { - if (maxY >= interval) { - selectedInterval = interval; - numIntervals = maxY / interval; - break; - } - } - - if (!selectedInterval) { - // If no suitable interval is found, use a default interval - selectedInterval = 1; - numIntervals = maxY / selectedInterval; - } + selectedInterval = 1; // Default interval for other scales } - // Round up maxY to ensure it's not smaller than the calculated maxY - maxY = Math.ceil(maxY / selectedInterval) * selectedInterval; + // Calculate the number of intervals based on maxY and the selectedInterval + numIntervals = Math.ceil(maxY / selectedInterval); + + // Adjust the interval and numIntervals if needed + while (selectedInterval * numIntervals > maxY) { + // Reduce the interval until it doesn't exceed maxY + selectedInterval /= 2; + numIntervals = Math.ceil(maxY / selectedInterval); + } // Set a maximum of 4 intervals if (numIntervals > 3) { diff --git a/components/layout/OverviewMetrics.tsx b/components/layout/OverviewMetrics.tsx index 2ece650c..18371c98 100644 --- a/components/layout/OverviewMetrics.tsx +++ b/components/layout/OverviewMetrics.tsx @@ -883,11 +883,11 @@ export default function OverviewMetrics({ } } - let roundingFactor = selectedMode.includes("share") ? 0.05 : 1000; // 0.05 for percentages, 1000 for absolute values + let roundingFactor = selectedMode.includes("share") ? 0.05 : 100; // 0.05 for percentages, 1000 for absolute values returnValue = returnValue / roundingFactor; returnValue = Math.ceil(returnValue) * roundingFactor; - if (!selectedMode.includes("share")) { + if (!selectedMode.includes("share") && returnValue > 10000) { returnValue = Math.ceil(returnValue / 10000) * 10000; } @@ -975,6 +975,7 @@ export default function OverviewMetrics({ return number.toFixed(2); } } + console.log(chartAvg / chartMax); return (
@@ -1491,7 +1492,7 @@ export default function OverviewMetrics({ : {categories[selectedCategory]}
-
+
-
+
+
0.45 + ? chartAvg / chartMax > 0.5 + ? 7 + : 10 + : 14), + backgroundColor: + AllChainsByKeys[selectedChain ? selectedChain : "all_l2s"] + ?.colors[theme ?? "dark"][0], + color: selectedChain + ? selectedChain === "arbitrum" + ? "black" + : "white" + : "black", + }} + > + {selectedMode.includes("share") + ? (chartAvg * 100).toFixed(1) + "%" + : chartAvg.toFixed(1)} +
+
From 9a378a321889b1ec2dbac17e1ffbdb6314327212 Mon Sep 17 00:00:00 2001 From: mokelgit Date: Tue, 5 Sep 2023 12:23:38 -0400 Subject: [PATCH 05/33] Added $ values --- components/layout/OverviewMetrics.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/components/layout/OverviewMetrics.tsx b/components/layout/OverviewMetrics.tsx index 18371c98..716dec77 100644 --- a/components/layout/OverviewMetrics.tsx +++ b/components/layout/OverviewMetrics.tsx @@ -23,6 +23,7 @@ import { LandingURL, MasterURL } from "@/lib/urls"; import useSWR from "swr"; import { MasterResponse } from "@/types/api/MasterResponse"; import { useLocalStorage } from "usehooks-ts"; +import { animated, useSpring } from "@react-spring/web"; const DisabledStates: { [mode: string]: { @@ -883,7 +884,7 @@ export default function OverviewMetrics({ } } - let roundingFactor = selectedMode.includes("share") ? 0.05 : 100; // 0.05 for percentages, 1000 for absolute values + let roundingFactor = selectedMode.includes("share") ? 0.05 : 1; // 0.05 for percentages, 1000 for absolute values returnValue = returnValue / roundingFactor; returnValue = Math.ceil(returnValue) * roundingFactor; @@ -975,7 +976,6 @@ export default function OverviewMetrics({ return number.toFixed(2); } } - console.log(chartAvg / chartMax); return (
@@ -1510,7 +1510,7 @@ export default function OverviewMetrics({ chartAvg={chartAvg} />
-
{selectedMode.includes("share") ? (chartAvg * 100).toFixed(1) + "%" - : chartAvg.toFixed(1)} -
+ : (showUsd ? "$ " : "Ξ ") + formatNumber(chartAvg)} +
From 780d7f703341d3b1d1fda49d875e97679991167b Mon Sep 17 00:00:00 2001 From: mokelgit Date: Tue, 5 Sep 2023 13:37:10 -0400 Subject: [PATCH 06/33] Added animations and fixed 180days value for newer chains --- components/layout/OverviewMetrics.tsx | 31 +++++++++++++++++++-------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/components/layout/OverviewMetrics.tsx b/components/layout/OverviewMetrics.tsx index 716dec77..168e893f 100644 --- a/components/layout/OverviewMetrics.tsx +++ b/components/layout/OverviewMetrics.tsx @@ -922,6 +922,9 @@ export default function OverviewMetrics({ sum / (selectedTimespan === "max" ? data[selectedChain].daily[selectedCategory].data.length + : timespans[selectedTimespan].value >= + data[selectedChain].daily[selectedCategory].data.length + ? data[selectedChain].daily[selectedCategory].data.length : timespans[selectedTimespan].value); } else { let sum = 0; @@ -943,16 +946,32 @@ export default function OverviewMetrics({ ][typeIndex]; } } + returnValue = sum / (selectedTimespan === "max" ? data["all_l2s"].daily[selectedCategory].data.length + : timespans[selectedTimespan].value >= + data["all_l2s"].daily[selectedCategory].data.length + ? data["all_l2s"].daily[selectedCategory].data.length : timespans[selectedTimespan].value); } return returnValue; }, [selectedTimespan, selectedMode, selectedCategory, selectedChain]); + const avgHeight = useSpring({ + y: + -1 * + (163 * (chartAvg / chartMax) + + (chartAvg / chartMax > 0.45 + ? chartAvg / chartMax > 0.5 + ? 7 + : 10 + : 14)), + config: { mass: 1, tension: 70, friction: 20 }, + }); + function formatNumber(number: number): string { if (number === 0) { return "0"; @@ -1509,17 +1528,10 @@ export default function OverviewMetrics({ maxY={chartMax} chartAvg={chartAvg} /> -
+
0.45 - ? chartAvg / chartMax > 0.5 - ? 7 - : 10 - : 14), backgroundColor: AllChainsByKeys[selectedChain ? selectedChain : "all_l2s"] ?.colors[theme ?? "dark"][0], @@ -1528,6 +1540,7 @@ export default function OverviewMetrics({ ? "black" : "white" : "black", + ...avgHeight, }} > {selectedMode.includes("share") From ccc91a5f0033637270525f6883dfdc167d2aaabf Mon Sep 17 00:00:00 2001 From: Manish Gupta Date: Thu, 7 Sep 2023 10:34:20 -0700 Subject: [PATCH 07/33] Fundmentals - added rent_paid and earnings/profit --- components/layout/ComparisonChart.tsx | 62 ++++++++++----------------- lib/navigation.tsx | 26 +++++++++++ lib/urls.ts | 2 + 3 files changed, 51 insertions(+), 39 deletions(-) diff --git a/components/layout/ComparisonChart.tsx b/components/layout/ComparisonChart.tsx index e73b4439..9d44b30a 100644 --- a/components/layout/ComparisonChart.tsx +++ b/components/layout/ComparisonChart.tsx @@ -249,6 +249,26 @@ export default function ComparisonChart({ const isMobile = useMediaQuery("(max-width: 767px)"); + const SourcesDisplay = useMemo(() => { + return sources && sources.length > 0 ? ( + sources + .map((s) => ( + + {s} + + )) + .reduce((prev, curr) => [prev, ", ", curr]) + ) : ( + <>Unavailable + ); + }, [sources]); + const getTickPositions = useCallback( (xMin: any, xMax: any): number[] => { const tickPositions: number[] = []; @@ -1310,19 +1330,7 @@ export default function ComparisonChart({ Data Sources:
- {sources - .map((s) => ( - - {s} - - )) - .reduce((prev, curr) => [prev, ", ", curr])} + {SourcesDisplay}
@@ -1393,19 +1401,7 @@ export default function ComparisonChart({ Data Sources:
- {sources - .map((s) => ( - - {s} - - )) - .reduce((prev, curr) => [prev, ", ", curr])} + {SourcesDisplay}
@@ -1479,19 +1475,7 @@ export default function ComparisonChart({ Data Sources:
- {sources - .map((s) => ( - - {s} - - )) - .reduce((prev, curr) => [prev, ", ", curr])} + {SourcesDisplay}
diff --git a/lib/navigation.tsx b/lib/navigation.tsx index b67e5446..1ad8b90b 100644 --- a/lib/navigation.tsx +++ b/lib/navigation.tsx @@ -126,6 +126,32 @@ export const navigationItems: NavigationItem[] = [ rootKey: "metricsFeesPaidToEthereum", urlKey: "fees-paid-by-users", }, + { + label: "Rent Paid", + page: { + title: "Rent Paid", + description: "The sum of rent that was paid ...", + why: "Rent paid is a critical metric for ...", + icon: "feather:credit-card", + }, + icon: "feather:credit-card", + key: "rent_paid", + rootKey: "metricsRentPaid", + urlKey: "rent-paid", + }, + { + label: "Earnings", + page: { + title: "Earnings", + description: "The sum of earnings that were paid ...", + why: "Earnings is a critical metric for ...", + icon: "feather:credit-card", + }, + icon: "feather:credit-card", + key: "profit", + rootKey: "metricsEarnings", + urlKey: "earnings", + }, { label: "Stablecoin Market Cap", page: { diff --git a/lib/urls.ts b/lib/urls.ts index 8a64d5e5..f2fe1cc6 100644 --- a/lib/urls.ts +++ b/lib/urls.ts @@ -6,6 +6,8 @@ export const MetricsURLs = { "total-value-locked": "https://api.growthepie.xyz/v1/metrics/tvl.json", "transaction-count": "https://api.growthepie.xyz/v1/metrics/txcount.json", "transaction-costs": "https://api.growthepie.xyz/v1/metrics/txcosts.json", + "rent-paid": "https://api.growthepie.xyz/v1/metrics/rent_paid.json", + earnings: "https://api.growthepie.xyz/v1/metrics/profit.json", }; export const ChainURLs = { From 802d99ee8a92836213d8b127577fa656f29d2533 Mon Sep 17 00:00:00 2001 From: Manish Gupta Date: Fri, 8 Sep 2023 11:38:17 -0700 Subject: [PATCH 08/33] nav menu changes for fundamentals and updated tooltips on nav menu --- components/layout/Sidebar.tsx | 10 +- components/layout/SidebarContainer.tsx | 2 +- components/layout/SidebarMenuGroup.tsx | 176 +++++++++++++++++-------- lib/navigation.tsx | 125 +++++++++++------- 4 files changed, 203 insertions(+), 110 deletions(-) diff --git a/components/layout/Sidebar.tsx b/components/layout/Sidebar.tsx index d92e2d7a..e0d0e57b 100644 --- a/components/layout/Sidebar.tsx +++ b/components/layout/Sidebar.tsx @@ -64,7 +64,7 @@ export default function Sidebar({ isMobile = false }: SidebarProps) { -
+
{navigationItems.map((item) => ( -
+
{navigationItems.map((item) => ( +
{isSidebarOpen ? (
diff --git a/components/layout/SidebarMenuGroup.tsx b/components/layout/SidebarMenuGroup.tsx index cfce59e7..c937300b 100644 --- a/components/layout/SidebarMenuGroup.tsx +++ b/components/layout/SidebarMenuGroup.tsx @@ -8,6 +8,7 @@ import { Tooltip, TooltipTrigger, TooltipContent } from "./Tooltip"; import { MasterURL } from "@/lib/urls"; import { NavigationItem } from "@/lib/navigation"; import { IS_PREVIEW } from "@/lib/helpers"; +import { navigationCategories } from "@/lib/navigation"; type SidebarProps = { item: NavigationItem; @@ -157,11 +158,10 @@ export default function SidebarMenuGroup({ return (
-
@@ -169,32 +169,37 @@ export default function SidebarMenuGroup({
- {sidebarOpen ? ( + {/* {sidebarOpen ? (
{item.label}
- ) : ( -
- + ) : ( */} +
+ +
+ {sidebarOpen && ( +
+
+ {item.label} +
)} + {/* )} */}
{!sidebarOpen && ( @@ -205,55 +210,110 @@ export default function SidebarMenuGroup({
- {item.options.map((option) => { + {item.options.map((option, i) => { return ( - - - -
+ {option.category && + Object.keys(navigationCategories).includes(option.category) && + (i === 0 || + (i > 0 && + item.options[i - 1].category != option.category)) && ( +
+
+
+ {navigationCategories[option.category].icon && ( + + )} +
+
+ {sidebarOpen ? ( + navigationCategories[option.category].label + ) : ( +   + )} +
+
+
+ )} + + + - {["Fundamentals", "Chains", "Blockspace"].includes( - item.name, - ) && ( - + {!sidebarOpen && ( +
)} -
-
+ {["Chains", "Blockspace"].includes(item.name) && ( + + )} +
+ {option.category ? ( +
+ {option.label} +
+ ) : ( +
+ {sidebarOpen ? option.label :  } +
+ )} + +
+ {!sidebarOpen && ( + - {sidebarOpen ? option.label :  } -
- - - {!sidebarOpen && ( - - {option.label} - - )} - + {option.label} + + )} + + ); })}
diff --git a/lib/navigation.tsx b/lib/navigation.tsx index 1ad8b90b..6bc52a6b 100644 --- a/lib/navigation.tsx +++ b/lib/navigation.tsx @@ -11,6 +11,7 @@ export type NavigationItem = { icon: string; options: { label: string; + category?: string; page?: { title?: string; description: string; @@ -28,6 +29,29 @@ export type NavigationItem = { href?: string; }; +export const navigationCategories = { + activity: { + label: "Activity", + icon: "feather:clock", + }, + "value-locked": { + label: "Value Locked", + icon: "feather:star", + }, + economics: { + label: "Economics", + icon: "feather:credit-card", + }, + developer: { + label: "Developer", + icon: "feather:code", + }, + convenience: { + label: "Convenience", + icon: "gtp:transaction-costs", + }, +}; + export const navigationItems: NavigationItem[] = [ { name: "Home", @@ -43,22 +67,9 @@ export const navigationItems: NavigationItem[] = [ key: "metrics", icon: "gtp:fundamentals", options: [ - { - label: "Transaction Count", - page: { - title: "Transaction Count", - description: - "The number of daily transactions. We try to only count transactions that are executed by users/smart contracts - no system transactions.", - why: "The number of transactions processed on a blockchain is a reliable metric for measuring its usage. However, it should be noted that this metric alone may not provide sufficient insight into the actual value of the transactions being conducted. For instance, while some chains may have a lower transaction count, the value of these transactions may be significantly higher due to their use in decentralized finance (DeFi) applications. On the other hand, certain chains may have a higher transaction count due to their use in gaming or other applications involving lower value transactions.", - icon: "feather:clock", - }, - icon: "feather:clock", - key: "txcount", - rootKey: "metricsTxCount", - urlKey: "transaction-count", - }, { label: "Daily Active Addresses", + category: "activity", page: { title: "Daily Active Addresses", description: @@ -72,34 +83,37 @@ export const navigationItems: NavigationItem[] = [ urlKey: "daily-active-addresses", }, { - label: "Transaction Costs", + label: "Transaction Count", + category: "activity", page: { - title: "Transaction Costs", - description: "The median amount that is paid per transaction.", - note: ( - <> - 1 Billion Gwei equals 1{" "} - ETH. - - ), - why: "This is the amount that users pay per transaction. On EVM chains, transaction costs depend on the complexity of the transaction (which is measured in gas). A simple transaction, e.g. a native ETH transfer, uses less gas than a more complex transaction, e.g. an ERC20 swap. Hence, we calculated this metric by looking at the median transaction costs. IMX doesn't charge transaction costs.", - icon: "gtp:transaction-costs", - showGwei: true, - reversePerformer: true, + title: "Transaction Count", + description: + "The number of daily transactions. We try to only count transactions that are executed by users/smart contracts - no system transactions.", + why: "The number of transactions processed on a blockchain is a reliable metric for measuring its usage. However, it should be noted that this metric alone may not provide sufficient insight into the actual value of the transactions being conducted. For instance, while some chains may have a lower transaction count, the value of these transactions may be significantly higher due to their use in decentralized finance (DeFi) applications. On the other hand, certain chains may have a higher transaction count due to their use in gaming or other applications involving lower value transactions.", + icon: "feather:clock", }, - icon: "gtp:transaction-costs", - key: "txcosts", - rootKey: "metricsTxCosts", - urlKey: "transaction-costs", + icon: "feather:clock", + key: "txcount", + rootKey: "metricsTxCount", + urlKey: "transaction-count", + }, + { + label: "Stablecoin Market Cap", + category: "value-locked", + page: { + title: "Stablecoin Market Cap", + description: "The sum of stablecoins that are locked on the chain.", + why: "Stablecoin market cap is a crucial metric for evaluating the growth and development of a blockchain's decentralized finance (DeFi) ecosystem.Stables are a popular choice for use in DeFi applications such as lending, borrowing, and trading. The market cap of stablecoins on a particular chain can provide valuable insights into the level of adoption and usage of DeFi applications on the network. A high stablecoin market cap is indicative of a robust and thriving DeFi ecosystem, where users are actively engaged in utilizing the various financial applications available on the chain.", + icon: "feather:dollar-sign", + }, + icon: "feather:dollar-sign", + key: "stables_mcap", + rootKey: "metricsStablesMcap", + urlKey: "stablecoin-market-cap", }, - // // put navigation items that we want to hide in production here - // ...(IS_PREVIEW - // ? [ - - // ] - // : []), { label: "Total Value Locked", + category: "value-locked", page: { title: "Total Value Locked", description: @@ -112,8 +126,16 @@ export const navigationItems: NavigationItem[] = [ rootKey: "metricsTvl", urlKey: "total-value-locked", }, + + // // put navigation items that we want to hide in production here + // ...(IS_PREVIEW + // ? [ + + // ] + // : []), { label: "Fees Paid by Users", + category: "economics", page: { title: "Fees Paid by Users", description: @@ -128,6 +150,7 @@ export const navigationItems: NavigationItem[] = [ }, { label: "Rent Paid", + category: "economics", page: { title: "Rent Paid", description: "The sum of rent that was paid ...", @@ -141,6 +164,7 @@ export const navigationItems: NavigationItem[] = [ }, { label: "Earnings", + category: "economics", page: { title: "Earnings", description: "The sum of earnings that were paid ...", @@ -153,17 +177,26 @@ export const navigationItems: NavigationItem[] = [ urlKey: "earnings", }, { - label: "Stablecoin Market Cap", + label: "Transaction Costs", + category: "convenience", page: { - title: "Stablecoin Market Cap", - description: "The sum of stablecoins that are locked on the chain.", - why: "Stablecoin market cap is a crucial metric for evaluating the growth and development of a blockchain's decentralized finance (DeFi) ecosystem.Stables are a popular choice for use in DeFi applications such as lending, borrowing, and trading. The market cap of stablecoins on a particular chain can provide valuable insights into the level of adoption and usage of DeFi applications on the network. A high stablecoin market cap is indicative of a robust and thriving DeFi ecosystem, where users are actively engaged in utilizing the various financial applications available on the chain.", - icon: "feather:dollar-sign", + title: "Transaction Costs", + description: "The median amount that is paid per transaction.", + note: ( + <> + 1 Billion Gwei equals 1{" "} + ETH. + + ), + why: "This is the amount that users pay per transaction. On EVM chains, transaction costs depend on the complexity of the transaction (which is measured in gas). A simple transaction, e.g. a native ETH transfer, uses less gas than a more complex transaction, e.g. an ERC20 swap. Hence, we calculated this metric by looking at the median transaction costs. IMX doesn't charge transaction costs.", + icon: "gtp:transaction-costs", + showGwei: true, + reversePerformer: true, }, - icon: "feather:dollar-sign", - key: "stables_mcap", - rootKey: "metricsStablesMcap", - urlKey: "stablecoin-market-cap", + icon: "gtp:transaction-costs", + key: "txcosts", + rootKey: "metricsTxCosts", + urlKey: "transaction-costs", }, // { From 5ab8bc8cf0c1fd9821847cf9a8ef76536e4137ca Mon Sep 17 00:00:00 2001 From: Manish Gupta Date: Fri, 8 Sep 2023 12:00:43 -0700 Subject: [PATCH 09/33] fix ts error --- components/layout/SidebarMenuGroup.tsx | 19 ++++++++++--------- components/layout/Tooltip.tsx | 8 ++++---- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/components/layout/SidebarMenuGroup.tsx b/components/layout/SidebarMenuGroup.tsx index c937300b..5b061bb0 100644 --- a/components/layout/SidebarMenuGroup.tsx +++ b/components/layout/SidebarMenuGroup.tsx @@ -77,7 +77,7 @@ export default function SidebarMenuGroup({ if (item.name === "") return (
- +
@@ -109,15 +109,17 @@ export default function SidebarMenuGroup({
); + console.log(item.name); + if ( ["API Documentation", "Wiki", "Contributors", "Home", "Blog"].includes( item.name, ) ) return ( -
+
{/* open in new tab */} - + - +
+
{item.options.map((option, i) => { return ( - <> +
{option.category && Object.keys(navigationCategories).includes(option.category) && (i === 0 || @@ -249,7 +251,6 @@ export default function SidebarMenuGroup({
)} {!sidebarOpen && ( -
+
)}
)} - +
); })}
diff --git a/components/layout/Tooltip.tsx b/components/layout/Tooltip.tsx index 7f9af879..2aba1eb1 100644 --- a/components/layout/Tooltip.tsx +++ b/components/layout/Tooltip.tsx @@ -14,12 +14,12 @@ import { FloatingPortal, safePolygon, } from "@floating-ui/react"; -import type { Placement } from "@floating-ui/react"; +import type { Placement, Alignment } from "@floating-ui/react"; import { motion } from "framer-motion"; interface TooltipOptions { initialOpen?: boolean; - placement?: Placement; + placement?: Placement | Alignment; open?: boolean; onOpenChange?: (open: boolean) => void; allowInteract?: boolean; @@ -73,7 +73,7 @@ export function useTooltip({ ...interactions, ...data, }), - [open, setOpen, interactions, data] + [open, setOpen, interactions, data], ); } @@ -122,7 +122,7 @@ export const TooltipTrigger = React.forwardRef< ...props, ...children.props, "data-state": context.open ? "open" : "closed", - }) + }), ); } From b217ca1d828e6d726df367ade6a7fa7824e9295a Mon Sep 17 00:00:00 2001 From: Manish Gupta Date: Fri, 8 Sep 2023 12:39:23 -0700 Subject: [PATCH 10/33] ts --- components/layout/SidebarMenuGroup.tsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/components/layout/SidebarMenuGroup.tsx b/components/layout/SidebarMenuGroup.tsx index 5b061bb0..152aa0d0 100644 --- a/components/layout/SidebarMenuGroup.tsx +++ b/components/layout/SidebarMenuGroup.tsx @@ -250,11 +250,7 @@ export default function SidebarMenuGroup({
)} - + Date: Sat, 9 Sep 2023 14:40:19 -0700 Subject: [PATCH 11/33] ts --- components/layout/SidebarMenuGroup.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/layout/SidebarMenuGroup.tsx b/components/layout/SidebarMenuGroup.tsx index 152aa0d0..31222572 100644 --- a/components/layout/SidebarMenuGroup.tsx +++ b/components/layout/SidebarMenuGroup.tsx @@ -250,7 +250,7 @@ export default function SidebarMenuGroup({
)} - + Date: Sun, 10 Sep 2023 21:00:02 -0700 Subject: [PATCH 12/33] ts error --- components/layout/SidebarMenuGroup.tsx | 4 ++-- components/layout/Tooltip.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/components/layout/SidebarMenuGroup.tsx b/components/layout/SidebarMenuGroup.tsx index 31222572..262de7ed 100644 --- a/components/layout/SidebarMenuGroup.tsx +++ b/components/layout/SidebarMenuGroup.tsx @@ -250,7 +250,7 @@ export default function SidebarMenuGroup({
)} - + {!sidebarOpen && ( void; allowInteract?: boolean; From 279e05f2baf945566a662f87ac595ec5dc60a447 Mon Sep 17 00:00:00 2001 From: Manish Gupta Date: Mon, 11 Sep 2023 09:19:43 -0700 Subject: [PATCH 13/33] Chain page updates --- components/layout/ChainChart.tsx | 62 ++++++++++++++++++++------------ components/layout/Tooltip.tsx | 2 +- lib/navigation.tsx | 6 ++-- 3 files changed, 44 insertions(+), 26 deletions(-) diff --git a/components/layout/ChainChart.tsx b/components/layout/ChainChart.tsx index dd60355a..b284725e 100644 --- a/components/layout/ChainChart.tsx +++ b/components/layout/ChainChart.tsx @@ -22,7 +22,7 @@ import d3 from "d3"; import { AllChainsByKeys } from "@/lib/chains"; import { debounce, forEach } from "lodash"; -import { navigationItems } from "@/lib/navigation"; +import { navigationItems, navigationCategories } from "@/lib/navigation"; import { useUIContext } from "@/contexts/UIContext"; import { useMediaQuery } from "usehooks-ts"; import ChartWatermark from "./ChartWatermark"; @@ -887,6 +887,21 @@ export default function ChainChart({ }, }; + const getNavIcon = useCallback( + (key: string) => { + const navItem = navigationItems[1].options.find( + (item) => item.key === key, + ); + + if (!navItem) return null; + + return navigationCategories[navItem.category] + ? navigationCategories[navItem.category].icon + : null; + }, + [navigationItems], + ); + const lastPointLines = useMemo<{ [key: string]: Highcharts.SVGElement; }>(() => ({}), []); @@ -1037,7 +1052,7 @@ export default function ChainChart({ {data && (
{data.chain_id === "ethereum" && ( <> - {key === "tvl" && ( - <> - TVL On-Chain data is not available for - Ethereum - + {["tvl", "rent_paid", "profit"].includes(key) && ( + <>Data is not available for Ethereum + )} + + )} + {data.chain_id === "imx" && ( + <> + {["rent_paid", "profit"].includes(key) && ( + <>Data is not available for Ethereum )} )} @@ -1099,11 +1118,15 @@ export default function ChainChart({
{data.chain_id === "ethereum" && ( <> - {key === "tvl" && ( - <> - TVL On-Chain data is not available for - Ethereum - + {["tvl", "rent_paid", "profit"].includes(key) && ( + <>Data is not available for Ethereum + )} + + )} + {data.chain_id === "imx" && ( + <> + {["rent_paid", "profit"].includes(key) && ( + <>Data is not available for Ethereum )} )} @@ -1116,12 +1139,8 @@ export default function ChainChart({ )}
o.key === key, - )?.icon ?? "" - } - className="absolute h-[64px] w-[64px] top-[55px] right-[26px] dark:text-[#CDD8D3] opacity-5 pointer-events-none" + icon={getNavIcon(key)} + className="absolute h-[50px] w-[50px] bottom-[16px] left-[36px] dark:text-[#CDD8D3] opacity-20 pointer-events-none" />
@@ -1370,11 +1389,8 @@ export default function ChainChart({
o.key === key) - ?.icon ?? "" - } - className="absolute h-[64px] w-[64px] top-[55px] right-[26px] dark:text-[#CDD8D3] opacity-5 pointer-events-none" + icon={getNavIcon(key)} + className="absolute h-[50px] w-[50px] bottom-[16px] left-[36px] dark:text-[#CDD8D3] opacity-20 pointer-events-none" />
diff --git a/components/layout/Tooltip.tsx b/components/layout/Tooltip.tsx index 2aba1eb1..b13d5fff 100644 --- a/components/layout/Tooltip.tsx +++ b/components/layout/Tooltip.tsx @@ -19,7 +19,7 @@ import { motion } from "framer-motion"; interface TooltipOptions { initialOpen?: boolean; - placement?: Placement | Alignment; + placement?: Placement; open?: boolean; onOpenChange?: (open: boolean) => void; allowInteract?: boolean; diff --git a/lib/navigation.tsx b/lib/navigation.tsx index 6bc52a6b..4f799d7d 100644 --- a/lib/navigation.tsx +++ b/lib/navigation.tsx @@ -153,7 +153,8 @@ export const navigationItems: NavigationItem[] = [ category: "economics", page: { title: "Rent Paid", - description: "The sum of rent that was paid ...", + description: + "The gas fees paid by L2s to post transaction data & verification states onto Ethereum.", why: "Rent paid is a critical metric for ...", icon: "feather:credit-card", }, @@ -167,7 +168,8 @@ export const navigationItems: NavigationItem[] = [ category: "economics", page: { title: "Earnings", - description: "The sum of earnings that were paid ...", + description: + "The net profit of L2s, accounting for revenues as L2 gas fees collected and expenses as posting transaction data & verification states onto Ethereum.", why: "Earnings is a critical metric for ...", icon: "feather:credit-card", }, From 2327d872359f1f568bc76359c53a4b42921c629f Mon Sep 17 00:00:00 2001 From: Manish Gupta Date: Mon, 11 Sep 2023 09:25:22 -0700 Subject: [PATCH 14/33] tweaks --- components/layout/ChainChart.tsx | 2 +- lib/navigation.tsx | 10 +++++----- lib/urls.ts | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/components/layout/ChainChart.tsx b/components/layout/ChainChart.tsx index b284725e..0fd01566 100644 --- a/components/layout/ChainChart.tsx +++ b/components/layout/ChainChart.tsx @@ -893,7 +893,7 @@ export default function ChainChart({ (item) => item.key === key, ); - if (!navItem) return null; + if (!navItem || !navItem.category) return null; return navigationCategories[navItem.category] ? navigationCategories[navItem.category].icon diff --git a/lib/navigation.tsx b/lib/navigation.tsx index 4f799d7d..abe45174 100644 --- a/lib/navigation.tsx +++ b/lib/navigation.tsx @@ -149,10 +149,10 @@ export const navigationItems: NavigationItem[] = [ urlKey: "fees-paid-by-users", }, { - label: "Rent Paid", + label: "Rent Paid to L1", category: "economics", page: { - title: "Rent Paid", + title: "Rent Paid to L1", description: "The gas fees paid by L2s to post transaction data & verification states onto Ethereum.", why: "Rent paid is a critical metric for ...", @@ -164,10 +164,10 @@ export const navigationItems: NavigationItem[] = [ urlKey: "rent-paid", }, { - label: "Earnings", + label: "On-chain Profit", category: "economics", page: { - title: "Earnings", + title: "On-chain Profit", description: "The net profit of L2s, accounting for revenues as L2 gas fees collected and expenses as posting transaction data & verification states onto Ethereum.", why: "Earnings is a critical metric for ...", @@ -176,7 +176,7 @@ export const navigationItems: NavigationItem[] = [ icon: "feather:credit-card", key: "profit", rootKey: "metricsEarnings", - urlKey: "earnings", + urlKey: "profit", }, { label: "Transaction Costs", diff --git a/lib/urls.ts b/lib/urls.ts index f2fe1cc6..dc758083 100644 --- a/lib/urls.ts +++ b/lib/urls.ts @@ -7,7 +7,7 @@ export const MetricsURLs = { "transaction-count": "https://api.growthepie.xyz/v1/metrics/txcount.json", "transaction-costs": "https://api.growthepie.xyz/v1/metrics/txcosts.json", "rent-paid": "https://api.growthepie.xyz/v1/metrics/rent_paid.json", - earnings: "https://api.growthepie.xyz/v1/metrics/profit.json", + profit: "https://api.growthepie.xyz/v1/metrics/profit.json", }; export const ChainURLs = { From 7d9342f058169f9de1c8691ca90440f5674cfb74 Mon Sep 17 00:00:00 2001 From: Manish Gupta Date: Mon, 11 Sep 2023 10:05:57 -0700 Subject: [PATCH 15/33] Farcaster icon is now SVG --- components/layout/Header.tsx | 9 +-------- icons/gtp.json | 5 +++++ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/components/layout/Header.tsx b/components/layout/Header.tsx index 061ecf49..6cb7da10 100644 --- a/components/layout/Header.tsx +++ b/components/layout/Header.tsx @@ -73,14 +73,7 @@ export default function Header() { rel="noopener" className="w-6 h-6" > - Forest + \r\n\r\n\r\n\r\n\r\n", "width": 15, "height": 15 + }, + "farcaster": { + "body": "", + "width": 27, + "height": 24 } }, "width": 15, From 753add4aba6a7557384d497bea0b033842f727ad Mon Sep 17 00:00:00 2001 From: Manish Gupta Date: Mon, 11 Sep 2023 10:17:56 -0700 Subject: [PATCH 16/33] Nav - On-chain -> Onchain --- lib/navigation.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/navigation.tsx b/lib/navigation.tsx index abe45174..d51d9e49 100644 --- a/lib/navigation.tsx +++ b/lib/navigation.tsx @@ -164,10 +164,10 @@ export const navigationItems: NavigationItem[] = [ urlKey: "rent-paid", }, { - label: "On-chain Profit", + label: "Onchain Profit", category: "economics", page: { - title: "On-chain Profit", + title: "Onchain Profit", description: "The net profit of L2s, accounting for revenues as L2 gas fees collected and expenses as posting transaction data & verification states onto Ethereum.", why: "Earnings is a critical metric for ...", From bf7d80a1b3e2262547c11aee64417935bc2c9d16 Mon Sep 17 00:00:00 2001 From: Manish Gupta Date: Mon, 11 Sep 2023 18:12:48 -0700 Subject: [PATCH 17/33] WIP: Landing page overhaul --- app/fundamentals/[metric]/page.tsx | 4 +- app/page.tsx | 107 ++++++++++++++++++- components/charts/ChainComponent.tsx | 6 +- components/layout/ChainChart.tsx | 10 +- components/layout/ContractCard.tsx | 147 +++++++++++++++++++++++++++ components/layout/LandingChart.tsx | 4 +- 6 files changed, 262 insertions(+), 16 deletions(-) create mode 100644 components/layout/ContractCard.tsx diff --git a/app/fundamentals/[metric]/page.tsx b/app/fundamentals/[metric]/page.tsx index 22b95666..41440ae7 100644 --- a/app/fundamentals/[metric]/page.tsx +++ b/app/fundamentals/[metric]/page.tsx @@ -5,7 +5,7 @@ import { MetricsResponse } from "@/types/api/MetricsResponse"; import Heading from "@/components/layout/Heading"; import Subheading from "@/components/layout/Subheading"; import ComparisonChart from "@/components/layout/ComparisonChart"; -import { useSessionStorage } from "usehooks-ts"; +import { useLocalStorage, useSessionStorage } from "usehooks-ts"; import useSWR from "swr"; import MetricsTable from "@/components/layout/MetricsTable"; import { MetricsURLs } from "@/lib/urls"; @@ -18,7 +18,7 @@ import Container from "@/components/layout/Container"; import ShowLoading from "@/components/layout/ShowLoading"; const Chain = ({ params }: { params: any }) => { - const [showUsd, setShowUsd] = useSessionStorage("showUsd", true); + const [showUsd, setShowUsd] = useLocalStorage("showUsd", true); const [errorCode, setErrorCode] = useState(null); const { diff --git a/app/page.tsx b/app/page.tsx index 1505d77a..4c294f5b 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -19,6 +19,11 @@ import LoadingAnimation from "@/components/layout/LoadingAnimation"; import { useSessionStorage } from "usehooks-ts"; import Container from "@/components/layout/Container"; import ShowLoading from "@/components/layout/ShowLoading"; +import ChainComponent from "@/components/charts/ChainComponent"; +import { ChainURLs, BlockspaceURLs } from "@/lib/urls"; +import ContractCard from "@/components/layout/ContractCard"; +import { ChainResponse } from "@/types/api/ChainResponse"; +import { ChainOverviewResponse } from "@/types/api/ChainOverviewResponse"; export default function Home() { const isLargeScreen = useMediaQuery("(min-width: 768px)"); @@ -43,6 +48,20 @@ export default function Home() { isValidating: masterValidating, } = useSWR(MasterURL); + const { + data: chainData, + error: chainError, + isValidating: chainValidating, + isLoading: chainLoading, + } = useSWR(ChainURLs["arbitrum"]); + + const { + data: blockspaceData, + error: blockspaceError, + isValidating: blockspaceValidating, + isLoading: blockspaceLoading, + } = useSWR(BlockspaceURLs["chain-overview"]); + const [data, setData] = useState(null); const [selectedTimeInterval, setSelectedTimeInterval] = useState("weekly"); @@ -83,15 +102,64 @@ export default function Home() { /> {/* )} */} - - Growing Ethereum’s Ecosystem Together + + Mastering Ethereum Layer-2s: Your Gateway to Curated Analytics and + Knowledge - {data && landing && master && } + + +
+ + + Most Recent Metrics + +
+
+ {chainData && ( + +
+ + + +
+
+ + Compare {" "} + +
+
+ )} + + {/* {data && landing && master && } */} {/* Compare Ethereum's Layer-2 solutions and better understand the metrics to grow the ecosystem. */} -
+
)} + +
+ + + Blockspace + +
+ + Top 6 gas-consuming contracts across all tracked Layer-2s. + + {blockspaceData && ( +
+ {new Array(6).fill(0).map((_, i) => ( + + ))} +
+ )} +
diff --git a/components/charts/ChainComponent.tsx b/components/charts/ChainComponent.tsx index 0e465bcf..c0e45127 100644 --- a/components/charts/ChainComponent.tsx +++ b/components/charts/ChainComponent.tsx @@ -867,7 +867,7 @@ export default function ChainComponent({ return (
-
+
- {!zoomed + {/* {!zoomed ? (category === "stables_mcap" || category === "txcosts") && (
- )} + )} */}
); } diff --git a/components/layout/ChainChart.tsx b/components/layout/ChainChart.tsx index 0fd01566..57b6246b 100644 --- a/components/layout/ChainChart.tsx +++ b/components/layout/ChainChart.tsx @@ -1052,7 +1052,7 @@ export default function ChainChart({ {data && (
{!zoomed - ? (key === "stables_mcap" || key === "txcosts") && ( + ? (key === "profit" || key === "txcosts") && (
) - : (key === "stables_mcap" || key === "txcosts") && + : (key === "profit" || key === "txcosts") && intervalShown && (
{!zoomed - ? (key === "stables_mcap" || key === "txcosts") && ( + ? (key === "profit" || key === "txcosts") && (
) - : (key === "stables_mcap" || key === "txcosts") && + : (key === "profit" || key === "txcosts") && intervalShown && (
+
+
+
+
+
+ {/*
*/} + +
+
+ {AllChainsByKeys[data[types.indexOf("chain")]].label} +
+
+
+
+
+ <> + {showUsd ? ( + <> +
$
+
+ {Intl.NumberFormat(undefined, { + maximumFractionDigits: 2, + minimumFractionDigits: 2, + }).format(data[types.indexOf("gas_fees_absolute_usd")])} +
+ + ) : ( + <> +
Ξ
+
+ {Intl.NumberFormat(undefined, { + maximumFractionDigits: 2, + minimumFractionDigits: 2, + }).format(data[types.indexOf("gas_fees_absolute_eth")])}{" "} + ETH +
+ + )} + +
+
+
+ {data[types.indexOf("project_name")]} +
+
+
+
+ {data[types.indexOf("main_category_key")]} >{" "} + {data[types.indexOf("sub_category_key")]} +
+
+ + +
+
+ ); +} diff --git a/components/layout/LandingChart.tsx b/components/layout/LandingChart.tsx index 7d3ecc6f..91c2fa0b 100644 --- a/components/layout/LandingChart.tsx +++ b/components/layout/LandingChart.tsx @@ -7,7 +7,7 @@ import Highcharts, { AxisLabelsFormatterContextObject, } from "highcharts/highstock"; import { useState, useEffect, useMemo, useRef, useCallback } from "react"; -import { useSessionStorage } from "usehooks-ts"; +import { useLocalStorage, useSessionStorage } from "usehooks-ts"; import { useTheme } from "next-themes"; import { merge } from "lodash"; import { Switch } from "../Switch"; @@ -218,7 +218,7 @@ export default function LandingChart({ const { theme } = useTheme(); - const [showUsd, setShowUsd] = useSessionStorage("showUsd", true); + const [showUsd, setShowUsd] = useLocalStorage("showUsd", true); const [selectedTimespan, setSelectedTimespan] = useState("max"); From 2f962a22742b3ffa8b5fadb7fa8cc4a1f68758bf Mon Sep 17 00:00:00 2001 From: mokelgit Date: Tue, 12 Sep 2023 10:17:28 -0400 Subject: [PATCH 18/33] Adjusted average bar to only use share data --- components/layout/OverviewMetrics.tsx | 104 +++++++++++++++----------- 1 file changed, 60 insertions(+), 44 deletions(-) diff --git a/components/layout/OverviewMetrics.tsx b/components/layout/OverviewMetrics.tsx index 168e893f..5efef4c6 100644 --- a/components/layout/OverviewMetrics.tsx +++ b/components/layout/OverviewMetrics.tsx @@ -455,7 +455,7 @@ export default function OverviewMetrics({ useEffect(() => { if (selectedMode.includes("gas_fees_share")) { setSelectedMode(showUsd ? "gas_fees_share_usd" : "gas_fees_share_eth"); - } else { + } else if (selectedMode.includes("gas_fees")) { setSelectedMode( showUsd ? "gas_fees_usd_absolute" : "gas_fees_eth_absolute", ); @@ -897,35 +897,49 @@ export default function OverviewMetrics({ const chartAvg = useMemo(() => { let typeIndex = data["all_l2s"].daily["types"].indexOf(selectedMode); + let overviewIndex = data["all_l2s"].overview["types"].indexOf(selectedMode); let returnValue = 0; + + if (selectedMode.includes("absolute")) { + return null; + } + if (selectedChain) { let sum = 0; - for ( - let i = 0; - i < - (selectedTimespan === "max" - ? data[selectedChain].daily[selectedCategory].data.length - : timespans[selectedTimespan].value); - i++ - ) { - if ( - data[selectedChain].daily[selectedCategory].data.length - (i + 1) >= - 0 + if (selectedMode.includes("share")) { + returnValue = + data[selectedChain].overview[selectedTimespan][selectedCategory].data[ + overviewIndex + ]; + } else { + for ( + let i = 0; + i < + (selectedTimespan === "max" + ? data[selectedChain].daily[selectedCategory].data.length + : timespans[selectedTimespan].value); + i++ ) { - sum += - data[selectedChain].daily[selectedCategory].data[ - data[selectedChain].daily[selectedCategory].data.length - (i + 1) - ][typeIndex]; + if ( + data[selectedChain].daily[selectedCategory].data.length - (i + 1) >= + 0 + ) { + sum += + data[selectedChain].daily[selectedCategory].data[ + data[selectedChain].daily[selectedCategory].data.length - + (i + 1) + ][typeIndex]; + } } + returnValue = + sum / + (selectedTimespan === "max" + ? data[selectedChain].daily[selectedCategory].data.length + : timespans[selectedTimespan].value >= + data[selectedChain].daily[selectedCategory].data.length + ? data[selectedChain].daily[selectedCategory].data.length + : timespans[selectedTimespan].value); } - returnValue = - sum / - (selectedTimespan === "max" - ? data[selectedChain].daily[selectedCategory].data.length - : timespans[selectedTimespan].value >= - data[selectedChain].daily[selectedCategory].data.length - ? data[selectedChain].daily[selectedCategory].data.length - : timespans[selectedTimespan].value); } else { let sum = 0; for ( @@ -1528,26 +1542,28 @@ export default function OverviewMetrics({ maxY={chartMax} chartAvg={chartAvg} /> -
- - {selectedMode.includes("share") - ? (chartAvg * 100).toFixed(1) + "%" - : (showUsd ? "$ " : "Ξ ") + formatNumber(chartAvg)} - -
+ {chartAvg && ( +
+ + {selectedMode.includes("share") + ? (chartAvg * 100).toFixed(2) + "%" + : (showUsd ? "$ " : "Ξ ") + formatNumber(chartAvg)} + +
+ )}
From bf2429ceaf983df26d965dd3c30bfa4c71525914 Mon Sep 17 00:00:00 2001 From: mokelgit Date: Tue, 12 Sep 2023 10:34:21 -0400 Subject: [PATCH 19/33] Fixed build errors --- components/layout/OverviewMetrics.tsx | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/components/layout/OverviewMetrics.tsx b/components/layout/OverviewMetrics.tsx index 6722973f..f176e342 100644 --- a/components/layout/OverviewMetrics.tsx +++ b/components/layout/OverviewMetrics.tsx @@ -897,7 +897,8 @@ export default function OverviewMetrics({ const chartAvg = useMemo(() => { let typeIndex = data["all_l2s"].daily["types"].indexOf(selectedMode); - let overviewIndex = data["all_l2s"].overview["types"].indexOf(selectedMode); + let overviewIndex = data.all_l2s["overview"]["types"].indexOf(selectedMode); + let returnValue = 0; if (selectedMode.includes("absolute")) { @@ -975,14 +976,15 @@ export default function OverviewMetrics({ }, [selectedTimespan, selectedMode, selectedCategory, selectedChain]); const avgHeight = useSpring({ - y: - -1 * - (163 * (chartAvg / chartMax) + - (chartAvg / chartMax > 0.45 - ? chartAvg / chartMax > 0.5 - ? 7 - : 10 - : 14)), + y: chartAvg + ? -1 * + (163 * (chartAvg / chartMax) + + (chartAvg / chartMax > 0.45 + ? chartAvg / chartMax > 0.5 + ? 7 + : 10 + : 14)) + : 0, config: { mass: 1, tension: 70, friction: 20 }, }); @@ -1540,7 +1542,7 @@ export default function OverviewMetrics({ chartHeight="196px" chartWidth="100%" maxY={chartMax} - chartAvg={chartAvg} + chartAvg={chartAvg || undefined} /> {chartAvg && (
From 129b5601b49ccbaff5720182d6accb270f4b6a02 Mon Sep 17 00:00:00 2001 From: Manish Gupta Date: Tue, 12 Sep 2023 13:37:43 -0700 Subject: [PATCH 20/33] Landing Page - cursor & zoom UI, Chain Pages - updated icon sizes and placement in charts --- app/globals.css | 9 ++ components/layout/ChainChart.tsx | 4 +- components/layout/LandingChart.tsx | 200 ++++++++++++++++++++++++++++- public/cursors/leftArrow.svg | 17 +++ public/cursors/rightArrow.svg | 17 +++ public/cursors/zoom.svg | 19 +++ 6 files changed, 262 insertions(+), 4 deletions(-) create mode 100644 public/cursors/leftArrow.svg create mode 100644 public/cursors/rightArrow.svg create mode 100644 public/cursors/zoom.svg diff --git a/app/globals.css b/app/globals.css index c6866406..872511fe 100644 --- a/app/globals.css +++ b/app/globals.css @@ -35,6 +35,15 @@ shape-rendering: crispEdges; } +.highcharts-selection-marker { + fill: rgba(205, 216, 211, 0.2); + /* stroke: rgba(205, 216, 211, 1); + stroke-width: 1px; + stroke-linejoin: round; + stroke-dasharray: 2, 2; + shape-rendering: crispEdges; */ +} + .scroller::-webkit-scrollbar-button:end:increment { width: 50px; display: block; diff --git a/components/layout/ChainChart.tsx b/components/layout/ChainChart.tsx index 57b6246b..2c27b736 100644 --- a/components/layout/ChainChart.tsx +++ b/components/layout/ChainChart.tsx @@ -1140,7 +1140,7 @@ export default function ChainChart({
@@ -1390,7 +1390,7 @@ export default function ChainChart({
diff --git a/components/layout/LandingChart.tsx b/components/layout/LandingChart.tsx index 91c2fa0b..11172af6 100644 --- a/components/layout/LandingChart.tsx +++ b/components/layout/LandingChart.tsx @@ -42,6 +42,7 @@ const baseOptions: Highcharts.Options = { animation: false, backgroundColor: "transparent", showAxes: false, + zooming: { type: "x", resetButton: { @@ -202,6 +203,8 @@ export default function LandingChart({ }) { const [highchartsLoaded, setHighchartsLoaded] = useState(false); + const [isDragging, setIsDragging] = useState(false); + useEffect(() => { Highcharts.setOptions({ lang: { @@ -212,6 +215,166 @@ export default function LandingChart({ highchartsAnnotations(Highcharts); setHighchartsLoaded(true); + + Highcharts.wrap(Highcharts.Pointer.prototype, "dragStart", function (p, e) { + console.log("dragStart"); + // place vertical dotted line on click + if (this.chart.series.length > 0) { + const x = e.chartX; + const y = e.chartY; + + this.chart.zoomStartX = x; + this.chart.zoomStartY = y; + } + + p.call(this); + }); + + Highcharts.wrap(Highcharts.Pointer.prototype, "drag", function (p, e) { + console.log("drag"); + + setIsDragging(true); + + // update vertical dotted line on drag + if (this.chart.series.length > 0) { + const x = e.chartX; + const y = e.chartY; + + const leftX = this.chart.zoomStartX < x ? this.chart.zoomStartX : x; + const rightX = this.chart.zoomStartX < x ? x : this.chart.zoomStartX; + + if (this.chart.zoomLineStart) { + this.chart.zoomLineStart.destroy(); + } + + this.chart.zoomLineStart = this.chart.renderer + .path([ + "M", + this.chart.zoomStartX, + this.chart.plotTop, + "L", + this.chart.zoomStartX, + this.chart.plotTop + this.chart.plotHeight, + ]) + .attr({ + stroke: "#fff", + stroke: "rgba(205, 216, 211, 1)", + "stroke-width": "1px", + "stroke-linejoin": "round", + "stroke-dasharray": "2, 1", + "shape-rendering": "crispEdges", + zIndex: 100, + }) + .add(); + + if (this.chart.zoomStartIcon) { + this.chart.zoomStartIcon.destroy(); + } + + // place "rightArrow.svg" icon in middle of vertical dotted line + this.chart.zoomStartIcon = this.chart.renderer + .image( + "/cursors/rightArrow.svg", + leftX - 17, + this.chart.zoomStartY, + 34, + 34, + ) + .attr({ + zIndex: 999, + }) + .add(); + + this.chart.zoomStartIcon.toFront(); + + if (this.chart.zoomLineEnd) { + this.chart.zoomLineEnd.destroy(); + } + + this.chart.zoomLineEnd = this.chart.renderer + .path([ + "M", + x, + this.chart.plotTop, + "L", + x, + this.chart.plotTop + this.chart.plotHeight, + ]) + .attr({ + stroke: "#fff", + stroke: "rgba(205, 216, 211, 1)", + "stroke-width": "1px", + "stroke-linejoin": "round", + "stroke-dasharray": "2, 1", + "shape-rendering": "crispEdges", + zIndex: 100, + }) + .add(); + + this.chart.zoomLineEnd.toFront(); + + if (this.chart.zoomEndIcon) { + this.chart.zoomEndIcon.destroy(); + } + + // place "leftArrow.svg" icon in middle of vertical dotted line + this.chart.zoomEndIcon = this.chart.renderer + .image("/cursors/leftArrow.svg", rightX - 17, y, 34, 34) + .attr({ + zIndex: 999, + }) + .add(); + + this.chart.zoomEndIcon.toFront(); + } + + p.call(this); + }); + + Highcharts.wrap(Highcharts.Pointer.prototype, "drop", function (p, e) { + console.log("drop"); + + setIsDragging(false); + + // remove vertical dotted line on release + if (this.chart.zoomLineStart) { + try { + this.chart.zoomLineStart.destroy(); + this.chart.zoomLineStart = null; + } catch (e) { + console.log(e); + } + } + + if (this.chart.zoomLineEnd) { + try { + this.chart.zoomLineEnd.destroy(); + this.chart.zoomLineEnd = null; + } catch (e) { + console.log(e); + } + } + + if (this.chart.zoomStartIcon) { + try { + this.chart.zoomStartIcon.destroy(); + this.chart.zoomStartIcon = null; + } catch (e) { + console.log(e); + } + } + + if (this.chart.zoomEndIcon) { + try { + this.chart.zoomEndIcon.destroy(); + this.chart.zoomEndIcon = null; + } catch (e) { + console.log(e); + } + } + + p.call(this); + }); }, []); const { isSidebarOpen } = useUIContext(); @@ -558,6 +721,7 @@ export default function LandingChart({ height: isMobile ? 250 : 400, type: selectedScale === "percentage" ? "area" : "column", plotBorderColor: "transparent", + zooming: { resetButton: { theme: { @@ -950,7 +1114,7 @@ export default function LandingChart({ ? AllChainsByKeys[series.name]?.colors[theme][0] + "66" : "transparent", - strokeWidth: 0, + "stroke-width": 0, }, }, // lineWidth: 4, @@ -1309,7 +1473,39 @@ export default function LandingChart({ {highchartsLoaded ? (
-
+
{ + // const chart = chartComponent?.current; + + // if (!chart) + // return console.error("chartComponent.current is null"); + + // if (chart.isInsidePlot(e.chartX - chart.plotLeft, e.chartY)) { + // if (e.type === "mousedown") { + // const x = e.chartX - chart.plotLeft; + // const y = e.chartY - chart.plotTop; + + // // place vertical dotted line at the click position + // chart.xAxis[0].addPlotLine({ + // id: "plot-line", + // value: chart.xAxis[0].toValue(x, true), + // color: "rgba(215, 223, 222, 0.5)", + // width: 1, + // dashStyle: "Dash", + // zIndex: 100, + // }); + // } + // if (e.type === "mouseup") { + // } + // } + // }} + > + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/cursors/rightArrow.svg b/public/cursors/rightArrow.svg new file mode 100644 index 00000000..43d6cec6 --- /dev/null +++ b/public/cursors/rightArrow.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/cursors/zoom.svg b/public/cursors/zoom.svg new file mode 100644 index 00000000..6ff69316 --- /dev/null +++ b/public/cursors/zoom.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file From c0e23e8903d8ec8da7cf1cc6c03d58a09c351f4b Mon Sep 17 00:00:00 2001 From: Manish Gupta Date: Tue, 12 Sep 2023 13:45:26 -0700 Subject: [PATCH 21/33] fixing build error --- components/layout/LandingChart.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/components/layout/LandingChart.tsx b/components/layout/LandingChart.tsx index 11172af6..34b6edeb 100644 --- a/components/layout/LandingChart.tsx +++ b/components/layout/LandingChart.tsx @@ -257,7 +257,6 @@ export default function LandingChart({ this.chart.plotTop + this.chart.plotHeight, ]) .attr({ - stroke: "#fff", stroke: "rgba(205, 216, 211, 1)", "stroke-width": "1px", "stroke-linejoin": "round", @@ -301,7 +300,6 @@ export default function LandingChart({ this.chart.plotTop + this.chart.plotHeight, ]) .attr({ - stroke: "#fff", stroke: "rgba(205, 216, 211, 1)", "stroke-width": "1px", "stroke-linejoin": "round", From bbc49925e1ea31ceb731984faeaef25f327b0ed2 Mon Sep 17 00:00:00 2001 From: mokelgit Date: Tue, 12 Sep 2023 18:48:28 -0400 Subject: [PATCH 22/33] Fixed avg bar not properly adjusting height --- components/charts/chart.tsx | 9 ++++++++- components/layout/OverviewMetrics.tsx | 10 +--------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/components/charts/chart.tsx b/components/charts/chart.tsx index f0857313..8c5ba31c 100644 --- a/components/charts/chart.tsx +++ b/components/charts/chart.tsx @@ -381,6 +381,8 @@ export const Chart = ({ } const yAxisTicks = useYAxisTicks(maxY, yScale); + const numIntervals = Math.ceil(parseFloat(chartHeight) / 171); + const intervalSize = maxY ? maxY / numIntervals : 0; return ( <> @@ -462,7 +464,12 @@ export const Chart = ({ minorTickInterval: ["7d", "30d"].includes(timespan) ? 1000 * 60 * 60 * 24 * 1 : 1000 * 60 * 60 * 24 * 7, - tickPositions: tickPositions, + tickPositions: maxY + ? Array.from( + { length: numIntervals + 1 }, + (_, i) => i * intervalSize, + ) + : undefined, labels: getXAxisLabels(), }, yAxis: { diff --git a/components/layout/OverviewMetrics.tsx b/components/layout/OverviewMetrics.tsx index f176e342..229c4199 100644 --- a/components/layout/OverviewMetrics.tsx +++ b/components/layout/OverviewMetrics.tsx @@ -976,15 +976,7 @@ export default function OverviewMetrics({ }, [selectedTimespan, selectedMode, selectedCategory, selectedChain]); const avgHeight = useSpring({ - y: chartAvg - ? -1 * - (163 * (chartAvg / chartMax) + - (chartAvg / chartMax > 0.45 - ? chartAvg / chartMax > 0.5 - ? 7 - : 10 - : 14)) - : 0, + y: chartAvg ? -1 * (171 * (chartAvg / chartMax) - 4) : 0, config: { mass: 1, tension: 70, friction: 20 }, }); From a02f3718d385d70fb69bfb667c9b1ca9f1ee0aa7 Mon Sep 17 00:00:00 2001 From: mokelgit Date: Wed, 13 Sep 2023 09:44:56 -0400 Subject: [PATCH 23/33] Temporary fix for x-axis ticks --- components/charts/chart.tsx | 17 +++++++++-------- components/layout/OverviewMetrics.tsx | 10 +++++++++- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/components/charts/chart.tsx b/components/charts/chart.tsx index 8c5ba31c..469c74d5 100644 --- a/components/charts/chart.tsx +++ b/components/charts/chart.tsx @@ -384,6 +384,10 @@ export const Chart = ({ const numIntervals = Math.ceil(parseFloat(chartHeight) / 171); const intervalSize = maxY ? maxY / numIntervals : 0; + const lastTick = tickPositions[tickPositions.length - 1]; + const displayMinorTicksOnly = + lastTick < timespans[timespan].xMin || lastTick > timespans[timespan].xMax; + return ( <> { @@ -464,12 +468,9 @@ export const Chart = ({ minorTickInterval: ["7d", "30d"].includes(timespan) ? 1000 * 60 * 60 * 24 * 1 : 1000 * 60 * 60 * 24 * 7, - tickPositions: maxY - ? Array.from( - { length: numIntervals + 1 }, - (_, i) => i * intervalSize, - ) - : undefined, + tickPositions: displayMinorTicksOnly + ? undefined + : tickPositions, labels: getXAxisLabels(), }, yAxis: { @@ -479,8 +480,8 @@ export const Chart = ({ max: maxY ? maxY : undefined, tickPositions: maxY ? Array.from( - { length: yAxisTicks.numIntervals + 1 }, - (_, i) => i * yAxisTicks.interval, + { length: numIntervals + 1 }, + (_, i) => i * intervalSize, ) : undefined, tickInterval: maxY ? yAxisTicks.interval : undefined, diff --git a/components/layout/OverviewMetrics.tsx b/components/layout/OverviewMetrics.tsx index 229c4199..f176e342 100644 --- a/components/layout/OverviewMetrics.tsx +++ b/components/layout/OverviewMetrics.tsx @@ -976,7 +976,15 @@ export default function OverviewMetrics({ }, [selectedTimespan, selectedMode, selectedCategory, selectedChain]); const avgHeight = useSpring({ - y: chartAvg ? -1 * (171 * (chartAvg / chartMax) - 4) : 0, + y: chartAvg + ? -1 * + (163 * (chartAvg / chartMax) + + (chartAvg / chartMax > 0.45 + ? chartAvg / chartMax > 0.5 + ? 7 + : 10 + : 14)) + : 0, config: { mass: 1, tension: 70, friction: 20 }, }); From b80f603fa53f6e23525e2322a1d202240f5caad2 Mon Sep 17 00:00:00 2001 From: Manish Gupta Date: Wed, 13 Sep 2023 09:52:03 -0700 Subject: [PATCH 24/33] Landing Page zoom UI tweaks --- components/layout/LandingChart.tsx | 264 +++++++++++++++++++++-------- 1 file changed, 189 insertions(+), 75 deletions(-) diff --git a/components/layout/LandingChart.tsx b/components/layout/LandingChart.tsx index 34b6edeb..6ab26def 100644 --- a/components/layout/LandingChart.tsx +++ b/components/layout/LandingChart.tsx @@ -205,17 +205,7 @@ export default function LandingChart({ const [isDragging, setIsDragging] = useState(false); - useEffect(() => { - Highcharts.setOptions({ - lang: { - numericSymbols: ["K", " M", "B", "T", "P", "E"], - }, - }); - highchartsRoundedCorners(Highcharts); - highchartsAnnotations(Highcharts); - - setHighchartsLoaded(true); - + const loadHighchartsWrappers = () => { Highcharts.wrap(Highcharts.Pointer.prototype, "dragStart", function (p, e) { console.log("dragStart"); // place vertical dotted line on click @@ -250,10 +240,10 @@ export default function LandingChart({ this.chart.zoomLineStart = this.chart.renderer .path([ "M", - this.chart.zoomStartX, + leftX, this.chart.plotTop, "L", - this.chart.zoomStartX, + leftX, this.chart.plotTop + this.chart.plotHeight, ]) .attr({ @@ -264,27 +254,8 @@ export default function LandingChart({ "shape-rendering": "crispEdges", zIndex: 100, }) - .add(); - - if (this.chart.zoomStartIcon) { - this.chart.zoomStartIcon.destroy(); - } - - // place "rightArrow.svg" icon in middle of vertical dotted line - this.chart.zoomStartIcon = this.chart.renderer - .image( - "/cursors/rightArrow.svg", - leftX - 17, - this.chart.zoomStartY, - 34, - 34, - ) - .attr({ - zIndex: 999, - }) - .add(); - - this.chart.zoomStartIcon.toFront(); + .add() + .toFront(); if (this.chart.zoomLineEnd) { this.chart.zoomLineEnd.destroy(); @@ -293,10 +264,10 @@ export default function LandingChart({ this.chart.zoomLineEnd = this.chart.renderer .path([ "M", - x, + rightX, this.chart.plotTop, "L", - x, + rightX, this.chart.plotTop + this.chart.plotHeight, ]) .attr({ @@ -307,9 +278,29 @@ export default function LandingChart({ "shape-rendering": "crispEdges", zIndex: 100, }) - .add(); + .add() + .toFront(); - this.chart.zoomLineEnd.toFront(); + if (this.chart.zoomStartIcon) { + this.chart.zoomStartIcon.destroy(); + } + + // place "rightArrow.svg" icon in middle of vertical dotted line + this.chart.zoomStartIcon = this.chart.renderer + .image( + x < this.chart.zoomStartX + ? "/cursors/leftArrow.svg" + : "/cursors/rightArrow.svg", + this.chart.zoomStartX - 17, + this.chart.zoomStartY, + 34, + 34, + ) + .attr({ + zIndex: 999, + }) + .add() + .toFront(); if (this.chart.zoomEndIcon) { this.chart.zoomEndIcon.destroy(); @@ -317,13 +308,136 @@ export default function LandingChart({ // place "leftArrow.svg" icon in middle of vertical dotted line this.chart.zoomEndIcon = this.chart.renderer - .image("/cursors/leftArrow.svg", rightX - 17, y, 34, 34) + .image( + x < this.chart.zoomStartX + ? "/cursors/rightArrow.svg" + : "/cursors/leftArrow.svg", + x - 17, + y, + 34, + 34, + ) .attr({ zIndex: 999, }) - .add(); + .add() + .toFront(); + + // get the x value of the left and right edges of the selected area + const leftXValue = this.chart.xAxis[0].toValue( + leftX - this.chart.plotLeft, + true, + ); + const rightXValue = this.chart.xAxis[0].toValue( + rightX - this.chart.plotLeft, + true, + ); + + const leftDate = new Date(leftXValue); + const rightDate = new Date(rightXValue); + + // display the number of days selected + const numDays = Math.round( + (rightXValue - leftXValue) / (24 * 60 * 60 * 1000), + ); + + if (this.chart.numDaysText) { + this.chart.numDaysText.destroy(); + } - this.chart.zoomEndIcon.toFront(); + // display the number of days selected + this.chart.numDaysText = this.chart.renderer + .label( + `${numDays} day${numDays > 1 ? "s" : ""}`, + leftX + (rightX - leftX) / 2, + rightX - leftX < 160 + ? this.chart.plotHeight - 50 + : this.chart.plotHeight - 20, + ) + .attr({ + zIndex: 999, + fill: "rgb(215, 223, 222)", + r: 5, + padding: 5, + "font-size": "12px", + "font-weight": "500", + align: "center", + opacity: 0.7, + }) + .css({ + color: "#2A3433", + "font-family": "Inter", + }) + .add() + .shadow(true) + .toFront(); + + if (this.chart.leftDateText) { + this.chart.leftDateText.destroy(); + } + + // display the left date + this.chart.leftDateText = this.chart.renderer + .label( + `${leftDate.toLocaleDateString(undefined, { + timeZone: "UTC", + month: "short", + day: "numeric", + year: "numeric", + })}`, + leftX, + this.chart.plotHeight - 20, + ) + .attr({ + zIndex: 999, + fill: "#2A3433", + r: 5, + padding: 6, + "font-size": "12px", + "font-weight": "500", + align: "center", + }) + .css({ + color: "rgb(215, 223, 222)", + "font-family": "Inter", + }) + .add() + .shadow(true) + .toFront(); + + if (this.chart.rightDateText) { + this.chart.rightDateText.destroy(); + } + + // display the right date label with arrow pointing down + this.chart.rightDateText = this.chart.renderer + .label( + `${rightDate.toLocaleDateString(undefined, { + timeZone: "UTC", + month: "short", + day: "numeric", + year: "numeric", + })}`, + rightX, + this.chart.plotHeight - 20, + ) + .attr({ + zIndex: 999, + fill: "#2A3433", + r: 5, + padding: 6, + "font-size": "12px", + "font-weight": "500", + align: "center", + }) + .css({ + color: "rgb(215, 223, 222)", + "font-family": "Inter", + }) + .add() + .shadow(true); + + this.chart.rightDateText.toFront(); } p.call(this); @@ -334,45 +448,43 @@ export default function LandingChart({ setIsDragging(false); - // remove vertical dotted line on release - if (this.chart.zoomLineStart) { - try { - this.chart.zoomLineStart.destroy(); - this.chart.zoomLineStart = null; - } catch (e) { - console.log(e); + const elements = [ + "zoomLineStart", + "zoomLineEnd", + "zoomStartIcon", + "zoomEndIcon", + "numDaysText", + "leftDateText", + "rightDateText", + ]; + + elements.forEach((element) => { + if (this.chart[element]) { + try { + this.chart[element].destroy(); + this.chart[element] = null; + } catch (e) { + console.log(e); + } } - } + }); - if (this.chart.zoomLineEnd) { - try { - this.chart.zoomLineEnd.destroy(); - this.chart.zoomLineEnd = null; - } catch (e) { - console.log(e); - } - } + p.call(this); + }); + }; - if (this.chart.zoomStartIcon) { - try { - this.chart.zoomStartIcon.destroy(); - this.chart.zoomStartIcon = null; - } catch (e) { - console.log(e); - } - } + useEffect(() => { + Highcharts.setOptions({ + lang: { + numericSymbols: ["K", " M", "B", "T", "P", "E"], + }, + }); + highchartsRoundedCorners(Highcharts); + highchartsAnnotations(Highcharts); - if (this.chart.zoomEndIcon) { - try { - this.chart.zoomEndIcon.destroy(); - this.chart.zoomEndIcon = null; - } catch (e) { - console.log(e); - } - } + loadHighchartsWrappers(); - p.call(this); - }); + setHighchartsLoaded(true); }, []); const { isSidebarOpen } = useUIContext(); @@ -826,6 +938,7 @@ export default function LandingChart({ style: { color: theme === "dark" ? "rgb(215, 223, 222)" : "rgb(41 51 50)", }, + enabled: isDragging ? false : true, }, series: [ ...filteredData @@ -1229,6 +1342,7 @@ export default function LandingChart({ formatNumber, getSeriesType, getTickPositions, + isDragging, isMobile, metric, onXAxisSetExtremes, From dff166e2c3f83192153439653370dabdfd694879 Mon Sep 17 00:00:00 2001 From: mokelgit Date: Wed, 13 Sep 2023 14:03:02 -0400 Subject: [PATCH 25/33] Fixed chain component icon and added category label --- components/charts/ChainComponent.tsx | 48 +++++++++++++++++++++------- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/components/charts/ChainComponent.tsx b/components/charts/ChainComponent.tsx index c0e45127..38f9d224 100644 --- a/components/charts/ChainComponent.tsx +++ b/components/charts/ChainComponent.tsx @@ -22,7 +22,7 @@ import d3 from "d3"; import { AllChainsByKeys } from "@/lib/chains"; import { debounce, forEach } from "lodash"; -import { navigationItems } from "@/lib/navigation"; +import { navigationItems, navigationCategories } from "@/lib/navigation"; import { useUIContext } from "@/contexts/UIContext"; import { useMediaQuery } from "usehooks-ts"; import ChartWatermark from "@/components/layout/ChartWatermark"; @@ -319,6 +319,36 @@ export default function ChainComponent({ [selectedTimespan], ); + const getNavIcon = useCallback( + (key: string) => { + const navItem = navigationItems[1].options.find( + (item) => item.key === key, + ); + + if (!navItem || !navItem.category) return null; + + return navigationCategories[navItem.category] + ? navigationCategories[navItem.category].icon + : null; + }, + [navigationItems], + ); + + const getNavLabel = useCallback( + (key: string) => { + const navItem = navigationItems[1].options.find( + (item) => item.key === key, + ); + + if (!navItem || !navItem.category) return null; + + return navigationCategories[navItem.category] + ? navigationCategories[navItem.category].label + : null; + }, + [navigationItems], + ); + const displayValues = useMemo(() => { const p: { [key: string]: { @@ -1004,9 +1034,6 @@ export default function ChainComponent({ } }} /> -
- -
@@ -1032,14 +1059,11 @@ export default function ChainComponent({ className={`absolute top-[calc(50% - 0.5px)] right-[20px] w-[4px] h-[4px] rounded-full bg-forest-900 dark:bg-forest-50`} >
-
- o.key === category) - ?.icon ?? "" - } - className="absolute h-[64px] w-[64px] top-[55px] right-[26px] dark:text-[#CDD8D3] opacity-5 pointer-events-none" - /> +
+ +
+ {getNavLabel(category).toUpperCase()} +
From a6ad665446ab13d9206b0919db02e77d4ad050c5 Mon Sep 17 00:00:00 2001 From: Manish Gupta Date: Wed, 13 Sep 2023 20:33:39 -0700 Subject: [PATCH 26/33] zoom ui font fix --- components/layout/LandingChart.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/components/layout/LandingChart.tsx b/components/layout/LandingChart.tsx index 6ab26def..5e658f67 100644 --- a/components/layout/LandingChart.tsx +++ b/components/layout/LandingChart.tsx @@ -366,7 +366,6 @@ export default function LandingChart({ }) .css({ color: "#2A3433", - "font-family": "Inter", }) .add() .shadow(true) @@ -399,7 +398,6 @@ export default function LandingChart({ }) .css({ color: "rgb(215, 223, 222)", - "font-family": "Inter", }) .add() .shadow(true) From eff4ff97ed379eac941fe60f9b56b2d90a5afa78 Mon Sep 17 00:00:00 2001 From: Manish Gupta Date: Wed, 13 Sep 2023 20:36:53 -0700 Subject: [PATCH 27/33] removed console logs --- components/layout/LandingChart.tsx | 5 ----- 1 file changed, 5 deletions(-) diff --git a/components/layout/LandingChart.tsx b/components/layout/LandingChart.tsx index 5e658f67..f5e9f0f4 100644 --- a/components/layout/LandingChart.tsx +++ b/components/layout/LandingChart.tsx @@ -207,7 +207,6 @@ export default function LandingChart({ const loadHighchartsWrappers = () => { Highcharts.wrap(Highcharts.Pointer.prototype, "dragStart", function (p, e) { - console.log("dragStart"); // place vertical dotted line on click if (this.chart.series.length > 0) { const x = e.chartX; @@ -221,8 +220,6 @@ export default function LandingChart({ }); Highcharts.wrap(Highcharts.Pointer.prototype, "drag", function (p, e) { - console.log("drag"); - setIsDragging(true); // update vertical dotted line on drag @@ -442,8 +439,6 @@ export default function LandingChart({ }); Highcharts.wrap(Highcharts.Pointer.prototype, "drop", function (p, e) { - console.log("drop"); - setIsDragging(false); const elements = [ From fcf24064ee577884f2ee382c3c48917fef2cec7a Mon Sep 17 00:00:00 2001 From: Manish Gupta Date: Thu, 14 Sep 2023 08:05:14 -0700 Subject: [PATCH 28/33] zoom ui performance tweaks --- components/layout/LandingChart.tsx | 338 ++++++++++++++++------------- 1 file changed, 190 insertions(+), 148 deletions(-) diff --git a/components/layout/LandingChart.tsx b/components/layout/LandingChart.tsx index f5e9f0f4..598bdd88 100644 --- a/components/layout/LandingChart.tsx +++ b/components/layout/LandingChart.tsx @@ -206,6 +206,7 @@ export default function LandingChart({ const [isDragging, setIsDragging] = useState(false); const loadHighchartsWrappers = () => { + // on drag start Highcharts.wrap(Highcharts.Pointer.prototype, "dragStart", function (p, e) { // place vertical dotted line on click if (this.chart.series.length > 0) { @@ -214,6 +215,132 @@ export default function LandingChart({ this.chart.zoomStartX = x; this.chart.zoomStartY = y; + + if (!this.chart.zoomLineStart) { + this.chart.zoomLineStart = this.chart.renderer + .path([ + "M", + x, + this.chart.plotTop, + "L", + x, + this.chart.plotTop + this.chart.plotHeight, + ]) + .attr({ + stroke: "rgba(205, 216, 211, 1)", + "stroke-width": "1px", + "stroke-linejoin": "round", + "stroke-dasharray": "2, 1", + "shape-rendering": "crispEdges", + zIndex: 100, + }) + .add() + .toFront(); + } + + if (!this.chart.zoomLineEnd) { + this.chart.zoomLineEnd = this.chart.renderer + .path([ + "M", + x, + this.chart.plotTop, + "L", + x, + this.chart.plotTop + this.chart.plotHeight, + ]) + .attr({ + stroke: "rgba(205, 216, 211, 1)", + "stroke-width": "1px", + "stroke-linejoin": "round", + "stroke-dasharray": "2, 1", + "shape-rendering": "crispEdges", + zIndex: 100, + }) + .add() + .toFront(); + } + + if (!this.chart.zoomStartIcon) { + this.chart.zoomStartIcon = this.chart.renderer + .image("/cursors/rightArrow.svg", x - 17, y, 34, 34) + .attr({ + zIndex: 999, + }) + .add() + .toFront(); + } + + if (!this.chart.zoomEndIcon) { + this.chart.zoomEndIcon = this.chart.renderer + .image("/cursors/leftArrow.svg", x - 17, y, 34, 34) + .attr({ + zIndex: 999, + }) + .add() + .toFront(); + } + + if (!this.chart.numDaysText) { + this.chart.numDaysText = this.chart.renderer + .label(``, x, y) + .attr({ + zIndex: 999, + fill: "rgb(215, 223, 222)", + r: 5, + padding: 5, + "font-size": "12px", + "font-weight": "500", + align: "center", + opacity: 0.7, + }) + .css({ + color: "#2A3433", + }) + .add() + .shadow(true) + .toFront(); + } + + if (!this.chart.leftDateText) { + this.chart.leftDateText = this.chart.renderer + .label(``, x, this.chart.plotHeight - 20) + .attr({ + zIndex: 999, + fill: "#2A3433", + r: 5, + padding: 6, + "font-size": "12px", + "font-weight": "500", + align: "center", + }) + .css({ + color: "rgb(215, 223, 222)", + }) + .add() + .shadow(true) + .toFront(); + } + + if (!this.chart.rightDateText) { + this.chart.rightDateText = this.chart.renderer + .label(``, x, this.chart.plotHeight - 20) + .attr({ + zIndex: 999, + fill: "#2A3433", + r: 5, + padding: 6, + "font-size": "12px", + "font-weight": "500", + align: "center", + }) + .css({ + color: "rgb(215, 223, 222)", + "font-family": "Inter", + }) + .add() + .shadow(true) + .toFront(); + } } p.call(this); @@ -230,95 +357,62 @@ export default function LandingChart({ const leftX = this.chart.zoomStartX < x ? this.chart.zoomStartX : x; const rightX = this.chart.zoomStartX < x ? x : this.chart.zoomStartX; - if (this.chart.zoomLineStart) { - this.chart.zoomLineStart.destroy(); + if (this.chart.zoomLineStart.attr("visibility") === "hidden") { + this.chart.zoomLineStart.attr("visibility", "visible"); } - this.chart.zoomLineStart = this.chart.renderer - .path([ + this.chart.zoomLineStart.attr({ + d: [ "M", leftX, this.chart.plotTop, "L", leftX, this.chart.plotTop + this.chart.plotHeight, - ]) - .attr({ - stroke: "rgba(205, 216, 211, 1)", - "stroke-width": "1px", - "stroke-linejoin": "round", - "stroke-dasharray": "2, 1", - "shape-rendering": "crispEdges", - zIndex: 100, - }) - .add() - .toFront(); + ], + }); - if (this.chart.zoomLineEnd) { - this.chart.zoomLineEnd.destroy(); + if (this.chart.zoomLineEnd.attr("visibility") === "hidden") { + this.chart.zoomLineEnd.attr("visibility", "visible"); } - this.chart.zoomLineEnd = this.chart.renderer - .path([ + this.chart.zoomLineEnd.attr({ + d: [ "M", rightX, this.chart.plotTop, "L", rightX, this.chart.plotTop + this.chart.plotHeight, - ]) - .attr({ - stroke: "rgba(205, 216, 211, 1)", - "stroke-width": "1px", - "stroke-linejoin": "round", - "stroke-dasharray": "2, 1", - "shape-rendering": "crispEdges", - zIndex: 100, - }) - .add() - .toFront(); + ], + }); - if (this.chart.zoomStartIcon) { - this.chart.zoomStartIcon.destroy(); + if (this.chart.zoomStartIcon.attr("visibility") === "hidden") { + this.chart.zoomStartIcon.attr("visibility", "visible"); } - // place "rightArrow.svg" icon in middle of vertical dotted line - this.chart.zoomStartIcon = this.chart.renderer - .image( + this.chart.zoomStartIcon.attr({ + x: + x < this.chart.zoomStartX ? leftX - 17 : this.chart.zoomStartX - 17, + y: x < this.chart.zoomStartX ? y : this.chart.zoomStartY, + src: x < this.chart.zoomStartX - ? "/cursors/leftArrow.svg" - : "/cursors/rightArrow.svg", - this.chart.zoomStartX - 17, - this.chart.zoomStartY, - 34, - 34, - ) - .attr({ - zIndex: 999, - }) - .add() - .toFront(); + ? "/cursors/rightArrow.svg" + : "/cursors/leftArrow.svg", + }); - if (this.chart.zoomEndIcon) { - this.chart.zoomEndIcon.destroy(); + if (this.chart.zoomEndIcon.attr("visibility") === "hidden") { + this.chart.zoomEndIcon.attr("visibility", "visible"); } - // place "leftArrow.svg" icon in middle of vertical dotted line - this.chart.zoomEndIcon = this.chart.renderer - .image( + this.chart.zoomEndIcon.attr({ + x: x < this.chart.zoomStartX ? rightX - 17 : x - 17, + y: x < this.chart.zoomStartX ? this.chart.zoomStartY : y, + src: x < this.chart.zoomStartX - ? "/cursors/rightArrow.svg" - : "/cursors/leftArrow.svg", - x - 17, - y, - 34, - 34, - ) - .attr({ - zIndex: 999, - }) - .add() - .toFront(); + ? "/cursors/leftArrow.svg" + : "/cursors/rightArrow.svg", + }); // get the x value of the left and right edges of the selected area const leftXValue = this.chart.xAxis[0].toValue( @@ -338,101 +432,50 @@ export default function LandingChart({ (rightXValue - leftXValue) / (24 * 60 * 60 * 1000), ); - if (this.chart.numDaysText) { - this.chart.numDaysText.destroy(); + if (this.chart.numDaysText.attr("visibility") === "hidden") { + this.chart.numDaysText.attr("visibility", "visible"); } - // display the number of days selected - this.chart.numDaysText = this.chart.renderer - .label( - `${numDays} day${numDays > 1 ? "s" : ""}`, - leftX + (rightX - leftX) / 2, + this.chart.numDaysText.attr({ + text: `${numDays} day${numDays > 1 ? "s" : ""}`, + x: leftX + (rightX - leftX) / 2, + y: rightX - leftX < 160 ? this.chart.plotHeight - 50 : this.chart.plotHeight - 20, - ) - .attr({ - zIndex: 999, - fill: "rgb(215, 223, 222)", - r: 5, - padding: 5, - "font-size": "12px", - "font-weight": "500", - align: "center", - opacity: 0.7, - }) - .css({ - color: "#2A3433", - }) - .add() - .shadow(true) - .toFront(); + }); - if (this.chart.leftDateText) { - this.chart.leftDateText.destroy(); + if (this.chart.leftDateText.attr("visibility") === "hidden") { + this.chart.leftDateText.attr("visibility", "visible"); } // display the left date - this.chart.leftDateText = this.chart.renderer - .label( - `${leftDate.toLocaleDateString(undefined, { - timeZone: "UTC", - month: "short", - day: "numeric", - year: "numeric", - })}`, - leftX, - this.chart.plotHeight - 20, - ) - .attr({ - zIndex: 999, - fill: "#2A3433", - r: 5, - padding: 6, - "font-size": "12px", - "font-weight": "500", - align: "center", - }) - .css({ - color: "rgb(215, 223, 222)", - }) - .add() - .shadow(true) - .toFront(); + this.chart.leftDateText.attr({ + text: `${leftDate.toLocaleDateString(undefined, { + timeZone: "UTC", + month: "short", + day: "numeric", + year: "numeric", + })}`, + x: leftX, + y: this.chart.plotHeight - 20, + }); - if (this.chart.rightDateText) { - this.chart.rightDateText.destroy(); + if (this.chart.rightDateText.attr("visibility") === "hidden") { + this.chart.rightDateText.attr("visibility", "visible"); } // display the right date label with arrow pointing down - this.chart.rightDateText = this.chart.renderer - .label( - `${rightDate.toLocaleDateString(undefined, { - timeZone: "UTC", - month: "short", - day: "numeric", - year: "numeric", - })}`, - rightX, - this.chart.plotHeight - 20, - ) - .attr({ - zIndex: 999, - fill: "#2A3433", - r: 5, - padding: 6, - "font-size": "12px", - "font-weight": "500", - align: "center", - }) - .css({ - color: "rgb(215, 223, 222)", - "font-family": "Inter", - }) - .add() - .shadow(true); - - this.chart.rightDateText.toFront(); + this.chart.rightDateText.attr({ + text: `${rightDate.toLocaleDateString(undefined, { + timeZone: "UTC", + month: "short", + day: "numeric", + year: "numeric", + })}`, + x: rightX, + y: this.chart.plotHeight - 20, + }); } p.call(this); @@ -454,8 +497,7 @@ export default function LandingChart({ elements.forEach((element) => { if (this.chart[element]) { try { - this.chart[element].destroy(); - this.chart[element] = null; + this.chart[element].attr("visibility", "hidden"); } catch (e) { console.log(e); } From 4db4b917eb7b3be37ef5548b5a6fa9c752032cf8 Mon Sep 17 00:00:00 2001 From: Manish Gupta Date: Thu, 14 Sep 2023 08:09:10 -0700 Subject: [PATCH 29/33] zoom ui font fix --- components/layout/LandingChart.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/components/layout/LandingChart.tsx b/components/layout/LandingChart.tsx index 598bdd88..22dadb7c 100644 --- a/components/layout/LandingChart.tsx +++ b/components/layout/LandingChart.tsx @@ -335,7 +335,6 @@ export default function LandingChart({ }) .css({ color: "rgb(215, 223, 222)", - "font-family": "Inter", }) .add() .shadow(true) From c81cd63b8fe4e096de082230c374ae9a855a4f07 Mon Sep 17 00:00:00 2001 From: mokelgit Date: Thu, 14 Sep 2023 18:31:00 -0400 Subject: [PATCH 30/33] added why's to navigation --- lib/navigation.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/navigation.tsx b/lib/navigation.tsx index d51d9e49..318b6aa6 100644 --- a/lib/navigation.tsx +++ b/lib/navigation.tsx @@ -155,7 +155,7 @@ export const navigationItems: NavigationItem[] = [ title: "Rent Paid to L1", description: "The gas fees paid by L2s to post transaction data & verification states onto Ethereum.", - why: "Rent paid is a critical metric for ...", + why: "Rent paid to L1 quantifies the expenses associated with posting L2 transaction data and proofs onto the Ethereum blockchain. The term 'rent' signifies the gas fees L2s incur to leverage the security of the Ethereum blockchain. This metric provides valuable insights into the value accrual for ETH holders.", icon: "feather:credit-card", }, icon: "feather:credit-card", @@ -170,7 +170,7 @@ export const navigationItems: NavigationItem[] = [ title: "Onchain Profit", description: "The net profit of L2s, accounting for revenues as L2 gas fees collected and expenses as posting transaction data & verification states onto Ethereum.", - why: "Earnings is a critical metric for ...", + why: "Onchain Profit is a key metric for assessing the financial viability of scaling solutions. It quantifies profitability by comparing the revenue generated from L2 gas fees collected to the costs associated with data & proof posting onto the Ethereum blockchain. L2 profitability can increases for two reasons: firstly, when there is high demand for L2 blockspace, enabling an auction of the available blockspace for a premium. Secondly, if the operator (who controls the sequencer) increases the base fee scalar. This metric can be used to gauge the health and success of Layer 2 solutions.", icon: "feather:credit-card", }, icon: "feather:credit-card", From f29bee675ee8936eedbbf70381b87d1594aba1bd Mon Sep 17 00:00:00 2001 From: mokelgit Date: Thu, 14 Sep 2023 19:09:30 -0400 Subject: [PATCH 31/33] Fixed margins for overview page --- components/layout/CategoryMetrics.tsx | 2 +- components/layout/OverviewMetrics.tsx | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/components/layout/CategoryMetrics.tsx b/components/layout/CategoryMetrics.tsx index d98713b9..b0b2ae3e 100644 --- a/components/layout/CategoryMetrics.tsx +++ b/components/layout/CategoryMetrics.tsx @@ -1626,7 +1626,7 @@ export default function CategoryMetrics({
-
+
-
+
{chartAvg && ( -
+
{" "} -
+
{/* */} {/*
*/} {/* toggle ETH */} @@ -1655,7 +1655,7 @@ export default function OverviewMetrics({ -
+
+ {usageData && ( (MasterURL); + // get the category from the url + const queryCategory = useSearchParams().get("category"); + // subcategories is an array of strings + const querySubcategories = useSearchParams().get("subcategories")?.split(","); + type ContractInfo = { address: string; project_name: string; @@ -78,7 +84,9 @@ export default function CategoryMetrics({ }; const { isSidebarOpen } = useUIContext(); const [selectedMode, setSelectedMode] = useState("gas_fees_"); - const [selectedCategory, setSelectedCategory] = useState("nft"); + const [selectedCategory, setSelectedCategory] = useState( + queryCategory ?? "nft", + ); const [contractHover, setContractHover] = useState({}); const [animationFinished, setAnimationFinished] = useState(true); @@ -285,6 +293,20 @@ export default function CategoryMetrics({ const updatedSubcategories = useMemo(() => { const initialSelectedSubcategories = {}; Object.keys(categories).forEach((category) => { + if (queryCategory === category && querySubcategories.length > 0) { + const intersection = data[category].subcategories.list.filter( + (subcategory) => { + return querySubcategories.includes(subcategory); + }, + ); + + if (intersection.length > 0) { + initialSelectedSubcategories[category] = intersection; + return; + } + } + + // else use the default subcategories if (data[category]?.subcategories?.list) { initialSelectedSubcategories[category] = [ ...data[category].subcategories.list, @@ -294,7 +316,7 @@ export default function CategoryMetrics({ } }); return initialSelectedSubcategories; - }, [data, categories]); + }, [categories, queryCategory, data, querySubcategories]); const [selectedSubcategories, setSelectedSubcategories] = useState(updatedSubcategories); diff --git a/components/layout/ContractCard.tsx b/components/layout/ContractCard.tsx index 314c0773..e221c1e0 100644 --- a/components/layout/ContractCard.tsx +++ b/components/layout/ContractCard.tsx @@ -21,6 +21,7 @@ import Image from "next/image"; import d3 from "d3"; import { AllChainsByKeys } from "@/lib/chains"; import { debounce, forEach } from "lodash"; +import Link from "next/link"; import { navigationItems } from "@/lib/navigation"; import { useUIContext } from "@/contexts/UIContext"; @@ -63,85 +64,93 @@ export default function ContractCard({ const [showUsd, setShowUsd] = useLocalStorage("showUsd", true); return ( -
-
-
-
-
-
- {/*
+
+
+
+
+
+
+ {/*
*/} - -
-
- {AllChainsByKeys[data[types.indexOf("chain")]].label} + +
+
+ {AllChainsByKeys[data[types.indexOf("chain")]].label} +
+
+ <> + {showUsd ? ( + <> +
$
+
+ {Intl.NumberFormat(undefined, { + maximumFractionDigits: 2, + minimumFractionDigits: 2, + }).format(data[types.indexOf("gas_fees_absolute_usd")])} +
+ + ) : ( + <> +
Ξ
+
+ {Intl.NumberFormat(undefined, { + maximumFractionDigits: 2, + minimumFractionDigits: 2, + }).format( + data[types.indexOf("gas_fees_absolute_eth")], + )}{" "} + ETH +
+ + )} + +
-
- <> - {showUsd ? ( - <> -
$
-
- {Intl.NumberFormat(undefined, { - maximumFractionDigits: 2, - minimumFractionDigits: 2, - }).format(data[types.indexOf("gas_fees_absolute_usd")])} -
- - ) : ( - <> -
Ξ
-
- {Intl.NumberFormat(undefined, { - maximumFractionDigits: 2, - minimumFractionDigits: 2, - }).format(data[types.indexOf("gas_fees_absolute_eth")])}{" "} - ETH -
- - )} - +
+ {data[types.indexOf("project_name")]}
-
-
- {data[types.indexOf("project_name")]} -
-
-
-
- {data[types.indexOf("main_category_key")]} >{" "} - {data[types.indexOf("sub_category_key")]} +
+
+
+ {data[types.indexOf("main_category_key")]} >{" "} + {data[types.indexOf("sub_category_key")]} +
+ +
- -
-
+ ); } diff --git a/components/layout/LandingChart.tsx b/components/layout/LandingChart.tsx index 22dadb7c..193b662b 100644 --- a/components/layout/LandingChart.tsx +++ b/components/layout/LandingChart.tsx @@ -392,8 +392,10 @@ export default function LandingChart({ this.chart.zoomStartIcon.attr({ x: - x < this.chart.zoomStartX ? leftX - 17 : this.chart.zoomStartX - 17, - y: x < this.chart.zoomStartX ? y : this.chart.zoomStartY, + x < this.chart.zoomStartX + ? leftX - 14.5 + : this.chart.zoomStartX - 14.5, + y: x < this.chart.zoomStartX ? y - 15 : this.chart.zoomStartY - 15, src: x < this.chart.zoomStartX ? "/cursors/rightArrow.svg" @@ -405,8 +407,8 @@ export default function LandingChart({ } this.chart.zoomEndIcon.attr({ - x: x < this.chart.zoomStartX ? rightX - 17 : x - 17, - y: x < this.chart.zoomStartX ? this.chart.zoomStartY : y, + x: x < this.chart.zoomStartX ? rightX - 14.5 : x - 14.5, + y: x < this.chart.zoomStartX ? this.chart.zoomStartY - 15 : y - 15, src: x < this.chart.zoomStartX ? "/cursors/leftArrow.svg" @@ -1624,7 +1626,7 @@ export default function LandingChart({ style={{ cursor: isDragging ? "none" - : `url("/cursors/zoom.svg") 17 17, auto`, + : `url("/cursors/zoom.svg") 14.5 14.5, auto`, }} // onClick={(e) => { // const chart = chartComponent?.current; diff --git a/public/cursors/leftArrow.svg b/public/cursors/leftArrow.svg index 71f79e1d..0830e7aa 100644 --- a/public/cursors/leftArrow.svg +++ b/public/cursors/leftArrow.svg @@ -1,16 +1,18 @@ - - - - - - + + + + + + + + - + - - + + diff --git a/public/cursors/rightArrow.svg b/public/cursors/rightArrow.svg index 43d6cec6..fdd2c567 100644 --- a/public/cursors/rightArrow.svg +++ b/public/cursors/rightArrow.svg @@ -1,16 +1,18 @@ - - - - - - + + + + + + + + - + - - + + diff --git a/public/cursors/zoom.svg b/public/cursors/zoom.svg index 6ff69316..48f7953e 100644 --- a/public/cursors/zoom.svg +++ b/public/cursors/zoom.svg @@ -1,19 +1,21 @@ - - - - - - - - + + + + + + + + + + - + - - + + - + \ No newline at end of file From c22b9c6cb5ce29755d2ff668ea506074390b66ee Mon Sep 17 00:00:00 2001 From: Manish Gupta Date: Thu, 14 Sep 2023 17:52:12 -0700 Subject: [PATCH 33/33] commented new landing features for main deployment --- app/page.tsx | 39 ++++++++++++++++-------------- components/layout/LandingChart.tsx | 12 ++++----- 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/app/page.tsx b/app/page.tsx index 4c294f5b..1d8b22a7 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -48,19 +48,19 @@ export default function Home() { isValidating: masterValidating, } = useSWR(MasterURL); - const { - data: chainData, - error: chainError, - isValidating: chainValidating, - isLoading: chainLoading, - } = useSWR(ChainURLs["arbitrum"]); + // const { + // data: chainData, + // error: chainError, + // isValidating: chainValidating, + // isLoading: chainLoading, + // } = useSWR(ChainURLs["arbitrum"]); - const { - data: blockspaceData, - error: blockspaceError, - isValidating: blockspaceValidating, - isLoading: blockspaceLoading, - } = useSWR(BlockspaceURLs["chain-overview"]); + // const { + // data: blockspaceData, + // error: blockspaceError, + // isValidating: blockspaceValidating, + // isLoading: blockspaceLoading, + // } = useSWR(BlockspaceURLs["chain-overview"]); const [data, setData] = useState(null); @@ -103,11 +103,14 @@ export default function Home() { {/* )} */} + Growing Ethereum’s Ecosystem Together + + {/* Mastering Ethereum Layer-2s: Your Gateway to Curated Analytics and Knowledge - + */} - + {/*
- )} + )} */} - {/* {data && landing && master && } */} + {data && landing && master && } {/* Compare Ethereum's Layer-2 solutions and better understand the metrics to grow the ecosystem. @@ -211,7 +214,7 @@ export default function Home() { )} - + {/*
)} - + */}
diff --git a/components/layout/LandingChart.tsx b/components/layout/LandingChart.tsx index 193b662b..f537288b 100644 --- a/components/layout/LandingChart.tsx +++ b/components/layout/LandingChart.tsx @@ -518,7 +518,7 @@ export default function LandingChart({ highchartsRoundedCorners(Highcharts); highchartsAnnotations(Highcharts); - loadHighchartsWrappers(); + // loadHighchartsWrappers(); setHighchartsLoaded(true); }, []); @@ -1623,11 +1623,11 @@ export default function LandingChart({
{ // const chart = chartComponent?.current;