fix: 社区点击自动跳转步骤4 + 边显示 + 区分节点样式
修复: - loadClusterDetail: 无map时自动goStep(4)并等待初始化 - focusClusterOnMap: 边已正确添加到_clusterFocusLayer - renderMapData: 集群聚焦时保留_clusterFocusLayer - 节点样式按度数区分: 高流量(>20对端)大圆深色, 孤立节点小圆浅色 - 节点提示显示对端数和服务器标签 - clearClusterFocus简化,去除无用_clusterNodeLayer Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1432,10 +1432,19 @@ function renderMapData() {
|
||||
if (SA.hiddenClusters.has(n.cluster_id)) return;
|
||||
|
||||
const color = getSubnetColor(n.ip);
|
||||
// Larger circles, easy to click
|
||||
const peerCount = n.peer_count || 0;
|
||||
// High-degree servers: larger, brighter
|
||||
// Singletons: smaller, dimmer
|
||||
const isHighDeg = peerCount > 20;
|
||||
const isSingleton = peerCount <= 1;
|
||||
const radius = isHighDeg ? 10 : (isSingleton ? 4 : 7);
|
||||
const fillOpacity = isHighDeg ? 0.95 : (isSingleton ? 0.5 : 0.85);
|
||||
const weight = isHighDeg ? 3 : (isSingleton ? 1 : 2);
|
||||
const borderColor = isHighDeg ? '#222' : (isSingleton ? '#ccc' : '#fff');
|
||||
|
||||
const circle = L.circleMarker([n.lat, n.lon], {
|
||||
radius: 7, fillColor: color, color: '#fff', weight: 2,
|
||||
opacity: 0.95, fillOpacity: 0.85,
|
||||
radius, fillColor: color, color: borderColor, weight,
|
||||
opacity: 0.95, fillOpacity,
|
||||
interactive: true, bubblingMouseEvents: false,
|
||||
});
|
||||
circle.bindTooltip(buildNodeTooltip(n), {sticky: true, direction: 'top', offset: [0, -8]});
|
||||
@@ -1476,14 +1485,21 @@ function renderMapData() {
|
||||
SA.pointLayer = L.layerGroup(markers).addTo(SA.map);
|
||||
SA.centerLayer = L.layerGroup(centerMarkers).addTo(SA.map);
|
||||
renderLegend();
|
||||
// Restore cluster focus if active
|
||||
if (SA._clusterFocus && _clusterFocusLayer && !SA.map.hasLayer(_clusterFocusLayer)) {
|
||||
_clusterFocusLayer.addTo(SA.map);
|
||||
}
|
||||
}
|
||||
|
||||
function buildNodeTooltip(n) {
|
||||
const p = n.ip ? n.ip.split('.') : [];
|
||||
const sn = p.length >= 3 ? p[0]+'.'+p[1]+'.'+p[2]+'.0/24' : '';
|
||||
const srv = n.is_server ? ' 🖥' : '';
|
||||
return `<div class="sa-point-tooltip"><b>${escapeHtml(n.ip)}</b>${srv}<br>` +
|
||||
const pc = n.peer_count || 0;
|
||||
const label = pc > 20 ? ' 🔥服务器' : (n.is_server ? ' 🖥' : '');
|
||||
const degHint = pc > 0 ? `<span style="color:#e76f51;">${pc} 对端</span><br>` : '';
|
||||
return `<div class="sa-point-tooltip"><b>${escapeHtml(n.ip)}</b>${label}<br>` +
|
||||
(n.host ? `<span style="color:#2a9d8f;">${escapeHtml(n.host)}</span><br>` : '') +
|
||||
degHint +
|
||||
(sn ? `<span style="color:#888;">子网: ${sn}</span><br>` : '') +
|
||||
`${escapeHtml(n.city||'')}, ${escapeHtml(n.country||'')}<br>` +
|
||||
(n.isp ? `<span style="color:#666;">${escapeHtml(n.isp)}</span><br>` : '') +
|
||||
@@ -2184,8 +2200,28 @@ function loadClusterDetail(label) {
|
||||
.then(data => {
|
||||
hideLoading();
|
||||
if (data.error) { showError(data.error); return; }
|
||||
focusClusterOnMap(data);
|
||||
showClusterDetailPanelV2(data);
|
||||
// Ensure map exists — go to step 4 if needed
|
||||
if (!SA.map) {
|
||||
goStep(4);
|
||||
// Wait for map to finish initializing, then focus
|
||||
let attempts = 0;
|
||||
function waitThenFocus() {
|
||||
if (SA.map) {
|
||||
focusClusterOnMap(data);
|
||||
showClusterDetailPanelV2(data);
|
||||
} else if (attempts < 30) {
|
||||
attempts++;
|
||||
setTimeout(waitThenFocus, 200);
|
||||
} else {
|
||||
// Fallback: just show panel without map focus
|
||||
showClusterDetailPanelV2(data);
|
||||
}
|
||||
}
|
||||
setTimeout(waitThenFocus, 500);
|
||||
} else {
|
||||
focusClusterOnMap(data);
|
||||
showClusterDetailPanelV2(data);
|
||||
}
|
||||
})
|
||||
.catch(err => { hideLoading(); showError('加载失败: ' + err.message); });
|
||||
}
|
||||
@@ -2320,8 +2356,8 @@ function focusClusterOnMap(data) {
|
||||
|
||||
function clearClusterFocus() {
|
||||
if (_clusterFocusLayer && SA.map) { SA.map.removeLayer(_clusterFocusLayer); _clusterFocusLayer = null; }
|
||||
if (_clusterNodeLayer && SA.map) { SA.map.removeLayer(_clusterNodeLayer); _clusterNodeLayer = null; }
|
||||
SA._clusterFocus = null;
|
||||
SA._highlightedNodeEdges = null;
|
||||
|
||||
// Restore normal markers
|
||||
if (SA.map && SA.nodes && SA.nodes.length) {
|
||||
|
||||
Reference in New Issue
Block a user