From dc6070d6198ebbec3987d9c40c97bf09f23c486e Mon Sep 17 00:00:00 2001 From: htlee Date: Mon, 30 Mar 2026 12:45:30 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20=EB=AA=A8=EB=8D=B8=20=ED=86=A0=EA=B8=80?= =?UTF-8?q?=EC=9D=84=20=ED=98=B8=EB=B2=84=20=ED=8C=9D=EC=97=85=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=ED=95=98=EB=8B=A8=20=EA=B3=A0=EC=A0=95=20=ED=8C=A8?= =?UTF-8?q?=EB=84=90=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 호버 팝업은 마우스 이동 시 사라져서 토글 조작 불가 → 어구 그룹 선택 시 하단 중앙에 고정 패널 배치: - 좌측: 그룹 정보 + 폴리곤 오버레이 토글 (이름 기반 + 5개 모델) - 우측: 연관 선박 목록 (default 모델 상위 12건, 스크롤) - ✕ 버튼으로 선택 해제 - 히스토리 재생 컨트롤러와 동일 위치/스타일 Co-Authored-By: Claude Opus 4.6 (1M context) --- .../components/korea/FleetClusterLayer.tsx | 184 ++++++++++-------- 1 file changed, 104 insertions(+), 80 deletions(-) diff --git a/frontend/src/components/korea/FleetClusterLayer.tsx b/frontend/src/components/korea/FleetClusterLayer.tsx index e4c2e7b..86fc406 100644 --- a/frontend/src/components/korea/FleetClusterLayer.tsx +++ b/frontend/src/components/korea/FleetClusterLayer.tsx @@ -1240,86 +1240,6 @@ export function FleetClusterLayer({ ships, analysisMap: analysisMapProp, onShipS · {m.name || m.mmsi} ))} - {/* 모델 폴리곤 토글 (선택된 그룹만) */} - {selectedGearGroup === name && !correlationLoading && availableModels.length > 0 && ( -
-
- 폴리곤 오버레이 -
- {/* 이름 기반 (항상 표시) */} - - {/* 모델별 체크박스 */} - {availableModels.map(m => { - const color = MODEL_COLORS[m.name] ?? '#94a3b8'; - const modelItems = correlationByModel.get(m.name) ?? []; - const above70 = modelItems.filter(c => c.score >= 0.7).length; - return ( - - ); - })} -
- )} - {/* 연관 선박 상위 목록 (default 모델) */} - {selectedGearGroup === name && (() => { - const defaultItems = correlationData.filter(c => c.isDefault); - if (defaultItems.length === 0) return null; - return ( -
-
연관 선박 (default 상위 8)
- {defaultItems.slice(0, 8).map(c => { - const pct = (c.score * 100).toFixed(0); - const barW = Math.max(2, c.score * 60); - const barColor = c.score >= 0.7 ? '#22c55e' : c.score >= 0.5 ? '#eab308' : '#94a3b8'; - return ( -
- - {c.targetType === 'VESSEL' ? '⛴' : '◆'} - - - {c.targetName || c.targetMmsi} - -
-
-
-
- {pct}% -
-
- ); - })} - {defaultItems.length > 8 && ( -
+{defaultItems.length - 8}건 더
- )} -
- ); - })()} - {selectedGearGroup === name && correlationLoading && ( -
연관 분석 로딩...
- )}
클릭하여 선택/해제
@@ -1414,6 +1334,110 @@ export function FleetClusterLayer({ ships, analysisMap: analysisMapProp, onShipS )} + {/* ── 어구 연관성 패널 (선택된 그룹, 하단 고정) ── */} + {selectedGearGroup && !historyData && (() => { + const allGroups = groupPolygons + ? [...groupPolygons.gearInZoneGroups, ...groupPolygons.gearOutZoneGroups] + : []; + const group = allGroups.find(g => g.groupKey === selectedGearGroup); + if (!group) return null; + const defaultItems = correlationData.filter(c => c.isDefault); + return ( +
+ {/* 좌: 그룹 정보 + 모델 토글 */} +
+
+ {selectedGearGroup} + 어구 {group.memberCount}개 + +
+ {/* 폴리곤 오버레이 토글 */} +
폴리곤 오버레이
+ + {correlationLoading &&
로딩...
} + {availableModels.map(m => { + const color = MODEL_COLORS[m.name] ?? '#94a3b8'; + const modelItems = correlationByModel.get(m.name) ?? []; + const above70 = modelItems.filter(c => c.score >= 0.7).length; + return ( + + ); + })} +
+ {/* 우: 연관 선박 목록 (default 모델) */} + {defaultItems.length > 0 && ( +
+
+ 연관 선박 ({defaultItems.length}건) +
+
+ {defaultItems.slice(0, 12).map(c => { + const pct = (c.score * 100).toFixed(0); + const barW = Math.max(2, c.score * 60); + const barColor = c.score >= 0.7 ? '#22c55e' : c.score >= 0.5 ? '#eab308' : '#94a3b8'; + return ( +
+ + {c.targetType === 'VESSEL' ? '⛴' : '◆'} + + + {c.targetName || c.targetMmsi} + +
+
+
+
+ {pct}% +
+
+ ); + })} + {defaultItems.length > 12 && ( +
+{defaultItems.length - 12}건 더
+ )} +
+
+ )} +
+ ); + })()} + {/* 히스토리 재생 컨트롤러 */} {historyData && (() => { const curTime = new Date(currentTimeMs);