state election map
This commit is contained in:
		
							parent
							
								
									2f25093a51
								
							
						
					
					
						commit
						72a2c86012
					
				
							
								
								
									
										63
									
								
								web/components/usa-map/state-election-map.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								web/components/usa-map/state-election-map.tsx
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,63 @@ | |||
| import { zip } from 'lodash' | ||||
| import Router from 'next/router' | ||||
| import { useEffect, useState } from 'react' | ||||
| 
 | ||||
| import { getProbability } from 'common/calculate' | ||||
| import { Contract, CPMMBinaryContract } from 'common/contract' | ||||
| import { Customize, USAMap } from './usa-map' | ||||
| import { getContractFromSlug } from 'web/lib/firebase/contracts' | ||||
| 
 | ||||
| export interface StateElectionMarket { | ||||
|   creatorUsername: string | ||||
|   slug: string | ||||
|   isWinRepublican: boolean | ||||
|   state: string | ||||
| } | ||||
| 
 | ||||
| export function StateElectionMap(props: { markets: StateElectionMarket[] }) { | ||||
|   const { markets } = props | ||||
| 
 | ||||
|   const contracts = useContracts(markets.map((m) => m.slug)) | ||||
|   const probs = contracts.map((c) => | ||||
|     c ? getProbability(c as CPMMBinaryContract) : 0.5 | ||||
|   ) | ||||
|   const marketsWithProbs = zip(markets, probs) as [ | ||||
|     StateElectionMarket, | ||||
|     number | ||||
|   ][] | ||||
| 
 | ||||
|   const stateInfo = marketsWithProbs.map(([market, prob]) => [ | ||||
|     market.state, | ||||
|     { | ||||
|       fill: probToColor(prob, market.isWinRepublican), | ||||
|       clickHandler: () => | ||||
|         Router.push(`/${market.creatorUsername}/${market.slug}`), | ||||
|     }, | ||||
|   ]) | ||||
| 
 | ||||
|   const config = Object.fromEntries(stateInfo) as Customize | ||||
| 
 | ||||
|   return <USAMap customize={config} /> | ||||
| } | ||||
| 
 | ||||
| const probToColor = (prob: number, isWinRepublican: boolean) => { | ||||
|   const p = isWinRepublican ? prob : 1 - prob | ||||
|   const hue = p > 0.5 ? 350 : 240 | ||||
|   const saturation = 100 | ||||
|   const lightness = 100 - 50 * Math.abs(p - 0.5) | ||||
|   return `hsl(${hue}, ${saturation}%, ${lightness}%)` | ||||
| } | ||||
| 
 | ||||
| const useContracts = (slugs: string[]) => { | ||||
|   const [contracts, setContracts] = useState<(Contract | undefined)[]>( | ||||
|     slugs.map(() => undefined) | ||||
|   ) | ||||
| 
 | ||||
|   useEffect(() => { | ||||
|     Promise.all(slugs.map((slug) => getContractFromSlug(slug))).then( | ||||
|       (contracts) => setContracts(contracts) | ||||
|     ) | ||||
|   }, [slugs]) | ||||
| 
 | ||||
|   return contracts | ||||
| } | ||||
|  | @ -64,8 +64,7 @@ export const USAMap = ({ | |||
| 
 | ||||
|   const stateClickHandler = (state: string) => | ||||
|     customize?.[state]?.clickHandler | ||||
|       ? (customize[state].clickHandler as ClickHandler) | ||||
|       : onClick | ||||
|       | ||||
| 
 | ||||
|   return ( | ||||
|     <svg | ||||
|  |  | |||
|  | @ -1,10 +1,11 @@ | |||
| import clsx from 'clsx' | ||||
| import { ClickHandler } from './usa-map' | ||||
| 
 | ||||
| type USAStateProps = { | ||||
|   state: string | ||||
|   dimensions: string | ||||
|   fill: string | ||||
|   onClickState: ClickHandler | ||||
|   onClickState?: ClickHandler | ||||
|   stateName: string | ||||
|   hideStateTitle?: boolean | ||||
| } | ||||
|  | @ -21,14 +22,14 @@ export const USAState = ({ | |||
|       d={dimensions} | ||||
|       fill={fill} | ||||
|       data-name={state} | ||||
|       className={`${state} state hover:cursor-pointer hover:contrast-125`} | ||||
|       className={clsx( | ||||
|         !!onClickState && 'hover:cursor-pointer hover:contrast-125' | ||||
|       )} | ||||
|       onClick={onClickState} | ||||
|       id={state} | ||||
|     > | ||||
|       <text> | ||||
|         <textPath xlinkHref={`#${state}`}> | ||||
|           {stateName} | ||||
|         </textPath> | ||||
|         <textPath xlinkHref={`#${state}`}>{stateName}</textPath> | ||||
|       </text> | ||||
|       {hideStateTitle ? null : <title>{stateName}</title>} | ||||
|     </path> | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user