分开上下行统计
This commit is contained in:
@@ -557,6 +557,23 @@ input:checked+.slider:before {
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.stat-card-value-group {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.stat-card-value-group .stat-card-value {
|
||||
font-size: 1.3rem; /* Slightly smaller to fit two in one row */
|
||||
}
|
||||
|
||||
.stat-card-separator {
|
||||
font-size: 1rem;
|
||||
color: var(--text-muted);
|
||||
opacity: 0.5;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.stat-card-servers .stat-card-value {
|
||||
color: var(--accent-purple);
|
||||
}
|
||||
|
||||
@@ -181,9 +181,13 @@
|
||||
</svg>
|
||||
</div>
|
||||
<div class="stat-card-content">
|
||||
<span class="stat-card-label">实时总带宽</span>
|
||||
<span class="stat-card-value" id="totalBandwidth">0 B/s</span>
|
||||
<span class="stat-card-sub" id="bandwidthDetail">↓ 0 ↑ 0</span>
|
||||
<span class="stat-card-label">实时带宽 (↑/↓)</span>
|
||||
<div class="stat-card-value-group">
|
||||
<span class="stat-card-value" id="totalBandwidthTx">0 B/s</span>
|
||||
<span class="stat-card-separator">/</span>
|
||||
<span class="stat-card-value" id="totalBandwidthRx">0 B/s</span>
|
||||
</div>
|
||||
<span class="stat-card-sub" id="bandwidthDetail">实时期末统计</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -205,7 +209,7 @@
|
||||
<span class="legend-item"><span class="legend-dot legend-rx"></span>接收 (RX)</span>
|
||||
<span class="legend-item"><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计费 (P95)
|
||||
<span class="legend-dot legend-p95"></span>95计费 (上行)
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -222,7 +226,7 @@
|
||||
<span class="traffic-value" id="traffic24hTx">0 B</span>
|
||||
</div>
|
||||
<div class="traffic-stat traffic-stat-p95">
|
||||
<span class="traffic-label">95计费带宽</span>
|
||||
<span class="traffic-label">95计费 (上行)</span>
|
||||
<span class="traffic-value" id="trafficP95">0 B/s</span>
|
||||
</div>
|
||||
<div class="traffic-stat traffic-stat-total">
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
memDetail: document.getElementById('memDetail'),
|
||||
diskPercent: document.getElementById('diskPercent'),
|
||||
diskDetail: document.getElementById('diskDetail'),
|
||||
totalBandwidth: document.getElementById('totalBandwidth'),
|
||||
totalBandwidthTx: document.getElementById('totalBandwidthTx'),
|
||||
totalBandwidthRx: document.getElementById('totalBandwidthRx'),
|
||||
bandwidthDetail: document.getElementById('bandwidthDetail'),
|
||||
traffic24hRx: document.getElementById('traffic24hRx'),
|
||||
traffic24hTx: document.getElementById('traffic24hTx'),
|
||||
@@ -570,8 +571,9 @@
|
||||
dom.diskDetail.textContent = `${formatBytes(data.disk.used)}/${formatBytes(data.disk.total)}`;
|
||||
|
||||
// Bandwidth
|
||||
dom.totalBandwidth.textContent = formatBandwidth(data.network.total || 0);
|
||||
dom.bandwidthDetail.textContent = `↓ ${formatBandwidth(data.network.rx)} ↑ ${formatBandwidth(data.network.tx)}`;
|
||||
dom.totalBandwidthTx.textContent = formatBandwidth(data.network.tx || 0);
|
||||
dom.totalBandwidthRx.textContent = formatBandwidth(data.network.rx || 0);
|
||||
dom.bandwidthDetail.textContent = `当前实时数据聚合`;
|
||||
|
||||
// 24h traffic
|
||||
dom.traffic24hRx.textContent = formatBytes(data.traffic24h.rx);
|
||||
@@ -586,7 +588,7 @@
|
||||
|
||||
// Flash animation
|
||||
if (previousMetrics) {
|
||||
[dom.cpuPercent, dom.memPercent, dom.diskPercent, dom.totalBandwidth].forEach(el => {
|
||||
[dom.cpuPercent, dom.memPercent, dom.diskPercent, dom.totalBandwidthTx, dom.totalBandwidthRx].forEach(el => {
|
||||
el.classList.remove('value-update');
|
||||
void el.offsetWidth; // Force reflow
|
||||
el.classList.add('value-update');
|
||||
|
||||
@@ -49,9 +49,8 @@ class AreaChart {
|
||||
}
|
||||
|
||||
// Calculate P95 (95th percentile)
|
||||
// Common standard: 95th percentile of the peak (max of rx/tx or sum)
|
||||
// We'll use max(rx, tx) at each point which is common for billing
|
||||
const combined = data.rx.map((r, i) => Math.max(r || 0, data.tx[i] || 0));
|
||||
// Updated: Only count Upstream (TX) as requested
|
||||
const combined = data.tx.map(t => t || 0);
|
||||
if (combined.length > 0) {
|
||||
const sorted = [...combined].sort((a, b) => a - b);
|
||||
const p95Idx = Math.floor(sorted.length * 0.95);
|
||||
|
||||
Reference in New Issue
Block a user