Make binary and pseudonumeric charts re-render less on contract diff (#955)
This commit is contained in:
parent
1f2c7271b7
commit
7f7e7acd61
|
@ -3,7 +3,7 @@ import { last, sortBy } from 'lodash'
|
|||
import { scaleTime, scaleLinear } from 'd3-scale'
|
||||
|
||||
import { Bet } from 'common/bet'
|
||||
import { getInitialProbability, getProbability } from 'common/calculate'
|
||||
import { getProbability, getInitialProbability } from 'common/calculate'
|
||||
import { BinaryContract } from 'common/contract'
|
||||
import { useIsMobile } from 'web/hooks/use-is-mobile'
|
||||
import {
|
||||
|
@ -22,36 +22,31 @@ const getBetPoints = (bets: Bet[]) => {
|
|||
)
|
||||
}
|
||||
|
||||
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 [startDate, endDate] = getDateRange(contract)
|
||||
const startP = getInitialProbability(contract)
|
||||
const endP = getProbability(contract)
|
||||
const betPoints = useMemo(() => getBetPoints(bets), [bets])
|
||||
const data = useMemo(
|
||||
() => [
|
||||
getStartPoint(contract, contractStart),
|
||||
[startDate, startP] as const,
|
||||
...betPoints,
|
||||
getEndPoint(contract, contractEnd ?? MAX_DATE),
|
||||
[endDate ?? MAX_DATE, endP] as const,
|
||||
],
|
||||
[contract, betPoints, contractStart, contractEnd]
|
||||
[startDate, startP, endDate, endP, betPoints]
|
||||
)
|
||||
|
||||
const rightmostDate = getRightmostVisibleDate(
|
||||
contractEnd,
|
||||
endDate,
|
||||
last(betPoints)?.[0],
|
||||
new Date(Date.now())
|
||||
)
|
||||
const visibleRange = [contractStart, rightmostDate]
|
||||
const visibleRange = [startDate, rightmostDate]
|
||||
const isMobile = useIsMobile(800)
|
||||
const containerRef = useRef<HTMLDivElement>(null)
|
||||
const width = useElementWidth(containerRef) ?? 0
|
||||
|
|
|
@ -21,63 +21,57 @@ import { useElementWidth } from 'web/hooks/use-element-width'
|
|||
// contracts. the values are stored "linearly" and can include zero.
|
||||
// as a result, we have to do some weird-looking stuff in this code
|
||||
|
||||
const getY = (p: number, contract: PseudoNumericContract) => {
|
||||
const { min, max, isLogScale } = contract
|
||||
return isLogScale
|
||||
? 10 ** (p * Math.log10(max - min + 1)) + min - 1
|
||||
: p * (max - min) + min
|
||||
const getScaleP = (min: number, max: number, isLogScale: boolean) => {
|
||||
return (p: number) =>
|
||||
isLogScale
|
||||
? 10 ** (p * Math.log10(max - min + 1)) + min - 1
|
||||
: p * (max - min) + min
|
||||
}
|
||||
|
||||
const getBetPoints = (contract: PseudoNumericContract, bets: Bet[]) => {
|
||||
const getBetPoints = (bets: Bet[], scaleP: (p: number) => number) => {
|
||||
return sortBy(bets, (b) => b.createdTime).map(
|
||||
(b) => [new Date(b.createdTime), getY(b.probAfter, contract)] as const
|
||||
(b) => [new Date(b.createdTime), scaleP(b.probAfter)] as const
|
||||
)
|
||||
}
|
||||
|
||||
const getStartPoint = (contract: PseudoNumericContract, start: Date) => {
|
||||
return [start, getY(getInitialProbability(contract), contract)] as const
|
||||
}
|
||||
|
||||
const getEndPoint = (contract: PseudoNumericContract, end: Date) => {
|
||||
return [end, getY(getProbability(contract), contract)] as const
|
||||
}
|
||||
|
||||
export const PseudoNumericContractChart = (props: {
|
||||
contract: PseudoNumericContract
|
||||
bets: Bet[]
|
||||
height?: number
|
||||
}) => {
|
||||
const { contract, bets } = props
|
||||
const [contractStart, contractEnd] = getDateRange(contract)
|
||||
const betPoints = useMemo(
|
||||
() => getBetPoints(contract, bets),
|
||||
[contract, bets]
|
||||
const { min, max, isLogScale } = contract
|
||||
const [startDate, endDate] = getDateRange(contract)
|
||||
const scaleP = useMemo(
|
||||
() => getScaleP(min, max, isLogScale),
|
||||
[min, max, isLogScale]
|
||||
)
|
||||
const startP = scaleP(getInitialProbability(contract))
|
||||
const endP = scaleP(getProbability(contract))
|
||||
const betPoints = useMemo(() => getBetPoints(bets, scaleP), [bets, scaleP])
|
||||
const data = useMemo(
|
||||
() => [
|
||||
getStartPoint(contract, contractStart),
|
||||
[startDate, startP] as const,
|
||||
...betPoints,
|
||||
getEndPoint(contract, contractEnd ?? MAX_DATE),
|
||||
[endDate ?? MAX_DATE, endP] as const,
|
||||
],
|
||||
[contract, betPoints, contractStart, contractEnd]
|
||||
[betPoints, startDate, startP, endDate, endP]
|
||||
)
|
||||
const rightmostDate = getRightmostVisibleDate(
|
||||
contractEnd,
|
||||
endDate,
|
||||
last(betPoints)?.[0],
|
||||
new Date(Date.now())
|
||||
)
|
||||
const visibleRange = [contractStart, rightmostDate]
|
||||
const visibleRange = [startDate, rightmostDate]
|
||||
const isMobile = useIsMobile(800)
|
||||
const containerRef = useRef<HTMLDivElement>(null)
|
||||
const width = useElementWidth(containerRef) ?? 0
|
||||
const height = props.height ?? (isMobile ? 150 : 250)
|
||||
const xScale = scaleTime(visibleRange, [0, width - MARGIN_X]).clamp(true)
|
||||
const yScale = contract.isLogScale
|
||||
? scaleLog(
|
||||
[Math.max(contract.min, 1), contract.max],
|
||||
[height - MARGIN_Y, 0]
|
||||
).clamp(true) // make sure zeroes go to the bottom
|
||||
: scaleLinear([contract.min, contract.max], [height - MARGIN_Y, 0])
|
||||
// clamp log scale to make sure zeroes go to the bottom
|
||||
const yScale = isLogScale
|
||||
? scaleLog([Math.max(min, 1), max], [height - MARGIN_Y, 0]).clamp(true)
|
||||
: scaleLinear([min, max], [height - MARGIN_Y, 0])
|
||||
|
||||
return (
|
||||
<div ref={containerRef}>
|
||||
|
|
Loading…
Reference in New Issue
Block a user