"use client"; import React, { useMemo, useState } from 'react'; import { ComposableMap, Geographies, Geography, Line, Marker, ZoomableGroup } from "react-simple-maps"; import { useTheme } from "next-themes"; import { useGlobeData, GlobeDataInput } from './useGlobeData'; const geoUrl = "/ne_110m_admin_0_countries.geojson"; interface GlobeMapProps { data: GlobeDataInput[]; } export const GlobeMap = ({ data }: GlobeMapProps) => { const { theme } = useTheme(); const isLight = theme === 'light'; const [position, setPosition] = useState({ coordinates: [0, 20], zoom: 1 }); function handleMoveEnd(newPosition: any) { setPosition(newPosition); } const { arcsData, pointsData, labelsData } = useGlobeData(data, isLight); const mapBgColor = "transparent"; const mapBorderColor = isLight ? "#ffffff" : "#0ea5e9"; const mapFillColor = isLight ? "#4ade80" : "#0f172a"; const mapHoverFill = isLight ? "#22c55e" : "#1e293b"; return (
{({ geographies }) => geographies.map((geo) => ( )) } {arcsData.map((arc: any, i: number) => { const isLocal = arc.startLng === arc.endLng && arc.startLat === arc.endLat; const color = Array.isArray(arc.color) ? arc.color[0] : arc.color || '#0ea5e9'; if (isLocal) { return ( ); } // Force the line to go straight across the map (the "front") // by interpolating multiple points. This prevents d3-geo from // wrapping around the dateline for long distances. const coordinates: [number, number][] = []; const steps = 30; for (let j = 0; j <= steps; j++) { const t = j / steps; let lng = arc.startLng + (arc.endLng - arc.startLng) * t; // Dynamic arc height based on distance const dist = Math.sqrt( Math.pow(arc.endLng - arc.startLng, 2) + Math.pow(arc.endLat - arc.startLat, 2) ); const height = Math.min(dist * 0.15, 25); let lat = arc.startLat + (arc.endLat - arc.startLat) * t + Math.sin(t * Math.PI) * height; coordinates.push([lng, lat]); } return ( ); })} {pointsData.map((pt: any, i: number) => ( ))} {labelsData.map((lbl: any, i: number) => ( {lbl.name} ))}
); };