style: make map responsive and fill container with proper viewBox ratio

This commit is contained in:
Usman Baig
2026-01-16 21:17:20 +01:00
parent 472a6fbc63
commit 073a3a35eb

View File

@@ -1,7 +1,7 @@
'use client' 'use client'
import React, { memo, useMemo, useState } from 'react' import React, { memo, useMemo, useState } from 'react'
import { ComposableMap, Geographies, Geography, ZoomableGroup } from 'react-simple-maps' import { ComposableMap, Geographies, Geography } from 'react-simple-maps'
import { scaleLinear } from 'd3-scale' import { scaleLinear } from 'd3-scale'
import countries from 'i18n-iso-countries' import countries from 'i18n-iso-countries'
import enLocale from 'i18n-iso-countries/langs/en.json' import enLocale from 'i18n-iso-countries/langs/en.json'
@@ -44,53 +44,52 @@ const WorldMap = ({ data }: WorldMapProps) => {
const defaultStroke = isDark ? "#171717" : "#FFFFFF" // gray-900 / white const defaultStroke = isDark ? "#171717" : "#FFFFFF" // gray-900 / white
return ( return (
<div className="relative w-full h-[300px] overflow-hidden flex items-center justify-center"> <div className="relative w-full">
<ComposableMap <ComposableMap
width={800} width={475}
height={450} // Aspect ratio adjustment height={335}
projectionConfig={{ rotate: [-10, 0, 0], scale: 155 }} projectionConfig={{ rotate: [-10, 0, 0], scale: 90, center: [0, 20] }}
className="w-full h-auto"
> >
<ZoomableGroup center={[0, 10]} maxZoom={1}> <Geographies geography={geoUrl}>
<Geographies geography={geoUrl}> {({ geographies }) =>
{({ geographies }) => geographies
geographies .filter(geo => geo.id !== "010") // Remove Antarctica
.filter(geo => geo.id !== "010") // Remove Antarctica .map((geo) => {
.map((geo) => { const id = String(geo.id).padStart(3, '0')
const id = String(geo.id).padStart(3, '0') const count = processedData.map.get(id) || 0
const count = processedData.map.get(id) || 0
return (
return ( <Geography
<Geography key={geo.rsmKey}
key={geo.rsmKey} geography={geo}
geography={geo} fill={count > 0 ? colorScale(count) : defaultFill}
fill={count > 0 ? colorScale(count) : defaultFill} stroke={defaultStroke}
stroke={defaultStroke} strokeWidth={0.5}
strokeWidth={0.7} style={{
style={{ default: { outline: "none", transition: "all 250ms" },
default: { outline: "none", transition: "all 250ms" }, hover: { fill: "#FD5E0F", outline: "none", cursor: 'pointer' },
hover: { fill: "#FD5E0F", outline: "none", cursor: 'pointer' }, pressed: { outline: "none" },
pressed: { outline: "none" }, }}
}} onMouseEnter={(evt) => {
onMouseEnter={(evt) => { const { name } = geo.properties
const { name } = geo.properties setTooltipContent({
setTooltipContent({ content: `${name}: ${count} visitors`,
content: `${name}: ${count} visitors`, x: evt.clientX,
x: evt.clientX, y: evt.clientY
y: evt.clientY })
}) }}
}} onMouseLeave={() => {
onMouseLeave={() => { setTooltipContent(null)
setTooltipContent(null) }}
}} onMouseMove={(evt) => {
onMouseMove={(evt) => { setTooltipContent(prev => prev ? { ...prev, x: evt.clientX, y: evt.clientY } : null)
setTooltipContent(prev => prev ? { ...prev, x: evt.clientX, y: evt.clientY } : null) }}
}} />
/> )
) })
}) }
} </Geographies>
</Geographies>
</ZoomableGroup>
</ComposableMap> </ComposableMap>
{tooltipContent && ( {tooltipContent && (
<div <div