diff --git a/apps/dashboard/src/@/styles/globals.css b/apps/dashboard/src/@/styles/globals.css
index 130d30b7afa..d89596e0c75 100644
--- a/apps/dashboard/src/@/styles/globals.css
+++ b/apps/dashboard/src/@/styles/globals.css
@@ -40,8 +40,6 @@
/* Others */
--radius: 0.5rem;
- --chart-lightness: 50%;
- --chart-saturation: 50%;
}
.dark,
@@ -78,9 +76,6 @@
--border: 0 0% 15%;
--ring: 0 0% 30%;
--input: 0 0% 15%;
-
- --chart-lightness: 50%;
- --chart-saturation: 50%;
}
}
diff --git a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/analytics/_components/ConnectAnalyticsDashboard.stories.tsx b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/analytics/_components/ConnectAnalyticsDashboard.stories.tsx
index 6d638db5bd8..a958f48713d 100644
--- a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/analytics/_components/ConnectAnalyticsDashboard.stories.tsx
+++ b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/analytics/_components/ConnectAnalyticsDashboard.stories.tsx
@@ -27,7 +27,7 @@ export const Mobile: Story = {
function Component() {
return (
-
+
+
(
"uniqueWalletsConnected",
@@ -48,40 +50,59 @@ export function WalletConnectorsChartCard(props: {
const { chartConfig, chartData } = useMemo(() => {
const _chartConfig: ChartConfig = {};
const _chartDataMap: Map = new Map();
-
- for (const data of walletStats) {
- const chartData = _chartDataMap.get(data.date);
- const dataKey = data.walletType;
+ const walletTypeToValueMap: Map = new Map();
+ // for each stat, add it in _chartDataMap
+ for (const stat of walletStats) {
+ const chartData = _chartDataMap.get(stat.date);
+ const { walletType } = stat;
// if no data for current day - create new entry
if (!chartData) {
- _chartDataMap.set(data.date, {
- time: format(new Date(data.date), "MMM dd"),
- [data.walletType]: data[chartToShow],
+ _chartDataMap.set(stat.date, {
+ time: format(new Date(stat.date), "MMM dd"),
+ [walletType]: stat[chartToShow],
} as ChartData);
} else {
- if (dataKey in chartData) {
- chartData[dataKey] += data[chartToShow];
- } else {
- chartData[dataKey] = data[chartToShow];
- }
+ chartData[walletType] =
+ (chartData[walletType] || 0) + stat[chartToShow];
}
+
+ walletTypeToValueMap.set(
+ walletType,
+ stat[chartToShow] + (walletTypeToValueMap.get(walletType) || 0),
+ );
}
- // create chart config for each wallet type and assign a unique color, start from 0hue to 360hue
- const uniqueWalletTypes = Array.from(
- new Set(walletStats.map((data) => data.walletType)),
- );
- const hueIncrement = 360 / uniqueWalletTypes.length;
+ const walletTypesSorted = Array.from(walletTypeToValueMap.entries())
+ .sort((a, b) => b[1] - a[1])
+ .map((w) => w[0]);
- for (let i = 0; i < uniqueWalletTypes.length; i++) {
- const walletType = uniqueWalletTypes[i];
+ const walletTypesToShow = walletTypesSorted.slice(0, topWalletsToShow);
+ const walletTypesToTagAsOthers = walletTypesSorted.slice(topWalletsToShow);
+
+ // replace walletTypesToTagAsOthers walletType with "other"
+ for (const data of _chartDataMap.values()) {
+ for (const walletType in data) {
+ if (walletTypesToTagAsOthers.includes(walletType)) {
+ data.others = (data.others || 0) + (data[walletType] || 0);
+ delete data[walletType];
+ }
+ }
+ }
+ walletTypesToShow.forEach((walletType, i) => {
_chartConfig[walletType] = {
- label: uniqueWalletTypes[i],
- color: `hsl(${i + hueIncrement * i}deg, var(--chart-saturation), var(--chart-lightness))`,
+ label: walletTypesToShow[i],
+ color: `hsl(var(--chart-${(i % 10) + 1}))`,
};
- }
+ });
+
+ // Add Other
+ walletTypesToShow.push("others");
+ _chartConfig.others = {
+ label: "Others",
+ color: "hsl(var(--muted-foreground))",
+ };
return {
chartData: Array.from(_chartDataMap.values()),
diff --git a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/analytics/_components/WalletConnectorsChartChart.stories.tsx b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/analytics/_components/WalletConnectorsChartChart.stories.tsx
index a3c699bbecd..cf3e3cc8fc8 100644
--- a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/analytics/_components/WalletConnectorsChartChart.stories.tsx
+++ b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/analytics/_components/WalletConnectorsChartChart.stories.tsx
@@ -30,7 +30,7 @@ export const Mobile: Story = {
function Component() {
return (
-
+
+
= {
- unique: "Unique Wallets",
- total: "Total Wallets",
+ uniqueWalletsConnected: "Unique Wallets",
+ totalConnections: "Total Wallets",
};
export function WalletDistributionChartCard(props: {
walletStats: WalletStats[];
isPending: boolean;
}) {
+ // show these many top wallets as distinct, and combine the rest as "Others"
+ const topWalletsToShow = 10;
const { walletStats } = props;
- const [chartToShow, setChartToShow] = useState("total");
- const chartToShowOptions: ChartToShow[] = ["total", "unique"];
+ const [chartToShow, setChartToShow] =
+ useState("totalConnections");
+ const chartToShowOptions: ChartToShow[] = [
+ "totalConnections",
+ "uniqueWalletsConnected",
+ ];
const { chartConfig, chartData, totalConnections, uniqueConnections } =
useMemo(() => {
- const _chartConfig: ChartConfig = {};
- const _chartDataMap: Map<
- string,
- {
- total: number;
- unique: number;
- }
- > = new Map();
+ const _chartDataMap: Map = new Map();
+ const walletTypeToValueMap: Map = new Map();
let _totalConnections = 0;
let _uniqueConnections = 0;
- for (const data of walletStats) {
- const chartData = _chartDataMap.get(data.walletType);
-
- _totalConnections += data.totalConnections;
- _uniqueConnections += data.uniqueWalletsConnected;
-
- // if no data for current day - create new entry
- if (!chartData) {
- _chartDataMap.set(data.walletType, {
- total: data.totalConnections,
- unique: data.uniqueWalletsConnected,
- });
- } else {
- _chartDataMap.set(data.walletType, {
- total: chartData.total + data.totalConnections,
- unique: chartData.unique + data.uniqueWalletsConnected,
- });
- }
+ for (const stat of walletStats) {
+ const { walletType } = stat;
+ const chartData = _chartDataMap.get(walletType);
+
+ _totalConnections += stat.totalConnections;
+ _uniqueConnections += stat.uniqueWalletsConnected;
+ _chartDataMap.set(walletType, (chartData || 0) + stat[chartToShow]);
+ walletTypeToValueMap.set(
+ walletType,
+ (walletTypeToValueMap.get(walletType) || 0) + stat[chartToShow],
+ );
}
- // create chart config for each wallet type and assign a unique color, start from 0hue to 360hue
- const uniqueWalletTypes = Array.from(
- new Set(walletStats.map((data) => data.walletType)),
+ const walletTypesSortedByValue = Array.from(
+ walletTypeToValueMap.entries(),
+ )
+ .sort((a, b) => b[1] - a[1])
+ .map((w) => w[0]);
+
+ const walletTypesToShow = walletTypesSortedByValue.slice(
+ 0,
+ topWalletsToShow,
);
- const hueIncrement = 360 / uniqueWalletTypes.length;
+ const walletTypesToTagAsOthers =
+ walletTypesSortedByValue.slice(topWalletsToShow);
- for (let i = 0; i < uniqueWalletTypes.length; i++) {
- const walletType = uniqueWalletTypes[i];
+ for (const walletType of walletTypesToTagAsOthers) {
+ const val = _chartDataMap.get(walletType);
+ if (val) {
+ const othersVal = _chartDataMap.get("others");
+ _chartDataMap.set("others", othersVal ? othersVal + val : val);
+ }
+
+ _chartDataMap.delete(walletType);
+ }
+
+ const _chartConfig: ChartConfig = {};
+ walletTypesToShow.forEach((walletType, i) => {
_chartConfig[walletType] = {
- label: uniqueWalletTypes[i],
- color: `hsl(${i + hueIncrement * i}deg, var(--chart-saturation), var(--chart-lightness))`,
+ label: walletTypesToShow[i],
+ color: `hsl(var(--chart-${(i % 10) + 1}))`,
};
- }
+ });
+
+ // Add Others
+ _chartConfig.others = {
+ label: "Others",
+ color: "hsl(var(--muted-foreground))",
+ };
const _chartData: ChartData[] = Array.from(_chartDataMap).map(
([walletType, data]) => {
return {
walletType,
- totalWallets: data.total,
- uniqueWallets: data.unique,
+ value: data,
fill: _chartConfig[walletType].color || "transparent",
};
},
);
// sort the data
- _chartData.sort((a, b) => b.totalWallets - a.totalWallets);
+ _chartData.sort((a, b) => b.value - a.value);
return {
chartData: _chartData,
@@ -112,7 +126,7 @@ export function WalletDistributionChartCard(props: {
totalConnections: _totalConnections,
uniqueConnections: _uniqueConnections,
};
- }, [walletStats]);
+ }, [walletStats, chartToShow]);
const disableActions = props.isPending || chartData.length === 0;
return (
@@ -152,23 +166,14 @@ export function WalletDistributionChartCard(props: {
getData={async () => {
const header = [
"Wallet",
- "Total Connections",
- "Unique Connections",
- "Percentage of Total connections",
- "Percentage of Unique connections",
+ `${chartToShow === "totalConnections" ? "Total" : "Unique"} Connections`,
+ `Percentage of ${chartToShow === "totalConnections" ? "Total" : "Unique"} Connections`,
];
const rows = chartData.map((d) => {
return [
- // name
d.walletType,
- // total connections
- d.totalWallets.toString(),
- // unique connections
- d.uniqueWallets.toString(),
- // percentage of total connections
- `${((d.totalWallets / totalConnections) * 100).toFixed(2)}%`,
- // percentage of unique connections
- `${((d.uniqueWallets / uniqueConnections) * 100).toFixed(2)}%`,
+ d.value.toString(),
+ `${((d.value / (chartToShow === "totalConnections" ? totalConnections : uniqueConnections)) * 100).toFixed(2)}%`,
];
});
return {
@@ -197,7 +202,7 @@ export function WalletDistributionChartCard(props: {
valueFormatter={(v) => {
if (typeof v === "number") {
const sumValue =
- chartToShow === "unique"
+ chartToShow === "uniqueWalletsConnected"
? uniqueConnections
: totalConnections;
const percentageValue = ((v / sumValue) * 100).toFixed(2);
@@ -210,9 +215,7 @@ export function WalletDistributionChartCard(props: {
} className="" />
{