2022-09-30 23:57:48 +00:00
|
|
|
import { useMemo } from 'react'
|
2022-09-29 04:14:34 +00:00
|
|
|
import { range } from 'lodash'
|
2022-09-28 08:00:39 +00:00
|
|
|
import { scaleLinear } from 'd3-scale'
|
2022-09-28 03:24:42 +00:00
|
|
|
|
2022-09-29 04:14:34 +00:00
|
|
|
import { formatLargeNumber } from 'common/util/format'
|
2022-09-28 03:24:42 +00:00
|
|
|
import { getDpmOutcomeProbabilities } from 'common/calculate-dpm'
|
|
|
|
import { NumericContract } from 'common/contract'
|
|
|
|
import { NUMERIC_GRAPH_COLOR } from 'common/numeric-constants'
|
2022-10-04 08:18:22 +00:00
|
|
|
import { TooltipProps, formatPct } from '../helpers'
|
2022-09-29 19:51:38 +00:00
|
|
|
import { DistributionPoint, DistributionChart } from '../generic-charts'
|
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 getNumericChartData = (contract: NumericContract) => {
|
|
|
|
const { totalShares, bucketCount, min, max } = contract
|
|
|
|
const step = (max - min) / bucketCount
|
|
|
|
const bucketProbs = getDpmOutcomeProbabilities(totalShares)
|
2022-09-29 04:14:34 +00:00
|
|
|
return range(bucketCount).map((i) => ({
|
|
|
|
x: min + step * (i + 0.5),
|
|
|
|
y: bucketProbs[`${i}`],
|
|
|
|
}))
|
|
|
|
}
|
|
|
|
|
2022-09-30 23:16:04 +00:00
|
|
|
const NumericChartTooltip = (
|
|
|
|
props: TooltipProps<number, DistributionPoint>
|
|
|
|
) => {
|
2022-10-04 21:02:44 +00:00
|
|
|
const { data, x, xScale } = props
|
|
|
|
const amount = xScale.invert(x)
|
2022-09-29 04:14:34 +00:00
|
|
|
return (
|
2022-09-30 05:45:51 +00:00
|
|
|
<>
|
2022-10-04 21:02:44 +00:00
|
|
|
<span className="text-semibold">{formatLargeNumber(amount)}</span>
|
2022-09-30 23:16:04 +00:00
|
|
|
<span className="text-greyscale-6">{formatPct(data.y, 2)}</span>
|
2022-09-30 05:45:51 +00:00
|
|
|
</>
|
2022-09-28 03:24:42 +00:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
export const NumericContractChart = (props: {
|
|
|
|
contract: NumericContract
|
2022-09-30 23:57:48 +00:00
|
|
|
width: number
|
|
|
|
height: number
|
2022-09-30 03:18:33 +00:00
|
|
|
onMouseOver?: (p: DistributionPoint | undefined) => void
|
2022-09-28 03:24:42 +00:00
|
|
|
}) => {
|
2022-09-30 23:57:48 +00:00
|
|
|
const { contract, width, height, onMouseOver } = props
|
2022-09-29 04:14:34 +00:00
|
|
|
const { min, max } = contract
|
2022-09-28 03:24:42 +00:00
|
|
|
const data = useMemo(() => getNumericChartData(contract), [contract])
|
2022-09-29 04:14:34 +00:00
|
|
|
const maxY = Math.max(...data.map((d) => d.y))
|
|
|
|
const xScale = scaleLinear([min, max], [0, width - MARGIN_X])
|
2022-09-28 03:24:42 +00:00
|
|
|
const yScale = scaleLinear([0, maxY], [height - MARGIN_Y, 0])
|
|
|
|
return (
|
2022-09-30 23:57:48 +00:00
|
|
|
<DistributionChart
|
|
|
|
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}
|
|
|
|
data={data}
|
|
|
|
color={NUMERIC_GRAPH_COLOR}
|
|
|
|
onMouseOver={onMouseOver}
|
|
|
|
Tooltip={NumericChartTooltip}
|
|
|
|
/>
|
2022-09-28 03:24:42 +00:00
|
|
|
)
|
|
|
|
}
|