|
|
@ -2,7 +2,80 @@ |
|
|
|
ViewData["Title"] = "统计数据"; |
|
|
|
} |
|
|
|
|
|
|
|
<div class="container-fluid"> |
|
|
|
<style> |
|
|
|
/* 页面整体布局 */ |
|
|
|
.config-container { |
|
|
|
max-height: calc(100vh - 280px); |
|
|
|
display: flex; |
|
|
|
flex-direction: column; |
|
|
|
overflow: hidden; |
|
|
|
} |
|
|
|
|
|
|
|
/* 内容区域 */ |
|
|
|
.stats-content { |
|
|
|
flex: 1; |
|
|
|
overflow-y: auto; |
|
|
|
overflow-x: hidden; |
|
|
|
padding: 0.75rem; |
|
|
|
} |
|
|
|
|
|
|
|
/* 自定义滚动条 */ |
|
|
|
.stats-content::-webkit-scrollbar { |
|
|
|
width: 6px; |
|
|
|
} |
|
|
|
|
|
|
|
.stats-content::-webkit-scrollbar-track { |
|
|
|
background: #f1f1f1; |
|
|
|
border-radius: 3px; |
|
|
|
} |
|
|
|
|
|
|
|
.stats-content::-webkit-scrollbar-thumb { |
|
|
|
background: #c1c1c1; |
|
|
|
border-radius: 3px; |
|
|
|
} |
|
|
|
|
|
|
|
.stats-content::-webkit-scrollbar-thumb:hover { |
|
|
|
background: #a8a8a8; |
|
|
|
} |
|
|
|
|
|
|
|
/* 图表容器样式 */ |
|
|
|
.chart-container { |
|
|
|
position: relative; |
|
|
|
height: 300px; |
|
|
|
margin-bottom: 1rem; |
|
|
|
} |
|
|
|
|
|
|
|
/* 响应式调整 */ |
|
|
|
@@media (max-width: 768px) { |
|
|
|
.config-container { |
|
|
|
max-height: calc(100vh - 240px); |
|
|
|
} |
|
|
|
|
|
|
|
.stats-content { |
|
|
|
padding: 0.6rem; |
|
|
|
} |
|
|
|
|
|
|
|
.chart-container { |
|
|
|
height: 250px; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@@media (max-width: 576px) { |
|
|
|
.config-container { |
|
|
|
max-height: calc(100vh - 220px); |
|
|
|
} |
|
|
|
|
|
|
|
.stats-content { |
|
|
|
padding: 0.5rem; |
|
|
|
} |
|
|
|
|
|
|
|
.chart-container { |
|
|
|
height: 200px; |
|
|
|
} |
|
|
|
} |
|
|
|
</style> |
|
|
|
|
|
|
|
<div class="container"> |
|
|
|
<div class="row"> |
|
|
|
<div class="col-12"> |
|
|
|
<div class="card"> |
|
|
@ -20,114 +93,194 @@ |
|
|
|
</button> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div class="card-body"> |
|
|
|
<!-- 统计摘要 --> |
|
|
|
<div class="row mb-3"> |
|
|
|
<div class="col-md-3"> |
|
|
|
<div class="info-box"> |
|
|
|
<span class="info-box-icon bg-info"><i class="fas fa-server"></i></span> |
|
|
|
<div class="info-box-content"> |
|
|
|
<span class="info-box-text">客户端数量</span> |
|
|
|
<span class="info-box-number" id="clientCount">0</span> |
|
|
|
<div class="card-body p-0"> |
|
|
|
<div class="config-container"> |
|
|
|
<div class="stats-content"> |
|
|
|
<!-- 统计摘要 --> |
|
|
|
<div class="row mb-3"> |
|
|
|
<div class="col-md-3"> |
|
|
|
<div class="info-box"> |
|
|
|
<span class="info-box-icon bg-info"><i class="fas fa-server"></i></span> |
|
|
|
<div class="info-box-content"> |
|
|
|
<span class="info-box-text">客户端数量</span> |
|
|
|
<span class="info-box-number" id="clientCount">0</span> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div class="col-md-3"> |
|
|
|
<div class="info-box"> |
|
|
|
<span class="info-box-icon bg-success"><i class="fas fa-database"></i></span> |
|
|
|
<div class="info-box-content"> |
|
|
|
<span class="info-box-text">队列大小</span> |
|
|
|
<span class="info-box-number" id="queueCount">0</span> |
|
|
|
<div class="col-md-3"> |
|
|
|
<div class="info-box"> |
|
|
|
<span class="info-box-icon bg-success"><i class="fas fa-database"></i></span> |
|
|
|
<div class="info-box-content"> |
|
|
|
<span class="info-box-text">队列大小</span> |
|
|
|
<span class="info-box-number" id="queueCount">0</span> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div class="col-md-3"> |
|
|
|
<div class="info-box"> |
|
|
|
<span class="info-box-icon bg-warning"><i class="fas fa-clock"></i></span> |
|
|
|
<div class="info-box-content"> |
|
|
|
<span class="info-box-text">最后更新</span> |
|
|
|
<span class="info-box-number" id="lastUpdate">-</span> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div class="col-md-3"> |
|
|
|
<div class="info-box"> |
|
|
|
<span class="info-box-icon bg-primary"><i class="fas fa-signal"></i></span> |
|
|
|
<div class="info-box-content"> |
|
|
|
<span class="info-box-text">SSE状态</span> |
|
|
|
<span class="info-box-number" id="sseStatus">未连接</span> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div class="col-md-3"> |
|
|
|
<div class="info-box"> |
|
|
|
<span class="info-box-icon bg-warning"><i class="fas fa-clock"></i></span> |
|
|
|
<div class="info-box-content"> |
|
|
|
<span class="info-box-text">最后更新</span> |
|
|
|
<span class="info-box-number" id="lastUpdate">-</span> |
|
|
|
|
|
|
|
<!-- 客户端选择 --> |
|
|
|
<div class="row mb-3"> |
|
|
|
<div class="col-md-6"> |
|
|
|
<div class="form-group"> |
|
|
|
<label for="clientSelect">选择客户端:</label> |
|
|
|
<select class="form-control" id="clientSelect" onchange="loadClientStats()"> |
|
|
|
<option value="">所有客户端</option> |
|
|
|
</select> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div class="col-md-6"> |
|
|
|
<div class="form-group"> |
|
|
|
<label for="refreshInterval">刷新间隔 (秒):</label> |
|
|
|
<input type="number" class="form-control" id="refreshInterval" value="5" min="1" max="60" onchange="updateRefreshInterval()"> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div class="col-md-3"> |
|
|
|
<div class="info-box"> |
|
|
|
<span class="info-box-icon bg-primary"><i class="fas fa-signal"></i></span> |
|
|
|
<div class="info-box-content"> |
|
|
|
<span class="info-box-text">SSE状态</span> |
|
|
|
<span class="info-box-number" id="sseStatus">未连接</span> |
|
|
|
|
|
|
|
<!-- 图表区域 --> |
|
|
|
<div class="row mb-4"> |
|
|
|
<!-- CPU使用率图表 --> |
|
|
|
<div class="col-md-6"> |
|
|
|
<div class="card"> |
|
|
|
<div class="card-header"> |
|
|
|
<h5 class="card-title">CPU使用率</h5> |
|
|
|
</div> |
|
|
|
<div class="card-body"> |
|
|
|
<div class="chart-container"> |
|
|
|
<canvas id="cpuChart"></canvas> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- RF采样率图表 --> |
|
|
|
<div class="col-md-6"> |
|
|
|
<div class="card"> |
|
|
|
<div class="card-header"> |
|
|
|
<h5 class="card-title">RF采样率</h5> |
|
|
|
</div> |
|
|
|
<div class="card-body"> |
|
|
|
<div class="chart-container"> |
|
|
|
<canvas id="rfChart"></canvas> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 客户端选择 --> |
|
|
|
<div class="row mb-3"> |
|
|
|
<div class="col-md-6"> |
|
|
|
<div class="form-group"> |
|
|
|
<label for="clientSelect">选择客户端:</label> |
|
|
|
<select class="form-control" id="clientSelect" onchange="loadClientStats()"> |
|
|
|
<option value="">所有客户端</option> |
|
|
|
</select> |
|
|
|
<!-- 小区性能图表 --> |
|
|
|
<div class="row mb-4"> |
|
|
|
<div class="col-md-12"> |
|
|
|
<div class="card"> |
|
|
|
<div class="card-header"> |
|
|
|
<h5 class="card-title">小区性能指标</h5> |
|
|
|
</div> |
|
|
|
<div class="card-body"> |
|
|
|
<div class="chart-container"> |
|
|
|
<canvas id="cellPerformanceChart"></canvas> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div class="col-md-6"> |
|
|
|
<div class="form-group"> |
|
|
|
<label for="refreshInterval">刷新间隔 (秒):</label> |
|
|
|
<input type="number" class="form-control" id="refreshInterval" value="5" min="1" max="60" onchange="updateRefreshInterval()"> |
|
|
|
|
|
|
|
<!-- 样本数据图表 --> |
|
|
|
<div class="row mb-4"> |
|
|
|
<div class="col-md-6"> |
|
|
|
<div class="card"> |
|
|
|
<div class="card-header"> |
|
|
|
<h5 class="card-title">TX样本数据</h5> |
|
|
|
</div> |
|
|
|
<div class="card-body"> |
|
|
|
<div class="chart-container"> |
|
|
|
<canvas id="txSamplesChart"></canvas> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="col-md-6"> |
|
|
|
<div class="card"> |
|
|
|
<div class="card-header"> |
|
|
|
<h5 class="card-title">RX样本数据</h5> |
|
|
|
</div> |
|
|
|
<div class="card-body"> |
|
|
|
<div class="chart-container"> |
|
|
|
<canvas id="rxSamplesChart"></canvas> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 统计数据表格 --> |
|
|
|
<div class="table-responsive"> |
|
|
|
<table class="table table-bordered table-striped" id="statsTable"> |
|
|
|
<thead> |
|
|
|
<tr> |
|
|
|
<th>客户端</th> |
|
|
|
<th>实例ID</th> |
|
|
|
<th>CPU使用率</th> |
|
|
|
<th>小区数量</th> |
|
|
|
<th>RF端口</th> |
|
|
|
<th>消息ID</th> |
|
|
|
<th>持续时间</th> |
|
|
|
<th>接收时间</th> |
|
|
|
<th>操作</th> |
|
|
|
</tr> |
|
|
|
</thead> |
|
|
|
<tbody id="statsTableBody"> |
|
|
|
<!-- 数据将通过JavaScript动态填充 --> |
|
|
|
</tbody> |
|
|
|
</table> |
|
|
|
</div> |
|
|
|
<!-- 统计数据表格 --> |
|
|
|
<div class="table-responsive"> |
|
|
|
<table class="table table-bordered table-striped" id="statsTable"> |
|
|
|
<thead> |
|
|
|
<tr> |
|
|
|
<th>客户端</th> |
|
|
|
<th>实例ID</th> |
|
|
|
<th>CPU使用率</th> |
|
|
|
<th>小区数量</th> |
|
|
|
<th>RF端口</th> |
|
|
|
<th>消息ID</th> |
|
|
|
<th>持续时间</th> |
|
|
|
<th>接收时间</th> |
|
|
|
<th>操作</th> |
|
|
|
</tr> |
|
|
|
</thead> |
|
|
|
<tbody id="statsTableBody"> |
|
|
|
<!-- 数据将通过JavaScript动态填充 --> |
|
|
|
</tbody> |
|
|
|
</table> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 小区详细信息 --> |
|
|
|
<div class="row mt-4" id="cellDetails" style="display: none;"> |
|
|
|
<div class="col-12"> |
|
|
|
<div class="card"> |
|
|
|
<div class="card-header"> |
|
|
|
<h4 class="card-title">小区详细信息 - <span id="selectedClientName"></span></h4> |
|
|
|
</div> |
|
|
|
<div class="card-body"> |
|
|
|
<div class="table-responsive"> |
|
|
|
<table class="table table-bordered table-striped" id="cellTable"> |
|
|
|
<thead> |
|
|
|
<tr> |
|
|
|
<th>小区ID</th> |
|
|
|
<th>下行比特率</th> |
|
|
|
<th>上行比特率</th> |
|
|
|
<th>下行使用率(平均)</th> |
|
|
|
<th>上行使用率(平均)</th> |
|
|
|
<th>UE数量(平均)</th> |
|
|
|
<th>ERAB数量(平均)</th> |
|
|
|
<th>调度用户(下行)</th> |
|
|
|
<th>调度用户(上行)</th> |
|
|
|
</tr> |
|
|
|
</thead> |
|
|
|
<tbody id="cellTableBody"> |
|
|
|
<!-- 小区数据将通过JavaScript动态填充 --> |
|
|
|
</tbody> |
|
|
|
</table> |
|
|
|
<!-- 小区详细信息 --> |
|
|
|
<div class="row mt-4" id="cellDetails" style="display: none;"> |
|
|
|
<div class="col-12"> |
|
|
|
<div class="card"> |
|
|
|
<div class="card-header"> |
|
|
|
<h4 class="card-title">小区详细信息 - <span id="selectedClientName"></span></h4> |
|
|
|
</div> |
|
|
|
<div class="card-body"> |
|
|
|
<div class="table-responsive"> |
|
|
|
<table class="table table-bordered table-striped" id="cellTable"> |
|
|
|
<thead> |
|
|
|
<tr> |
|
|
|
<th>小区ID</th> |
|
|
|
<th>下行比特率</th> |
|
|
|
<th>上行比特率</th> |
|
|
|
<th>下行使用率(平均)</th> |
|
|
|
<th>上行使用率(平均)</th> |
|
|
|
<th>UE数量(平均)</th> |
|
|
|
<th>ERAB数量(平均)</th> |
|
|
|
<th>调度用户(下行)</th> |
|
|
|
<th>调度用户(上行)</th> |
|
|
|
</tr> |
|
|
|
</thead> |
|
|
|
<tbody id="cellTableBody"> |
|
|
|
<!-- 小区数据将通过JavaScript动态填充 --> |
|
|
|
</tbody> |
|
|
|
</table> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
@ -140,18 +293,247 @@ |
|
|
|
</div> |
|
|
|
|
|
|
|
@section Scripts { |
|
|
|
<!-- Chart.js --> |
|
|
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script> |
|
|
|
|
|
|
|
<script> |
|
|
|
let sseConnection = null; |
|
|
|
let refreshTimer = null; |
|
|
|
let currentStats = {}; |
|
|
|
|
|
|
|
// 图表实例 |
|
|
|
let cpuChart = null; |
|
|
|
let rfChart = null; |
|
|
|
let cellPerformanceChart = null; |
|
|
|
let txSamplesChart = null; |
|
|
|
let rxSamplesChart = null; |
|
|
|
|
|
|
|
// 页面加载完成后初始化 |
|
|
|
$(document).ready(function() { |
|
|
|
initializeCharts(); |
|
|
|
loadSummary(); |
|
|
|
loadAllStats(); |
|
|
|
startRefreshTimer(); |
|
|
|
}); |
|
|
|
|
|
|
|
// 初始化图表 |
|
|
|
function initializeCharts() { |
|
|
|
// CPU使用率图表 |
|
|
|
const cpuCtx = document.getElementById('cpuChart').getContext('2d'); |
|
|
|
cpuChart = new Chart(cpuCtx, { |
|
|
|
type: 'doughnut', |
|
|
|
data: { |
|
|
|
labels: ['CPU使用率', '空闲'], |
|
|
|
datasets: [{ |
|
|
|
data: [0, 100], |
|
|
|
backgroundColor: ['#ff6384', '#36a2eb'], |
|
|
|
borderWidth: 0 |
|
|
|
}] |
|
|
|
}, |
|
|
|
options: { |
|
|
|
responsive: true, |
|
|
|
maintainAspectRatio: false, |
|
|
|
plugins: { |
|
|
|
legend: { |
|
|
|
position: 'bottom' |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
// RF采样率图表 |
|
|
|
const rfCtx = document.getElementById('rfChart').getContext('2d'); |
|
|
|
rfChart = new Chart(rfCtx, { |
|
|
|
type: 'bar', |
|
|
|
data: { |
|
|
|
labels: ['RX采样率', 'TX采样率'], |
|
|
|
datasets: [{ |
|
|
|
label: '采样率 (MHz)', |
|
|
|
data: [0, 0], |
|
|
|
backgroundColor: ['#4bc0c0', '#ff9f40'], |
|
|
|
borderWidth: 1 |
|
|
|
}] |
|
|
|
}, |
|
|
|
options: { |
|
|
|
responsive: true, |
|
|
|
maintainAspectRatio: false, |
|
|
|
scales: { |
|
|
|
y: { |
|
|
|
beginAtZero: true |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
// 小区性能图表 |
|
|
|
const cellCtx = document.getElementById('cellPerformanceChart').getContext('2d'); |
|
|
|
cellPerformanceChart = new Chart(cellCtx, { |
|
|
|
type: 'line', |
|
|
|
data: { |
|
|
|
labels: [], |
|
|
|
datasets: [{ |
|
|
|
label: '下行使用率 (%)', |
|
|
|
data: [], |
|
|
|
borderColor: '#ff6384', |
|
|
|
backgroundColor: 'rgba(255, 99, 132, 0.1)', |
|
|
|
tension: 0.1 |
|
|
|
}, { |
|
|
|
label: '上行使用率 (%)', |
|
|
|
data: [], |
|
|
|
borderColor: '#36a2eb', |
|
|
|
backgroundColor: 'rgba(54, 162, 235, 0.1)', |
|
|
|
tension: 0.1 |
|
|
|
}] |
|
|
|
}, |
|
|
|
options: { |
|
|
|
responsive: true, |
|
|
|
maintainAspectRatio: false, |
|
|
|
scales: { |
|
|
|
y: { |
|
|
|
beginAtZero: true, |
|
|
|
max: 100 |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
// TX样本图表 |
|
|
|
const txCtx = document.getElementById('txSamplesChart').getContext('2d'); |
|
|
|
txSamplesChart = new Chart(txCtx, { |
|
|
|
type: 'scatter', |
|
|
|
data: { |
|
|
|
datasets: [{ |
|
|
|
label: 'TX样本', |
|
|
|
data: [], |
|
|
|
backgroundColor: '#ff6384', |
|
|
|
pointRadius: 4 |
|
|
|
}] |
|
|
|
}, |
|
|
|
options: { |
|
|
|
responsive: true, |
|
|
|
maintainAspectRatio: false, |
|
|
|
scales: { |
|
|
|
x: { |
|
|
|
title: { |
|
|
|
display: true, |
|
|
|
text: 'RMS (dB)' |
|
|
|
} |
|
|
|
}, |
|
|
|
y: { |
|
|
|
title: { |
|
|
|
display: true, |
|
|
|
text: 'Max (dB)' |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
// RX样本图表 |
|
|
|
const rxCtx = document.getElementById('rxSamplesChart').getContext('2d'); |
|
|
|
rxSamplesChart = new Chart(rxCtx, { |
|
|
|
type: 'scatter', |
|
|
|
data: { |
|
|
|
datasets: [{ |
|
|
|
label: 'RX样本', |
|
|
|
data: [], |
|
|
|
backgroundColor: '#36a2eb', |
|
|
|
pointRadius: 4 |
|
|
|
}] |
|
|
|
}, |
|
|
|
options: { |
|
|
|
responsive: true, |
|
|
|
maintainAspectRatio: false, |
|
|
|
scales: { |
|
|
|
x: { |
|
|
|
title: { |
|
|
|
display: true, |
|
|
|
text: 'RMS (dB)' |
|
|
|
} |
|
|
|
}, |
|
|
|
y: { |
|
|
|
title: { |
|
|
|
display: true, |
|
|
|
text: 'Max (dB)' |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
// 更新图表数据 |
|
|
|
function updateCharts() { |
|
|
|
const clients = Object.keys(currentStats); |
|
|
|
if (clients.length === 0) return; |
|
|
|
|
|
|
|
// 获取第一个客户端的数据作为示例 |
|
|
|
const firstClient = currentStats[clients[0]]; |
|
|
|
|
|
|
|
// 更新CPU图表 |
|
|
|
if (firstClient.cpu) { |
|
|
|
const cpuUsage = firstClient.cpu.global || 0; |
|
|
|
cpuChart.data.datasets[0].data = [cpuUsage, 100 - cpuUsage]; |
|
|
|
cpuChart.update(); |
|
|
|
} |
|
|
|
|
|
|
|
// 更新RF图表 |
|
|
|
if (firstClient.rf) { |
|
|
|
rfChart.data.datasets[0].data = [ |
|
|
|
firstClient.rf.rxSampleRate || 0, |
|
|
|
firstClient.rf.txSampleRate || 0 |
|
|
|
]; |
|
|
|
rfChart.update(); |
|
|
|
} |
|
|
|
|
|
|
|
// 更新小区性能图表 |
|
|
|
if (firstClient.cells) { |
|
|
|
const cellIds = Object.keys(firstClient.cells); |
|
|
|
const dlUsage = []; |
|
|
|
const ulUsage = []; |
|
|
|
|
|
|
|
cellIds.forEach(cellId => { |
|
|
|
const cell = firstClient.cells[cellId]; |
|
|
|
dlUsage.push(cell.dlUseAvg || 0); |
|
|
|
ulUsage.push(cell.ulUseAvg || 0); |
|
|
|
}); |
|
|
|
|
|
|
|
cellPerformanceChart.data.labels = cellIds; |
|
|
|
cellPerformanceChart.data.datasets[0].data = dlUsage; |
|
|
|
cellPerformanceChart.data.datasets[1].data = ulUsage; |
|
|
|
cellPerformanceChart.update(); |
|
|
|
} |
|
|
|
|
|
|
|
// 更新样本图表 |
|
|
|
if (firstClient.samples) { |
|
|
|
// TX样本 |
|
|
|
const txData = []; |
|
|
|
if (firstClient.samples.txSamples) { |
|
|
|
firstClient.samples.txSamples.forEach(sample => { |
|
|
|
txData.push({ |
|
|
|
x: sample.rms, |
|
|
|
y: sample.max |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
txSamplesChart.data.datasets[0].data = txData; |
|
|
|
txSamplesChart.update(); |
|
|
|
|
|
|
|
// RX样本 |
|
|
|
const rxData = []; |
|
|
|
if (firstClient.samples.rxSamples) { |
|
|
|
firstClient.samples.rxSamples.forEach(sample => { |
|
|
|
rxData.push({ |
|
|
|
x: sample.rms, |
|
|
|
y: sample.max |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
rxSamplesChart.data.datasets[0].data = rxData; |
|
|
|
rxSamplesChart.update(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 加载统计摘要 |
|
|
|
function loadSummary() { |
|
|
|
$.get('/Statistics/GetSummary', function(response) { |
|
|
@ -172,6 +554,7 @@ |
|
|
|
currentStats = response.data; |
|
|
|
updateStatsTable(); |
|
|
|
updateClientSelect(); |
|
|
|
updateCharts(); |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
@ -256,6 +639,7 @@ |
|
|
|
if (response.success) { |
|
|
|
currentStats = { [clientName]: response.data }; |
|
|
|
updateStatsTable(); |
|
|
|
updateCharts(); |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
@ -304,6 +688,7 @@ |
|
|
|
if (data.type === 'stats_update') { |
|
|
|
currentStats = data.data; |
|
|
|
updateStatsTable(); |
|
|
|
updateCharts(); |
|
|
|
loadSummary(); |
|
|
|
} |
|
|
|
} catch (e) { |
|
|
|