diff --git a/web/components/charts/contract/pseudo-numeric.tsx b/web/components/charts/contract/pseudo-numeric.tsx index 6b9a436a..a53edd9b 100644 --- a/web/components/charts/contract/pseudo-numeric.tsx +++ b/web/components/charts/contract/pseudo-numeric.tsx @@ -11,14 +11,23 @@ import { MARGIN_X, MARGIN_Y, getDateRange } from '../helpers' import { SingleValueHistoryChart } from '../generic-charts' import { useElementWidth } from 'web/hooks/use-element-width' +// mqp: note that we have an idiosyncratic version of 'log scale' +// 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 getChartData = ( contract: PseudoNumericContract, bets: Bet[], start: Date, end: Date ) => { - const { min, max } = contract - const getY = (p: number) => p * (max - min) + min + const { min, max, isLogScale } = contract + const getY = (p: number) => + isLogScale + ? 10 ** (p * Math.log10(contract.max - contract.min + 1)) + + contract.min - + 1 + : p * (max - min) + min const sortedBets = sortBy(bets, (b) => b.createdTime) const startProb = getInitialProbability(contract) const endProb = getProbability(contract) @@ -46,9 +55,14 @@ export const PseudoNumericContractChart = (props: { const containerRef = useRef(null) const width = useElementWidth(containerRef) ?? 0 const height = props.height ?? (isMobile ? 150 : 250) - const scaleType = contract.isLogScale ? scaleLog : scaleLinear const xScale = scaleTime([start, end], [0, width - MARGIN_X]) - const yScale = scaleType([contract.min, contract.max], [height - MARGIN_Y, 0]) + 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]) + return (
{width && ( diff --git a/web/components/charts/generic-charts.tsx b/web/components/charts/generic-charts.tsx index c8844899..34010a24 100644 --- a/web/components/charts/generic-charts.tsx +++ b/web/components/charts/generic-charts.tsx @@ -115,7 +115,7 @@ export const SingleValueDistributionChart = (props: { useState>() const px = useCallback((p: DistributionPoint) => xScale(p[0]), [xScale]) - const py0 = yScale(0) + const py0 = yScale(yScale.domain()[0]) const py1 = useCallback((p: DistributionPoint) => yScale(p[1]), [yScale]) const xBisector = bisector((p: DistributionPoint) => p[0]) @@ -209,11 +209,11 @@ export const MultiValueHistoryChart = (props: { const fmtY = (n: number) => (pct ? formatPct(n, 0) : formatLargeNumber(n)) const [min, max] = yScale.domain() - const tickValues = getTickValues(min, max, h < 200 ? 3 : 5) + const pctTickValues = getTickValues(min, max, h < 200 ? 3 : 5) const xAxis = axisBottom(xScale) - const yAxis = axisLeft(yScale) - .tickValues(tickValues) - .tickFormat(fmtY) + const yAxis = pct + ? axisLeft(yScale).tickValues(pctTickValues).tickFormat(fmtY) + : axisLeft(yScale) return { fmtX, fmtY, xAxis, yAxis } }, [h, pct, xScale, yScale]) @@ -311,7 +311,7 @@ export const SingleValueHistoryChart = (props: { const [mouseState, setMouseState] = useState>() const px = useCallback((p: HistoryPoint) => xScale(p[0]), [xScale]) - const py0 = yScale(0) + const py0 = yScale(yScale.domain()[0]) const py1 = useCallback((p: HistoryPoint) => yScale(p[1]), [yScale]) const xBisector = bisector((p: HistoryPoint) => p[0]) @@ -321,11 +321,11 @@ export const SingleValueHistoryChart = (props: { const fmtY = (n: number) => (pct ? formatPct(n, 0) : formatLargeNumber(n)) const [min, max] = yScale.domain() - const tickValues = getTickValues(min, max, h < 200 ? 3 : 5) + const pctTickValues = getTickValues(min, max, h < 200 ? 3 : 5) const xAxis = axisBottom(xScale) - const yAxis = axisLeft(yScale) - .tickValues(tickValues) - .tickFormat(fmtY) + const yAxis = pct + ? axisLeft(yScale).tickValues(pctTickValues).tickFormat(fmtY) + : axisLeft(yScale) return { fmtX, fmtY, xAxis, yAxis } }, [h, pct, xScale, yScale])