e0d9b4d335
* Fiddle around with everything, WIP FR charts * Implement numeric chart * Reorganize everything into neat little files * Add `AreaWithTopStroke` helper * Tidying, don't gratuitously use d3.format * Remove duplicate code * Better tooltip bisection * `NumericPoint` -> `DistributionPoint` * Add numeric market tooltip * Make numeric chart bucket points less wrong * Clean up numeric bucket computation * Clean up a bunch of tooltip stuff, add FR legend tooltips * Fix a dumb bug * Implement basic time selection * Fix fishy Date.now inconsistency bugs * Might as well show all the FR outcomes now * Make tooltips accurate on curveStepAfter charts * Make log scale PN charts work properly * Adjust x-axis tick count * Display tooltip on charts only for mouse * Fix up deps * Tighter chart tooltips * Adjustments to chart time range management * Better date formatting * Continue tweaking time selection handling to be perfect * Make FR charts taller by default
66 lines
2.0 KiB
TypeScript
66 lines
2.0 KiB
TypeScript
import { useMemo, useRef } from 'react'
|
|
import { sortBy } from 'lodash'
|
|
import { scaleTime, scaleLinear } from 'd3'
|
|
|
|
import { Bet } from 'common/bet'
|
|
import { getInitialProbability, getProbability } from 'common/calculate'
|
|
import { BinaryContract } from 'common/contract'
|
|
import { useIsMobile } from 'web/hooks/use-is-mobile'
|
|
import { MARGIN_X, MARGIN_Y, MAX_DATE, getDateRange } from '../helpers'
|
|
import { SingleValueHistoryChart } from '../generic-charts'
|
|
import { useElementWidth } from 'web/hooks/use-element-width'
|
|
|
|
const getBetPoints = (bets: Bet[]) => {
|
|
return sortBy(bets, (b) => b.createdTime).map(
|
|
(b) => [new Date(b.createdTime), b.probAfter] as const
|
|
)
|
|
}
|
|
|
|
const getStartPoint = (contract: BinaryContract, start: Date) => {
|
|
return [start, getInitialProbability(contract)] as const
|
|
}
|
|
|
|
const getEndPoint = (contract: BinaryContract, end: Date) => {
|
|
return [end, getProbability(contract)] as const
|
|
}
|
|
|
|
export const BinaryContractChart = (props: {
|
|
contract: BinaryContract
|
|
bets: Bet[]
|
|
height?: number
|
|
}) => {
|
|
const { contract, bets } = props
|
|
const [contractStart, contractEnd] = getDateRange(contract)
|
|
const betPoints = useMemo(() => getBetPoints(bets), [bets])
|
|
const data = useMemo(
|
|
() => [
|
|
getStartPoint(contract, contractStart),
|
|
...betPoints,
|
|
getEndPoint(contract, contractEnd ?? MAX_DATE),
|
|
],
|
|
[contract, betPoints, contractStart, contractEnd]
|
|
)
|
|
const visibleRange = [contractStart, contractEnd ?? Date.now()]
|
|
const isMobile = useIsMobile(800)
|
|
const containerRef = useRef<HTMLDivElement>(null)
|
|
const width = useElementWidth(containerRef) ?? 0
|
|
const height = props.height ?? (isMobile ? 250 : 350)
|
|
const xScale = scaleTime(visibleRange, [0, width - MARGIN_X])
|
|
const yScale = scaleLinear([0, 1], [height - MARGIN_Y, 0])
|
|
return (
|
|
<div ref={containerRef}>
|
|
{width && (
|
|
<SingleValueHistoryChart
|
|
w={width}
|
|
h={height}
|
|
xScale={xScale}
|
|
yScale={yScale}
|
|
data={data}
|
|
color="#11b981"
|
|
pct
|
|
/>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|