Week-on-week retention graph

This commit is contained in:
James Grugett 2022-03-22 16:24:26 -05:00
parent 1a44124a59
commit 6d5a4d6e3f
2 changed files with 89 additions and 1 deletions

View File

@ -47,3 +47,51 @@ export function DailyCountChart(props: {
</div> </div>
) )
} }
export function DailyPercentChart(props: {
startDate: number
dailyPercent: number[]
small?: boolean
}) {
const { dailyPercent, startDate, small } = props
const { width } = useWindowSize()
const dates = dailyPercent.map((_, i) =>
dayjs(startDate).add(i, 'day').toDate()
)
const points = _.zip(dates, dailyPercent).map(([date, betCount]) => ({
x: date,
y: betCount,
}))
const data = [{ id: 'Percent', data: points, color: '#11b981' }]
return (
<div
className="w-full"
style={{ height: !small && (!width || width >= 800) ? 400 : 250 }}
>
<ResponsiveLine
data={data}
yScale={{ type: 'linear', stacked: false }}
xScale={{
type: 'time',
}}
axisLeft={{
format: (value) => `${value}%`,
}}
axisBottom={{
format: (date) => dayjs(date).format('MMM DD'),
}}
colors={{ datum: 'color' }}
pointSize={0}
pointBorderWidth={1}
pointBorderColor="#fff"
enableSlices="x"
enableGridX={!!width && width >= 800}
enableArea
margin={{ top: 20, right: 28, bottom: 22, left: 40 }}
/>
</div>
)
}

View File

@ -1,7 +1,10 @@
import dayjs from 'dayjs' import dayjs from 'dayjs'
import _ from 'lodash' import _ from 'lodash'
import { IS_PRIVATE_MANIFOLD } from '../../common/envs/constants' import { IS_PRIVATE_MANIFOLD } from '../../common/envs/constants'
import { DailyCountChart } from '../components/analytics/charts' import {
DailyCountChart,
DailyPercentChart,
} from '../components/analytics/charts'
import { Col } from '../components/layout/col' import { Col } from '../components/layout/col'
import { Spacer } from '../components/layout/spacer' import { Spacer } from '../components/layout/spacer'
import { Page } from '../components/page' import { Page } from '../components/page'
@ -58,6 +61,31 @@ export async function getStaticPropz() {
return uniques.size return uniques.size
}) })
const weekOnWeekRetention = dailyUserIds.map((_userId, i) => {
const twoWeeksAgo = {
start: Math.max(0, i - 13),
end: Math.max(0, i - 7),
}
const lastWeek = {
start: Math.max(0, i - 6),
end: i,
}
const activeTwoWeeksAgo = new Set<string>()
for (let j = twoWeeksAgo.start; j <= twoWeeksAgo.end; j++) {
dailyUserIds[j].forEach((userId) => activeTwoWeeksAgo.add(userId))
}
const activeLastWeek = new Set<string>()
for (let j = lastWeek.start; j <= lastWeek.end; j++) {
dailyUserIds[j].forEach((userId) => activeLastWeek.add(userId))
}
const retainedCount = _.sumBy(Array.from(activeTwoWeeksAgo), (userId) =>
activeLastWeek.has(userId) ? 1 : 0
)
const retainedFrac = retainedCount / activeTwoWeeksAgo.size
return Math.round(retainedFrac * 100 * 100) / 100
})
return { return {
props: { props: {
startDate: startDate.valueOf(), startDate: startDate.valueOf(),
@ -67,6 +95,7 @@ export async function getStaticPropz() {
dailyBetCounts, dailyBetCounts,
dailyContractCounts, dailyContractCounts,
dailyCommentCounts, dailyCommentCounts,
weekOnWeekRetention,
}, },
revalidate: 12 * 60 * 60, // regenerate after half a day revalidate: 12 * 60 * 60, // regenerate after half a day
} }
@ -80,6 +109,7 @@ export default function Analytics(props: {
dailyBetCounts: number[] dailyBetCounts: number[]
dailyContractCounts: number[] dailyContractCounts: number[]
dailyCommentCounts: number[] dailyCommentCounts: number[]
weekOnWeekRetention: number[]
}) { }) {
props = usePropz(props, getStaticPropz) ?? { props = usePropz(props, getStaticPropz) ?? {
startDate: 0, startDate: 0,
@ -89,6 +119,7 @@ export default function Analytics(props: {
dailyBetCounts: [], dailyBetCounts: [],
dailyContractCounts: [], dailyContractCounts: [],
dailyCommentCounts: [], dailyCommentCounts: [],
weekOnWeekRetention: [],
} }
return ( return (
<Page> <Page>
@ -107,6 +138,7 @@ export function CustomAnalytics(props: {
dailyBetCounts: number[] dailyBetCounts: number[]
dailyContractCounts: number[] dailyContractCounts: number[]
dailyCommentCounts: number[] dailyCommentCounts: number[]
weekOnWeekRetention: number[]
}) { }) {
const { const {
startDate, startDate,
@ -116,6 +148,7 @@ export function CustomAnalytics(props: {
dailyCommentCounts, dailyCommentCounts,
weeklyActiveUsers, weeklyActiveUsers,
monthlyActiveUsers, monthlyActiveUsers,
weekOnWeekRetention,
} = props } = props
return ( return (
<Col> <Col>
@ -140,6 +173,13 @@ export function CustomAnalytics(props: {
small small
/> />
<Title text="Week-on-week retention" />
<DailyPercentChart
dailyPercent={weekOnWeekRetention}
startDate={startDate}
small
/>
<Title text="Trades" /> <Title text="Trades" />
<DailyCountChart <DailyCountChart
dailyCounts={dailyBetCounts} dailyCounts={dailyBetCounts}