修复地图渲染的问题

This commit is contained in:
CN-JS-HuiBai
2026-04-06 00:45:17 +08:00
parent cc3c67eae9
commit b2f14528a9
2 changed files with 100 additions and 75 deletions

View File

@@ -205,8 +205,10 @@
</h2>
</div>
<div class="chart-legend">
<span class="legend-item" id="legendRx" style="cursor: pointer;" title="点击切换 接收 (RX) 显示/隐藏"><span class="legend-dot legend-rx"></span>接收 (RX)</span>
<span class="legend-item" id="legendTx" style="cursor: pointer;" title="点击切换 发送 (TX) 显示/隐藏"><span class="legend-dot legend-tx"></span>发送 (TX)</span>
<span class="legend-item" id="legendRx" style="cursor: pointer;" title="点击切换 接收 (RX) 显示/隐藏"><span
class="legend-dot legend-rx"></span>接收 (RX)</span>
<span class="legend-item" id="legendTx" style="cursor: pointer;" title="点击切换 发送 (TX) 显示/隐藏"><span
class="legend-dot legend-tx"></span>发送 (TX)</span>
<span class="legend-item disabled" id="legendP95" style="cursor: pointer;" title="点击切换 P95 线显示/隐藏">
<span class="legend-dot legend-p95"></span>95计费 (<span id="p95LabelText">上行</span>)
</span>
@@ -252,7 +254,8 @@
</h2>
<div class="chart-header-actions">
<button class="btn-icon" id="btnExpandGlobe" title="放大显示">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="width: 18px; height: 18px;">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
style="width: 18px; height: 18px;">
<path d="M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7" />
</svg>
</button>
@@ -291,8 +294,8 @@
</h2>
<div class="chart-header-right">
<div class="search-box">
<input type="search" id="serverSearchFilter" name="q-filter-server" placeholder="检索服务器名称..." autocomplete="one-time-code"
spellcheck="false">
<input type="search" id="serverSearchFilter" name="q-filter-server" placeholder="检索服务器名称..."
autocomplete="one-time-code" spellcheck="false">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
stroke-linejoin="round" class="search-icon">
<circle cx="11" cy="11" r="8"></circle>
@@ -370,15 +373,16 @@
<h3>添加数据源</h3>
<div class="form-row">
<div class="form-group" style="flex: 0.8;">
<label for="sourceType">类型</label>
<select id="sourceType" style="padding: 10px 14px; background: var(--bg-input); border: 1px solid var(--border-color); border-radius: var(--radius-sm); color: var(--text-primary); outline: none;">
<option value="prometheus">Prometheus</option>
<option value="blackbox">Blackbox Exporter</option>
</select>
<label for="sourceType">类型</label>
<select id="sourceType"
style="padding: 10px 14px; background: var(--bg-input); border: 1px solid var(--border-color); border-radius: var(--radius-sm); color: var(--text-primary); outline: none;">
<option value="prometheus">Prometheus</option>
<option value="blackbox">Blackbox Exporter</option>
</select>
</div>
<div class="form-group" style="flex: 1;">
<label for="sourceName">名称</label>
<input type="text" id="sourceName" placeholder="例:生产环境" autocomplete="off">
<label for="sourceName">名称</label>
<input type="text" id="sourceName" placeholder="例:生产环境" autocomplete="off">
</div>
<div class="form-group form-group-wide">
<label for="sourceUrl">URL 地址</label>
@@ -390,11 +394,14 @@
<label for="sourceDesc">描述 (可选)</label>
<input type="text" id="sourceDesc" placeholder="数据源描述" autocomplete="off">
</div>
<div class="form-group" id="serverSourceOption" style="display: flex; align-items: flex-end; padding-bottom: 8px;">
<label style="display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: 0.85rem; color: var(--text-secondary); white-space: nowrap;">
<input type="checkbox" id="isServerSource" checked style="width: 16px; height: 16px; accent-color: var(--accent-indigo);">
<span>用于服务器展示</span>
</label>
<div class="form-group" id="serverSourceOption"
style="display: flex; align-items: flex-end; padding-bottom: 8px;">
<label
style="display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: 0.85rem; color: var(--text-secondary); white-space: nowrap;">
<input type="checkbox" id="isServerSource" checked
style="width: 16px; height: 16px; accent-color: var(--accent-indigo);">
<span>用于服务器展示</span>
</label>
</div>
<div class="form-actions">
<button class="btn btn-test" id="btnTest">测试连接</button>
@@ -454,46 +461,55 @@
<option value="both">统计上行+下行 (Sum)</option>
</select>
</div>
<h3 style="margin-top: 30px; border-top: 1px solid var(--border-color); padding-top: 20px;">Blackbox 延迟连线管理</h3>
<h3 style="margin-top: 30px; border-top: 1px solid var(--border-color); padding-top: 20px;">Blackbox
延迟连线管理</h3>
<div class="latency-routes-manager">
<!-- Add Route Form -->
<div class="add-route-mini-form" style="background: rgba(255,255,255,0.02); padding: 15px; border-radius: 8px; margin-bottom: 20px; border: 1px solid var(--border-color);">
<div class="form-row">
<div class="form-group" style="flex: 1.5;">
<label>数据源 (Blackbox)</label>
<select id="routeSourceSelect" style="padding: 10px 14px; background: var(--bg-input); border: 1px solid var(--border-color); border-radius: var(--radius-sm); color: var(--text-primary);">
<option value="">-- 选择数据源 --</option>
</select>
</div>
<div class="form-group">
<label>起航点</label>
<input type="text" id="routeSourceInput" placeholder="例China">
</div>
<div class="form-group">
<label>目的地</label>
<input type="text" id="routeDestInput" placeholder="例United States">
</div>
</div>
<div class="form-row" style="margin-top: 10px; align-items: flex-end;">
<div class="form-group" style="flex: 2;">
<label>Blackbox 探测目标 (IP 或 域名)</label>
<input type="text" id="routeTargetInput" placeholder="例1.1.1.1 或 google.com">
</div>
<div class="form-actions" style="padding-bottom: 0; display: flex; gap: 8px;">
<button class="btn btn-add" id="btnAddRoute" style="padding: 10px 24px;">添加线路</button>
<button class="btn btn-test" id="btnCancelEditRoute" style="display: none; padding: 10px 15px; background: rgba(0,0,0,0.3);">取消</button>
</div>
</div>
<!-- Add Route Form -->
<div class="add-route-mini-form"
style="background: rgba(255,255,255,0.02); padding: 15px; border-radius: 8px; margin-bottom: 20px; border: 1px solid var(--border-color);">
<div class="form-row">
<div class="form-group" style="flex: 1.5;">
<label>数据源 (Blackbox)</label>
<select id="routeSourceSelect"
style="padding: 10px 14px; background: var(--bg-input); border: 1px solid var(--border-color); border-radius: var(--radius-sm); color: var(--text-primary);">
<option value="">-- 选择数据源 --</option>
</select>
</div>
<div class="form-group">
<label>起航点</label>
<input type="text" id="routeSourceInput" placeholder="例China">
</div>
<div class="form-group">
<label>目的地</label>
<input type="text" id="routeDestInput" placeholder="例United States">
</div>
</div>
<!-- Routes List -->
<div class="latency-routes-list-container">
<h4 style="font-size: 0.75rem; color: var(--text-muted); text-transform: uppercase;; margin-bottom: 10px;">已配置线路</h4>
<div id="latencyRoutesList" class="latency-routes-list" style="display: flex; flex-direction: column; gap: 10px;">
<!-- Routes will be injected here -->
<div class="route-empty" style="text-align: center; padding: 20px; color: var(--text-muted); font-size: 0.85rem; background: rgba(0,0,0,0.1); border-radius: 8px;">暂无线路</div>
</div>
<div class="form-row" style="margin-top: 10px; align-items: flex-end;">
<div class="form-group" style="flex: 2;">
<label>Blackbox 探测目标 (IP 或 域名)</label>
<input type="text" id="routeTargetInput" placeholder="例1.1.1.1 或 google.com">
</div>
<div class="form-actions" style="padding-bottom: 0; display: flex; gap: 8px;">
<button class="btn btn-add" id="btnAddRoute" style="padding: 10px 24px;">添加线路</button>
<button class="btn btn-test" id="btnCancelEditRoute"
style="display: none; padding: 10px 15px; background: rgba(0,0,0,0.3);">取消</button>
</div>
</div>
</div>
<!-- Routes List -->
<div class="latency-routes-list-container">
<h4
style="font-size: 0.75rem; color: var(--text-muted); text-transform: uppercase;; margin-bottom: 10px;">
已配置线路</h4>
<div id="latencyRoutesList" class="latency-routes-list"
style="display: flex; flex-direction: column; gap: 10px;">
<!-- Routes will be injected here -->
<div class="route-empty"
style="text-align: center; padding: 20px; color: var(--text-muted); font-size: 0.85rem; background: rgba(0,0,0,0.1); border-radius: 8px;">
暂无线路</div>
</div>
</div>
</div>
<div class="form-actions" style="margin-top: 25px; display: flex; justify-content: flex-end;">
<button class="btn btn-add" id="btnSaveSiteSettings">保存基础设置</button>
@@ -547,8 +563,7 @@
<!-- Metric Items are injected here -->
<div class="detail-metrics-list" id="detailMetricsList"></div>
<div class="detail-partitions-container metric-item" id="detailPartitionsContainer"
style="display: none;">
<div class="detail-partitions-container metric-item" id="detailPartitionsContainer" style="display: none;">
<div class="metric-item-header" id="partitionHeader">
<div class="metric-label-group">
<span class="metric-label">磁盘分区详情 (已挂载)</span>

