'use client' import * as React from 'react' import { scaleLinear } from 'd3-scale' import { ComposableMap, Geographies, Geography, Marker, ZoomableGroup, } from 'react-simple-maps' import ReactTooltip from 'react-tooltip' import { CircularProgress } from '@mui/material' import { useTheme } from '@mui/material/styles' import { ApiState, CountryDataResponse } from '../typeDefs/explorer-api' import MAP_TOPOJSON from '../assets/world-110m.json' type MapProps = { userLocation?: [number, number] countryData?: ApiState loading: boolean } export const WorldMap: FCWithChildren = ({ countryData, userLocation, loading, }) => { const { palette } = useTheme() const colorScale = React.useMemo(() => { if (countryData?.data) { const heighestNumberOfNodes = Math.max( ...Object.values(countryData.data).map((country) => country.nodes) ) return scaleLinear() .domain([ 0, 1, heighestNumberOfNodes / 4, heighestNumberOfNodes / 2, heighestNumberOfNodes, ]) .range(palette.nym.networkExplorer.map.fills) .unknown(palette.nym.networkExplorer.map.fills[0]) } return () => palette.nym.networkExplorer.map.fills[0] }, [countryData, palette]) const [tooltipContent, setTooltipContent] = React.useState( null ) if (loading) { return } return ( <> {({ geographies }) => geographies.map((geo) => { const d = (countryData?.data || {})[geo.properties.ISO_A3] return ( { const { NAME_LONG } = geo.properties if (!userLocation) { setTooltipContent(`${NAME_LONG} | ${d?.nodes || 0}`) } }} onMouseLeave={() => { setTooltipContent('') }} style={{ hover: !userLocation && countryData ? { fill: palette.nym.highlight, outline: 'white', } : undefined, }} /> ) }) } {userLocation && ( )} {tooltipContent} ) }