修复地图渲染的问题
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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: [{
|
||||
|
||||
Reference in New Issue
Block a user