Add numeric graph (coded without testing)
This commit is contained in:
		
							parent
							
								
									0ab1c67470
								
							
						
					
					
						commit
						00bc8d6068
					
				|  | @ -19,6 +19,13 @@ export function getDpmOutcomeProbability( | ||||||
|   return shares ** 2 / squareSum |   return shares ** 2 / squareSum | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | export function getDpmOutcomeProbabilities(totalShares: { | ||||||
|  |   [outcome: string]: number | ||||||
|  | }) { | ||||||
|  |   const squareSum = _.sumBy(Object.values(totalShares), (shares) => shares ** 2) | ||||||
|  |   return _.mapValues(totalShares, (shares) => shares ** 2 / squareSum) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| export function getDpmOutcomeProbabilityAfterBet( | export function getDpmOutcomeProbabilityAfterBet( | ||||||
|   totalShares: { |   totalShares: { | ||||||
|     [outcome: string]: number |     [outcome: string]: number | ||||||
|  |  | ||||||
|  | @ -40,7 +40,10 @@ export type FullContract< | ||||||
| } & M & | } & M & | ||||||
|   T |   T | ||||||
| 
 | 
 | ||||||
| export type Contract = FullContract<DPM | CPMM, Binary | Multi | FreeResponse> | export type Contract = FullContract< | ||||||
|  |   DPM | CPMM, | ||||||
|  |   Binary | Multi | FreeResponse | Numeric | ||||||
|  | > | ||||||
| export type BinaryContract = FullContract<DPM | CPMM, Binary> | export type BinaryContract = FullContract<DPM | CPMM, Binary> | ||||||
| export type FreeResponseContract = FullContract<DPM | CPMM, FreeResponse> | export type FreeResponseContract = FullContract<DPM | CPMM, FreeResponse> | ||||||
| export type NumericContract = FullContract<DPM, Numeric> | export type NumericContract = FullContract<DPM, Numeric> | ||||||
|  |  | ||||||
|  | @ -14,10 +14,16 @@ import { Bet } from '../../../common/bet' | ||||||
| import { Comment } from '../../../common/comment' | import { Comment } from '../../../common/comment' | ||||||
| import BetRow from '../bet-row' | import BetRow from '../bet-row' | ||||||
| import { AnswersGraph } from '../answers/answers-graph' | import { AnswersGraph } from '../answers/answers-graph' | ||||||
| import { DPM, FreeResponse, FullContract } from '../../../common/contract' | import { | ||||||
|  |   DPM, | ||||||
|  |   FreeResponse, | ||||||
|  |   FullContract, | ||||||
|  |   NumericContract, | ||||||
|  | } from '../../../common/contract' | ||||||
| import { ContractDescription } from './contract-description' | import { ContractDescription } from './contract-description' | ||||||
| import { ContractDetails } from './contract-details' | import { ContractDetails } from './contract-details' | ||||||
| import { ShareMarket } from '../share-market' | import { ShareMarket } from '../share-market' | ||||||
|  | import { NumericGraph } from './numeric-graph' | ||||||
| 
 | 
 | ||||||
| export const ContractOverview = (props: { | export const ContractOverview = (props: { | ||||||
|   contract: Contract |   contract: Contract | ||||||
|  | @ -73,22 +79,19 @@ export const ContractOverview = (props: { | ||||||
|           isCreator={isCreator} |           isCreator={isCreator} | ||||||
|         /> |         /> | ||||||
|       </Col> |       </Col> | ||||||
| 
 |  | ||||||
|       <Spacer h={4} /> |       <Spacer h={4} /> | ||||||
| 
 |       {isBinary && <ContractProbGraph contract={contract} bets={bets} />}{' '} | ||||||
|       {isBinary ? ( |       {outcomeType === 'FREE_RESPONSE' && ( | ||||||
|         <ContractProbGraph contract={contract} bets={bets} /> |  | ||||||
|       ) : ( |  | ||||||
|         <AnswersGraph |         <AnswersGraph | ||||||
|           contract={contract as FullContract<DPM, FreeResponse>} |           contract={contract as FullContract<DPM, FreeResponse>} | ||||||
|           bets={bets} |           bets={bets} | ||||||
|         /> |         /> | ||||||
|       )} |       )} | ||||||
| 
 |       {outcomeType === 'NUMERIC' && ( | ||||||
|  |         <NumericGraph contract={contract as NumericContract} /> | ||||||
|  |       )} | ||||||
|       {(contract.description || isCreator) && <Spacer h={6} />} |       {(contract.description || isCreator) && <Spacer h={6} />} | ||||||
| 
 |  | ||||||
|       {isCreator && <ShareMarket className="px-2" contract={contract} />} |       {isCreator && <ShareMarket className="px-2" contract={contract} />} | ||||||
| 
 |  | ||||||
|       <ContractDescription |       <ContractDescription | ||||||
|         className="px-2" |         className="px-2" | ||||||
|         contract={contract} |         contract={contract} | ||||||
|  |  | ||||||
							
								
								
									
										70
									
								
								web/components/contract/numeric-graph.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								web/components/contract/numeric-graph.tsx
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,70 @@ | ||||||
|  | import { DatumValue } from '@nivo/core' | ||||||
|  | import { ResponsiveLine } from '@nivo/line' | ||||||
|  | import _ from 'lodash' | ||||||
|  | import { memo } from 'react' | ||||||
|  | import { getDpmOutcomeProbabilities } from '../../../common/calculate-dpm' | ||||||
|  | import { NumericContract } from '../../../common/contract' | ||||||
|  | import { useWindowSize } from '../../hooks/use-window-size' | ||||||
|  | 
 | ||||||
|  | export const NumericGraph = memo(function NumericGraph(props: { | ||||||
|  |   contract: NumericContract | ||||||
|  |   height?: number | ||||||
|  | }) { | ||||||
|  |   const { contract, height } = props | ||||||
|  |   const { totalShares, bucketCount, min, max } = contract | ||||||
|  | 
 | ||||||
|  |   const bucketProbs = getDpmOutcomeProbabilities(totalShares) | ||||||
|  | 
 | ||||||
|  |   const xs = _.range(bucketCount).map( | ||||||
|  |     (i) => min + ((max - min) * i) / bucketCount | ||||||
|  |   ) | ||||||
|  |   const probs = _.range(bucketCount).map((i) => bucketProbs[`${i}`]) | ||||||
|  |   const points = probs.map((prob, i) => ({ x: xs[i], y: prob * 100 })) | ||||||
|  |   const data = [{ id: 'Probability', data: points, color: '#b91181' }] | ||||||
|  | 
 | ||||||
|  |   const yTickValues = [0, 25, 50, 75, 100] | ||||||
|  | 
 | ||||||
|  |   const { width } = useWindowSize() | ||||||
|  | 
 | ||||||
|  |   const numXTickValues = !width || width < 800 ? 2 : 5 | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <div | ||||||
|  |       className="w-full overflow-hidden" | ||||||
|  |       style={{ height: height ?? (!width || width >= 800 ? 350 : 250) }} | ||||||
|  |     > | ||||||
|  |       <ResponsiveLine | ||||||
|  |         data={data} | ||||||
|  |         yScale={{ min: 0, max: 100, type: 'linear' }} | ||||||
|  |         yFormat={formatPercent} | ||||||
|  |         gridYValues={yTickValues} | ||||||
|  |         axisLeft={{ | ||||||
|  |           tickValues: yTickValues, | ||||||
|  |           format: formatPercent, | ||||||
|  |         }} | ||||||
|  |         xScale={{ | ||||||
|  |           type: 'linear', | ||||||
|  |           min: min, | ||||||
|  |           max: max, | ||||||
|  |         }} | ||||||
|  |         xFormat={(d) => `${Math.round(+d * 100) / 100}`} | ||||||
|  |         axisBottom={{ | ||||||
|  |           tickValues: numXTickValues, | ||||||
|  |           format: (d) => `${Math.round(+d * 100) / 100}`, | ||||||
|  |         }} | ||||||
|  |         colors={{ datum: 'color' }} | ||||||
|  |         pointSize={0} | ||||||
|  |         pointBorderWidth={1} | ||||||
|  |         pointBorderColor="#fff" | ||||||
|  |         enableSlices="x" | ||||||
|  |         enableGridX={!!width && width >= 800} | ||||||
|  |         enableArea | ||||||
|  |         margin={{ top: 20, right: 28, bottom: 22, left: 40 }} | ||||||
|  |       /> | ||||||
|  |     </div> | ||||||
|  |   ) | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | function formatPercent(y: DatumValue) { | ||||||
|  |   return `${Math.round(+y.toString())}%` | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user