Make binary and pseudonumeric charts re-render less on contract diff (#955)

This commit is contained in:
Marshall Polaris 2022-09-28 18:03:30 -07:00 committed by GitHub
parent 1f2c7271b7
commit 7f7e7acd61
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 45 deletions

View File

@ -3,7 +3,7 @@ import { last, sortBy } from 'lodash'
import { scaleTime, scaleLinear } from 'd3-scale' import { scaleTime, scaleLinear } from 'd3-scale'
import { Bet } from 'common/bet' import { Bet } from 'common/bet'
import { getInitialProbability, getProbability } from 'common/calculate' import { getProbability, getInitialProbability } from 'common/calculate'
import { BinaryContract } from 'common/contract' import { BinaryContract } from 'common/contract'
import { useIsMobile } from 'web/hooks/use-is-mobile' import { useIsMobile } from 'web/hooks/use-is-mobile'
import { 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: { export const BinaryContractChart = (props: {
contract: BinaryContract contract: BinaryContract
bets: Bet[] bets: Bet[]
height?: number height?: number
}) => { }) => {
const { contract, bets } = props 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 betPoints = useMemo(() => getBetPoints(bets), [bets])
const data = useMemo( const data = useMemo(
() => [ () => [
getStartPoint(contract, contractStart), [startDate, startP] as const,
...betPoints, ...betPoints,
getEndPoint(contract, contractEnd ?? MAX_DATE), [endDate ?? MAX_DATE, endP] as const,
], ],
[contract, betPoints, contractStart, contractEnd] [startDate, startP, endDate, endP, betPoints]
) )
const rightmostDate = getRightmostVisibleDate( const rightmostDate = getRightmostVisibleDate(
contractEnd, endDate,
last(betPoints)?.[0], last(betPoints)?.[0],
new Date(Date.now()) new Date(Date.now())
) )
const visibleRange = [contractStart, rightmostDate] const visibleRange = [startDate, rightmostDate]
const isMobile = useIsMobile(800) const isMobile = useIsMobile(800)
const containerRef = useRef<HTMLDivElement>(null) const containerRef = useRef<HTMLDivElement>(null)
const width = useElementWidth(containerRef) ?? 0 const width = useElementWidth(containerRef) ?? 0

View File

@ -21,63 +21,57 @@ import { useElementWidth } from 'web/hooks/use-element-width'
// contracts. the values are stored "linearly" and can include zero. // contracts. the values are stored "linearly" and can include zero.
// as a result, we have to do some weird-looking stuff in this code // as a result, we have to do some weird-looking stuff in this code
const getY = (p: number, contract: PseudoNumericContract) => { const getScaleP = (min: number, max: number, isLogScale: boolean) => {
const { min, max, isLogScale } = contract return (p: number) =>
return isLogScale isLogScale
? 10 ** (p * Math.log10(max - min + 1)) + min - 1 ? 10 ** (p * Math.log10(max - min + 1)) + min - 1
: p * (max - min) + min : 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( 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: { export const PseudoNumericContractChart = (props: {
contract: PseudoNumericContract contract: PseudoNumericContract
bets: Bet[] bets: Bet[]
height?: number height?: number
}) => { }) => {
const { contract, bets } = props const { contract, bets } = props
const [contractStart, contractEnd] = getDateRange(contract) const { min, max, isLogScale } = contract
const betPoints = useMemo( const [startDate, endDate] = getDateRange(contract)
() => getBetPoints(contract, bets), const scaleP = useMemo(
[contract, bets] () => 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( const data = useMemo(
() => [ () => [
getStartPoint(contract, contractStart), [startDate, startP] as const,
...betPoints, ...betPoints,
getEndPoint(contract, contractEnd ?? MAX_DATE), [endDate ?? MAX_DATE, endP] as const,
], ],
[contract, betPoints, contractStart, contractEnd] [betPoints, startDate, startP, endDate, endP]
) )
const rightmostDate = getRightmostVisibleDate( const rightmostDate = getRightmostVisibleDate(
contractEnd, endDate,
last(betPoints)?.[0], last(betPoints)?.[0],
new Date(Date.now()) new Date(Date.now())
) )
const visibleRange = [contractStart, rightmostDate] const visibleRange = [startDate, rightmostDate]
const isMobile = useIsMobile(800) const isMobile = useIsMobile(800)
const containerRef = useRef<HTMLDivElement>(null) const containerRef = useRef<HTMLDivElement>(null)
const width = useElementWidth(containerRef) ?? 0 const width = useElementWidth(containerRef) ?? 0
const height = props.height ?? (isMobile ? 150 : 250) const height = props.height ?? (isMobile ? 150 : 250)
const xScale = scaleTime(visibleRange, [0, width - MARGIN_X]).clamp(true) const xScale = scaleTime(visibleRange, [0, width - MARGIN_X]).clamp(true)
const yScale = contract.isLogScale // clamp log scale to make sure zeroes go to the bottom
? scaleLog( const yScale = isLogScale
[Math.max(contract.min, 1), contract.max], ? scaleLog([Math.max(min, 1), max], [height - MARGIN_Y, 0]).clamp(true)
[height - MARGIN_Y, 0] : scaleLinear([min, max], [height - MARGIN_Y, 0])
).clamp(true) // make sure zeroes go to the bottom
: scaleLinear([contract.min, contract.max], [height - MARGIN_Y, 0])
return ( return (
<div ref={containerRef}> <div ref={containerRef}>