feat: add GeoMap component for visualizing country-specific scan data.
This commit is contained in:
parent
57d6e3a449
commit
036500f6d1
|
|
@ -144,8 +144,16 @@ const GeoMap: React.FC<GeoMapProps> = ({ countryStats, totalScans }) => {
|
|||
.domain([0, maxCount || 1])
|
||||
.range(['#E0F2FE', '#1E40AF']);
|
||||
|
||||
const [tooltipContent, setTooltipContent] = React.useState<{ name: string; count: number } | null>(null);
|
||||
const [tooltipPos, setTooltipPos] = React.useState({ x: 0, y: 0 });
|
||||
|
||||
return (
|
||||
<div className="w-full h-full">
|
||||
<div
|
||||
className="w-full h-full relative group"
|
||||
onMouseMove={(evt) => {
|
||||
setTooltipPos({ x: evt.clientX, y: evt.clientY });
|
||||
}}
|
||||
>
|
||||
<ComposableMap
|
||||
projection="geoMercator"
|
||||
projectionConfig={{
|
||||
|
|
@ -179,6 +187,13 @@ const GeoMap: React.FC<GeoMapProps> = ({ countryStats, totalScans }) => {
|
|||
},
|
||||
pressed: { outline: 'none' },
|
||||
}}
|
||||
onMouseEnter={() => {
|
||||
const { name } = geo.properties;
|
||||
setTooltipContent({ name, count: scanCount });
|
||||
}}
|
||||
onMouseLeave={() => {
|
||||
setTooltipContent(null);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
})
|
||||
|
|
@ -186,6 +201,24 @@ const GeoMap: React.FC<GeoMapProps> = ({ countryStats, totalScans }) => {
|
|||
</Geographies>
|
||||
</ZoomableGroup>
|
||||
</ComposableMap>
|
||||
|
||||
{tooltipContent && (
|
||||
<div
|
||||
className="fixed z-50 px-3 py-2 text-sm font-medium text-white bg-gray-900 rounded-lg shadow-xl pointer-events-none transform -translate-x-1/2 -translate-y-full"
|
||||
style={{
|
||||
left: tooltipPos.x,
|
||||
top: tooltipPos.y - 10,
|
||||
}}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<span>{tooltipContent.name}</span>
|
||||
<span className="text-gray-400">|</span>
|
||||
<span className="font-bold text-blue-400">{tooltipContent.count} scans</span>
|
||||
</div>
|
||||
{/* Arrow */}
|
||||
<div className="absolute bottom-0 left-1/2 -translate-x-1/2 translate-y-full w-0 h-0 border-l-4 border-r-4 border-t-4 border-l-transparent border-r-transparent border-t-gray-900"></div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue