import React, { useState } from 'react'; import { cn } from '../lib/utils'; interface RegionData { sido: string; count: number; } interface KoreaMapProps { data: RegionData[]; onRegionClick?: (sido: string) => void; className?: string; } // 지역별 색상 (축제 수에 따라 그라데이션) const getRegionColor = (count: number, maxCount: number) => { if (count === 0) return '#e5e7eb'; // gray-200 const intensity = Math.min(count / Math.max(maxCount, 1), 1); // Orange gradient from light to dark if (intensity < 0.2) return '#fed7aa'; // orange-200 if (intensity < 0.4) return '#fdba74'; // orange-300 if (intensity < 0.6) return '#fb923c'; // orange-400 if (intensity < 0.8) return '#f97316'; // orange-500 return '#ea580c'; // orange-600 }; // 한국 지도 SVG 경로 데이터 (간략화된 버전) const REGION_PATHS: Record = { '서울': { path: 'M 145 95 L 155 90 L 165 95 L 165 105 L 155 110 L 145 105 Z', labelX: 155, labelY: 100 }, '인천': { path: 'M 120 90 L 140 85 L 145 95 L 145 110 L 135 115 L 120 105 Z', labelX: 132, labelY: 100 }, '경기': { path: 'M 120 70 L 180 60 L 195 80 L 190 120 L 165 130 L 135 125 L 110 110 L 115 85 Z', labelX: 155, labelY: 85 }, '강원': { path: 'M 180 45 L 250 30 L 280 60 L 270 120 L 220 140 L 190 120 L 195 80 Z', labelX: 230, labelY: 85 }, '충북': { path: 'M 165 130 L 220 140 L 230 170 L 200 195 L 165 185 L 155 155 Z', labelX: 190, labelY: 165 }, '충남': { path: 'M 90 130 L 155 125 L 165 155 L 155 190 L 120 210 L 80 190 L 70 155 Z', labelX: 115, labelY: 170 }, '세종': { path: 'M 145 155 L 165 155 L 165 175 L 145 175 Z', labelX: 155, labelY: 165 }, '대전': { path: 'M 155 175 L 175 175 L 175 195 L 155 195 Z', labelX: 165, labelY: 185 }, '전북': { path: 'M 80 190 L 155 190 L 165 185 L 175 210 L 155 250 L 100 260 L 70 230 Z', labelX: 120, labelY: 225 }, '전남': { path: 'M 70 230 L 100 260 L 155 250 L 170 280 L 150 320 L 90 330 L 50 300 L 45 260 Z', labelX: 105, labelY: 290 }, '광주': { path: 'M 95 270 L 115 265 L 120 285 L 100 290 Z', labelX: 107, labelY: 278 }, '경북': { path: 'M 200 140 L 270 120 L 290 160 L 280 220 L 240 240 L 200 230 L 175 210 L 175 175 L 200 170 Z', labelX: 235, labelY: 185 }, '대구': { path: 'M 225 210 L 250 205 L 255 225 L 230 230 Z', labelX: 240, labelY: 218 }, '울산': { path: 'M 275 220 L 295 210 L 300 235 L 280 245 Z', labelX: 287, labelY: 228 }, '부산': { path: 'M 260 265 L 290 255 L 300 280 L 275 295 L 255 285 Z', labelX: 275, labelY: 275 }, '경남': { path: 'M 155 250 L 200 230 L 240 240 L 260 265 L 255 285 L 220 310 L 170 300 L 150 280 Z', labelX: 200, labelY: 270 }, '제주': { path: 'M 80 380 L 150 375 L 160 400 L 140 420 L 90 420 L 70 400 Z', labelX: 115, labelY: 400 } }; const KoreaMap: React.FC = ({ data, onRegionClick, className }) => { const [hoveredRegion, setHoveredRegion] = useState(null); // 데이터를 지역명으로 매핑 const dataMap = new Map(data.map(d => [d.sido, d.count])); const maxCount = Math.max(...data.map(d => d.count), 1); const getCount = (sido: string) => dataMap.get(sido) || 0; return (
{/* 배경 */} {/* 지역별 경로 */} {Object.entries(REGION_PATHS).map(([sido, { path, labelX, labelY }]) => { const count = getCount(sido); const isHovered = hoveredRegion === sido; return ( {/* 지역 영역 */} setHoveredRegion(sido)} onMouseLeave={() => setHoveredRegion(null)} onClick={() => onRegionClick?.(sido)} /> {/* 지역명 & 축제 수 */} {sido} {count > 0 && ( {count}개 )} ); })} {/* 호버 툴팁 */} {hoveredRegion && (

{hoveredRegion}

{getCount(hoveredRegion)}개 축제

)} {/* 범례 */}
적음
{['#e5e7eb', '#fed7aa', '#fdba74', '#fb923c', '#f97316', '#ea580c'].map((color, i) => (
))}
많음
); }; export default KoreaMap;