2022-05-19 20:14:13 +00:00
|
|
|
import { Point, ResponsiveLine } from '@nivo/line'
|
2022-08-26 21:23:06 +00:00
|
|
|
import clsx from 'clsx'
|
2022-09-19 22:45:52 +00:00
|
|
|
import { formatPercent } from 'common/util/format'
|
2022-03-03 01:52:41 +00:00
|
|
|
import dayjs from 'dayjs'
|
2022-05-22 08:36:05 +00:00
|
|
|
import { zip } from 'lodash'
|
2022-05-09 13:04:36 +00:00
|
|
|
import { useWindowSize } from 'web/hooks/use-window-size'
|
2022-05-19 20:14:13 +00:00
|
|
|
import { Col } from '../layout/col'
|
2022-03-03 01:52:41 +00:00
|
|
|
|
|
|
|
export function DailyCountChart(props: {
|
|
|
|
startDate: number
|
|
|
|
dailyCounts: number[]
|
2022-03-03 20:59:12 +00:00
|
|
|
small?: boolean
|
2022-03-03 01:52:41 +00:00
|
|
|
}) {
|
2022-03-03 20:59:12 +00:00
|
|
|
const { dailyCounts, startDate, small } = props
|
2022-03-03 01:52:41 +00:00
|
|
|
const { width } = useWindowSize()
|
|
|
|
|
|
|
|
const dates = dailyCounts.map((_, i) =>
|
|
|
|
dayjs(startDate).add(i, 'day').toDate()
|
|
|
|
)
|
|
|
|
|
2022-05-22 08:36:05 +00:00
|
|
|
const points = zip(dates, dailyCounts).map(([date, betCount]) => ({
|
2022-03-03 01:52:41 +00:00
|
|
|
x: date,
|
|
|
|
y: betCount,
|
|
|
|
}))
|
2022-03-03 20:59:12 +00:00
|
|
|
const data = [{ id: 'Count', data: points, color: '#11b981' }]
|
2022-03-03 01:52:41 +00:00
|
|
|
|
2022-03-23 02:05:28 +00:00
|
|
|
const bottomAxisTicks = width && width < 600 ? 6 : undefined
|
|
|
|
|
2022-03-03 01:52:41 +00:00
|
|
|
return (
|
|
|
|
<div
|
2022-08-26 21:23:06 +00:00
|
|
|
className={clsx(
|
|
|
|
'h-[250px] w-full overflow-hidden',
|
|
|
|
!small && 'md:h-[400px]'
|
|
|
|
)}
|
2022-03-03 01:52:41 +00:00
|
|
|
>
|
|
|
|
<ResponsiveLine
|
|
|
|
data={data}
|
2022-03-03 20:59:12 +00:00
|
|
|
yScale={{ type: 'linear', stacked: false }}
|
2022-03-03 01:52:41 +00:00
|
|
|
xScale={{
|
|
|
|
type: 'time',
|
|
|
|
}}
|
|
|
|
axisBottom={{
|
2022-03-23 02:05:28 +00:00
|
|
|
tickValues: bottomAxisTicks,
|
2022-03-03 01:52:41 +00:00
|
|
|
format: (date) => dayjs(date).format('MMM DD'),
|
|
|
|
}}
|
|
|
|
colors={{ datum: 'color' }}
|
2022-03-20 21:23:25 +00:00
|
|
|
pointSize={0}
|
2022-03-03 01:52:41 +00:00
|
|
|
pointBorderWidth={1}
|
|
|
|
pointBorderColor="#fff"
|
|
|
|
enableSlices="x"
|
|
|
|
enableGridX={!!width && width >= 800}
|
|
|
|
enableArea
|
|
|
|
margin={{ top: 20, right: 28, bottom: 22, left: 40 }}
|
2022-05-19 20:14:13 +00:00
|
|
|
sliceTooltip={({ slice }) => {
|
|
|
|
const point = slice.points[0]
|
|
|
|
return <Tooltip point={point} />
|
|
|
|
}}
|
2022-03-03 01:52:41 +00:00
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|
2022-03-22 21:24:26 +00:00
|
|
|
|
|
|
|
export function DailyPercentChart(props: {
|
|
|
|
startDate: number
|
|
|
|
dailyPercent: number[]
|
|
|
|
small?: boolean
|
2022-09-19 23:41:24 +00:00
|
|
|
excludeFirstDays?: number
|
2022-03-22 21:24:26 +00:00
|
|
|
}) {
|
2022-09-19 23:41:24 +00:00
|
|
|
const { dailyPercent, startDate, small, excludeFirstDays } = props
|
2022-03-22 21:24:26 +00:00
|
|
|
const { width } = useWindowSize()
|
|
|
|
|
|
|
|
const dates = dailyPercent.map((_, i) =>
|
|
|
|
dayjs(startDate).add(i, 'day').toDate()
|
|
|
|
)
|
|
|
|
|
2022-09-19 23:41:24 +00:00
|
|
|
const points = zip(dates, dailyPercent)
|
|
|
|
.map(([date, percent]) => ({
|
|
|
|
x: date,
|
|
|
|
y: percent,
|
|
|
|
}))
|
|
|
|
.slice(excludeFirstDays ?? 0)
|
2022-03-22 21:24:26 +00:00
|
|
|
const data = [{ id: 'Percent', data: points, color: '#11b981' }]
|
|
|
|
|
2022-03-23 02:05:28 +00:00
|
|
|
const bottomAxisTicks = width && width < 600 ? 6 : undefined
|
|
|
|
|
2022-03-22 21:24:26 +00:00
|
|
|
return (
|
|
|
|
<div
|
2022-08-26 21:23:06 +00:00
|
|
|
className={clsx(
|
|
|
|
'h-[250px] w-full overflow-hidden',
|
|
|
|
!small && 'md:h-[400px]'
|
|
|
|
)}
|
2022-03-22 21:24:26 +00:00
|
|
|
>
|
|
|
|
<ResponsiveLine
|
|
|
|
data={data}
|
|
|
|
yScale={{ type: 'linear', stacked: false }}
|
|
|
|
xScale={{
|
|
|
|
type: 'time',
|
|
|
|
}}
|
|
|
|
axisLeft={{
|
2022-09-19 22:45:52 +00:00
|
|
|
format: formatPercent,
|
2022-03-22 21:24:26 +00:00
|
|
|
}}
|
|
|
|
axisBottom={{
|
2022-03-23 02:05:28 +00:00
|
|
|
tickValues: bottomAxisTicks,
|
2022-03-22 21:24:26 +00:00
|
|
|
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 }}
|
2022-05-19 20:14:13 +00:00
|
|
|
sliceTooltip={({ slice }) => {
|
|
|
|
const point = slice.points[0]
|
2022-09-19 22:45:52 +00:00
|
|
|
return <Tooltip point={point} isPercent />
|
2022-05-19 20:14:13 +00:00
|
|
|
}}
|
2022-03-22 21:24:26 +00:00
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|
2022-05-19 20:14:13 +00:00
|
|
|
|
2022-09-19 22:45:52 +00:00
|
|
|
function Tooltip(props: { point: Point; isPercent?: boolean }) {
|
|
|
|
const { point, isPercent } = props
|
2022-05-19 20:14:13 +00:00
|
|
|
return (
|
2022-05-22 22:48:02 +00:00
|
|
|
<Col className="border border-gray-300 bg-white py-2 px-3">
|
2022-05-19 20:14:13 +00:00
|
|
|
<div
|
2022-05-22 22:48:02 +00:00
|
|
|
className="pb-1"
|
2022-05-19 20:14:13 +00:00
|
|
|
style={{
|
|
|
|
color: point.serieColor,
|
|
|
|
}}
|
|
|
|
>
|
2022-09-19 22:45:52 +00:00
|
|
|
<strong>{point.serieId}</strong>{' '}
|
2022-09-19 23:41:24 +00:00
|
|
|
{isPercent ? formatPercent(+point.data.y) : Math.round(+point.data.y)}
|
2022-05-19 20:14:13 +00:00
|
|
|
</div>
|
|
|
|
<div>{dayjs(point.data.x).format('MMM DD')}</div>
|
|
|
|
</Col>
|
|
|
|
)
|
|
|
|
}
|