View File

@@ -569,23 +569,32 @@
const resp = await fetch('https://cdn.jsdelivr.net/npm/echarts@4.9.0/map/json/world.json');
const worldJSON = await resp.json();
// Transform to Pacific-centered: shift longitudes < -20 to 340-360 range
// This puts America on the right of Asia
// Transform to Pacific-centered correctly
const transformCoords = (coords) => {
if (!Array.isArray(coords)) return;
if (typeof coords[0] === 'number') return; // Point
if (typeof coords[0][0] === 'number') { // Ring
// Calculate average to decide if we should shift the whole ring
let sum = 0;
coords.forEach(pt => sum += pt[0]);
let avg = sum / coords.length;
if (avg < -20) {
coords.forEach(pt => pt[0] += 360);
}
// Fix internal wrap-around jumps to keep polygons contiguous
for (let i = 1; i < coords.length; i++) {
let prev = coords[i - 1][0];
while (coords[i][0] - prev > 180) coords[i][0] -= 360;
while (coords[i][0] - prev < -180) coords[i][0] += 360;
}
} else {
coords.forEach(transformCoords);
}
};
worldJSON.features.forEach(feature => {
if (feature.geometry.type === 'Polygon') {
feature.geometry.coordinates.forEach(ring => {
ring.forEach(coords => {
if (coords[0] < -20) coords[0] += 360;
});
});
} else if (feature.geometry.type === 'MultiPolygon') {
feature.geometry.coordinates.forEach(polygon => {
polygon.forEach(ring => {
ring.forEach(coords => {
if (coords[0] < -20) coords[0] += 360;
});
});
});
if (feature.geometry && feature.geometry.coordinates) {
transformCoords(feature.geometry.coordinates);
}
});
@@ -625,19 +634,20 @@
geo: {
map: 'world',
roam: true,
center: [165, 20], // Centered in Pacific
center: [160, 25], // Centered slightly better for global view
zoom: 1.1,
aspectScale: 0.85, // Adjust aspect ratio to reduce vertical stretching in northern regions
emphasis: {
label: { show: false },
itemStyle: { areaColor: isLight ? '#f0f2f5' : '#2d334d' }
},
itemStyle: {
areaColor: isLight ? '#eef0f5' : '#1a1d2d',
areaColor: isLight ? '#f4f6fa' : '#1a1d2e',
borderColor: isLight ? '#cbd5e1' : '#2d334d',
borderWidth: 1
},
select: {
itemStyle: { areaColor: isLight ? '#f0f2f5' : '#2d334d' }
itemStyle: { areaColor: isLight ? '#f4f8ff' : '#2d334d' }
}
},
series: [{