Create bet count and market count charts in our analytics
This commit is contained in:
parent
4d8af33c85
commit
c30962bf80
48
web/components/analytics/charts.tsx
Normal file
48
web/components/analytics/charts.tsx
Normal file
|
@ -0,0 +1,48 @@
|
|||
import { ResponsiveLine } from '@nivo/line'
|
||||
import dayjs from 'dayjs'
|
||||
import _ from 'lodash'
|
||||
import { useWindowSize } from '../../hooks/use-window-size'
|
||||
|
||||
export function DailyCountChart(props: {
|
||||
startDate: number
|
||||
dailyCounts: number[]
|
||||
}) {
|
||||
const { dailyCounts, startDate } = props
|
||||
const { width } = useWindowSize()
|
||||
|
||||
const dates = dailyCounts.map((_, i) =>
|
||||
dayjs(startDate).add(i, 'day').toDate()
|
||||
)
|
||||
|
||||
const points = _.zip(dates, dailyCounts).map(([date, betCount]) => ({
|
||||
x: date,
|
||||
y: betCount,
|
||||
}))
|
||||
const data = [{ id: 'Yes', data: points, color: '#11b981' }]
|
||||
|
||||
return (
|
||||
<div
|
||||
className="w-full"
|
||||
style={{ height: !width || width >= 800 ? 400 : 250 }}
|
||||
>
|
||||
<ResponsiveLine
|
||||
data={data}
|
||||
yScale={{ type: 'linear' }}
|
||||
xScale={{
|
||||
type: 'time',
|
||||
}}
|
||||
axisBottom={{
|
||||
format: (date) => dayjs(date).format('MMM DD'),
|
||||
}}
|
||||
colors={{ datum: 'color' }}
|
||||
pointSize={10}
|
||||
pointBorderWidth={1}
|
||||
pointBorderColor="#fff"
|
||||
enableSlices="x"
|
||||
enableGridX={!!width && width >= 800}
|
||||
enableArea
|
||||
margin={{ top: 20, right: 28, bottom: 22, left: 40 }}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
|
@ -103,3 +103,24 @@ export function withoutAnteBets(contract: Contract, bets?: Bet[]) {
|
|||
|
||||
return bets?.filter((bet) => !bet.isAnte) ?? []
|
||||
}
|
||||
|
||||
const getBetsQuery = (startTime: number, endTime: number) =>
|
||||
query(
|
||||
collectionGroup(db, 'bets'),
|
||||
where('createdTime', '>=', startTime),
|
||||
where('createdTime', '<', endTime),
|
||||
orderBy('createdTime', 'asc')
|
||||
)
|
||||
|
||||
export async function getDailyBets(startTime: number, numberOfDays: number) {
|
||||
const query = getBetsQuery(startTime, startTime + DAY_IN_MS * numberOfDays)
|
||||
const bets = await getValues<Bet>(query)
|
||||
|
||||
const betsByDay = _.range(0, numberOfDays).map(() => [] as Bet[])
|
||||
for (const bet of bets) {
|
||||
const dayIndex = Math.floor((bet.createdTime - startTime) / DAY_IN_MS)
|
||||
betsByDay[dayIndex].push(bet)
|
||||
}
|
||||
|
||||
return betsByDay
|
||||
}
|
||||
|
|
|
@ -209,3 +209,32 @@ export async function getClosingSoonContracts() {
|
|||
(contract) => contract.closeTime
|
||||
)
|
||||
}
|
||||
|
||||
const getContractsQuery = (startTime: number, endTime: number) =>
|
||||
query(
|
||||
collection(db, 'contracts'),
|
||||
where('createdTime', '>=', startTime),
|
||||
where('createdTime', '<', endTime),
|
||||
orderBy('createdTime', 'asc')
|
||||
)
|
||||
|
||||
const DAY_IN_MS = 24 * 60 * 60 * 1000
|
||||
|
||||
export async function getDailyContracts(
|
||||
startTime: number,
|
||||
numberOfDays: number
|
||||
) {
|
||||
const query = getContractsQuery(
|
||||
startTime,
|
||||
startTime + DAY_IN_MS * numberOfDays
|
||||
)
|
||||
const contracts = await getValues<Contract>(query)
|
||||
|
||||
const contractsByDay = _.range(0, numberOfDays).map(() => [] as Contract[])
|
||||
for (const contract of contracts) {
|
||||
const dayIndex = Math.floor((contract.createdTime - startTime) / DAY_IN_MS)
|
||||
contractsByDay[dayIndex].push(contract)
|
||||
}
|
||||
|
||||
return contractsByDay
|
||||
}
|
||||
|
|
|
@ -1,17 +1,81 @@
|
|||
import dayjs from 'dayjs'
|
||||
import _ from 'lodash'
|
||||
import { DailyCountChart } from '../components/analytics/charts'
|
||||
import { Col } from '../components/layout/col'
|
||||
import { Page } from '../components/page'
|
||||
import { Title } from '../components/title'
|
||||
import { getDailyBets } from '../lib/firebase/bets'
|
||||
import { getDailyContracts } from '../lib/firebase/contracts'
|
||||
|
||||
export default function Analytics() {
|
||||
// Edit dashboard at https://datastudio.google.com/u/0/reporting/faeaf3a4-c8da-4275-b157-98dad017d305/page/Gg3/edit
|
||||
export async function getStaticProps() {
|
||||
const numberOfDays = 80
|
||||
const today = dayjs(dayjs().format('YYYY-MM-DD'))
|
||||
const startDate = today.subtract(numberOfDays, 'day')
|
||||
|
||||
const dailyBets = await getDailyBets(startDate.valueOf(), numberOfDays)
|
||||
const dailyBetCounts = dailyBets.map((bets) => bets.length)
|
||||
|
||||
const dailyContracts = await getDailyContracts(
|
||||
startDate.valueOf(),
|
||||
numberOfDays
|
||||
)
|
||||
const dailyContractCounts = dailyContracts.map(
|
||||
(contracts) => contracts.length
|
||||
)
|
||||
|
||||
return {
|
||||
props: {
|
||||
startDate: startDate.valueOf(),
|
||||
dailyBetCounts,
|
||||
dailyContractCounts,
|
||||
},
|
||||
revalidate: 12 * 60 * 60, // regenerate after half a day
|
||||
}
|
||||
}
|
||||
|
||||
export default function Analytics(props: {
|
||||
startDate: number
|
||||
dailyBetCounts: number[]
|
||||
dailyContractCounts: number[]
|
||||
}) {
|
||||
return (
|
||||
<Page>
|
||||
<iframe
|
||||
className="w-full"
|
||||
height={2200}
|
||||
src="https://datastudio.google.com/embed/reporting/faeaf3a4-c8da-4275-b157-98dad017d305/page/Gg3"
|
||||
frameBorder="0"
|
||||
style={{ border: 0 }}
|
||||
allowFullScreen
|
||||
></iframe>
|
||||
<CustomAnalytics {...props} />
|
||||
<FirebaseAnalytics />
|
||||
</Page>
|
||||
)
|
||||
}
|
||||
|
||||
function CustomAnalytics(props: {
|
||||
startDate: number
|
||||
dailyBetCounts: number[]
|
||||
dailyContractCounts: number[]
|
||||
}) {
|
||||
const { startDate, dailyBetCounts, dailyContractCounts } = props
|
||||
return (
|
||||
<Col className="mb-8">
|
||||
<Title text="Bets count" />
|
||||
<DailyCountChart dailyCounts={dailyBetCounts} startDate={startDate} />
|
||||
|
||||
<Title text="Markets count" />
|
||||
<DailyCountChart
|
||||
dailyCounts={dailyContractCounts}
|
||||
startDate={startDate}
|
||||
/>
|
||||
</Col>
|
||||
)
|
||||
}
|
||||
|
||||
function FirebaseAnalytics() {
|
||||
// Edit dashboard at https://datastudio.google.com/u/0/reporting/faeaf3a4-c8da-4275-b157-98dad017d305/page/Gg3/edit
|
||||
return (
|
||||
<iframe
|
||||
className="w-full"
|
||||
height={2200}
|
||||
src="https://datastudio.google.com/embed/reporting/faeaf3a4-c8da-4275-b157-98dad017d305/page/Gg3"
|
||||
frameBorder="0"
|
||||
style={{ border: 0 }}
|
||||
allowFullScreen
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user