diff --git a/packages/client/src/components/instance-stats.vue b/packages/client/src/components/instance-stats.vue index 2f83b2f89..c210371c6 100644 --- a/packages/client/src/components/instance-stats.vue +++ b/packages/client/src/components/instance-stats.vue @@ -106,7 +106,7 @@ const { handler: externalTooltipHandler1 } = useChartTooltip(); const { handler: externalTooltipHandler2 } = useChartTooltip(); function createDoughnut(chartEl, tooltip, data) { - return new Chart(chartEl, { + const chartInstance = new Chart(chartEl, { type: 'doughnut', data: { labels: data.map(x => x.name), @@ -127,6 +127,12 @@ function createDoughnut(chartEl, tooltip, data) { bottom: 16, }, }, + onClick: (ev) => { + const hit = chartInstance.getElementsAtEventForMode(ev, 'nearest', { intersect: true }, false)[0]; + if (hit && data[hit.index].onClick) { + data[hit.index].onClick(); + } + }, plugins: { legend: { display: false, @@ -142,12 +148,29 @@ function createDoughnut(chartEl, tooltip, data) { }, }, }); + + return chartInstance; } onMounted(() => { os.apiGet('federation/stats', { limit: 15 }).then(fedStats => { - createDoughnut(subDoughnutEl, externalTooltipHandler1, fedStats.topSubInstances.map(x => ({ name: x.host, color: x.themeColor, value: x.followersCount })).concat([{ name: '(other)', color: '#80808080', value: fedStats.otherFollowersCount }])); - createDoughnut(pubDoughnutEl, externalTooltipHandler1, fedStats.topPubInstances.map(x => ({ name: x.host, color: x.themeColor, value: x.followingCount })).concat([{ name: '(other)', color: '#80808080', value: fedStats.otherFollowingCount }])); + createDoughnut(subDoughnutEl, externalTooltipHandler1, fedStats.topSubInstances.map(x => ({ + name: x.host, + color: x.themeColor, + value: x.followersCount, + onClick: () => { + os.pageWindow(`/instance-info/${x.host}`); + }, + })).concat([{ name: '(other)', color: '#80808080', value: fedStats.otherFollowersCount }])); + + createDoughnut(pubDoughnutEl, externalTooltipHandler2, fedStats.topPubInstances.map(x => ({ + name: x.host, + color: x.themeColor, + value: x.followingCount, + onClick: () => { + os.pageWindow(`/instance-info/${x.host}`); + }, + })).concat([{ name: '(other)', color: '#80808080', value: fedStats.otherFollowingCount }])); }); }); diff --git a/packages/client/src/pages/admin/overview.pie.vue b/packages/client/src/pages/admin/overview.pie.vue index 667f236d9..d3b203287 100644 --- a/packages/client/src/pages/admin/overview.pie.vue +++ b/packages/client/src/pages/admin/overview.pie.vue @@ -45,7 +45,7 @@ Chart.register( ); const props = defineProps<{ - data: { name: string; value: number; color: string; }[]; + data: { name: string; value: number; color: string; onClick?: () => void }[]; }>(); const chartEl = ref(null); @@ -79,6 +79,12 @@ onMounted(() => { bottom: 16, }, }, + onClick: (ev) => { + const hit = chartInstance.getElementsAtEventForMode(ev, 'nearest', { intersect: true }, false)[0]; + if (hit && props.data[hit.index].onClick) { + props.data[hit.index].onClick(); + } + }, plugins: { legend: { display: false, diff --git a/packages/client/src/pages/admin/overview.vue b/packages/client/src/pages/admin/overview.vue index 393ee6645..d2fa4e0e4 100644 --- a/packages/client/src/pages/admin/overview.vue +++ b/packages/client/src/pages/admin/overview.vue @@ -119,16 +119,16 @@ -
+
Sub
- +
Top 10
Pub
- +
Top 10
@@ -200,7 +200,8 @@ const rootEl = $ref(); const chartEl = $ref(null); let stats: any = $ref(null); let serverInfo: any = $ref(null); -let fedStats: any = $ref(null); +let topSubInstancesForPie: any = $ref(null); +let topPubInstancesForPie: any = $ref(null); let usersComparedToThePrevDay: any = $ref(null); let notesComparedToThePrevDay: any = $ref(null); let federationPubActive = $ref(null); @@ -412,7 +413,22 @@ onMounted(async () => { }); os.apiGet('federation/stats', { limit: 10 }).then(res => { - fedStats = res; + topSubInstancesForPie = fedStats.topSubInstances.map(x => ({ + name: x.host, + color: x.themeColor, + value: x.followersCount, + onClick: () => { + os.pageWindow(`/instance-info/${x.host}`); + }, + })).concat([{ name: '(other)', color: '#80808080', value: fedStats.otherFollowersCount }]); + topPubInstancesForPie = fedStats.topPubInstances.map(x => ({ + name: x.host, + color: x.themeColor, + value: x.followingCount, + onClick: () => { + os.pageWindow(`/instance-info/${x.host}`); + }, + })).concat([{ name: '(other)', color: '#80808080', value: fedStats.otherFollowingCount }]); }); os.api('admin/server-info').then(serverInfoResponse => {