"use client"; import React, { memo, useState, useEffect } from "react"; import { ComposableMap, Geographies, Geography, Sphere, Graticule, ZoomableGroup } from "react-simple-maps"; import { scaleLinear } from "d3-scale"; import { fmtBytes } from "@/lib/utils"; import { useTheme } from "next-themes"; // The topojson file containing the world shapes const geoUrl = "https://cdn.jsdelivr.net/npm/world-atlas@2/countries-110m.json"; interface WorldMapProps { data: { countryCode: string; // ISO A2 code value: number; // The value used for heatmap label: string; // Country name for tooltip }[]; } const WorldMapComponent = ({ data }: WorldMapProps) => { const [tooltipContent, setTooltipContent] = useState(""); const [maxValue, setMaxValue] = useState(0); const [mounted, setMounted] = useState(false); useEffect(() => { setMounted(true); }, []); const { theme } = useTheme(); const isLight = theme === 'light'; useEffect(() => { if (data.length > 0) { const max = Math.max(...data.map(d => d.value)); setMaxValue(max); } }, [data]); const colorScale = scaleLinear() .domain(maxValue > 0 ? [0, maxValue * 0.33, maxValue * 0.66, maxValue] : [0, 1, 2, 3]) .range(isLight ? ["#bbf7d0", "#fef08a", "#fb923c", "#ef4444"] // Light: Green -> Yellow -> Orange -> Red : ["#1e293b", "#0f172a", "#0284c7", "#38bdf8"] // Dark: Slate -> Sky ); const defaultLandColor = isLight ? "#86efac" : "#1e293b"; const oceanColor = isLight ? "#bfdbfe" : "transparent"; const strokeColor = isLight ? "rgba(0,0,0,0.15)" : "rgba(255,255,255,0.1)"; if (!mounted) return null; return (
Heatmap Activity
Low
High
{/* Tooltip Overlay */} {tooltipContent && (
{tooltipContent.split(':')[0]}
{tooltipContent.split(':')[1]}
)} {({ geographies }) => geographies.map((geo) => { // geo.properties.name contains the country name in this TopoJSON // Try to find if we have data for this country const d = data.find((s) => { if (!geo.properties.name) return false; const geoName = geo.properties.name.toLowerCase(); const sLabel = s.label.toLowerCase(); return geoName === sLabel || (sLabel === 'united states' && geoName === 'united states of america') || (sLabel === 'the netherlands' && geoName === 'netherlands') || (sLabel === 'south korea' && geoName === 'korea'); }); const color = d ? colorScale(d.value) : defaultLandColor; return ( { if (d) { setTooltipContent(`${d.label}: ${fmtBytes(d.value)}`); } else { setTooltipContent(`${geo.properties.name}: No data`); } }} onMouseLeave={() => { setTooltipContent(""); }} /> ); }) }
); }; export const WorldMap = memo(WorldMapComponent);