2022-09-30 23:57:48 +00:00
|
|
|
import { useMemo } from 'react'
|
2022-09-28 04:18:22 +00:00
|
|
|
import { last, sortBy } from 'lodash'
|
2022-09-28 08:00:39 +00:00
|
|
|
import { scaleTime, scaleLinear } from 'd3-scale'
|
2022-10-03 16:31:07 +00:00
|
|
|
import { curveStepAfter } from 'd3-shape'
|
2022-09-28 03:24:42 +00:00
|
|
|
|
|
|
|
import { Bet } from 'common/bet'
|
2022-09-29 01:03:30 +00:00
|
|
|
import { getProbability, getInitialProbability } from 'common/calculate'
|
2022-09-28 03:24:42 +00:00
|
|
|
import { BinaryContract } from 'common/contract'
|
2022-09-29 06:27:42 +00:00
|
|
|
import { DAY_MS } from 'common/util/time'
|
2022-09-28 04:18:22 +00:00
|
|
|
import {
|
2022-09-29 19:51:38 +00:00
|
|
|
TooltipProps,
|
2022-09-28 04:18:22 +00:00
|
|
|
getDateRange,
|
|
|
|
getRightmostVisibleDate,
|
2022-09-29 04:14:34 +00:00
|
|
|
formatDateInRange,
|
|
|
|
formatPct,
|
2022-09-28 04:18:22 +00:00
|
|
|
} from '../helpers'
|
2022-09-29 19:51:38 +00:00
|
|
|
import { HistoryPoint, SingleValueHistoryChart } from '../generic-charts'
|
2022-09-29 04:14:34 +00:00
|
|
|
import { Row } from 'web/components/layout/row'
|
|
|
|
import { Avatar } from 'web/components/avatar'
|
2022-09-28 03:24:42 +00:00
|
|
|
|
2022-10-04 08:18:22 +00:00
|
|
|
const MARGIN = { top: 20, right: 10, bottom: 20, left: 40 }
|
|
|
|
const MARGIN_X = MARGIN.left + MARGIN.right
|
|
|
|
const MARGIN_Y = MARGIN.top + MARGIN.bottom
|
|
|
|
|
2022-09-28 03:24:42 +00:00
|
|
|
const getBetPoints = (bets: Bet[]) => {
|
2022-09-29 04:14:34 +00:00
|
|
|
return sortBy(bets, (b) => b.createdTime).map((b) => ({
|
|
|
|
x: new Date(b.createdTime),
|
|
|
|
y: b.probAfter,
|
2022-09-30 23:16:04 +00:00
|
|
|
obj: b,
|
2022-09-29 04:14:34 +00:00
|
|
|
}))
|
|
|
|
}
|
|
|
|
|
2022-09-30 23:16:04 +00:00
|
|
|
const BinaryChartTooltip = (props: TooltipProps<Date, HistoryPoint<Bet>>) => {
|
|
|
|
const { data, mouseX, xScale } = props
|
2022-09-29 04:14:34 +00:00
|
|
|
const [start, end] = xScale.domain()
|
2022-09-30 23:16:04 +00:00
|
|
|
const d = xScale.invert(mouseX)
|
2022-09-29 04:14:34 +00:00
|
|
|
return (
|
2022-09-30 05:45:51 +00:00
|
|
|
<Row className="items-center gap-2">
|
2022-09-30 23:16:04 +00:00
|
|
|
{data.obj && <Avatar size="xs" avatarUrl={data.obj.userAvatarUrl} />}
|
|
|
|
<span className="font-semibold">{formatDateInRange(d, start, end)}</span>
|
|
|
|
<span className="text-greyscale-6">{formatPct(data.y)}</span>
|
2022-09-29 04:14:34 +00:00
|
|
|
</Row>
|
2022-09-28 03:24:42 +00:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
export const BinaryContractChart = (props: {
|
|
|
|
contract: BinaryContract
|
|
|
|
bets: Bet[]
|
2022-09-30 23:57:48 +00:00
|
|
|
width: number
|
|
|
|
height: number
|
2022-09-30 03:18:33 +00:00
|
|
|
onMouseOver?: (p: HistoryPoint<Bet> | undefined) => void
|
2022-09-28 03:24:42 +00:00
|
|
|
}) => {
|
2022-09-30 23:57:48 +00:00
|
|
|
const { contract, bets, width, height, onMouseOver } = props
|
2022-09-30 04:35:20 +00:00
|
|
|
const [start, end] = getDateRange(contract)
|
2022-09-29 01:03:30 +00:00
|
|
|
const startP = getInitialProbability(contract)
|
|
|
|
const endP = getProbability(contract)
|
2022-09-28 03:24:42 +00:00
|
|
|
const betPoints = useMemo(() => getBetPoints(bets), [bets])
|
2022-09-30 03:18:33 +00:00
|
|
|
const data = useMemo(() => {
|
|
|
|
return [
|
2022-09-30 04:35:20 +00:00
|
|
|
{ x: new Date(start), y: startP },
|
2022-09-28 03:24:42 +00:00
|
|
|
...betPoints,
|
2022-09-30 04:35:20 +00:00
|
|
|
{ x: new Date(end ?? Date.now() + DAY_MS), y: endP },
|
2022-09-30 03:18:33 +00:00
|
|
|
]
|
2022-09-30 04:35:20 +00:00
|
|
|
}, [start, startP, end, endP, betPoints])
|
2022-09-29 01:03:30 +00:00
|
|
|
|
2022-09-28 04:18:22 +00:00
|
|
|
const rightmostDate = getRightmostVisibleDate(
|
2022-09-30 04:35:20 +00:00
|
|
|
end,
|
|
|
|
last(betPoints)?.x?.getTime(),
|
|
|
|
Date.now()
|
2022-09-28 04:18:22 +00:00
|
|
|
)
|
2022-09-30 04:35:20 +00:00
|
|
|
const visibleRange = [start, rightmostDate]
|
2022-09-29 06:27:42 +00:00
|
|
|
const xScale = scaleTime(visibleRange, [0, width - MARGIN_X])
|
2022-09-28 03:24:42 +00:00
|
|
|
const yScale = scaleLinear([0, 1], [height - MARGIN_Y, 0])
|
|
|
|
return (
|
2022-09-30 23:57:48 +00:00
|
|
|
<SingleValueHistoryChart
|
|
|
|
w={width}
|
|
|
|
h={height}
|
2022-10-04 08:18:22 +00:00
|
|
|
margin={MARGIN}
|
2022-09-30 23:57:48 +00:00
|
|
|
xScale={xScale}
|
|
|
|
yScale={yScale}
|
2022-10-04 08:18:22 +00:00
|
|
|
yKind="percent"
|
2022-09-30 23:57:48 +00:00
|
|
|
data={data}
|
|
|
|
color="#11b981"
|
2022-10-03 16:31:07 +00:00
|
|
|
curve={curveStepAfter}
|
2022-09-30 23:57:48 +00:00
|
|
|
onMouseOver={onMouseOver}
|
|
|
|
Tooltip={BinaryChartTooltip}
|
|
|
|
/>
|
2022-09-28 03:24:42 +00:00
|
|
|
)
|
|
|
|
}
|