Add D1 and W1 (new users) to stats
This commit is contained in:
parent
a9e5020904
commit
b93af31d2f
|
@ -3,6 +3,9 @@ export type Stats = {
|
||||||
dailyActiveUsers: number[]
|
dailyActiveUsers: number[]
|
||||||
weeklyActiveUsers: number[]
|
weeklyActiveUsers: number[]
|
||||||
monthlyActiveUsers: number[]
|
monthlyActiveUsers: number[]
|
||||||
|
d1: number[]
|
||||||
|
d1Weekly: number[]
|
||||||
|
w1NewUsers: number[]
|
||||||
dailyBetCounts: number[]
|
dailyBetCounts: number[]
|
||||||
dailyContractCounts: number[]
|
dailyContractCounts: number[]
|
||||||
dailyCommentCounts: number[]
|
dailyCommentCounts: number[]
|
||||||
|
|
|
@ -142,40 +142,77 @@ export const updateStatsCore = async () => {
|
||||||
|
|
||||||
const weeklyActiveUsers = dailyUserIds.map((_, i) => {
|
const weeklyActiveUsers = dailyUserIds.map((_, i) => {
|
||||||
const start = Math.max(0, i - 6)
|
const start = Math.max(0, i - 6)
|
||||||
const end = i
|
const end = i + 1
|
||||||
const uniques = new Set<string>()
|
const uniques = new Set<string>(dailyUserIds.slice(start, end).flat())
|
||||||
for (let j = start; j <= end; j++)
|
|
||||||
dailyUserIds[j].forEach((userId) => uniques.add(userId))
|
|
||||||
return uniques.size
|
return uniques.size
|
||||||
})
|
})
|
||||||
|
|
||||||
const monthlyActiveUsers = dailyUserIds.map((_, i) => {
|
const monthlyActiveUsers = dailyUserIds.map((_, i) => {
|
||||||
const start = Math.max(0, i - 29)
|
const start = Math.max(0, i - 29)
|
||||||
const end = i
|
const end = i + 1
|
||||||
const uniques = new Set<string>()
|
const uniques = new Set<string>(dailyUserIds.slice(start, end).flat())
|
||||||
for (let j = start; j <= end; j++)
|
|
||||||
dailyUserIds[j].forEach((userId) => uniques.add(userId))
|
|
||||||
return uniques.size
|
return uniques.size
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const d1 = dailyUserIds.map((userIds, i) => {
|
||||||
|
if (i === 0) return 0
|
||||||
|
|
||||||
|
const uniques = new Set(userIds)
|
||||||
|
const yesterday = dailyUserIds[i - 1]
|
||||||
|
|
||||||
|
const retainedCount = sumBy(yesterday, (userId) =>
|
||||||
|
uniques.has(userId) ? 1 : 0
|
||||||
|
)
|
||||||
|
return retainedCount / uniques.size
|
||||||
|
})
|
||||||
|
|
||||||
|
const d1Weekly = d1.map((_, i) => {
|
||||||
|
const start = Math.max(0, i - 6)
|
||||||
|
const end = i + 1
|
||||||
|
return average(d1.slice(start, end))
|
||||||
|
})
|
||||||
|
|
||||||
|
const dailyNewUserIds = dailyNewUsers.map((users) => users.map((u) => u.id))
|
||||||
|
const w1NewUsers = dailyNewUserIds.map((_userIds, i) => {
|
||||||
|
if (i < 13) return 0
|
||||||
|
|
||||||
|
const twoWeeksAgo = {
|
||||||
|
start: Math.max(0, i - 13),
|
||||||
|
end: Math.max(0, i - 6),
|
||||||
|
}
|
||||||
|
const lastWeek = {
|
||||||
|
start: Math.max(0, i - 6),
|
||||||
|
end: i + 1,
|
||||||
|
}
|
||||||
|
const newTwoWeeksAgo = new Set<string>(
|
||||||
|
dailyNewUserIds.slice(twoWeeksAgo.start, twoWeeksAgo.end).flat()
|
||||||
|
)
|
||||||
|
const activeLastWeek = new Set<string>(
|
||||||
|
dailyUserIds.slice(lastWeek.start, lastWeek.end).flat()
|
||||||
|
)
|
||||||
|
const retainedCount = sumBy(Array.from(newTwoWeeksAgo), (userId) =>
|
||||||
|
activeLastWeek.has(userId) ? 1 : 0
|
||||||
|
)
|
||||||
|
const retainedFrac = retainedCount / newTwoWeeksAgo.size
|
||||||
|
return Math.round(retainedFrac * 100 * 100) / 100
|
||||||
|
})
|
||||||
|
|
||||||
const weekOnWeekRetention = dailyUserIds.map((_userId, i) => {
|
const weekOnWeekRetention = dailyUserIds.map((_userId, i) => {
|
||||||
const twoWeeksAgo = {
|
const twoWeeksAgo = {
|
||||||
start: Math.max(0, i - 13),
|
start: Math.max(0, i - 13),
|
||||||
end: Math.max(0, i - 7),
|
end: Math.max(0, i - 6),
|
||||||
}
|
}
|
||||||
const lastWeek = {
|
const lastWeek = {
|
||||||
start: Math.max(0, i - 6),
|
start: Math.max(0, i - 6),
|
||||||
end: i,
|
end: i + 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
const activeTwoWeeksAgo = new Set<string>()
|
const activeTwoWeeksAgo = new Set<string>(
|
||||||
for (let j = twoWeeksAgo.start; j <= twoWeeksAgo.end; j++) {
|
dailyUserIds.slice(twoWeeksAgo.start, twoWeeksAgo.end).flat()
|
||||||
dailyUserIds[j].forEach((userId) => activeTwoWeeksAgo.add(userId))
|
)
|
||||||
}
|
const activeLastWeek = new Set<string>(
|
||||||
const activeLastWeek = new Set<string>()
|
dailyUserIds.slice(lastWeek.start, lastWeek.end).flat()
|
||||||
for (let j = lastWeek.start; j <= lastWeek.end; j++) {
|
)
|
||||||
dailyUserIds[j].forEach((userId) => activeLastWeek.add(userId))
|
|
||||||
}
|
|
||||||
const retainedCount = sumBy(Array.from(activeTwoWeeksAgo), (userId) =>
|
const retainedCount = sumBy(Array.from(activeTwoWeeksAgo), (userId) =>
|
||||||
activeLastWeek.has(userId) ? 1 : 0
|
activeLastWeek.has(userId) ? 1 : 0
|
||||||
)
|
)
|
||||||
|
@ -185,22 +222,20 @@ export const updateStatsCore = async () => {
|
||||||
|
|
||||||
const monthlyRetention = dailyUserIds.map((_userId, i) => {
|
const monthlyRetention = dailyUserIds.map((_userId, i) => {
|
||||||
const twoMonthsAgo = {
|
const twoMonthsAgo = {
|
||||||
start: Math.max(0, i - 60),
|
start: Math.max(0, i - 59),
|
||||||
end: Math.max(0, i - 30),
|
end: Math.max(0, i - 29),
|
||||||
}
|
}
|
||||||
const lastMonth = {
|
const lastMonth = {
|
||||||
start: Math.max(0, i - 30),
|
start: Math.max(0, i - 29),
|
||||||
end: i,
|
end: i + 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
const activeTwoMonthsAgo = new Set<string>()
|
const activeTwoMonthsAgo = new Set<string>(
|
||||||
for (let j = twoMonthsAgo.start; j <= twoMonthsAgo.end; j++) {
|
dailyUserIds.slice(twoMonthsAgo.start, twoMonthsAgo.end).flat()
|
||||||
dailyUserIds[j].forEach((userId) => activeTwoMonthsAgo.add(userId))
|
)
|
||||||
}
|
const activeLastMonth = new Set<string>(
|
||||||
const activeLastMonth = new Set<string>()
|
dailyUserIds.slice(lastMonth.start, lastMonth.end).flat()
|
||||||
for (let j = lastMonth.start; j <= lastMonth.end; j++) {
|
)
|
||||||
dailyUserIds[j].forEach((userId) => activeLastMonth.add(userId))
|
|
||||||
}
|
|
||||||
const retainedCount = sumBy(Array.from(activeTwoMonthsAgo), (userId) =>
|
const retainedCount = sumBy(Array.from(activeTwoMonthsAgo), (userId) =>
|
||||||
activeLastMonth.has(userId) ? 1 : 0
|
activeLastMonth.has(userId) ? 1 : 0
|
||||||
)
|
)
|
||||||
|
@ -254,12 +289,12 @@ export const updateStatsCore = async () => {
|
||||||
})
|
})
|
||||||
const weeklyTopTenthActions = dailyTopTenthActions.map((_, i) => {
|
const weeklyTopTenthActions = dailyTopTenthActions.map((_, i) => {
|
||||||
const start = Math.max(0, i - 6)
|
const start = Math.max(0, i - 6)
|
||||||
const end = i
|
const end = i + 1
|
||||||
return average(dailyTopTenthActions.slice(start, end))
|
return average(dailyTopTenthActions.slice(start, end))
|
||||||
})
|
})
|
||||||
const monthlyTopTenthActions = dailyTopTenthActions.map((_, i) => {
|
const monthlyTopTenthActions = dailyTopTenthActions.map((_, i) => {
|
||||||
const start = Math.max(0, i - 29)
|
const start = Math.max(0, i - 29)
|
||||||
const end = i
|
const end = i + 1
|
||||||
return average(dailyTopTenthActions.slice(start, end))
|
return average(dailyTopTenthActions.slice(start, end))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -269,16 +304,16 @@ export const updateStatsCore = async () => {
|
||||||
})
|
})
|
||||||
const weeklyManaBet = dailyManaBet.map((_, i) => {
|
const weeklyManaBet = dailyManaBet.map((_, i) => {
|
||||||
const start = Math.max(0, i - 6)
|
const start = Math.max(0, i - 6)
|
||||||
const end = i
|
const end = i + 1
|
||||||
const total = sum(dailyManaBet.slice(start, end))
|
const total = sum(dailyManaBet.slice(start, end))
|
||||||
if (end - start < 7) return (total * 7) / (end - start)
|
if (end - start < 7) return (total * 7) / (end - start)
|
||||||
return total
|
return total
|
||||||
})
|
})
|
||||||
const monthlyManaBet = dailyManaBet.map((_, i) => {
|
const monthlyManaBet = dailyManaBet.map((_, i) => {
|
||||||
const start = Math.max(0, i - 29)
|
const start = Math.max(0, i - 29)
|
||||||
const end = i
|
const end = i + 1
|
||||||
const total = sum(dailyManaBet.slice(start, end))
|
const total = sum(dailyManaBet.slice(start, end))
|
||||||
const range = end - start + 1
|
const range = end - start
|
||||||
if (range < 30) return (total * 30) / range
|
if (range < 30) return (total * 30) / range
|
||||||
return total
|
return total
|
||||||
})
|
})
|
||||||
|
@ -288,6 +323,9 @@ export const updateStatsCore = async () => {
|
||||||
dailyActiveUsers,
|
dailyActiveUsers,
|
||||||
weeklyActiveUsers,
|
weeklyActiveUsers,
|
||||||
monthlyActiveUsers,
|
monthlyActiveUsers,
|
||||||
|
d1,
|
||||||
|
d1Weekly,
|
||||||
|
w1NewUsers,
|
||||||
dailyBetCounts,
|
dailyBetCounts,
|
||||||
dailyContractCounts,
|
dailyContractCounts,
|
||||||
dailyCommentCounts,
|
dailyCommentCounts,
|
||||||
|
|
|
@ -47,30 +47,11 @@ export default function Analytics() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function CustomAnalytics(props: {
|
export function CustomAnalytics(props: Stats) {
|
||||||
startDate: number
|
|
||||||
dailyActiveUsers: number[]
|
|
||||||
weeklyActiveUsers: number[]
|
|
||||||
monthlyActiveUsers: number[]
|
|
||||||
dailyBetCounts: number[]
|
|
||||||
dailyContractCounts: number[]
|
|
||||||
dailyCommentCounts: number[]
|
|
||||||
dailySignups: number[]
|
|
||||||
weekOnWeekRetention: number[]
|
|
||||||
monthlyRetention: number[]
|
|
||||||
weeklyActivationRate: number[]
|
|
||||||
topTenthActions: {
|
|
||||||
daily: number[]
|
|
||||||
weekly: number[]
|
|
||||||
monthly: number[]
|
|
||||||
}
|
|
||||||
manaBet: {
|
|
||||||
daily: number[]
|
|
||||||
weekly: number[]
|
|
||||||
monthly: number[]
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
const {
|
const {
|
||||||
|
d1,
|
||||||
|
d1Weekly,
|
||||||
|
w1NewUsers,
|
||||||
dailyActiveUsers,
|
dailyActiveUsers,
|
||||||
dailyBetCounts,
|
dailyBetCounts,
|
||||||
dailyContractCounts,
|
dailyContractCounts,
|
||||||
|
@ -153,6 +134,60 @@ export function CustomAnalytics(props: {
|
||||||
/>
|
/>
|
||||||
<Spacer h={8} />
|
<Spacer h={8} />
|
||||||
|
|
||||||
|
<Title text="D1" />
|
||||||
|
<p className="text-gray-500">
|
||||||
|
The fraction of users that took an action yesterday that took an action
|
||||||
|
today.
|
||||||
|
</p>
|
||||||
|
<Spacer h={4} />
|
||||||
|
|
||||||
|
<Tabs
|
||||||
|
defaultIndex={1}
|
||||||
|
tabs={[
|
||||||
|
{
|
||||||
|
title: 'D1',
|
||||||
|
content: (
|
||||||
|
<DailyCountChart dailyCounts={d1} startDate={startDate} small />
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'D1 weekly average',
|
||||||
|
content: (
|
||||||
|
<DailyCountChart
|
||||||
|
dailyCounts={d1Weekly}
|
||||||
|
startDate={startDate}
|
||||||
|
small
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
<Spacer h={8} />
|
||||||
|
|
||||||
|
<Title text="W1 New users" />
|
||||||
|
<p className="text-gray-500">
|
||||||
|
The fraction of new users two weeks ago that took an action in the past
|
||||||
|
week.
|
||||||
|
</p>
|
||||||
|
<Spacer h={4} />
|
||||||
|
|
||||||
|
<Tabs
|
||||||
|
defaultIndex={0}
|
||||||
|
tabs={[
|
||||||
|
{
|
||||||
|
title: 'W1',
|
||||||
|
content: (
|
||||||
|
<DailyCountChart
|
||||||
|
dailyCounts={w1NewUsers}
|
||||||
|
startDate={startDate}
|
||||||
|
small
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
<Spacer h={8} />
|
||||||
|
|
||||||
<Title text="Daily activity" />
|
<Title text="Daily activity" />
|
||||||
<Tabs
|
<Tabs
|
||||||
defaultIndex={0}
|
defaultIndex={0}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user