812 lines
34 KiB
HTML
812 lines
34 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="zh-CN">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>系统监控 - 多任务YOLO检测系统</title>
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css">
|
|
<link href="css/style.css" rel="stylesheet">
|
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
|
</head>
|
|
<body>
|
|
<!-- 导航栏 -->
|
|
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
|
|
<div class="container-fluid">
|
|
<a class="navbar-brand" href="index.html">
|
|
<i class="bi bi-cpu-fill me-2"></i>多任务YOLO检测系统
|
|
</a>
|
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
|
|
<span class="navbar-toggler-icon"></span>
|
|
</button>
|
|
<div class="collapse navbar-collapse" id="navbarNav">
|
|
<ul class="navbar-nav ms-auto">
|
|
<li class="nav-item">
|
|
<a class="nav-link" href="index.html">
|
|
<i class="bi bi-house-door me-1"></i>首页
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" href="task-management.html">
|
|
<i class="bi bi-list-task me-1"></i>任务管理
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link active" href="monitoring.html">
|
|
<i class="bi bi-graph-up me-1"></i>系统监控
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" href="video-player.html">
|
|
<i class="bi bi-camera-video me-1"></i>视频播放
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
|
|
<!-- 主内容区 -->
|
|
<div class="container-fluid mt-4">
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<h2><i class="bi bi-graph-up text-primary me-2"></i>系统监控</h2>
|
|
<div>
|
|
<button class="btn btn-outline-primary me-2" id="refreshCharts">
|
|
<i class="bi bi-arrow-clockwise me-1"></i>刷新数据
|
|
</button>
|
|
<div class="btn-group">
|
|
<button class="btn btn-outline-secondary" id="autoRefreshToggle">
|
|
<i class="bi bi-play-circle me-1"></i>自动刷新
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 系统资源卡片 -->
|
|
<div class="row mb-4">
|
|
<div class="col-md-3 mb-3">
|
|
<div class="card border-0 shadow-sm h-100">
|
|
<div class="card-body">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<h6 class="text-muted mb-2">CPU使用率</h6>
|
|
<h2 id="cpuPercent">42%</h2>
|
|
</div>
|
|
<div class="icon-circle bg-danger">
|
|
<i class="bi bi-cpu text-white"></i>
|
|
</div>
|
|
</div>
|
|
<div class="progress mt-2" style="height: 6px;">
|
|
<div class="progress-bar bg-danger" id="cpuBar" style="width: 42%"></div>
|
|
</div>
|
|
<p class="text-muted small mt-2 mb-0">总核心: 8, 使用中: 3</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3 mb-3">
|
|
<div class="card border-0 shadow-sm h-100">
|
|
<div class="card-body">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<h6 class="text-muted mb-2">内存使用</h6>
|
|
<h2 id="memoryPercent">68%</h2>
|
|
</div>
|
|
<div class="icon-circle bg-info">
|
|
<i class="bi bi-memory text-white"></i>
|
|
</div>
|
|
</div>
|
|
<div class="progress mt-2" style="height: 6px;">
|
|
<div class="progress-bar bg-info" id="memoryBar" style="width: 68%"></div>
|
|
</div>
|
|
<p class="text-muted small mt-2 mb-0">已用: 10.2GB / 总: 16GB</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3 mb-3">
|
|
<div class="card border-0 shadow-sm h-100">
|
|
<div class="card-body">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<h6 class="text-muted mb-2">GPU使用率</h6>
|
|
<h2 id="gpuPercent">78%</h2>
|
|
</div>
|
|
<div class="icon-circle bg-warning">
|
|
<i class="bi bi-gpu-card text-white"></i>
|
|
</div>
|
|
</div>
|
|
<div class="progress mt-2" style="height: 6px;">
|
|
<div class="progress-bar bg-warning" id="gpuBar" style="width: 78%"></div>
|
|
</div>
|
|
<p class="text-muted small mt-2 mb-0">显存: 6.4GB / 总: 8GB</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3 mb-3">
|
|
<div class="card border-0 shadow-sm h-100">
|
|
<div class="card-body">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<div>
|
|
<h6 class="text-muted mb-2">磁盘使用</h6>
|
|
<h2 id="diskPercent">34%</h2>
|
|
</div>
|
|
<div class="icon-circle bg-success">
|
|
<i class="bi bi-hdd text-white"></i>
|
|
</div>
|
|
</div>
|
|
<div class="progress mt-2" style="height: 6px;">
|
|
<div class="progress-bar bg-success" id="diskBar" style="width: 34%"></div>
|
|
</div>
|
|
<p class="text-muted small mt-2 mb-0">可用: 256GB / 总: 512GB</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 图表区域 -->
|
|
<div class="row mb-4">
|
|
<div class="col-md-6 mb-4">
|
|
<div class="card border-0 shadow-sm h-100">
|
|
<div class="card-header bg-white">
|
|
<h5 class="mb-0">CPU使用率趋势</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<canvas id="cpuChart" height="250"></canvas>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6 mb-4">
|
|
<div class="card border-0 shadow-sm h-100">
|
|
<div class="card-header bg-white">
|
|
<h5 class="mb-0">内存使用趋势</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<canvas id="memoryChart" height="250"></canvas>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-4">
|
|
<div class="col-md-6 mb-4">
|
|
<div class="card border-0 shadow-sm h-100">
|
|
<div class="card-header bg-white">
|
|
<h5 class="mb-0">任务FPS分布</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<canvas id="fpsChart" height="250"></canvas>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6 mb-4">
|
|
<div class="card border-0 shadow-sm h-100">
|
|
<div class="card-header bg-white">
|
|
<h5 class="mb-0">模型使用统计</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<canvas id="modelChart" height="250"></canvas>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 任务性能表 -->
|
|
<div class="card border-0 shadow-sm mb-4">
|
|
<div class="card-header bg-white">
|
|
<h5 class="mb-0">任务性能监控</h5>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
<div class="table-responsive">
|
|
<table class="table table-hover mb-0">
|
|
<thead class="table-light">
|
|
<tr>
|
|
<th>任务名称</th>
|
|
<th>状态</th>
|
|
<th>FPS</th>
|
|
<th>处理时间</th>
|
|
<th>检测数</th>
|
|
<th>模型数</th>
|
|
<th>GPU显存</th>
|
|
<th>运行时长</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="performanceTable">
|
|
<!-- 性能数据将通过JavaScript动态生成 -->
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 系统信息 -->
|
|
<div class="row">
|
|
<div class="col-md-6 mb-4">
|
|
<div class="card border-0 shadow-sm h-100">
|
|
<div class="card-header bg-white">
|
|
<h5 class="mb-0">系统信息</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<table class="table table-sm">
|
|
<tr>
|
|
<td><strong>操作系统</strong></td>
|
|
<td>Ubuntu 20.04 LTS</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Python版本</strong></td>
|
|
<td>3.8.10</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>PyTorch版本</strong></td>
|
|
<td>2.0.1+cu118</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>CUDA版本</strong></td>
|
|
<td>11.8</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Ultralytics版本</strong></td>
|
|
<td>8.0.0</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>OpenCV版本</strong></td>
|
|
<td>4.8.0</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>FFmpeg版本</strong></td>
|
|
<td>4.4.2</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>启动时间</strong></td>
|
|
<td id="systemUptime">2天 5小时 30分钟</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6 mb-4">
|
|
<div class="card border-0 shadow-sm h-100">
|
|
<div class="card-header bg-white">
|
|
<h5 class="mb-0">硬件信息</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<table class="table table-sm">
|
|
<tr>
|
|
<td><strong>CPU型号</strong></td>
|
|
<td>Intel Core i9-13900K</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>CPU核心数</strong></td>
|
|
<td>24核心 (8P+16E)</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>GPU型号</strong></td>
|
|
<td>NVIDIA RTX 4090</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>GPU显存</strong></td>
|
|
<td>24GB GDDR6X</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>系统内存</strong></td>
|
|
<td>32GB DDR5 5600MHz</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>磁盘型号</strong></td>
|
|
<td>Samsung 980 Pro 1TB NVMe</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>网络接口</strong></td>
|
|
<td>2.5Gbps Ethernet</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>系统温度</strong></td>
|
|
<td id="systemTemp">42°C</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 页脚 -->
|
|
<footer class="bg-dark text-white mt-5 py-4">
|
|
<div class="container-fluid">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<h5>系统监控</h5>
|
|
<p class="text-light">多任务YOLO检测系统的实时监控界面</p>
|
|
</div>
|
|
<div class="col-md-6 text-md-end">
|
|
<p class="mb-0">© 2023 多任务YOLO检测系统 | 演示版本 v1.0.0</p>
|
|
<p class="text-light small">此页面为演示版本,使用模拟数据</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</footer>
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
|
<script>
|
|
// 图表实例
|
|
let cpuChart, memoryChart, fpsChart, modelChart;
|
|
let autoRefreshInterval = null;
|
|
let isAutoRefreshing = false;
|
|
|
|
// 模拟性能数据
|
|
const mockPerformanceData = [
|
|
{ name: "交通监控-路口A", status: "running", fps: 24.5, processTime: "45ms", detections: 156, models: 3, gpuMem: "2.4GB", uptime: "5h 30m" },
|
|
{ name: "安全监控-入口", status: "running", fps: 28.1, processTime: "38ms", detections: 89, models: 2, gpuMem: "1.8GB", uptime: "4h 15m" },
|
|
{ name: "停车场监控", status: "stopped", fps: 0, processTime: "0ms", detections: 0, models: 1, gpuMem: "0GB", uptime: "0m" },
|
|
{ name: "生产线检测", status: "error", fps: 15.3, processTime: "62ms", detections: 0, models: 2, gpuMem: "1.2GB", uptime: "2h 45m" },
|
|
{ name: "测试任务", status: "creating", fps: 0, processTime: "0ms", detections: 0, models: 1, gpuMem: "0GB", uptime: "5m" }
|
|
];
|
|
|
|
// 模拟图表数据
|
|
let timeLabels = [];
|
|
let cpuData = [];
|
|
let memoryData = [];
|
|
let gpuData = [];
|
|
|
|
// 初始化时间标签
|
|
function initTimeLabels() {
|
|
timeLabels = [];
|
|
const now = new Date();
|
|
for (let i = 9; i >= 0; i--) {
|
|
const time = new Date(now.getTime() - i * 60000);
|
|
timeLabels.push(time.getHours().toString().padStart(2, '0') + ':' + time.getMinutes().toString().padStart(2, '0'));
|
|
}
|
|
}
|
|
|
|
// 初始化数据
|
|
function initChartData() {
|
|
cpuData = [];
|
|
memoryData = [];
|
|
gpuData = [];
|
|
|
|
for (let i = 0; i < 10; i++) {
|
|
cpuData.push(Math.floor(Math.random() * 30) + 30);
|
|
memoryData.push(Math.floor(Math.random() * 20) + 50);
|
|
gpuData.push(Math.floor(Math.random() * 30) + 50);
|
|
}
|
|
}
|
|
|
|
// 初始化CPU图表
|
|
function initCpuChart() {
|
|
const ctx = document.getElementById('cpuChart').getContext('2d');
|
|
|
|
if (cpuChart) {
|
|
cpuChart.destroy();
|
|
}
|
|
|
|
cpuChart = new Chart(ctx, {
|
|
type: 'line',
|
|
data: {
|
|
labels: timeLabels,
|
|
datasets: [{
|
|
label: 'CPU使用率 (%)',
|
|
data: cpuData,
|
|
borderColor: '#dc3545',
|
|
backgroundColor: 'rgba(220, 53, 69, 0.1)',
|
|
borderWidth: 2,
|
|
fill: true,
|
|
tension: 0.4
|
|
}]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
plugins: {
|
|
legend: {
|
|
display: true,
|
|
position: 'top'
|
|
}
|
|
},
|
|
scales: {
|
|
y: {
|
|
beginAtZero: true,
|
|
max: 100,
|
|
ticks: {
|
|
callback: function(value) {
|
|
return value + '%';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// 初始化内存图表
|
|
function initMemoryChart() {
|
|
const ctx = document.getElementById('memoryChart').getContext('2d');
|
|
|
|
if (memoryChart) {
|
|
memoryChart.destroy();
|
|
}
|
|
|
|
memoryChart = new Chart(ctx, {
|
|
type: 'line',
|
|
data: {
|
|
labels: timeLabels,
|
|
datasets: [{
|
|
label: '内存使用率 (%)',
|
|
data: memoryData,
|
|
borderColor: '#0dcaf0',
|
|
backgroundColor: 'rgba(13, 202, 240, 0.1)',
|
|
borderWidth: 2,
|
|
fill: true,
|
|
tension: 0.4
|
|
}]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
plugins: {
|
|
legend: {
|
|
display: true,
|
|
position: 'top'
|
|
}
|
|
},
|
|
scales: {
|
|
y: {
|
|
beginAtZero: true,
|
|
max: 100,
|
|
ticks: {
|
|
callback: function(value) {
|
|
return value + '%';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// 初始化FPS图表
|
|
function initFpsChart() {
|
|
const ctx = document.getElementById('fpsChart').getContext('2d');
|
|
|
|
if (fpsChart) {
|
|
fpsChart.destroy();
|
|
}
|
|
|
|
// 获取运行中任务的FPS数据
|
|
const runningTasks = mockPerformanceData.filter(task => task.status === 'running');
|
|
const taskNames = runningTasks.map(task => task.name);
|
|
const taskFps = runningTasks.map(task => task.fps);
|
|
|
|
fpsChart = new Chart(ctx, {
|
|
type: 'bar',
|
|
data: {
|
|
labels: taskNames,
|
|
datasets: [{
|
|
label: 'FPS',
|
|
data: taskFps,
|
|
backgroundColor: [
|
|
'rgba(255, 99, 132, 0.7)',
|
|
'rgba(54, 162, 235, 0.7)',
|
|
'rgba(255, 206, 86, 0.7)',
|
|
'rgba(75, 192, 192, 0.7)',
|
|
'rgba(153, 102, 255, 0.7)'
|
|
],
|
|
borderColor: [
|
|
'rgba(255, 99, 132, 1)',
|
|
'rgba(54, 162, 235, 1)',
|
|
'rgba(255, 206, 86, 1)',
|
|
'rgba(75, 192, 192, 1)',
|
|
'rgba(153, 102, 255, 1)'
|
|
],
|
|
borderWidth: 1
|
|
}]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
plugins: {
|
|
legend: {
|
|
display: false
|
|
}
|
|
},
|
|
scales: {
|
|
y: {
|
|
beginAtZero: true,
|
|
title: {
|
|
display: true,
|
|
text: 'FPS'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// 初始化模型图表
|
|
function initModelChart() {
|
|
const ctx = document.getElementById('modelChart').getContext('2d');
|
|
|
|
if (modelChart) {
|
|
modelChart.destroy();
|
|
}
|
|
|
|
// 模拟模型使用数据
|
|
const modelNames = ['yolov8n.pt', 'yolov8s.pt', 'yolov8m.pt', 'custom.pt', 'yolov5s.pt'];
|
|
const modelUsage = [45, 30, 15, 7, 3];
|
|
|
|
modelChart = new Chart(ctx, {
|
|
type: 'doughnut',
|
|
data: {
|
|
labels: modelNames,
|
|
datasets: [{
|
|
data: modelUsage,
|
|
backgroundColor: [
|
|
'rgba(255, 99, 132, 0.7)',
|
|
'rgba(54, 162, 235, 0.7)',
|
|
'rgba(255, 206, 86, 0.7)',
|
|
'rgba(75, 192, 192, 0.7)',
|
|
'rgba(153, 102, 255, 0.7)'
|
|
],
|
|
borderColor: [
|
|
'rgba(255, 99, 132, 1)',
|
|
'rgba(54, 162, 235, 1)',
|
|
'rgba(255, 206, 86, 1)',
|
|
'rgba(75, 192, 192, 1)',
|
|
'rgba(153, 102, 255, 1)'
|
|
],
|
|
borderWidth: 1
|
|
}]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
plugins: {
|
|
legend: {
|
|
position: 'right'
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// 渲染性能表格
|
|
function renderPerformanceTable() {
|
|
const tbody = document.getElementById('performanceTable');
|
|
tbody.innerHTML = '';
|
|
|
|
mockPerformanceData.forEach(task => {
|
|
const row = document.createElement('tr');
|
|
|
|
// 状态颜色
|
|
let statusColor = 'secondary';
|
|
let statusText = task.status;
|
|
if (task.status === 'running') {
|
|
statusColor = 'success';
|
|
statusText = '运行中';
|
|
} else if (task.status === 'error') {
|
|
statusColor = 'danger';
|
|
statusText = '错误';
|
|
} else if (task.status === 'creating') {
|
|
statusColor = 'info';
|
|
statusText = '创建中';
|
|
} else if (task.status === 'stopped') {
|
|
statusColor = 'secondary';
|
|
statusText = '已停止';
|
|
}
|
|
|
|
row.innerHTML = `
|
|
<td><strong>${task.name}</strong></td>
|
|
<td><span class="badge bg-${statusColor}">${statusText}</span></td>
|
|
<td>${task.fps > 0 ? task.fps.toFixed(1) : '0'}</td>
|
|
<td>${task.processTime}</td>
|
|
<td>${task.detections}</td>
|
|
<td>${task.models}</td>
|
|
<td>${task.gpuMem}</td>
|
|
<td>${task.uptime}</td>
|
|
`;
|
|
|
|
tbody.appendChild(row);
|
|
});
|
|
}
|
|
|
|
// 更新系统资源数据
|
|
function updateResourceData() {
|
|
// 更新资源百分比
|
|
const cpuPercent = Math.floor(Math.random() * 30) + 30;
|
|
const memoryPercent = Math.floor(Math.random() * 20) + 50;
|
|
const gpuPercent = Math.floor(Math.random() * 30) + 50;
|
|
const diskPercent = Math.floor(Math.random() * 20) + 30;
|
|
|
|
document.getElementById('cpuPercent').textContent = cpuPercent + '%';
|
|
document.getElementById('cpuBar').style.width = cpuPercent + '%';
|
|
|
|
document.getElementById('memoryPercent').textContent = memoryPercent + '%';
|
|
document.getElementById('memoryBar').style.width = memoryPercent + '%';
|
|
|
|
document.getElementById('gpuPercent').textContent = gpuPercent + '%';
|
|
document.getElementById('gpuBar').style.width = gpuPercent + '%';
|
|
|
|
document.getElementById('diskPercent').textContent = diskPercent + '%';
|
|
document.getElementById('diskBar').style.width = diskPercent + '%';
|
|
|
|
// 更新系统温度和运行时间
|
|
const temp = Math.floor(Math.random() * 10) + 38;
|
|
document.getElementById('systemTemp').textContent = temp + '°C';
|
|
|
|
// 更新图表数据
|
|
updateChartData();
|
|
|
|
// 更新性能数据
|
|
updatePerformanceData();
|
|
|
|
// 更新运行时间
|
|
updateUptime();
|
|
}
|
|
|
|
// 更新图表数据
|
|
function updateChartData() {
|
|
// 移除第一个数据点,添加新的数据点
|
|
cpuData.shift();
|
|
memoryData.shift();
|
|
gpuData.shift();
|
|
|
|
// 添加新的数据点
|
|
cpuData.push(Math.floor(Math.random() * 30) + 30);
|
|
memoryData.push(Math.floor(Math.random() * 20) + 50);
|
|
gpuData.push(Math.floor(Math.random() * 30) + 50);
|
|
|
|
// 更新时间标签
|
|
const now = new Date();
|
|
const timeStr = now.getHours().toString().padStart(2, '0') + ':' + now.getMinutes().toString().padStart(2, '0');
|
|
timeLabels.shift();
|
|
timeLabels.push(timeStr);
|
|
|
|
// 更新图表
|
|
cpuChart.update();
|
|
memoryChart.update();
|
|
fpsChart.update();
|
|
}
|
|
|
|
// 更新性能数据
|
|
function updatePerformanceData() {
|
|
mockPerformanceData.forEach(task => {
|
|
if (task.status === 'running') {
|
|
// 随机更新FPS
|
|
task.fps = (Math.random() * 10 + 20).toFixed(1);
|
|
|
|
// 增加检测数量
|
|
task.detections += Math.floor(Math.random() * 10);
|
|
|
|
// 更新运行时间
|
|
if (task.uptime.includes('h')) {
|
|
const hours = parseInt(task.uptime.split('h')[0]);
|
|
const minutes = parseInt(task.uptime.split('h')[1].split('m')[0]);
|
|
let newMinutes = minutes + 1;
|
|
let newHours = hours;
|
|
|
|
if (newMinutes >= 60) {
|
|
newHours++;
|
|
newMinutes = 0;
|
|
}
|
|
|
|
task.uptime = newHours + 'h ' + newMinutes + 'm';
|
|
} else if (task.uptime.includes('m')) {
|
|
const minutes = parseInt(task.uptime.split('m')[0]);
|
|
if (minutes >= 60) {
|
|
task.uptime = '1h ' + (minutes - 60) + 'm';
|
|
} else {
|
|
task.uptime = (minutes + 1) + 'm';
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
renderPerformanceTable();
|
|
initFpsChart(); // 重新初始化FPS图表以更新数据
|
|
}
|
|
|
|
// 更新运行时间
|
|
function updateUptime() {
|
|
const uptimeElement = document.getElementById('systemUptime');
|
|
let text = uptimeElement.textContent;
|
|
|
|
if (text.includes('天')) {
|
|
const days = parseInt(text.split('天')[0]);
|
|
const hours = parseInt(text.split('天')[1].split('小时')[0]);
|
|
const minutes = parseInt(text.split('小时')[1].split('分钟')[0]);
|
|
|
|
let newMinutes = minutes + 1;
|
|
let newHours = hours;
|
|
let newDays = days;
|
|
|
|
if (newMinutes >= 60) {
|
|
newHours++;
|
|
newMinutes = 0;
|
|
}
|
|
|
|
if (newHours >= 24) {
|
|
newDays++;
|
|
newHours = 0;
|
|
}
|
|
|
|
uptimeElement.textContent = newDays + '天 ' + newHours + '小时 ' + newMinutes + '分钟';
|
|
}
|
|
}
|
|
|
|
// 切换自动刷新
|
|
function toggleAutoRefresh() {
|
|
const button = document.getElementById('autoRefreshToggle');
|
|
const icon = button.querySelector('i');
|
|
|
|
if (isAutoRefreshing) {
|
|
// 停止自动刷新
|
|
clearInterval(autoRefreshInterval);
|
|
autoRefreshInterval = null;
|
|
button.innerHTML = '<i class="bi bi-play-circle me-1"></i>自动刷新';
|
|
button.classList.remove('btn-primary');
|
|
button.classList.add('btn-outline-secondary');
|
|
isAutoRefreshing = false;
|
|
showNotification('自动刷新已停止', '系统将不再自动更新数据', 'info');
|
|
} else {
|
|
// 开始自动刷新
|
|
autoRefreshInterval = setInterval(updateResourceData, 5000);
|
|
button.innerHTML = '<i class="bi bi-pause-circle me-1"></i>停止自动刷新';
|
|
button.classList.remove('btn-outline-secondary');
|
|
button.classList.add('btn-primary');
|
|
isAutoRefreshing = true;
|
|
showNotification('自动刷新已启动', '系统将每5秒自动更新数据', 'success');
|
|
}
|
|
}
|
|
|
|
// 显示通知
|
|
function showNotification(title, message, type) {
|
|
// 创建通知元素
|
|
const notification = document.createElement('div');
|
|
notification.className = `alert alert-${type} alert-dismissible fade show position-fixed`;
|
|
notification.style.cssText = 'top: 20px; right: 20px; z-index: 1050; min-width: 300px;';
|
|
notification.innerHTML = `
|
|
<strong>${title}</strong> ${message}
|
|
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
|
`;
|
|
|
|
document.body.appendChild(notification);
|
|
|
|
// 3秒后自动移除
|
|
setTimeout(() => {
|
|
if (notification.parentNode) {
|
|
notification.remove();
|
|
}
|
|
}, 3000);
|
|
}
|
|
|
|
// 初始化
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// 初始化数据
|
|
initTimeLabels();
|
|
initChartData();
|
|
|
|
// 初始化图表
|
|
initCpuChart();
|
|
initMemoryChart();
|
|
initFpsChart();
|
|
initModelChart();
|
|
|
|
// 渲染性能表格
|
|
renderPerformanceTable();
|
|
|
|
// 更新资源数据
|
|
updateResourceData();
|
|
|
|
// 绑定事件
|
|
document.getElementById('refreshCharts').addEventListener('click', updateResourceData);
|
|
document.getElementById('autoRefreshToggle').addEventListener('click', toggleAutoRefresh);
|
|
|
|
// 显示欢迎消息
|
|
setTimeout(() => {
|
|
showNotification('监控系统已就绪', '系统监控数据已加载完成', 'success');
|
|
}, 1000);
|
|
});
|
|
</script>
|
|
</body>
|
|
</html> |