From 206baa13e6242c99bbaa21576ee74b4447bc542e Mon Sep 17 00:00:00 2001
From: syuilo <Syuilotan@yahoo.co.jp>
Date: Thu, 20 Apr 2023 10:41:09 +0900
Subject: enhance(frontend): tweak retention rate heatmap rendering

---
 .../frontend/src/components/MkRetentionHeatmap.vue | 26 ++++++++++++++++------
 1 file changed, 19 insertions(+), 7 deletions(-)

(limited to 'packages/frontend/src/components/MkRetentionHeatmap.vue')

diff --git a/packages/frontend/src/components/MkRetentionHeatmap.vue b/packages/frontend/src/components/MkRetentionHeatmap.vue
index 85c009f746..f33f68cab7 100644
--- a/packages/frontend/src/components/MkRetentionHeatmap.vue
+++ b/packages/frontend/src/components/MkRetentionHeatmap.vue
@@ -44,7 +44,13 @@ async function renderChart() {
 
 	const data = [];
 	for (const record of raw) {
-		let i = 0;
+		data.push({
+			x: 0,
+			y: record.createdAt,
+			v: record.users,
+		});
+
+		let i = 1;
 		for (const date of Object.keys(record.data).sort((a, b) => new Date(a).getTime() - new Date(b).getTime())) {
 			data.push({
 				x: i,
@@ -61,8 +67,14 @@ async function renderChart() {
 
 	const color = defaultStore.state.darkMode ? '#b4e900' : '#86b300';
 
-	// 視覚上の分かりやすさのため上から最も大きい3つの値の平均を最大値とする
-	const max = raw.map(x => x.users).slice().sort((a, b) => b - a).slice(0, 3).reduce((a, b) => a + b, 0) / 3;
+	const getYYYYMMDD = (date: Date) => {
+		const y = date.getFullYear().toString().padStart(2, '0');
+		const m = (date.getMonth() + 1).toString().padStart(2, '0');
+		const d = date.getDate().toString().padStart(2, '0');
+		return `${y}/${m}/${d}`;
+	};
+
+	const max = (createdAt: string) => raw.find(x => x.createdAt === createdAt)!.users;
 
 	const marginEachCell = 12;
 
@@ -78,7 +90,7 @@ async function renderChart() {
 				borderRadius: 3,
 				backgroundColor(c) {
 					const value = c.dataset.data[c.dataIndex].v;
-					const a = value / max;
+					const a = value / max(c.dataset.data[c.dataIndex].y);
 					return alpha(color, a);
 				},
 				fill: true,
@@ -115,7 +127,7 @@ async function renderChart() {
 						maxRotation: 0,
 						autoSkipPadding: 0,
 						autoSkip: false,
-						callback: (value, index, values) => value + 1,
+						callback: (value, index, values) => value,
 					},
 				},
 				y: {
@@ -150,11 +162,11 @@ async function renderChart() {
 					callbacks: {
 						title(context) {
 							const v = context[0].dataset.data[context[0].dataIndex];
-							return v.d;
+							return getYYYYMMDD(new Date(new Date(v.y).getTime() + (v.x * 86400000)));
 						},
 						label(context) {
 							const v = context.dataset.data[context.dataIndex];
-							return ['Active: ' + v.v];
+							return [`Active: ${v.v} (${Math.round((v.v / max(v.y)) * 100)}%)`];
 						},
 					},
 					//mode: 'index',
-- 
cgit v1.2.3-freya

