manifold/web/components/charts/contract/binary.tsx
Marshall Polaris e0d9b4d335
Rewrite contract graphs (#935)
* 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
2022-09-27 20:24:42 -07:00

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>
)
}