Week-on-week retention graph
This commit is contained in:
parent
1a44124a59
commit
6d5a4d6e3f
|
@ -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>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -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}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user