You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
930 lines
33 KiB
HTML
930 lines
33 KiB
HTML
1 week ago
|
<!DOCTYPE html>
|
||
|
<html lang="zh-CN">
|
||
|
<head>
|
||
|
<meta charset="UTF-8">
|
||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
|
<title>统计分析 - 智慧河道管理平台</title>
|
||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||
|
<link rel="stylesheet" href="all.min.css">
|
||
|
<script src="chart.js"></script>
|
||
|
<style>
|
||
|
/* 滚动条美化 */
|
||
|
html {
|
||
|
scrollbar-color: rgba(42, 125, 225, 0.5) rgba(209, 224, 245, 0.3);
|
||
|
scrollbar-width: thin;
|
||
|
}
|
||
|
/* Webkit 浏览器滚动条样式 */
|
||
|
::-webkit-scrollbar {
|
||
|
width: 8px;
|
||
|
background: rgba(209, 224, 245, 0.3);
|
||
|
}
|
||
|
::-webkit-scrollbar-thumb {
|
||
|
background: rgba(42, 125, 225, 0.5);
|
||
|
border-radius: 4px;
|
||
|
}
|
||
|
* {
|
||
|
margin: 0;
|
||
|
padding: 0;
|
||
|
box-sizing: border-box;
|
||
|
}
|
||
|
|
||
|
body {
|
||
|
background-color: #f5f9ff;
|
||
|
font-family: 'Arial', sans-serif;
|
||
|
color: #1a4b8c;
|
||
|
min-height: 100vh;
|
||
|
padding: 20px;
|
||
|
|
||
|
}
|
||
|
|
||
|
.dashboard {
|
||
|
display: grid;
|
||
|
grid-template-columns: 1fr;
|
||
|
gap: 20px;
|
||
|
margin: 0 auto;
|
||
|
}
|
||
|
|
||
|
.main-content {
|
||
|
background: #ffffff;
|
||
|
border-radius: 12px;
|
||
|
padding: 20px;
|
||
|
box-shadow: 0 4px 20px rgba(0, 75, 150, 0.1);
|
||
|
}
|
||
|
|
||
|
.header {
|
||
|
display: flex;
|
||
|
justify-content: space-between;
|
||
|
align-items: center;
|
||
|
margin-bottom: 20px;
|
||
|
padding-bottom: 15px;
|
||
|
border-bottom: 1px solid #e1e9f5;
|
||
|
}
|
||
|
|
||
|
.header h1 {
|
||
|
color: #1a4b8c;
|
||
|
font-size: 24px;
|
||
|
font-weight: 600;
|
||
|
}
|
||
|
|
||
|
.stats-overview {
|
||
|
display: grid;
|
||
|
grid-template-columns: repeat(6, 1fr);
|
||
|
gap: 15px;
|
||
|
margin-bottom: 20px;
|
||
|
}
|
||
|
|
||
|
.stat-card {
|
||
|
background: #f5f9ff;
|
||
|
border: 1px solid #d1e0f5;
|
||
|
border-radius: 10px;
|
||
|
padding: 15px;
|
||
|
text-align: center;
|
||
|
transition: all 0.3s ease;
|
||
|
}
|
||
|
|
||
|
.stat-card:hover {
|
||
|
transform: translateY(-3px);
|
||
|
box-shadow: 0 4px 12px rgba(42, 125, 225, 0.15);
|
||
|
}
|
||
|
|
||
|
.stat-number {
|
||
|
font-size: 20px;
|
||
|
font-weight: bold;
|
||
|
color: #2a7de1;
|
||
|
margin-bottom: 5px;
|
||
|
}
|
||
|
|
||
|
.stat-label {
|
||
|
font-size: 12px;
|
||
|
color: #4a6fa5;
|
||
|
}
|
||
|
|
||
|
.stat-change {
|
||
|
font-size: 12px;
|
||
|
margin-top: 5px;
|
||
|
}
|
||
|
|
||
|
.change-up {
|
||
|
color: #28a745;
|
||
|
}
|
||
|
|
||
|
.change-down {
|
||
|
color: #dc3545;
|
||
|
}
|
||
|
|
||
|
.filter-section {
|
||
|
display: flex;
|
||
|
gap: 10px;
|
||
|
margin-bottom: 20px;
|
||
|
flex-wrap: wrap;
|
||
|
}
|
||
|
|
||
|
.filter-btn {
|
||
|
background: #f5f9ff;
|
||
|
border: 1px solid #d1e0f5;
|
||
|
color: #2a7de1;
|
||
|
padding: 8px 16px;
|
||
|
border-radius: 6px;
|
||
|
cursor: pointer;
|
||
|
transition: all 0.3s ease;
|
||
|
font-size: 14px;
|
||
|
}
|
||
|
|
||
|
.filter-btn:hover,
|
||
|
.filter-btn.active {
|
||
|
background: rgba(42, 125, 225, 0.1);
|
||
|
border-color: rgba(42, 125, 225, 0.3);
|
||
|
color: #1a4b8c;
|
||
|
}
|
||
|
|
||
|
.charts-grid {
|
||
|
display: grid;
|
||
|
grid-template-columns: 2fr 1fr;
|
||
|
gap: 20px;
|
||
|
margin-bottom: 20px;
|
||
|
}
|
||
|
|
||
|
.main-charts {
|
||
|
display: grid;
|
||
|
grid-template-columns: 1fr 1fr;
|
||
|
gap: 15px;
|
||
|
}
|
||
|
|
||
|
.side-charts {
|
||
|
display: grid;
|
||
|
grid-template-rows: 1fr 1fr;
|
||
|
gap: 15px;
|
||
|
}
|
||
|
|
||
|
.chart-container {
|
||
|
background: #ffffff;
|
||
|
border: 1px solid #e1e9f5;
|
||
|
border-radius: 10px;
|
||
|
padding: 15px;
|
||
|
box-shadow: 0 2px 8px rgba(0, 75, 150, 0.05);
|
||
|
}
|
||
|
|
||
|
.chart-title {
|
||
|
color: #1a4b8c;
|
||
|
font-size: 16px;
|
||
|
font-weight: 600;
|
||
|
margin-bottom: 10px;
|
||
|
border-bottom: 1px solid #e1e9f5;
|
||
|
padding-bottom: 10px;
|
||
|
}
|
||
|
|
||
|
.chart-canvas {
|
||
|
height: 250px;
|
||
|
}
|
||
|
|
||
|
.large-chart {
|
||
|
grid-column: 1 / -1;
|
||
|
}
|
||
|
|
||
|
.large-chart .chart-canvas {
|
||
|
height: 300px;
|
||
|
}
|
||
|
|
||
|
.bottom-section {
|
||
|
display: grid;
|
||
|
grid-template-columns: 1fr 1fr 1fr;
|
||
|
gap: 20px;
|
||
|
}
|
||
|
|
||
|
.data-table {
|
||
|
background: #ffffff;
|
||
|
border: 1px solid #e1e9f5;
|
||
|
border-radius: 10px;
|
||
|
padding: 15px;
|
||
|
box-shadow: 0 2px 8px rgba(0, 75, 150, 0.05);
|
||
|
}
|
||
|
|
||
|
.table-title {
|
||
|
color: #1a4b8c;
|
||
|
font-size: 16px;
|
||
|
font-weight: 600;
|
||
|
margin-bottom: 10px;
|
||
|
border-bottom: 1px solid #e1e9f5;
|
||
|
padding-bottom: 10px;
|
||
|
}
|
||
|
|
||
|
.data-list {
|
||
|
list-style: none;
|
||
|
}
|
||
|
|
||
|
.data-item {
|
||
|
display: flex;
|
||
|
justify-content: space-between;
|
||
|
padding: 8px 0;
|
||
|
border-bottom: 1px solid #e1e9f5;
|
||
|
color: #4a6fa5;
|
||
|
}
|
||
|
|
||
|
.data-item:last-child {
|
||
|
border-bottom: none;
|
||
|
}
|
||
|
|
||
|
.data-value {
|
||
|
color: #2a7de1;
|
||
|
font-weight: bold;
|
||
|
}
|
||
|
|
||
|
.progress-bar {
|
||
|
width: 100%;
|
||
|
height: 8px;
|
||
|
background: #e1e9f5;
|
||
|
border-radius: 4px;
|
||
|
margin-top: 5px;
|
||
|
overflow: hidden;
|
||
|
}
|
||
|
|
||
|
.progress-fill {
|
||
|
height: 100%;
|
||
|
background: linear-gradient(90deg, #2a7de1, #1a4b8c);
|
||
|
border-radius: 4px;
|
||
|
transition: width 0.3s;
|
||
|
}
|
||
|
|
||
|
.kpi-grid {
|
||
|
display: grid;
|
||
|
grid-template-columns: 1fr 1fr;
|
||
|
gap: 10px;
|
||
|
}
|
||
|
|
||
|
.kpi-item {
|
||
|
background: #f5f9ff;
|
||
|
border-radius: 8px;
|
||
|
padding: 30px;
|
||
|
text-align: center;
|
||
|
border: 1px solid #e1e9f5;
|
||
|
}
|
||
|
|
||
|
.kpi-value {
|
||
|
font-size: 18px;
|
||
|
font-weight: bold;
|
||
|
color: #2a7de1;
|
||
|
}
|
||
|
|
||
|
.kpi-label {
|
||
|
font-size: 12px;
|
||
|
color: #4a6fa5;
|
||
|
margin-top: 5px;
|
||
|
}
|
||
|
|
||
|
.header-info {
|
||
|
display: flex;
|
||
|
gap: 30px;
|
||
|
align-items: center;
|
||
|
}
|
||
|
|
||
|
.weather-info {
|
||
|
display: flex;
|
||
|
align-items: center;
|
||
|
gap: 10px;
|
||
|
color: #4a6fa5;
|
||
|
font-size: 14px;
|
||
|
}
|
||
|
|
||
|
.back-button {
|
||
|
cursor: pointer;
|
||
|
font-size: 20px;
|
||
|
margin-left: 20px;
|
||
|
transition: transform 0.3s;
|
||
|
color: #4a6fa5;
|
||
|
}
|
||
|
|
||
|
.back-button:hover {
|
||
|
transform: scale(1.1);
|
||
|
color: #2a7de1;
|
||
|
}
|
||
|
|
||
|
/* 响应式调整 */
|
||
|
@media (max-width: 1200px) {
|
||
|
.stats-overview {
|
||
|
grid-template-columns: repeat(3, 1fr);
|
||
|
}
|
||
|
|
||
|
.bottom-section {
|
||
|
grid-template-columns: 1fr 1fr;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@media (max-width: 768px) {
|
||
|
.stats-overview {
|
||
|
grid-template-columns: repeat(2, 1fr);
|
||
|
}
|
||
|
|
||
|
.charts-grid {
|
||
|
grid-template-columns: 1fr;
|
||
|
}
|
||
|
|
||
|
.main-charts {
|
||
|
grid-template-columns: 1fr;
|
||
|
}
|
||
|
|
||
|
.bottom-section {
|
||
|
grid-template-columns: 1fr;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
.header-actions {
|
||
|
display: flex;
|
||
|
gap: 10px;
|
||
|
}
|
||
|
|
||
|
.action-btn {
|
||
|
background: linear-gradient(135deg, #2a7de1, #1a4b8c);
|
||
|
color: #fff;
|
||
|
border: none;
|
||
|
padding: 8px 16px;
|
||
|
border-radius: 6px;
|
||
|
cursor: pointer;
|
||
|
transition: all 0.3s ease;
|
||
|
font-size: 14px;
|
||
|
box-shadow: 0 2px 8px rgba(42, 125, 225, 0.2);
|
||
|
display: flex;
|
||
|
align-items: center;
|
||
|
gap: 8px;
|
||
|
}
|
||
|
|
||
|
.action-btn:hover {
|
||
|
background: linear-gradient(135deg, #1a4b8c, #2a7de1);
|
||
|
transform: translateY(-2px);
|
||
|
box-shadow: 0 4px 12px rgba(42, 125, 225, 0.3);
|
||
|
}
|
||
|
|
||
|
</style>
|
||
|
</head>
|
||
|
<body>
|
||
|
<div class="dashboard">
|
||
|
<div class="main-content">
|
||
|
<div class="header">
|
||
|
<h1><i class="fas fa-chart-bar"></i> 数据统计分析</h1>
|
||
|
<div class="header-actions">
|
||
|
<button class="action-btn" onclick="location.href='index.html'">
|
||
|
<i class="fas fa-home-alt" style="color: orange;"></i> 回到首页
|
||
|
</button>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<div class="stats-overview">
|
||
|
<div class="stat-card">
|
||
|
<div class="stat-number" id="totalCleanup">1,245</div>
|
||
|
<div class="stat-label">总清理次数</div>
|
||
|
<div class="stat-change change-up">↗ +8.5%</div>
|
||
|
</div>
|
||
|
<div class="stat-card">
|
||
|
<div class="stat-number" id="waterQualityIndex">85.6</div>
|
||
|
<div class="stat-label">水质指数</div>
|
||
|
<div class="stat-change change-up">↗ +2.3%</div>
|
||
|
</div>
|
||
|
<div class="stat-card">
|
||
|
<div class="stat-number" id="deviceEfficiency">92.1%</div>
|
||
|
<div class="stat-label">设备效率</div>
|
||
|
<div class="stat-change change-down">↘ -1.2%</div>
|
||
|
</div>
|
||
|
<div class="stat-card">
|
||
|
<div class="stat-number" id="energyConsumption">2,156</div>
|
||
|
<div class="stat-label">能耗(kWh)</div>
|
||
|
<div class="stat-change change-down">↘ -5.8%</div>
|
||
|
</div>
|
||
|
<div class="stat-card">
|
||
|
<div class="stat-number" id="costSaving">¥18.5万</div>
|
||
|
<div class="stat-label">成本节约</div>
|
||
|
<div class="stat-change change-up">↗ +12.4%</div>
|
||
|
</div>
|
||
|
<div class="stat-card">
|
||
|
<div class="stat-number" id="responseTime">4.2分</div>
|
||
|
<div class="stat-label">平均响应</div>
|
||
|
<div class="stat-change change-down">↘ -15.6%</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<div class="filter-section">
|
||
|
<button class="filter-btn active" data-period="today">今日</button>
|
||
|
<button class="filter-btn" data-period="week">本周</button>
|
||
|
<button class="filter-btn" data-period="month">本月</button>
|
||
|
<button class="filter-btn" data-period="quarter">本季度</button>
|
||
|
<button class="filter-btn" data-period="year">本年</button>
|
||
|
<button class="filter-btn" onclick="exportData()"><i class="fas fa-download"></i> 导出数据</button>
|
||
|
<button class="filter-btn" onclick="generateReport()"><i class="fas fa-file-alt"></i> 生成报告</button>
|
||
|
</div>
|
||
|
|
||
|
<div class="charts-grid">
|
||
|
<div class="main-charts">
|
||
|
<div class="chart-container">
|
||
|
<div class="chart-title">水质趋势分析</div>
|
||
|
<div class="chart-canvas">
|
||
|
<canvas id="waterQualityChart"></canvas>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<div class="chart-container">
|
||
|
<div class="chart-title">清理效率统计</div>
|
||
|
<div class="chart-canvas">
|
||
|
<canvas id="cleanupEfficiencyChart"></canvas>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<div class="chart-container">
|
||
|
<div class="chart-title">设备运行状态</div>
|
||
|
<div class="chart-canvas">
|
||
|
<canvas id="deviceStatusChart"></canvas>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<div class="chart-container">
|
||
|
<div class="chart-title">成本效益分析</div>
|
||
|
<div class="chart-canvas">
|
||
|
<canvas id="costBenefitChart"></canvas>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<div class="side-charts">
|
||
|
<div class="chart-container">
|
||
|
<div class="chart-title">区域分布</div>
|
||
|
<div class="chart-canvas">
|
||
|
<canvas id="areaDistributionChart"></canvas>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<div class="chart-container">
|
||
|
<div class="chart-title">工作负载</div>
|
||
|
<div class="chart-canvas">
|
||
|
<canvas id="workloadChart"></canvas>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<div class="chart-container large-chart">
|
||
|
<div class="chart-title">综合性能仪表板</div>
|
||
|
<div class="chart-canvas">
|
||
|
<canvas id="performanceDashboard"></canvas>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<div class="bottom-section">
|
||
|
<div class="data-table">
|
||
|
<div class="table-title">热点区域排行</div>
|
||
|
<ul class="data-list" id="hotspotList">
|
||
|
<li class="data-item">
|
||
|
<span>湘江大桥段</span>
|
||
|
<span class="data-value">156次</span>
|
||
|
</li>
|
||
|
<li class="data-item">
|
||
|
<span>橘子洲头</span>
|
||
|
<span class="data-value">142次</span>
|
||
|
</li>
|
||
|
<li class="data-item">
|
||
|
<span>猴子石大桥</span>
|
||
|
<span class="data-value">128次</span>
|
||
|
</li>
|
||
|
<li class="data-item">
|
||
|
<span>银盆岭大桥</span>
|
||
|
<span class="data-value">115次</span>
|
||
|
</li>
|
||
|
<li class="data-item">
|
||
|
<span>湘江中路段</span>
|
||
|
<span class="data-value">98次</span>
|
||
|
</li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
|
||
|
<div class="data-table">
|
||
|
<div class="table-title">设备使用率</div>
|
||
|
<div class="data-list">
|
||
|
<div class="data-item">
|
||
|
<span>清理船A号</span>
|
||
|
<span class="data-value">95.2%</span>
|
||
|
</div>
|
||
|
<div class="progress-bar">
|
||
|
<div class="progress-fill" style="width: 95.2%"></div>
|
||
|
</div>
|
||
|
|
||
|
<div class="data-item">
|
||
|
<span>清理船B号</span>
|
||
|
<span class="data-value">87.8%</span>
|
||
|
</div>
|
||
|
<div class="progress-bar">
|
||
|
<div class="progress-fill" style="width: 87.8%"></div>
|
||
|
</div>
|
||
|
|
||
|
<div class="data-item">
|
||
|
<span>监测设备</span>
|
||
|
<span class="data-value">92.5%</span>
|
||
|
</div>
|
||
|
<div class="progress-bar">
|
||
|
<div class="progress-fill" style="width: 92.5%"></div>
|
||
|
</div>
|
||
|
|
||
|
<div class="data-item">
|
||
|
<span>传感器网络</span>
|
||
|
<span class="data-value">98.1%</span>
|
||
|
</div>
|
||
|
<div class="progress-bar">
|
||
|
<div class="progress-fill" style="width: 98.1%"></div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<div class="data-table">
|
||
|
<div class="table-title">关键指标</div>
|
||
|
<div class="kpi-grid">
|
||
|
<div class="kpi-item">
|
||
|
<div class="kpi-value" id="avgResponseTime">4.2分</div>
|
||
|
<div class="kpi-label">平均响应时间</div>
|
||
|
</div>
|
||
|
<div class="kpi-item">
|
||
|
<div class="kpi-value" id="completionRate">96.8%</div>
|
||
|
<div class="kpi-label">任务完成率</div>
|
||
|
</div>
|
||
|
<div class="kpi-item">
|
||
|
<div class="kpi-value" id="customerSatisfaction">4.7/5</div>
|
||
|
<div class="kpi-label">满意度评分</div>
|
||
|
</div>
|
||
|
<div class="kpi-item">
|
||
|
<div class="kpi-value" id="costPerCleanup">¥285</div>
|
||
|
<div class="kpi-label">单次清理成本</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<script src="script.js"></script>
|
||
|
<script>
|
||
|
// 更新时间
|
||
|
function updateDateTime() {
|
||
|
const now = new Date();
|
||
|
const dateStr = now.getFullYear() + '-' +
|
||
|
String(now.getMonth() + 1).padStart(2, '0') + '-' +
|
||
|
String(now.getDate()).padStart(2, '0');
|
||
|
const timeStr = String(now.getHours()).padStart(2, '0') + ':' +
|
||
|
String(now.getMinutes()).padStart(2, '0') + ':' +
|
||
|
String(now.getSeconds()).padStart(2, '0');
|
||
|
document.getElementById('datetime').textContent = dateStr + ' | ' + timeStr;
|
||
|
}
|
||
|
|
||
|
// 初始化所有图表
|
||
|
function initializeCharts() {
|
||
|
// 水质趋势分析
|
||
|
const ctx1 = document.getElementById('waterQualityChart').getContext('2d');
|
||
|
new Chart(ctx1, {
|
||
|
type: 'line',
|
||
|
data: {
|
||
|
labels: ['1月', '2月', '3月', '4月', '5月', '6月'],
|
||
|
datasets: [{
|
||
|
label: 'pH值',
|
||
|
data: [7.2, 7.1, 7.3, 7.0, 7.2, 7.1],
|
||
|
borderColor: '#2a7de1',
|
||
|
backgroundColor: 'rgba(42, 125, 225, 0.1)',
|
||
|
tension: 0.4,
|
||
|
borderWidth: 2
|
||
|
}, {
|
||
|
label: '溶解氧',
|
||
|
data: [8.5, 8.2, 8.7, 8.1, 8.4, 8.3],
|
||
|
borderColor: '#1a4b8c',
|
||
|
backgroundColor: 'rgba(26, 75, 140, 0.1)',
|
||
|
tension: 0.4,
|
||
|
borderWidth: 2
|
||
|
}]
|
||
|
},
|
||
|
options: {
|
||
|
responsive: true,
|
||
|
maintainAspectRatio: false,
|
||
|
plugins: {
|
||
|
legend: {
|
||
|
labels: {
|
||
|
color: '#1a4b8c',
|
||
|
font: {
|
||
|
weight: 'bold'
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
scales: {
|
||
|
x: {
|
||
|
ticks: { color: '#4a6fa5' },
|
||
|
grid: { color: 'rgba(209, 224, 245, 0.5)' }
|
||
|
},
|
||
|
y: {
|
||
|
ticks: { color: '#4a6fa5' },
|
||
|
grid: { color: 'rgba(209, 224, 245, 0.5)' }
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// 清理效率统计
|
||
|
const ctx2 = document.getElementById('cleanupEfficiencyChart').getContext('2d');
|
||
|
new Chart(ctx2, {
|
||
|
type: 'bar',
|
||
|
data: {
|
||
|
labels: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
|
||
|
datasets: [{
|
||
|
label: '清理次数',
|
||
|
data: [25, 32, 28, 35, 30, 20, 15],
|
||
|
backgroundColor: 'rgba(42, 125, 225, 0.6)',
|
||
|
borderColor: '#2a7de1',
|
||
|
borderWidth: 1
|
||
|
}]
|
||
|
},
|
||
|
options: {
|
||
|
responsive: true,
|
||
|
maintainAspectRatio: false,
|
||
|
plugins: {
|
||
|
legend: {
|
||
|
labels: {
|
||
|
color: '#1a4b8c',
|
||
|
font: {
|
||
|
weight: 'bold'
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
scales: {
|
||
|
x: {
|
||
|
ticks: { color: '#4a6fa5' },
|
||
|
grid: { color: 'rgba(209, 224, 245, 0.5)' }
|
||
|
},
|
||
|
y: {
|
||
|
ticks: { color: '#4a6fa5' },
|
||
|
grid: { color: 'rgba(209, 224, 245, 0.5)' }
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// 设备运行状态
|
||
|
const ctx3 = document.getElementById('deviceStatusChart').getContext('2d');
|
||
|
new Chart(ctx3, {
|
||
|
type: 'doughnut',
|
||
|
data: {
|
||
|
labels: ['正常运行', '维护中', '故障', '离线'],
|
||
|
datasets: [{
|
||
|
data: [85, 8, 4, 3],
|
||
|
backgroundColor: ['#28a745', '#ffc107', '#dc3545', '#6c757d'],
|
||
|
borderWidth: 1
|
||
|
}]
|
||
|
},
|
||
|
options: {
|
||
|
responsive: true,
|
||
|
maintainAspectRatio: false,
|
||
|
plugins: {
|
||
|
legend: {
|
||
|
labels: {
|
||
|
color: '#1a4b8c',
|
||
|
font: {
|
||
|
weight: 'bold'
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// 成本效益分析
|
||
|
const ctx4 = document.getElementById('costBenefitChart').getContext('2d');
|
||
|
new Chart(ctx4, {
|
||
|
type: 'line',
|
||
|
data: {
|
||
|
labels: ['1月', '2月', '3月', '4月', '5月', '6月'],
|
||
|
datasets: [{
|
||
|
label: '成本(万元)',
|
||
|
data: [45, 42, 48, 40, 44, 41],
|
||
|
borderColor: '#dc3545',
|
||
|
backgroundColor: 'rgba(220, 53, 69, 0.1)',
|
||
|
yAxisID: 'y',
|
||
|
borderWidth: 2
|
||
|
}, {
|
||
|
label: '收益(万元)',
|
||
|
data: [65, 68, 72, 70, 75, 78],
|
||
|
borderColor: '#28a745',
|
||
|
backgroundColor: 'rgba(40, 167, 69, 0.1)',
|
||
|
yAxisID: 'y1',
|
||
|
borderWidth: 2
|
||
|
}]
|
||
|
},
|
||
|
options: {
|
||
|
responsive: true,
|
||
|
maintainAspectRatio: false,
|
||
|
plugins: {
|
||
|
legend: {
|
||
|
labels: {
|
||
|
color: '#1a4b8c',
|
||
|
font: {
|
||
|
weight: 'bold'
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
scales: {
|
||
|
x: {
|
||
|
ticks: { color: '#4a6fa5' },
|
||
|
grid: { color: 'rgba(209, 224, 245, 0.5)' }
|
||
|
},
|
||
|
y: {
|
||
|
type: 'linear',
|
||
|
display: true,
|
||
|
position: 'left',
|
||
|
ticks: { color: '#4a6fa5' },
|
||
|
grid: { color: 'rgba(209, 224, 245, 0.5)' }
|
||
|
},
|
||
|
y1: {
|
||
|
type: 'linear',
|
||
|
display: true,
|
||
|
position: 'right',
|
||
|
ticks: { color: '#4a6fa5' },
|
||
|
grid: { drawOnChartArea: false }
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// 区域分布
|
||
|
const ctx5 = document.getElementById('areaDistributionChart').getContext('2d');
|
||
|
new Chart(ctx5, {
|
||
|
type: 'pie',
|
||
|
data: {
|
||
|
labels: ['湘江大桥段', '橘子洲头', '猴子石大桥', '银盆岭大桥', '其他'],
|
||
|
datasets: [{
|
||
|
data: [25, 22, 20, 18, 15],
|
||
|
backgroundColor: ['#2a7de1', '#1a4b8c', '#28a745', '#ffc107', '#6c757d'],
|
||
|
borderWidth: 1
|
||
|
}]
|
||
|
},
|
||
|
options: {
|
||
|
responsive: true,
|
||
|
maintainAspectRatio: false,
|
||
|
plugins: {
|
||
|
legend: {
|
||
|
labels: {
|
||
|
color: '#1a4b8c',
|
||
|
font: {
|
||
|
weight: 'bold'
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// 工作负载
|
||
|
const ctx6 = document.getElementById('workloadChart').getContext('2d');
|
||
|
new Chart(ctx6, {
|
||
|
type: 'radar',
|
||
|
data: {
|
||
|
labels: ['清理任务', '监测任务', '维护任务', '巡查任务', '应急任务'],
|
||
|
datasets: [{
|
||
|
label: '当前负载',
|
||
|
data: [85, 70, 60, 90, 45],
|
||
|
borderColor: '#2a7de1',
|
||
|
backgroundColor: 'rgba(42, 125, 225, 0.2)',
|
||
|
pointBackgroundColor: '#2a7de1',
|
||
|
borderWidth: 2
|
||
|
}]
|
||
|
},
|
||
|
options: {
|
||
|
responsive: true,
|
||
|
maintainAspectRatio: false,
|
||
|
plugins: {
|
||
|
legend: {
|
||
|
labels: {
|
||
|
color: '#1a4b8c',
|
||
|
font: {
|
||
|
weight: 'bold'
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
scales: {
|
||
|
r: {
|
||
|
ticks: { color: '#4a6fa5' },
|
||
|
grid: { color: 'rgba(209, 224, 245, 0.5)' },
|
||
|
pointLabels: {
|
||
|
color: '#1a4b8c',
|
||
|
font: {
|
||
|
weight: 'bold'
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// 综合性能仪表板
|
||
|
const ctx7 = document.getElementById('performanceDashboard').getContext('2d');
|
||
|
new Chart(ctx7, {
|
||
|
type: 'line',
|
||
|
data: {
|
||
|
labels: ['00:00', '04:00', '08:00', '12:00', '16:00', '20:00', '24:00'],
|
||
|
datasets: [{
|
||
|
label: '系统负载(%)',
|
||
|
data: [45, 35, 65, 85, 75, 55, 40],
|
||
|
borderColor: '#2a7de1',
|
||
|
backgroundColor: 'rgba(42, 125, 225, 0.1)',
|
||
|
tension: 0.4,
|
||
|
borderWidth: 2
|
||
|
}, {
|
||
|
label: '处理效率(%)',
|
||
|
data: [88, 92, 85, 78, 82, 90, 95],
|
||
|
borderColor: '#28a745',
|
||
|
backgroundColor: 'rgba(40, 167, 69, 0.1)',
|
||
|
tension: 0.4,
|
||
|
borderWidth: 2
|
||
|
}, {
|
||
|
label: '响应时间(分钟)',
|
||
|
data: [5.2, 4.8, 6.1, 7.5, 6.8, 4.9, 4.2],
|
||
|
borderColor: '#ffc107',
|
||
|
backgroundColor: 'rgba(255, 193, 7, 0.1)',
|
||
|
tension: 0.4,
|
||
|
borderWidth: 2
|
||
|
}]
|
||
|
},
|
||
|
options: {
|
||
|
responsive: true,
|
||
|
maintainAspectRatio: false,
|
||
|
plugins: {
|
||
|
legend: {
|
||
|
labels: {
|
||
|
color: '#1a4b8c',
|
||
|
font: {
|
||
|
weight: 'bold'
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
scales: {
|
||
|
x: {
|
||
|
ticks: { color: '#4a6fa5' },
|
||
|
grid: { color: 'rgba(209, 224, 245, 0.5)' }
|
||
|
},
|
||
|
y: {
|
||
|
ticks: { color: '#4a6fa5' },
|
||
|
grid: { color: 'rgba(209, 224, 245, 0.5)' }
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// 时间筛选功能
|
||
|
document.querySelectorAll('.filter-btn[data-period]').forEach(btn => {
|
||
|
btn.addEventListener('click', function() {
|
||
|
document.querySelectorAll('.filter-btn[data-period]').forEach(b => b.classList.remove('active'));
|
||
|
this.classList.add('active');
|
||
|
|
||
|
const period = this.dataset.period;
|
||
|
updateChartsForPeriod(period);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
function updateChartsForPeriod(period) {
|
||
|
// 根据时间段更新图表数据
|
||
|
console.log('更新图表数据,时间段:', period);
|
||
|
// 这里可以添加实际的数据更新逻辑
|
||
|
}
|
||
|
|
||
|
function exportData() {
|
||
|
alert('导出统计数据功能');
|
||
|
}
|
||
|
|
||
|
function generateReport() {
|
||
|
alert('生成分析报告功能');
|
||
|
}
|
||
|
|
||
|
// 实时数据更新
|
||
|
function updateRealTimeStats() {
|
||
|
// 模拟实时数据变化
|
||
|
const stats = {
|
||
|
totalCleanup: Math.floor(1200 + Math.random() * 100),
|
||
|
waterQualityIndex: (80 + Math.random() * 10).toFixed(1),
|
||
|
deviceEfficiency: (90 + Math.random() * 8).toFixed(1) + '%',
|
||
|
energyConsumption: Math.floor(2000 + Math.random() * 300),
|
||
|
costSaving: (15 + Math.random() * 8).toFixed(1) + '万',
|
||
|
responseTime: (3 + Math.random() * 3).toFixed(1) + '分'
|
||
|
};
|
||
|
|
||
|
Object.keys(stats).forEach(key => {
|
||
|
const element = document.getElementById(key);
|
||
|
if (element) {
|
||
|
element.textContent = stats[key];
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// 初始化
|
||
|
document.addEventListener('DOMContentLoaded', function() {
|
||
|
// updateDateTime();
|
||
|
// setInterval(updateDateTime, 1000);
|
||
|
initializeCharts();
|
||
|
updateRealTimeStats();
|
||
|
setInterval(updateRealTimeStats, 10000); // 每10秒更新统计数据
|
||
|
});
|
||
|
</script>
|
||
|
</body>
|
||
|
</html>
|