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.

3536 lines
124 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>海洋科考船态势感知系统</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js"></script>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', Arial, sans-serif;
}
body {
background: url('/assets/img/bg.png') no-repeat;
background-size: 100% 100%;
color: #e0f0ff;
overflow: hidden;
height: 100vh;
}
/* 新增顶部标题栏样式 */
.topDiv {
width: 100%;
height: 8vh;
background: url('/assets/img/topBg.png') top no-repeat;
background-size: 100% 115%;
display: flex;
justify-content: center;
z-index: 990;
position: relative;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}
.topDiv .center {
font-family: PangMenZhengDao, 'Source Han Sans CN';
font-weight: 400;
font-size: 4.1vh;
color: #ffffff;
align-self: center;
margin-top: -40px;
}
.topDiv .left {
position: absolute;
top: 4vh;
left: 3vw;
color: #ffffff;
}
.topDiv .left span:nth-child(1) {
font-weight: bold;
font-size: 0.8vw;
margin-right: 0.5vh;
}
.topDiv .left span:nth-child(2) {
font-weight: bold;
font-size: 1.2vw;
}
.topDiv .right {
position: absolute;
top: 3vh;
right: 0;
color: #ffffff;
display: flex;
align-items: center;
}
.topDiv .right img:nth-child(1) {}
.topDiv .right span {
font-weight: bold;
font-size: 1.2vw;
}
.topDiv .icon-home {
position: absolute;
top: 1vh;
right: 8vw;
width: 4vh;
cursor: pointer;
}
.container {
display: flex;
flex-direction: column;
height: calc(100vh - 8vh - 20px);
padding: 10px;
position: relative;
margin-bottom: 20px;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 20px;
background: rgba(12, 42, 73, 0.1);
backdrop-filter: blur(10px);
border-radius: 8px;
margin-bottom: 10px;
border: 1px solid rgba(64, 156, 255, 0.3);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}
.header h1 {
color: #4fc3f7;
font-size: 24px;
text-shadow: 0 0 10px rgba(79, 195, 247, 0.5);
}
.status-bar {
display: flex;
gap: 20px;
}
.status-item {
display: flex;
align-items: center;
gap: 5px;
}
.status-indicator {
width: 10px;
height: 10px;
border-radius: 50%;
}
.online {
background-color: #4caf50;
box-shadow: 0 0 8px #4caf50;
}
.warning {
background-color: #ff9800;
box-shadow: 0 0 8px #ff9800;
}
.error {
background-color: #f44336;
box-shadow: 0 0 8px #f44336;
}
.main-content {
/* display: flex;
flex: 1;
gap: 10px; */
display: flex;
flex: 1;
gap: 10px;
overflow: hidden;
}
.left-panel,
.right-panel {
width: 300px;
display: flex;
flex-direction: column;
gap: 10px;
}
.center-panel {
flex: 1;
display: flex;
flex-direction: column;
gap: 10px;
}
.map-container {
flex: 1;
border-radius: 8px;
overflow: hidden;
border: 1px solid rgba(64, 156, 255, 0.3);
position: relative;
background: linear-gradient(135deg, #0a3d62, #1a5276);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
min-height: 300px;
/* 设置最小高度 */
}
#map {
height: 100%;
width: 100%;
background: transparent;
z-index: 1;
}
.map-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(10, 61, 98, 0.6);
z-index: 0;
}
.panel {
background: rgba(12, 42, 73, 0.1);
backdrop-filter: blur(10px);
border-radius: 8px;
padding: 20px;
border: 1px solid rgba(64, 156, 255, 0.3);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}
/* 卡片头部样式 */
.card-header {
height: 40px;
background: url('/assets/img/common/homeTitle2.png') no-repeat;
background-position: center;
background-size: 108% 120%;
display: flex;
justify-content: center;
align-items: center;
border-radius: 8px 8px 0 0 !important;
border-bottom: 1px solid var(--light-blue);
padding: 32px 20px;
position: relative;
/* margin: -20px -20px 20px -20px; */
margin: -20px -20px 0px -20px;
}
.card-header span {
font-size: 1.2rem;
letter-spacing: 1px;
font-family: 'YouSheBiaoTiHei', 'Microsoft YaHei';
font-weight: 400;
color: #ffffff;
}
.panel-title {
color: #4fc3f7;
margin-bottom: 15px;
font-size: 18px;
border-bottom: 1px solid rgba(79, 195, 247, 0.3);
padding-bottom: 8px;
display: flex;
justify-content: space-between;
align-items: center;
}
.panel-title button {
background: rgba(25, 55, 95, 0.6);
color: #e3f2fd;
border: 1px solid rgba(79, 195, 247, 0.5);
border-radius: 4px;
padding: 4px 8px;
font-size: 12px;
cursor: pointer;
transition: all 0.3s;
}
.panel-title button:hover {
background: rgba(40, 80, 130, 0.7);
border-color: #4fc3f7;
}
.data-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 10px;
}
.data-item {
display: flex;
flex-direction: column;
padding: 8px;
background: rgba(25, 55, 95, 0.6);
border-radius: 4px;
transition: all 0.3s;
}
.data-item:hover {
background: rgba(40, 80, 130, 0.7);
transform: translateY(-2px);
}
.data-label {
font-size: 12px;
color: #a0d2ff;
}
.data-value {
font-size: 18px;
font-weight: bold;
color: #4fc3f7;
/* 主色调蓝色 */
text-shadow: 0 0 8px rgba(79, 195, 247, 0.7);
}
/* 为不同类型的数值添加不同颜色 */
.data-item:nth-child(1) .data-value,
/* 风速 */
.data-item:nth-child(3) .data-value,
/* 气温 */
.data-item:nth-child(6) .data-value {
/* 能见度 */
color: #4fc3f7;
/* 蓝色 */
text-shadow: 0 0 8px rgba(79, 195, 247, 0.7);
}
.data-item:nth-child(2) .data-value,
/* 风向 */
.data-item:nth-child(4) .data-value {
/* 气压 */
color: #64ffda;
/* 青色 */
text-shadow: 0 0 8px rgba(100, 255, 218, 0.7);
}
.data-item:nth-child(5) .data-value {
/* 湿度 */
color: #ff9800;
/* 橙色 */
text-shadow: 0 0 8px rgba(255, 152, 0, 0.7);
}
/* 水文要素颜色 */
.panel:nth-child(2) .data-item:nth-child(1) .data-value {
/* 水温 */
color: #29b6f6;
/* 浅蓝色 */
text-shadow: 0 0 8px rgba(41, 182, 246, 0.7);
}
.panel:nth-child(2) .data-item:nth-child(2) .data-value {
/* 盐度 */
color: #ab47bc;
/* 紫色 */
text-shadow: 0 0 8px rgba(171, 71, 188, 0.7);
}
.panel:nth-child(2) .data-item:nth-child(3) .data-value {
/* 水深 */
color: #5c6bc0;
/* 靛蓝色 */
text-shadow: 0 0 8px rgba(92, 107, 192, 0.7);
}
.panel:nth-child(2) .data-item:nth-child(4) .data-value {
/* 流速 */
color: #26c6da;
/* 青色 */
text-shadow: 0 0 8px rgba(38, 198, 218, 0.7);
}
.panel:nth-child(2) .data-item:nth-child(5) .data-value {
/* 流向 */
color: #66bb6a;
/* 绿色 */
text-shadow: 0 0 8px rgba(102, 187, 106, 0.7);
}
.panel:nth-child(2) .data-item:nth-child(6) .data-value {
/* 浊度 */
color: #ffee58;
/* 黄色 */
text-shadow: 0 0 8px rgba(255, 238, 88, 0.7);
}
/* 船舶状态颜色 */
.right-panel .data-item:nth-child(1) .data-value {
/* 航速 */
color: #ef5350;
/* 红色 */
text-shadow: 0 0 8px rgba(239, 83, 80, 0.7);
}
.right-panel .data-item:nth-child(2) .data-value {
/* 航向 */
color: #ec407a;
/* 粉色 */
text-shadow: 0 0 8px rgba(236, 64, 122, 0.7);
}
.right-panel .data-item:nth-child(3) .data-value {
/* 主机转速 */
color: #ab47bc;
/* 紫色 */
text-shadow: 0 0 8px rgba(171, 71, 188, 0.7);
}
.right-panel .data-item:nth-child(4) .data-value {
/* 燃油存量 */
color: #66bb6a;
/* 绿色 */
text-shadow: 0 0 8px rgba(102, 187, 106, 0.7);
}
/* 叶绿素浓度 */
.data-value:has(+ .data-unit) {
color: #64dd17;
/* 亮绿色 */
text-shadow: 0 0 8px rgba(100, 221, 23, 0.7);
}
/* 仪表数值颜色 */
.gauge-value {
font-weight: bold;
color: #4fc3f7;
text-shadow: 0 0 8px rgba(79, 195, 247, 0.7);
}
/* 态势图数值颜色 */
.wind-detail-value,
.wind-speed-detail-value,
.wave-detail-value,
.wave-direction-detail-value {
color: #4fc3f7;
text-shadow: 0 0 8px rgba(79, 195, 247, 0.7);
font-weight: bold;
font-size: 12px;
}
/* 模态框数据项颜色 */
.modal-data-value {
color: #4fc3f7;
text-shadow: 0 0 8px rgba(79, 195, 247, 0.7);
font-weight: bold;
}
/* 系统数据面板颜色 */
.system-data-value {
color: #4fc3f7;
text-shadow: 0 0 8px rgba(79, 195, 247, 0.7);
font-weight: bold;
}
.data-unit {
font-size: 12px;
color: #a0d2ff;
margin-left: 2px;
}
.gauge-container {
display: flex;
justify-content: space-around;
margin: 10px 0;
}
.gauge {
width: 80px;
height: 80px;
position: relative;
}
.gauge-bg {
width: 100%;
height: 100%;
border-radius: 50%;
background: #0d1b2a;
position: relative;
overflow: hidden;
border: 2px solid rgba(79, 195, 247, 0.5);
}
.gauge-fill {
position: absolute;
bottom: 0;
width: 100%;
background: linear-gradient(to top, #4fc3f7, #0277bd);
border-radius: 0 0 100px 100px;
transform-origin: bottom;
transition: height 0.5s ease;
}
.gauge-value {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-weight: bold;
color: #e3f2fd;
}
.table-container {
max-height: 300px;
overflow-y: auto;
}
table {
width: 100%;
border-collapse: collapse;
}
th,
td {
padding: 8px 12px;
text-align: left;
border-bottom: 1px solid rgba(64, 156, 255, 0.3);
}
th {
color: #4fc3f7;
font-weight: normal;
}
.footer {
display: flex;
justify-content: space-between;
padding: 10px 20px;
background: rgba(12, 42, 73, 0.1);
backdrop-filter: blur(10px);
border-radius: 8px;
margin-top: 10px;
border: 1px solid rgba(64, 156, 255, 0.3);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
flex-shrink: 0;
/* 防止被压缩 */
}
/* 时间轴样式修改 */
.timeline {
flex: 1;
height: 60px;
background: rgba(12, 42, 73, 0.3);
border-radius: 30px;
position: relative;
margin-right: 20px;
border: 1px solid rgba(64, 156, 255, 0.3);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
overflow: visible;
/* 修改为visible以显示完整的标签 */
}
/* 已经过的时间轴部分 - 渐变色 */
.timeline-progress {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 75%;
/* 默认位置会通过JS动态更新 */
background: linear-gradient(90deg, #0277bd, #4fc3f7);
border-radius: 30px 0 0 30px;
z-index: 1;
}
/* 时间轴轨道 */
.timeline-track {
position: absolute;
top: 50%;
left: 0;
width: 100%;
height: 6px;
background: rgba(25, 55, 95, 0.8);
border-radius: 3px;
transform: translateY(-50%);
z-index: 2;
}
/* 时间轴拖动按钮 */
.timeline-handle {
position: absolute;
top: 50%;
left: 75%;
width: 30px;
height: 30px;
transform: translate(-50%, -50%);
cursor: pointer;
z-index: 4;
transition: all 0.2s ease;
user-select: none;
background: url('img/进度指示.png') no-repeat center center;
background-size: contain;
}
.timeline-handle:hover {
transform: translate(-50%, -50%) scale(1.1);
}
.timeline-handle:active {
transform: translate(-50%, -50%) scale(1.2);
}
/* 时间标记 */
.time-marker {
position: absolute;
top: 0;
width: 2px;
height: 100%;
background: rgba(79, 195, 247, 0.6);
z-index: 3;
}
.time-marker::before {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 10px;
height: 10px;
background: #4fc3f7;
border-radius: 50%;
box-shadow: 0 0 8px rgba(79, 195, 247, 0.8);
}
.time-label {
position: absolute;
top: -25px;
/* 修改位置以确保完全显示 */
transform: translateX(-50%);
font-size: 12px;
color: #a0d2ff;
font-weight: bold;
text-shadow: 0 0 5px rgba(0, 0, 0, 0.7);
white-space: nowrap;
/* 防止文本换行 */
}
/* 船舶图标 */
/* .ship-icon {
width: 30px;
height: 15px;
background: #4fc3f7;
border-radius: 30% 30% 10% 10%;
position: absolute;
top: 50%;
left: 75%;
transform: translate(-50%, -50%);
transform-origin: center;
box-shadow: 0 0 15px rgba(79, 195, 247, 0.9);
z-index: 5;
transition: left 0.3s ease;
user-select: none;
}
.ship-icon::after {
content: '';
position: absolute;
top: -8px;
left: 50%;
transform: translateX(-50%);
width: 0;
height: 0;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-bottom: 8px solid #4fc3f7;
} */
/* 当前时间指示器 */
.current-time-indicator {
position: absolute;
top: 0;
left: 70%;
width: 2px;
height: 100%;
background: #ff9800;
box-shadow: 0 0 8px rgba(255, 152, 0, 0.8);
z-index: 3;
}
.current-time-indicator::after {
content: '现在';
position: absolute;
top: -25px;
left: 50%;
transform: translateX(-50%);
font-size: 12px;
color: #ff9800;
font-weight: bold;
text-shadow: 0 0 5px rgba(0, 0, 0, 0.7);
}
.controls {
display: flex;
gap: 10px;
}
button {
padding: 8px 15px;
background: rgba(25, 55, 95, 0.6);
color: #e3f2fd;
border: 1px solid rgba(79, 195, 247, 0.5);
border-radius: 4px;
cursor: pointer;
transition: background 0.3s;
}
button:hover {
background: rgba(40, 80, 130, 0.7);
border-color: #4fc3f7;
}
.alert {
color: #ff9800;
}
.critical {
color: #f44336;
}
.chart-container {
height: 200px;
margin-top: 10px;
display: none;
}
.chart-visible {
display: block;
}
/* 播放控制面板 */
.playback-controls {
position: absolute;
bottom: 20px;
right: 20px;
background: rgba(12, 42, 73, 0.9);
padding: 10px;
border-radius: 8px;
display: none;
z-index: 1000;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}
.playback-controls.active {
display: flex;
}
.playback-btn {
width: 30px;
height: 30px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
background: rgba(25, 55, 95, 0.6);
border: 1px solid rgba(79, 195, 247, 0.5);
cursor: pointer;
}
.playback-slider {
flex: 1;
height: 6px;
background: #0d1b2a;
border-radius: 3px;
position: relative;
margin: 0 10px;
}
.playback-progress {
position: absolute;
height: 100%;
background: #4fc3f7;
border-radius: 3px;
width: 30%;
}
.modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.7);
z-index: 1000;
align-items: center;
justify-content: center;
}
.modal-content1 {
background: rgba(12, 42, 73, 0.95);
border-radius: 8px;
padding: 20px;
width: 90%;
max-width: 1200px;
border: 1px solid rgba(64, 156, 255, 0.3);
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
max-height: 90vh;
overflow-y: auto;
}
.modal-content {
background: rgba(12, 42, 73, 0.95);
border-radius: 8px;
padding: 20px;
width: 40%;
max-width: 1200px;
border: 1px solid rgba(64, 156, 255, 0.3);
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
max-height: 90vh;
overflow-y: auto;
}
.modal-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
border-bottom: 1px solid rgba(79, 195, 247, 0.3);
padding-bottom: 10px;
}
.modal-title {
color: #4fc3f7;
font-size: 20px;
}
.close-btn {
background: none;
border: none;
color: #e3f2fd;
font-size: 24px;
cursor: pointer;
}
.modal-chart-container {
height: 500px;
margin-bottom: 20px;
}
.data-export-options {
display: flex;
gap: 10px;
margin-top: 15px;
}
.data-export-options select {
background: rgba(25, 55, 95, 0.6);
color: #e3f2fd;
border: 1px solid rgba(79, 195, 247, 0.5);
border-radius: 4px;
padding: 8px;
flex: 1;
}
.coordinates-info {
position: absolute;
top: 20px;
right: 20px;
background: rgba(12, 42, 73, 0.9);
padding: 10px 15px;
border-radius: 8px;
border: 1px solid rgba(64, 156, 255, 0.3);
font-size: 14px;
display: none;
z-index: 1000;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
display: none;
}
.coordinates-info.active {
display: block;
}
.coordinates-title {
color: #4fc3f7;
margin-bottom: 5px;
font-weight: bold;
}
.coordinates-value {
color: #e3f2fd;
}
.system-buttons {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-top: 10px;
}
.system-btn {
padding: 8px 12px;
background: rgba(25, 55, 95, 0.6);
border: 1px solid rgba(79, 195, 247, 0.5);
border-radius: 4px;
color: #e3f2fd;
cursor: pointer;
transition: all 0.3s;
flex: 1;
min-width: 120px;
text-align: center;
}
.system-btn:hover {
background: rgba(40, 80, 130, 0.7);
border-color: #4fc3f7;
transform: translateY(-2px);
}
.system-data-panel {
margin-top: 15px;
padding: 10px;
background: rgba(25, 55, 95, 0.3);
border-radius: 4px;
display: none;
}
.system-data-panel.active {
display: block;
}
.system-data-item {
display: flex;
justify-content: space-between;
margin-bottom: 8px;
padding-bottom: 8px;
border-bottom: 1px solid rgba(25, 55, 95, 0.5);
}
.system-data-label {
color: #a0d2ff;
}
.system-data-value {
color: #e3f2fd;
font-weight: bold;
}
.map-controls {
position: absolute;
bottom: 20px;
left: 20px;
display: flex;
flex-direction: column;
gap: 10px;
z-index: 1000;
}
.map-btn {
padding: 8px 12px;
background: rgba(12, 42, 73, 0.8);
border: 1px solid rgba(64, 156, 255, 0.3);
border-radius: 4px;
color: #e3f2fd;
cursor: pointer;
transition: all 0.3s;
}
.map-btn:hover {
background: rgba(12, 42, 73, 1);
border-color: #4fc3f7;
}
.situation-chart-container {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: 1fr;
gap: 10px;
height: 300px;
/* 固定高度,避免占用过多空间 */
}
.situation-chart {
background: rgba(12, 42, 73, 0.1);
backdrop-filter: blur(1px);
border-radius: 8px;
padding: 10px;
border: 1px solid rgba(64, 156, 255, 0.3);
display: flex;
flex-direction: column;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}
.situation-title {
color: #4fc3f7;
margin-bottom: 10px;
font-size: 16px;
border-bottom: 1px solid rgba(79, 195, 247, 0.3);
padding-bottom: 5px;
text-align: center;
text-shadow: 0 0 10px rgba(79, 195, 247, 0.5);
}
.situation-chart canvas {
flex: 1;
width: 100% !important;
height: auto !important;
}
/* 风向态势图优化 */
.wind-direction-container {
display: flex;
flex-direction: column;
align-items: center;
height: 100%;
}
.wind-direction-indicator {
width: 180px;
height: 180px;
/* 减小高度以适应容器 */
position: relative;
border-radius: 50%;
background: linear-gradient(135deg, #0a3d62, #1a5276);
border: 3px solid rgba(79, 195, 247, 0.5);
box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
/* width: 280px;
height: 280px;
margin: 10px auto;
position: relative;
border-radius: 50%;
background: linear-gradient(135deg, #0a3d62, #1a5276);
border: 3px solid rgba(79, 195, 247, 0.5);
box-shadow: 0 0 20px rgba(0, 0, 0, 0.5); */
}
.wind-direction-compass {
position: absolute;
width: 100%;
height: 100%;
border-radius: 50%;
background: rgba(10, 25, 41, 0.3);
}
.wind-direction-arrow {
position: absolute;
top: 50%;
left: 50%;
width: 4px;
height: 70px;
background: linear-gradient(to top, #4fc3f7, #0277bd);
transform-origin: 50% 100%;
transform: translate(-50%, -100%) rotate(0deg);
border-radius: 2px;
z-index: 10;
box-shadow: 0 0 10px rgba(79, 195, 247, 0.7);
transition: transform 1s ease;
}
.wind-direction-arrow::after {
content: '';
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
width: 0;
height: 0;
border-left: 8px solid transparent;
border-right: 8px solid transparent;
border-bottom: 12px solid #4fc3f7;
}
.wind-direction-labels {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
.wind-direction-label {
position: absolute;
font-size: 10px;
/* 减小字体 */
color: #e3f2fd;
font-weight: bold;
}
/* 方向标签颜色 */
/* .wind-direction-label,
.wave-direction-label {
color: #e3f2fd;
font-weight: bold;
text-shadow: 0 0 5px rgba(255, 255, 255, 0.5);
} */
.north {
top: 2px;
left: 50%;
transform: translateX(-50%);
}
.east {
top: 50%;
right: 2px;
transform: translateY(-50%);
}
.south {
bottom: 2px;
left: 50%;
transform: translateX(-50%);
}
.west {
top: 50%;
left: 2px;
transform: translateY(-50%);
}
.wind-direction-details {
display: flex;
justify-content: space-around;
width: 100%;
margin-top: 5px;
gap: 5px;
/* display: flex;
justify-content: space-around;
width: 100%;
margin-top: 10px; */
}
/* .wind-detail-item {
display: flex;
flex-direction: column;
align-items: center;
padding: 8px;
background: rgba(25, 55, 95, 0.6);
border-radius: 8px;
min-width: 70px;
} */
/* .wind-detail-label {
color: #a0d2ff;
font-size: 12px;
} */
.wind-detail-value {
color: #4fc3f7;
text-shadow: 0 0 8px rgba(79, 195, 247, 0.7);
font-weight: bold;
/* font-size: 16px; */
}
/* 风速态势图 */
.wind-speed-container {
display: flex;
flex-direction: column;
align-items: center;
height: 100%;
}
.wind-speed-gauge {
width: 180px;
height: 180px;
/* 减小高度以适应容器 */
/* margin: 5px auto; */
position: relative;
background: linear-gradient(135deg, #0a3d62, #1a5276);
border-radius: 10px;
border: 3px solid rgba(79, 195, 247, 0.5);
overflow: hidden;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
/* width: 260px;
height: 280px;
margin: 10px auto;
position: relative;
background: linear-gradient(135deg, #0a3d62, #1a5276);
border-radius: 10px;
border: 3px solid rgba(79, 195, 247, 0.5);
overflow: hidden;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.5); */
}
.wind-speed-fill {
position: absolute;
bottom: 0;
width: 100%;
background: linear-gradient(to top, #4fc3f7, #0277bd);
border-radius: 8px 8px 0 0;
transition: height 1s ease;
}
.wind-speed-value {
color: #64ffda;
/* 青色 */
text-shadow: 0 0 10px rgba(100, 255, 218, 0.8);
font-weight: bold;
font-size: 18px;
}
.wind-speed-value {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 22px;
font-weight: bold;
/* color: #e3f2fd;
text-shadow: 0 0 10px rgba(0, 0, 0, 0.7); */
z-index: 10;
}
.wind-speed-label {
color: #a0d2ff;
font-size: 10px;
font-weight: bold;
}
.wind-speed-label {
position: absolute;
bottom: 5px;
left: 0;
width: 100%;
text-align: center;
font-size: 10px;
color: #a0d2ff;
font-weight: bold;
}
.wind-speed-details {
display: flex;
justify-content: space-around;
width: 100%;
margin-top: 5px;
gap: 5px;
/* display: flex;
justify-content: space-around;
width: 100%;
margin-top: 10px; */
}
/* .wind-speed-detail-item {
display: flex;
flex-direction: column;
align-items: center;
padding: 8px;
background: rgba(25, 55, 95, 0.6);
border-radius: 8px;
min-width: 70px;
} */
/* .wind-speed-detail-label {
color: #a0d2ff;
font-size: 12px;
} */
.wind-speed-detail-value {
color: #64ffda;
/* 青色 */
text-shadow: 0 0 8px rgba(100, 255, 218, 0.7);
font-weight: bold;
/* font-size: 16px; */
}
/* 波高态势图优化 */
.wave-height-container {
display: flex;
flex-direction: column;
align-items: center;
height: 100%;
}
.wave-height-gauge {
width: 180px;
height: 180px;
/* 减小高度以适应容器 */
position: relative;
background: linear-gradient(135deg, #0a3d62, #1a5276);
border-radius: 10px;
border: 3px solid rgba(79, 195, 247, 0.5);
overflow: hidden;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
/* margin: 5px auto; */
/* width: 260px;
height: 280px;
margin: 10px auto;
position: relative;
background: linear-gradient(135deg, #0a3d62, #1a5276);
border-radius: 10px;
border: 3px solid rgba(79, 195, 247, 0.5);
overflow: hidden;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.5); */
}
.wave-height-fill {
position: absolute;
bottom: 0;
width: 100%;
background: linear-gradient(to top, #4fc3f7, #0277bd);
border-radius: 8px 8px 0 0;
transition: height 1s ease;
}
.wave-height-value {
color: #29b6f6;
/* 浅蓝色 */
text-shadow: 0 0 10px rgba(41, 182, 246, 0.8);
font-weight: bold;
font-size: 18px;
}
.wave-height-value {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
/* font-size: 22px; */
/* font-weight: bold; */
/* color: #e3f2fd;
text-shadow: 0 0 10px rgba(0, 0, 0, 0.7); */
z-index: 10;
}
.wave-height-label {
position: absolute;
bottom: 5px;
left: 0;
width: 100%;
text-align: center;
font-size: 10px;
color: #a0d2ff;
font-weight: bold;
}
.wave-height-details {
display: flex;
justify-content: space-around;
width: 100%;
margin-top: 5px;
gap: 5px;
/* display: flex;
justify-content: space-around;
width: 100%;
margin-top: 10px; */
}
/* .wave-detail-item {
display: flex;
flex-direction: column;
align-items: center;
padding: 8px;
background: rgba(25, 55, 95, 0.6);
border-radius: 8px;
min-width: 70px;
} */
/* .wave-detail-label {
font-size: 12px;
color: #a0d2ff;
} */
.wave-detail-value {
color: #29b6f6;
/* 浅蓝色 */
text-shadow: 0 0 8px rgba(41, 182, 246, 0.7);
font-weight: bold;
/* font-size: 16px; */
}
/* 波向态势图 */
.wave-direction-container {
display: flex;
flex-direction: column;
align-items: center;
height: 100%;
}
.wave-direction-indicator {
width: 180px;
height: 180px;
/* 减小高度以适应容器 */
position: relative;
border-radius: 50%;
background: linear-gradient(135deg, #0a3d62, #1a5276);
border: 3px solid rgba(79, 195, 247, 0.5);
box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
/* margin: 5px auto; */
/* width: 280px;
height: 280px;
margin: 10px auto;
position: relative;
border-radius: 50%;
background: linear-gradient(135deg, #0a3d62, #1a5276);
border: 3px solid rgba(79, 195, 247, 0.5);
box-shadow: 0 0 20px rgba(0, 0, 0, 0.5); */
}
.wave-direction-compass {
position: absolute;
width: 100%;
height: 100%;
border-radius: 50%;
background: rgba(10, 25, 41, 0.3);
}
.wave-direction-arrow {
position: absolute;
top: 50%;
left: 50%;
width: 4px;
height: 70px;
background: linear-gradient(to top, #4fc3f7, #0277bd);
transform-origin: 50% 100%;
transform: translate(-50%, -100%) rotate(0deg);
border-radius: 2px;
z-index: 10;
box-shadow: 0 0 10px rgba(79, 195, 247, 0.7);
transition: transform 1s ease;
}
.wave-direction-arrow::after {
content: '';
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
width: 0;
height: 0;
border-left: 8px solid transparent;
border-right: 8px solid transparent;
border-bottom: 12px solid #4fc3f7;
}
.wave-direction-labels {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
.wave-direction-label {
position: absolute;
font-size: 12px;
color: #e3f2fd;
font-weight: bold;
}
.wave-direction-details {
display: flex;
justify-content: space-around;
width: 100%;
margin-top: 5px;
gap: 5px;
/* display: flex;
justify-content: space-around;
width: 100%;
margin-top: 10px; */
}
/* .wave-direction-detail-item {
display: flex;
flex-direction: column;
align-items: center;
padding: 8px;
background: rgba(25, 55, 95, 0.6);
border-radius: 8px;
min-width: 70px;
} */
/* .wave-direction-detail-label {
color: #a0d2ff;
font-size: 12px;
} */
.wave-direction-detail-value {
color: #5c6bc0;
/* 靛蓝色 */
text-shadow: 0 0 8px rgba(92, 107, 192, 0.7);
font-weight: bold;
/* font-size: 16px; */
}
.wind-detail-item,
.wind-speed-detail-item,
.wave-detail-item,
.wave-direction-detail-item {
display: flex;
flex-direction: column;
align-items: center;
padding: 4px;
background: rgba(25, 55, 95, 0.6);
border-radius: 4px;
min-width: 50px;
}
.wind-detail-label,
.wind-speed-detail-label,
.wave-detail-label,
.wave-direction-detail-label {
font-size: 10px;
color: #a0d2ff;
margin-bottom: 2px;
}
/* 预警颜色 */
.normal {
background: linear-gradient(to top, #4fc3f7, #0277bd) !important;
}
.warning {
background: linear-gradient(to top, #ff9800, #f57c00) !important;
}
.danger {
background: linear-gradient(to top, #f44336, #d32f2f) !important;
}
/* 海洋波纹效果 */
.wave-pattern {
position: absolute;
bottom: 0;
width: 100%;
height: 15px;
background: linear-gradient(90deg, transparent, rgba(79, 195, 247, 0.3), transparent);
animation: wave-animation 3s infinite linear;
}
@keyframes wave-animation {
0% {
transform: translateX(-100%);
}
100% {
transform: translateX(100%);
}
}
/* 图表模态框样式 */
.chart-modal-container {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
margin-bottom: 20px;
}
.chart-modal-item {
background: rgba(12, 42, 73, 0.1);
backdrop-filter: blur(10px);
border-radius: 8px;
padding: 15px;
border: 1px solid rgba(64, 156, 255, 0.3);
}
.chart-modal-title {
color: #4fc3f7;
margin-bottom: 15px;
font-size: 18px;
border-bottom: 1px solid rgba(79, 195, 247, 0.3);
padding-bottom: 8px;
text-align: center;
}
.chart-modal-canvas {
height: 300px;
width: 100%;
}
.modal-data-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
margin-top: 20px;
}
.modal-data-item {
display: flex;
flex-direction: column;
padding: 10px;
background: rgba(25, 55, 95, 0.6);
border-radius: 4px;
text-align: center;
}
.modal-data-label {
font-size: 12px;
color: #a0d2ff;
margin-bottom: 5px;
}
.modal-data-value {
font-size: 18px;
font-weight: bold;
color: #e3f2fd;
}
.modal-data-unit {
font-size: 12px;
color: #a0d2ff;
}
/* 滚动条样式 */
::-webkit-scrollbar {
width: 4px;
height: 4px;
}
::-webkit-scrollbar-track {
background: rgba(12, 42, 73, 0.3);
border-radius: 4px;
}
::-webkit-scrollbar-thumb {
background: rgba(106, 149, 201, 0.5);
border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
background: rgba(106, 149, 201, 0.7);
}
</style>
</head>
<body>
<!-- 顶部标题栏 -->
<div class="topDiv">
<div class="left">
<span id="current-date">2023年11月5日</span>
<span id="current-time">14:30:25</span>
</div>
<div class="center">海洋调查科考任务系统</div>
<div class="right">
<img src="/common/images/logo_gt.png" alt="" />
</div>
</div>
<div class="container">
<div class="header">
<h1>海洋调查科考任务系统 - 探索者号</h1>
<div class="status-bar">
<div class="status-item">
<div class="status-indicator online"></div>
<span>GPS: 在线</span>
</div>
<div class="status-item">
<div class="status-indicator online"></div>
<span>气象站: 在线</span>
</div>
<div class="status-item">
<div class="status-indicator warning"></div>
<span>声纳: 警告</span>
</div>
<div class="status-item">
<span>位置: 18.5°N, 115.5°E</span>
</div>
<div class="status-item">
<span>时间: 2025-10-18 20:47:02</span>
</div>
<div class="controls">
<button id="dataDownloadBtn">数据下载</button>
<button id="dataPlaybackBtn">数据回放</button>
<button id="weatherChartBtn">气象要素图表</button>
<button id="hydroChartBtn">水文要素图表</button>
</div>
</div>
</div>
<div class="main-content">
<div class="left-panel">
<div class="panel">
<div class="card-header">
<span>气象要素</span>
</div>
<div class="panel-title">
<span>气象要素</span>
<button id="showWeatherChart">显示图表</button>
</div>
<div class="data-grid">
<div class="data-item">
<span class="data-label">风速</span>
<div>
<span class="data-value">12.5</span>
<span class="data-unit">m/s</span>
</div>
</div>
<div class="data-item">
<span class="data-label">风向</span>
<div>
<span class="data-value">NE</span>
<span class="data-unit">45°</span>
</div>
</div>
<div class="data-item">
<span class="data-label">气温</span>
<div>
<span class="data-value">29.6</span>
<span class="data-unit">°C</span>
</div>
</div>
<div class="data-item">
<span class="data-label">气压</span>
<div>
<span class="data-value">1012.5</span>
<span class="data-unit">hPa</span>
</div>
</div>
<div class="data-item">
<span class="data-label">湿度</span>
<div>
<span class="data-value">78</span>
<span class="data-unit">%</span>
</div>
</div>
<div class="data-item">
<span class="data-label">能见度</span>
<div>
<span class="data-value">15.2</span>
<span class="data-unit">km</span>
</div>
</div>
</div>
<div class="chart-container" id="weatherChartContainer">
<canvas id="weatherChart"></canvas>
</div>
<div class="gauge-container">
<div class="gauge">
<div class="gauge-bg">
<div class="gauge-fill" style="height: 65%"></div>
</div>
<div class="gauge-value">65%</div>
<div style="text-align: center; margin-top: 5px; font-size: 12px; color: #a0d2ff;">云量</div>
</div>
<div class="gauge">
<div class="gauge-bg">
<div class="gauge-fill" style="height: 30%"></div>
</div>
<div class="gauge-value">30%</div>
<div style="text-align: center; margin-top: 5px; font-size: 12px; color: #a0d2ff;">降水概率
</div>
</div>
</div>
</div>
<div class="panel">
<div class="card-header">
<span>水文要素</span>
</div>
<div class="panel-title">
<span>水文要素</span>
<button id="showHydroChart">显示图表</button>
</div>
<div class="data-grid">
<div class="data-item">
<span class="data-label">水温</span>
<div>
<span class="data-value">23.9</span>
<span class="data-unit">°C</span>
</div>
</div>
<div class="data-item">
<span class="data-label">盐度</span>
<div>
<span class="data-value">34.2</span>
<span class="data-unit">PSU</span>
</div>
</div>
<div class="data-item">
<span class="data-label">水深</span>
<div>
<span class="data-value">1250</span>
<span class="data-unit">m</span>
</div>
</div>
<div class="data-item">
<span class="data-label">流速</span>
<div>
<span class="data-value">1.2</span>
<span class="data-unit">m/s</span>
</div>
</div>
<div class="data-item">
<span class="data-label">流向</span>
<div>
<span class="data-value">SE</span>
<span class="data-unit">135°</span>
</div>
</div>
<div class="data-item">
<span class="data-label">浊度</span>
<div>
<span class="data-value">0.08</span>
<span class="data-unit">NTU</span>
</div>
</div>
</div>
<div class="chart-container" id="hydroChartContainer">
<canvas id="hydroChart"></canvas>
</div>
<div style="margin-top: 15px;">
<div style="display: flex; justify-content: space-between; margin-bottom: 5px;">
<span class="data-label">叶绿素浓度</span>
<span class="data-value">2.8 µg/L</span>
</div>
<div style="height: 10px; background: #0d1b2a; border-radius: 5px; overflow: hidden;">
<div
style="height: 100%; width: 45%; background: linear-gradient(to right, #4caf50, #8bc34a);">
</div>
</div>
</div>
</div>
</div>
<div class="center-panel">
<div class="situation-chart-container">
<div class="situation-chart">
<div class="situation-title">风向态势图</div>
<div class="wind-direction-container">
<div class="wind-direction-indicator">
<div class="wind-direction-compass"></div>
<div class="wind-direction-arrow" id="windArrow"></div>
<div class="wind-direction-labels">
<div class="wind-direction-label north">N</div>
<div class="wind-direction-label east">E</div>
<div class="wind-direction-label south">S</div>
<div class="wind-direction-label west">W</div>
</div>
</div>
<div class="wind-direction-details">
<div class="wind-detail-item">
<div class="wind-detail-label">当前风向</div>
<div class="wind-detail-value" id="windDirectionValue">NE 45°</div>
</div>
<div class="wind-detail-item">
<div class="wind-detail-label">平均风速</div>
<div class="wind-detail-value">12.5 m/s</div>
</div>
</div>
</div>
</div>
<div class="situation-chart">
<div class="situation-title">风速态势图</div>
<div class="wind-speed-container">
<div class="wind-speed-gauge">
<div class="wind-speed-fill" id="windSpeedFill" style="height: 60%"></div>
<div class="wind-speed-value" id="windSpeedValue">12.5m/s</div>
<div class="wind-speed-label">风速 (m/s)</div>
</div>
<div class="wind-speed-details">
<div class="wind-speed-detail-item">
<div class="wind-speed-detail-label">平均风速</div>
<div class="wind-speed-detail-value">12.5 m/s</div>
</div>
<div class="wind-speed-detail-item">
<div class="wind-speed-detail-label">阵风风速</div>
<div class="wind-speed-detail-value">15.2 m/s</div>
</div>
</div>
</div>
</div>
<div class="situation-chart">
<div class="situation-title">波高态势图</div>
<div class="wave-height-container">
<div class="wave-height-gauge">
<div class="wave-height-fill" id="waveHeightFill" style="height: 60%"></div>
<div class="wave-height-value" id="waveHeightValue">2.5m</div>
<div class="wave-height-label">波高 (m)</div>
<div class="wave-pattern"></div>
</div>
<div class="wave-height-details">
<div class="wave-detail-item">
<div class="wave-detail-label">平均波高</div>
<div class="wave-detail-value">2.5 m</div>
</div>
<div class="wave-detail-item">
<div class="wave-detail-label">最大波高</div>
<div class="wave-detail-value">3.8 m</div>
</div>
</div>
</div>
</div>
<div class="situation-chart">
<div class="situation-title">波向态势图</div>
<div class="wave-direction-container">
<div class="wave-direction-indicator">
<div class="wave-direction-compass"></div>
<div class="wave-direction-arrow" id="waveDirectionArrow"></div>
<div class="wave-direction-labels">
<div class="wave-direction-label north">N</div>
<div class="wave-direction-label east">E</div>
<div class="wave-direction-label south">S</div>
<div class="wave-direction-label west">W</div>
</div>
</div>
<div class="wave-direction-details">
<div class="wave-direction-detail-item">
<div class="wave-direction-detail-label">当前波向</div>
<div class="wave-direction-detail-value" id="waveDirectionValue">SE 135°</div>
</div>
<div class="wave-direction-detail-item">
<div class="wave-direction-detail-label">波周期</div>
<div class="wave-direction-detail-value">8.2 s</div>
</div>
</div>
</div>
</div>
</div>
<div class="map-container">
<div class="map-overlay"></div>
<div id="map"></div>
<div class="coordinates-info" id="coordinatesInfo">
<div class="coordinates-title">船舶位置信息</div>
<div class="coordinates-value">纬度: <span id="latValue">18.5°N</span></div>
<div class="coordinates-value">经度: <span id="lngValue">115.5°E</span></div>
</div>
<div class="map-controls">
<button class="map-btn" id="toggleSatellite">切换卫星图</button>
<button class="map-btn" id="toggleTerrain">切换地形图</button>
<button class="map-btn" id="resetView">重置视图</button>
</div>
<div class="playback-controls"
style="position: absolute; bottom: 20px; right: 20px; background: rgba(12, 42, 73, 0.9); padding: 10px; border-radius: 8px; display: none;"
id="playbackPanel">
<div class="playback-btn" id="playPauseBtn"></div>
<div class="playback-slider">
<div class="playback-progress"></div>
</div>
<span id="playbackTime">10:30:00</span>
<button id="closePlayback">关闭</button>
</div>
</div>
</div>
<div class="right-panel">
<div class="panel">
<div class="card-header">
<span>船舶状态</span>
</div>
<div class="panel-title">船舶状态</div>
<div class="data-grid">
<div class="data-item">
<span class="data-label">航速</span>
<div>
<span class="data-value">8.0</span>
<span class="data-unit"></span>
</div>
</div>
<div class="data-item">
<span class="data-label">航向</span>
<div>
<span class="data-value">245</span>
<span class="data-unit">°</span>
</div>
</div>
<div class="data-item">
<span class="data-label">主机转速</span>
<div>
<span class="data-value">1250</span>
<span class="data-unit">RPM</span>
</div>
</div>
<div class="data-item">
<span class="data-label">燃油存量</span>
<div>
<span class="data-value">78</span>
<span class="data-unit">%</span>
</div>
</div>
</div>
<div style="margin-top: 15px;">
<div class="data-label">系统状态</div>
<div class="system-buttons">
<button class="system-btn" data-system="navigation">导航系统</button>
<button class="system-btn" data-system="communication">通信系统</button>
<button class="system-btn" data-system="sonar">声纳系统</button>
<button class="system-btn" data-system="sampling">采样系统</button>
</div>
</div>
</div>
<div class="panel">
<div class="card-header">
<span>数据记录</span>
</div>
<div class="panel-title">数据记录</div>
<div class="table-container">
<table>
<thead>
<tr>
<th>时间</th>
<th>参数</th>
<th>数值</th>
</tr>
</thead>
<tbody>
<tr>
<td>14:25:10</td>
<td>CTD采样</td>
<td>完成</td>
</tr>
<tr>
<td>14:20:35</td>
<td>浮游生物网</td>
<td>部署</td>
</tr>
<tr>
<td>14:15:42</td>
<td>水温异常</td>
<td class="alert">+1.2°C</td>
</tr>
<tr>
<td>14:10:18</td>
<td>ADCP数据</td>
<td>接收</td>
</tr>
<tr>
<td>14:05:55</td>
<td>气象数据</td>
<td>更新</td>
</tr>
<tr>
<td>14:00:30</td>
<td>GPS定位</td>
<td>正常</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="footer">
<div class="timeline">
<!-- <div class="timeline-progress"></div>
<div class="timeline-track"></div>
<div class="time-marker" style="left: 10%;">
<div class="time-label">14:00</div>
</div>
<div class="time-marker" style="left: 30%;">
<div class="time-label">14:10</div>
</div>
<div class="time-marker" style="left: 50%;">
<div class="time-label">14:20</div>
</div>
<div class="current-time-indicator"></div>
<div class="time-marker" style="left: 90%;">
<div class="time-label">14:40</div>
</div>
<div class="timeline-handle"></div>
<div class="ship-icon"></div> -->
</div>
<div class="controls">
<button>数据导出</button>
<button>警报设置</button>
<button>系统设置</button>
</div>
</div>
</div>
<!-- 数据下载模态框 -->
<div class="modal" id="downloadModal">
<div class="modal-content">
<div class="modal-header">
<h2 class="modal-title">数据下载</h2>
<button class="close-btn">&times;</button>
</div>
<div class="data-export-options">
<select>
<option>气象数据</option>
<option>水文数据</option>
<option>航行数据</option>
<option>全部数据</option>
</select>
<select>
<option>CSV格式</option>
<option>JSON格式</option>
<option>Excel格式</option>
</select>
<select>
<option>最近1小时</option>
<option>最近6小时</option>
<option>最近24小时</option>
<option>自定义时间段</option>
</select>
<button>下载</button>
</div>
</div>
</div>
<!-- 系统详情模态框 -->
<div class="modal" id="systemModal">
<div class="modal-content">
<div class="modal-header">
<h2 class="modal-title" id="systemModalTitle">系统详情</h2>
<button class="close-btn">&times;</button>
</div>
<div id="systemModalContent">
<!-- 内容将通过JavaScript动态填充 -->
</div>
</div>
</div>
<!-- 气象要素图表模态框 -->
<div class="modal" id="weatherChartModal">
<div class="modal-content1">
<div class="modal-header">
<h2 class="modal-title">气象要素详细图表</h2>
<button class="close-btn">&times;</button>
</div>
<div class="chart-modal-container">
<div class="chart-modal-item">
<div class="chart-modal-title">风速变化趋势</div>
<div class="chart-modal-canvas">
<canvas id="weatherWindChart"></canvas>
</div>
</div>
<div class="chart-modal-item">
<div class="chart-modal-title">气温变化趋势</div>
<div class="chart-modal-canvas">
<canvas id="weatherTempChart"></canvas>
</div>
</div>
<div class="chart-modal-item">
<div class="chart-modal-title">气压变化趋势</div>
<div class="chart-modal-canvas">
<canvas id="weatherPressureChart"></canvas>
</div>
</div>
<div class="chart-modal-item">
<div class="chart-modal-title">湿度变化趋势</div>
<div class="chart-modal-canvas">
<canvas id="weatherHumidityChart"></canvas>
</div>
</div>
</div>
<div class="modal-data-grid">
<div class="modal-data-item">
<div class="modal-data-label">平均风速</div>
<div class="modal-data-value">12.5</div>
<div class="modal-data-unit">m/s</div>
</div>
<div class="modal-data-item">
<div class="modal-data-label">最高气温</div>
<div class="modal-data-value">24.2</div>
<div class="modal-data-unit">°C</div>
</div>
<div class="modal-data-item">
<div class="modal-data-label">最低气温</div>
<div class="modal-data-value">20.5</div>
<div class="modal-data-unit">°C</div>
</div>
<div class="modal-data-item">
<div class="modal-data-label">平均气压</div>
<div class="modal-data-value">1012.5</div>
<div class="modal-data-unit">hPa</div>
</div>
<div class="modal-data-item">
<div class="modal-data-label">平均湿度</div>
<div class="modal-data-value">78</div>
<div class="modal-data-unit">%</div>
</div>
<div class="modal-data-item">
<div class="modal-data-label">能见度</div>
<div class="modal-data-value">15.2</div>
<div class="modal-data-unit">km</div>
</div>
</div>
</div>
</div>
<!-- 水文要素图表模态框 -->
<div class="modal" id="hydroChartModal">
<div class="modal-content1">
<div class="modal-header">
<h2 class="modal-title">水文要素详细图表</h2>
<button class="close-btn">&times;</button>
</div>
<div class="chart-modal-container">
<div class="chart-modal-item">
<div class="chart-modal-title">水温变化趋势</div>
<div class="chart-modal-canvas">
<canvas id="hydroTempChart"></canvas>
</div>
</div>
<div class="chart-modal-item">
<div class="chart-modal-title">盐度变化趋势</div>
<div class="chart-modal-canvas">
<canvas id="hydroSalinityChart"></canvas>
</div>
</div>
<div class="chart-modal-item">
<div class="chart-modal-title">流速变化趋势</div>
<div class="chart-modal-canvas">
<canvas id="hydroFlowChart"></canvas>
</div>
</div>
<div class="chart-modal-item">
<div class="chart-modal-title">浊度变化趋势</div>
<div class="chart-modal-canvas">
<canvas id="hydroTurbidityChart"></canvas>
</div>
</div>
</div>
<div class="modal-data-grid">
<div class="modal-data-item">
<div class="modal-data-label">平均水温</div>
<div class="modal-data-value">18.5</div>
<div class="modal-data-unit">°C</div>
</div>
<div class="modal-data-item">
<div class="modal-data-label">平均盐度</div>
<div class="modal-data-value">34.2</div>
<div class="modal-data-unit">PSU</div>
</div>
<div class="modal-data-item">
<div class="modal-data-label">平均流速</div>
<div class="modal-data-value">1.2</div>
<div class="modal-data-unit">m/s</div>
</div>
<div class="modal-data-item">
<div class="modal-data-label">平均浊度</div>
<div class="modal-data-value">4.5</div>
<div class="modal-data-unit">NTU</div>
</div>
<div class="modal-data-item">
<div class="modal-data-label">叶绿素浓度</div>
<div class="modal-data-value">2.8</div>
<div class="modal-data-unit">µg/L</div>
</div>
<div class="modal-data-item">
<div class="modal-data-label">水深</div>
<div class="modal-data-value">1250</div>
<div class="modal-data-unit">m</div>
</div>
</div>
</div>
</div>
<script>
// 在全局作用域声明变量
var map;
var shipMarker;
var seaMapLayer;
var satelliteLayer;
var terrainLayer;
// 确保地图正确初始化
document.addEventListener('DOMContentLoaded', function () {
// 检查地图容器是否存在
var mapContainer = document.getElementById('map');
if (mapContainer) {
console.log('地图容器已找到');
// 初始化地图 - 设置为南海区域
try {
map = L.map('map', {
minZoom: 5,
maxZoom: 18,
attributionControl: false,
}).setView([18.0, 115.0], 5);
// 使用OpenSeaMap海图瓦片 - 海洋区域呈现蓝色
seaMapLayer = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
attribution: '&copy; <a href="https://www.esri.com/">Esri</a>'
}).addTo(map);
// 添加卫星图层
satelliteLayer = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
attribution: '&copy; <a href="https://www.esri.com/">Esri</a>'
}).addTo(map);
// 添加地形图层
// terrainLayer = L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', {
// attribution: '&copy; <a href="https://www.opentopomap.org/">OpenTopoMap</a> contributors'
// });
terrainLayer = L.tileLayer(
'http://t{s}.tianditu.com/DataServer?T=ter_w&x={x}&y={y}&l={z}&tk=489fa3b53cd351877dcf69e9ed899a04',
//'http://t{s}.tianditu.gov.cn/DataServer?T=ter_w&x={x}&y={y}&l={z}&tk=cd7516c53e2e5bee9bad989b63db6ce4',
{ attribution: '天地图地形', subdomains: [0, 1, 2, 3, 4, 5, 6, 7] },
)
// // 创建自定义船形图标
// var shipIcon = L.divIcon({
// html: '<div class="ship-icon"></div>',
// iconSize: [30, 15],
// className: 'ship-marker'
// });
// // 添加船舶位置标记 - 设置在南海区域
// shipMarker = L.marker([18.5, 115.5], { icon: shipIcon }).addTo(map);
// 创建自定义船形图标
var shipIcon = L.icon({
iconUrl: 'img/科考船.png',
// iconSize: [30, 15],
// iconAnchor: [15, 7.5],
// popupAnchor: [0, -10]
});
// 添加船舶位置标记 - 设置在南海区域
shipMarker = L.marker([18.5, 115.5], { icon: shipIcon }).addTo(map);
// 添加采样点标记
var samplePoints = [
{ lat: 18.0, lng: 114.8, type: 'CTD' },
{ lat: 19.0, lng: 116.2, type: 'Plankton' },
{ lat: 17.5, lng: 115.0, type: 'CTD' },
{ lat: 18.3, lng: 114.5, type: 'Plankton' },
{ lat: 18.7, lng: 116.0, type: 'CTD' },
{ lat: 19.2, lng: 115.3, type: 'Plankton' },
{ lat: 17.8, lng: 115.8, type: 'CTD' },
{ lat: 18.9, lng: 114.2, type: 'Plankton' }
];
samplePoints.forEach(function (point) {
var color = point.type === 'CTD' ? '#4caf50' : '#ff9800';
L.circleMarker([point.lat, point.lng], {
color: color,
fillColor: color,
fillOpacity: 0.7,
radius: 6
}).addTo(map).bindPopup(point.type + ' 采样点');
});
// 添加船舶点击事件(在 shipMarker 创建之后)
if (shipMarker) {
shipMarker.on('click', function (e) {
var lat = e.latlng.lat;
var lng = e.latlng.lng;
// 更新坐标信息显示
document.getElementById('latValue').textContent = lat.toFixed(4) + '°N';
document.getElementById('lngValue').textContent = lng.toFixed(4) + '°E';
// 显示坐标信息框
var coordsInfo = document.getElementById('coordinatesInfo');
coordsInfo.classList.add('active');
// 3秒后自动隐藏
setTimeout(function () {
coordsInfo.classList.remove('active');
}, 3000);
});
}
console.log('地图初始化成功');
} catch (error) {
console.error('地图初始化失败:', error);
}
} else {
console.error('地图容器未找到');
}
initDateTime();
});
// 更新船舶位置函数
function updateShipPosition() {
// 确保 shipMarker 已定义且地图已初始化
if (typeof shipMarker === 'undefined' || !shipMarker) {
console.warn('shipMarker 未定义或未初始化');
return;
}
// 模拟船舶移动
var currentLat = shipMarker.getLatLng().lat;
var currentLng = shipMarker.getLatLng().lng;
// 在南海区域内随机移动
var newLat = currentLat + (Math.random() - 0.5) * 0.05;
var newLng = currentLng + (Math.random() - 0.5) * 0.05;
// 确保船舶在南海区域内
newLat = Math.min(Math.max(newLat, 10), 23);
newLng = Math.min(Math.max(newLng, 105), 120);
shipMarker.setLatLng([newLat, newLng]);
// 更新位置显示
var positionElement = document.querySelector('.status-item:nth-child(4) span:last-child');
if (positionElement) {
positionElement.textContent = newLat.toFixed(2) + '°N, ' + newLng.toFixed(2) + '°E';
}
}
// 地图控制按钮事件处理
document.addEventListener('DOMContentLoaded', function () {
// 等待DOM加载完成后添加事件监听器
setTimeout(function () {
// 切换卫星图
var toggleSatelliteBtn = document.getElementById('toggleSatellite');
if (toggleSatelliteBtn) {
toggleSatelliteBtn.addEventListener('click', function () {
if (map && seaMapLayer && satelliteLayer) {
if (map.hasLayer(seaMapLayer)) {
map.removeLayer(seaMapLayer);
satelliteLayer.addTo(map);
} else if (map.hasLayer(terrainLayer)) {
map.removeLayer(terrainLayer);
satelliteLayer.addTo(map);
}
}
});
}
// 切换地形图
var toggleTerrainBtn = document.getElementById('toggleTerrain');
if (toggleTerrainBtn) {
toggleTerrainBtn.addEventListener('click', function () {
if (map && seaMapLayer && terrainLayer) {
if (map.hasLayer(seaMapLayer)) {
map.removeLayer(seaMapLayer);
terrainLayer.addTo(map);
} else if (map.hasLayer(satelliteLayer)) {
map.removeLayer(satelliteLayer);
terrainLayer.addTo(map);
}
}
});
}
// 重置视图
var resetViewBtn = document.getElementById('resetView');
if (resetViewBtn) {
resetViewBtn.addEventListener('click', function () {
if (map && satelliteLayer && terrainLayer && seaMapLayer) {
if (map.hasLayer(satelliteLayer)) {
map.removeLayer(satelliteLayer);
}
if (map.hasLayer(terrainLayer)) {
map.removeLayer(terrainLayer);
}
seaMapLayer.addTo(map);
map.setView([18.0, 115.0], 5);
}
});
}
}, 500); // 延迟执行确保地图已初始化
});
// 创建气象图表
var weatherChart = new Chart(document.getElementById('weatherChart'), {
type: 'line',
data: {
labels: ['13:00', '13:15', '13:30', '13:45', '14:00', '14:15', '14:30'],
datasets: [{
label: '风速 (m/s)',
data: [10.2, 11.5, 12.1, 12.8, 12.5, 11.9, 12.3],
borderColor: '#4fc3f7',
backgroundColor: 'rgba(79, 195, 247, 0.1)',
tension: 0.4,
fill: true,
yAxisID: 'y'
}, {
label: '气压 (hPa)',
data: [1010.5, 1011.2, 1011.8, 1012.3, 1012.5, 1012.2, 1012.4],
borderColor: '#4caf50',
backgroundColor: 'rgba(76, 175, 80, 0.1)',
tension: 0.4,
fill: true,
yAxisID: 'y1'
}, {
label: '气温 (°C)',
data: [21.2, 21.5, 21.8, 22.1, 22.3, 22.1, 22.4],
borderColor: '#ff9800',
backgroundColor: 'rgba(255, 152, 0, 0.1)',
tension: 0.4,
fill: true,
yAxisID: 'y'
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
type: 'linear',
display: true,
position: 'left',
grid: {
color: 'rgba(255, 255, 255, 0.1)'
},
ticks: {
color: '#e0e0e0'
}
},
y1: {
type: 'linear',
display: true,
position: 'right',
grid: {
drawOnChartArea: false,
},
ticks: {
color: '#e0e0e0'
}
},
x: {
grid: {
color: 'rgba(255, 255, 255, 0.1)'
},
ticks: {
color: '#e0e0e0'
}
}
},
plugins: {
legend: {
labels: {
color: '#e0e0e0'
}
}
}
}
});
// 创建水文图表
var hydroChart = new Chart(document.getElementById('hydroChart'), {
type: 'line',
data: {
labels: ['13:00', '13:15', '13:30', '13:45', '14:00', '14:15', '14:30'],
datasets: [{
label: '水温 (°C)',
data: [17.8, 18.0, 18.2, 18.3, 18.5, 18.4, 18.6],
borderColor: '#4fc3f7',
backgroundColor: 'rgba(79, 195, 247, 0.1)',
tension: 0.4,
fill: true,
yAxisID: 'y'
}, {
label: '盐度 (PSU)',
data: [33.8, 33.9, 34.0, 34.1, 34.2, 34.1, 34.3],
borderColor: '#4caf50',
backgroundColor: 'rgba(76, 175, 80, 0.1)',
tension: 0.4,
fill: true,
yAxisID: 'y1'
}, {
label: '浊度 (NTU)',
data: [3.8, 4.0, 4.2, 4.3, 4.5, 4.4, 4.6],
borderColor: '#ff9800',
backgroundColor: 'rgba(255, 152, 0, 0.1)',
tension: 0.4,
fill: true,
yAxisID: 'y'
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
type: 'linear',
display: true,
position: 'left',
grid: {
color: 'rgba(255, 255, 255, 0.1)'
},
ticks: {
color: '#e0e0e0'
}
},
y1: {
type: 'linear',
display: true,
position: 'right',
grid: {
drawOnChartArea: false,
},
ticks: {
color: '#e0e0e0'
}
},
x: {
grid: {
color: 'rgba(255, 255, 255, 0.1)'
},
ticks: {
color: '#e0e0e0'
}
}
},
plugins: {
legend: {
labels: {
color: '#e0e0e0'
}
}
}
}
});
// 创建气象要素详细图表
var weatherWindChart = new Chart(document.getElementById('weatherWindChart'), {
type: 'line',
data: {
labels: ['12:00', '12:30', '13:00', '13:30', '14:00', '14:30', '15:00'],
datasets: [{
label: '风速 (m/s)',
data: [9.5, 10.2, 11.5, 12.1, 12.8, 12.5, 11.9],
borderColor: '#4fc3f7',
backgroundColor: 'rgba(79, 195, 247, 0.1)',
tension: 0.4,
fill: true
}, {
label: '阵风风速 (m/s)',
data: [11.2, 12.0, 13.5, 14.2, 15.0, 14.5, 13.8],
borderColor: '#ff9800',
backgroundColor: 'rgba(255, 152, 0, 0.1)',
tension: 0.4,
fill: true
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true,
grid: {
color: 'rgba(255, 255, 255, 0.1)'
},
ticks: {
color: '#e0e0e0'
}
},
x: {
grid: {
color: 'rgba(255, 255, 255, 0.1)'
},
ticks: {
color: '#e0e0e0'
}
}
},
plugins: {
legend: {
labels: {
color: '#e0e0e0'
}
}
}
}
});
var weatherTempChart = new Chart(document.getElementById('weatherTempChart'), {
type: 'line',
data: {
labels: ['12:00', '12:30', '13:00', '13:30', '14:00', '14:30', '15:00'],
datasets: [{
label: '气温 (°C)',
data: [20.5, 21.0, 21.5, 22.0, 22.3, 22.1, 21.8],
borderColor: '#4fc3f7',
backgroundColor: 'rgba(79, 195, 247, 0.1)',
tension: 0.4,
fill: true
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: false,
grid: {
color: 'rgba(255, 255, 255, 0.1)'
},
ticks: {
color: '#e0e0e0'
}
},
x: {
grid: {
color: 'rgba(255, 255, 255, 0.1)'
},
ticks: {
color: '#e0e0e0'
}
}
},
plugins: {
legend: {
labels: {
color: '#e0e0e0'
}
}
}
}
});
var weatherPressureChart = new Chart(document.getElementById('weatherPressureChart'), {
type: 'line',
data: {
labels: ['12:00', '12:30', '13:00', '13:30', '14:00', '14:30', '15:00'],
datasets: [{
label: '气压 (hPa)',
data: [1010.0, 1010.5, 1011.2, 1011.8, 1012.3, 1012.5, 1012.2],
borderColor: '#4fc3f7',
backgroundColor: 'rgba(79, 195, 247, 0.1)',
tension: 0.4,
fill: true
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: false,
grid: {
color: 'rgba(255, 255, 255, 0.1)'
},
ticks: {
color: '#e0e0e0'
}
},
x: {
grid: {
color: 'rgba(255, 255, 255, 0.1)'
},
ticks: {
color: '#e0e0e0'
}
}
},
plugins: {
legend: {
labels: {
color: '#e0e0e0'
}
}
}
}
});
var weatherHumidityChart = new Chart(document.getElementById('weatherHumidityChart'), {
type: 'line',
data: {
labels: ['12:00', '12:30', '13:00', '13:30', '14:00', '14:30', '15:00'],
datasets: [{
label: '湿度 (%)',
data: [75, 76, 77, 78, 78, 77, 76],
borderColor: '#4fc3f7',
backgroundColor: 'rgba(79, 195, 247, 0.1)',
tension: 0.4,
fill: true
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: false,
grid: {
color: 'rgba(255, 255, 255, 0.1)'
},
ticks: {
color: '#e0e0e0'
}
},
x: {
grid: {
color: 'rgba(255, 255, 255, 0.1)'
},
ticks: {
color: '#e0e0e0'
}
}
},
plugins: {
legend: {
labels: {
color: '#e0e0e0'
}
}
}
}
});
// 创建水文要素详细图表
var hydroTempChart = new Chart(document.getElementById('hydroTempChart'), {
type: 'line',
data: {
labels: ['12:00', '12:30', '13:00', '13:30', '14:00', '14:30', '15:00'],
datasets: [{
label: '水温 (°C)',
data: [17.5, 17.8, 18.0, 18.2, 18.3, 18.5, 18.4],
borderColor: '#4fc3f7',
backgroundColor: 'rgba(79, 195, 247, 0.1)',
tension: 0.4,
fill: true
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: false,
grid: {
color: 'rgba(255, 255, 255, 0.1)'
},
ticks: {
color: '#e0e0e0'
}
},
x: {
grid: {
color: 'rgba(255, 255, 255, 0.1)'
},
ticks: {
color: '#e0e0e0'
}
}
},
plugins: {
legend: {
labels: {
color: '#e0e0e0'
}
}
}
}
});
var hydroSalinityChart = new Chart(document.getElementById('hydroSalinityChart'), {
type: 'line',
data: {
labels: ['12:00', '12:30', '13:00', '13:30', '14:00', '14:30', '15:00'],
datasets: [{
label: '盐度 (PSU)',
data: [33.5, 33.7, 33.9, 34.0, 34.1, 34.2, 34.1],
borderColor: '#4fc3f7',
backgroundColor: 'rgba(79, 195, 247, 0.1)',
tension: 0.4,
fill: true
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: false,
grid: {
color: 'rgba(255, 255, 255, 0.1)'
},
ticks: {
color: '#e0e0e0'
}
},
x: {
grid: {
color: 'rgba(255, 255, 255, 0.1)'
},
ticks: {
color: '#e0e0e0'
}
}
},
plugins: {
legend: {
labels: {
color: '#e0e0e0'
}
}
}
}
});
var hydroFlowChart = new Chart(document.getElementById('hydroFlowChart'), {
type: 'line',
data: {
labels: ['12:00', '12:30', '13:00', '13:30', '14:00', '14:30', '15:00'],
datasets: [{
label: '流速 (m/s)',
data: [1.0, 1.1, 1.2, 1.2, 1.1, 1.2, 1.1],
borderColor: '#4fc3f7',
backgroundColor: 'rgba(79, 195, 247, 0.1)',
tension: 0.4,
fill: true
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: false,
grid: {
color: 'rgba(255, 255, 255, 0.1)'
},
ticks: {
color: '#e0e0e0'
}
},
x: {
grid: {
color: 'rgba(255, 255, 255, 0.1)'
},
ticks: {
color: '#e0e0e0'
}
}
},
plugins: {
legend: {
labels: {
color: '#e0e0e0'
}
}
}
}
});
var hydroTurbidityChart = new Chart(document.getElementById('hydroTurbidityChart'), {
type: 'line',
data: {
labels: ['12:00', '12:30', '13:00', '13:30', '14:00', '14:30', '15:00'],
datasets: [{
label: '浊度 (NTU)',
data: [3.5, 3.8, 4.0, 4.2, 4.3, 4.5, 4.4],
borderColor: '#4fc3f7',
backgroundColor: 'rgba(79, 195, 247, 0.1)',
tension: 0.4,
fill: true
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: false,
grid: {
color: 'rgba(255, 255, 255, 0.1)'
},
ticks: {
color: '#e0e0e0'
}
},
x: {
grid: {
color: 'rgba(255, 255, 255, 0.1)'
},
ticks: {
color: '#e0e0e0'
}
}
},
plugins: {
legend: {
labels: {
color: '#e0e0e0'
}
}
}
}
});
// 风向和波高态势图更新函数
function updateSituationCharts() {
// 随机更新风向0-360度
var windDirection = Math.floor(Math.random() * 360);
var windArrow = document.getElementById('windArrow');
windArrow.style.transform = 'translate(-50%, -100%) rotate(' + windDirection + 'deg)';
// 更新风向显示
var directions = ['N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE', 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW'];
var index = Math.round(windDirection / 22.5) % 16;
document.getElementById('windDirectionValue').textContent = directions[index] + ' ' + windDirection + '°';
// 随机更新风速5-20 m/s
var windSpeed = 5 + Math.random() * 15;
var windSpeedFill = document.getElementById('windSpeedFill');
var windSpeedValue = document.getElementById('windSpeedValue');
// 风速填充高度最大20 m/s对应100%
var windFillHeight = (windSpeed / 20) * 100;
windSpeedFill.style.height = windFillHeight + '%';
windSpeedValue.textContent = windSpeed.toFixed(1) + 'm/s';
// 根据风速设置预警颜色
if (windSpeed < 10) {
windSpeedFill.className = 'wind-speed-fill normal';
} else if (windSpeed < 15) {
windSpeedFill.className = 'wind-speed-fill warning';
} else {
windSpeedFill.className = 'wind-speed-fill danger';
}
// 随机更新波高0.5-5米
var waveHeight = 0.5 + Math.random() * 4.5;
var waveHeightFill = document.getElementById('waveHeightFill');
var waveHeightValue = document.getElementById('waveHeightValue');
// 波高填充高度最大5米对应100%
var waveFillHeight = (waveHeight / 5) * 100;
waveHeightFill.style.height = waveFillHeight + '%';
waveHeightValue.textContent = waveHeight.toFixed(1) + 'm';
// 根据波高设置预警颜色
if (waveHeight < 2) {
waveHeightFill.className = 'wave-height-fill normal';
} else if (waveHeight < 3) {
waveHeightFill.className = 'wave-height-fill warning';
} else {
waveHeightFill.className = 'wave-height-fill danger';
}
// 随机更新波向0-360度
var waveDirection = Math.floor(Math.random() * 360);
var waveDirectionArrow = document.getElementById('waveDirectionArrow');
waveDirectionArrow.style.transform = 'translate(-50%, -100%) rotate(' + waveDirection + 'deg)';
// 更新波向显示
var waveIndex = Math.round(waveDirection / 22.5) % 16;
document.getElementById('waveDirectionValue').textContent = directions[waveIndex] + ' ' + waveDirection + '°';
}
// 模拟实时数据更新
function updateData() {
// // 更新气象数据
// document.querySelectorAll('.data-value')[0].textContent = (12 + Math.random()).toFixed(1);
// document.querySelectorAll('.data-value')[2].textContent = (22 + Math.random()).toFixed(1);
// document.querySelectorAll('.data-value')[3].textContent = (1012 + Math.random() * 2).toFixed(1);
// // 更新水文数据
// //document.querySelectorAll('.data-value')[6].textContent = (18 + Math.random()).toFixed(1);
// document.querySelectorAll('.data-value')[8].textContent = Math.floor(1240 + Math.random() * 20);
// document.querySelectorAll('.data-value')[9].textContent = (1.1 + Math.random() * 0.2).toFixed(1);
// // 更新船舶状态
// document.querySelectorAll('.data-value')[12].textContent = (8 + Math.random()).toFixed(1);
// document.querySelectorAll('.data-value')[13].textContent = Math.floor(240 + Math.random() * 10);
// 更新仪表
document.querySelectorAll('.gauge-fill')[0].style.height = (60 + Math.random() * 10) + '%';
document.querySelectorAll('.gauge-value')[0].textContent = Math.round(parseFloat(document.querySelectorAll('.gauge-fill')[0].style.height)) + '%';
document.querySelectorAll('.gauge-fill')[1].style.height = (25 + Math.random() * 10) + '%';
document.querySelectorAll('.gauge-value')[1].textContent = Math.round(parseFloat(document.querySelectorAll('.gauge-fill')[1].style.height)) + '%';
// 更新图表数据
updateChartData();
// 更新船舶位置
updateShipPosition();
// 更新态势图
updateSituationCharts();
}
function updateChartData() {
// 更新气象图表数据
var newTime = getCurrentTime();
weatherChart.data.labels.push(newTime);
weatherChart.data.datasets[0].data.push(12 + Math.random());
weatherChart.data.datasets[1].data.push(1012 + Math.random() * 2);
weatherChart.data.datasets[2].data.push(22 + Math.random());
if (weatherChart.data.datasets[0].data.length > 10) {
weatherChart.data.labels.shift();
weatherChart.data.datasets[0].data.shift();
weatherChart.data.datasets[1].data.shift();
weatherChart.data.datasets[2].data.shift();
}
weatherChart.update();
// 更新水文图表数据
hydroChart.data.labels.push(newTime);
hydroChart.data.datasets[0].data.push(18 + Math.random());
hydroChart.data.datasets[1].data.push(34 + Math.random() * 0.5);
hydroChart.data.datasets[2].data.push(4 + Math.random() * 1);
if (hydroChart.data.datasets[0].data.length > 10) {
hydroChart.data.labels.shift();
hydroChart.data.datasets[0].data.shift();
hydroChart.data.datasets[1].data.shift();
hydroChart.data.datasets[2].data.shift();
}
hydroChart.update();
}
// function updateShipPosition() {
// // 模拟船舶移动
// var currentLat = shipMarker.getLatLng().lat;
// var currentLng = shipMarker.getLatLng().lng;
// // 在南海区域内随机移动
// var newLat = currentLat + (Math.random() - 0.5) * 0.05;
// var newLng = currentLng + (Math.random() - 0.5) * 0.05;
// // 确保船舶在南海区域内
// newLat = Math.min(Math.max(newLat, 10), 23);
// newLng = Math.min(Math.max(newLng, 105), 120);
// shipMarker.setLatLng([newLat, newLng]);
// // 更新位置显示
// document.querySelector('.status-item:nth-child(4) span:last-child').textContent =
// newLat.toFixed(2) + '°N, ' + newLng.toFixed(2) + '°E';
// }
function getCurrentTime() {
const now = new Date();
return `${now.getHours()}:${now.getMinutes().toString().padStart(2, '0')}`;
}
// // 添加船舶点击事件
// shipMarker.on('click', function (e) {
// var lat = e.latlng.lat;
// var lng = e.latlng.lng;
// // 更新坐标信息显示
// document.getElementById('latValue').textContent = lat.toFixed(4) + '°N';
// document.getElementById('lngValue').textContent = lng.toFixed(4) + '°E';
// // 显示坐标信息框
// var coordsInfo = document.getElementById('coordinatesInfo');
// coordsInfo.classList.add('active');
// // 3秒后自动隐藏
// setTimeout(function () {
// coordsInfo.classList.remove('active');
// }, 3000);
// });
// 系统按钮事件处理 - 改为弹出模态框
document.querySelectorAll('.system-btn').forEach(function (btn) {
btn.addEventListener('click', function () {
var system = this.getAttribute('data-system');
var systemModal = document.getElementById('systemModal');
var systemModalTitle = document.getElementById('systemModalTitle');
var systemModalContent = document.getElementById('systemModalContent');
// 设置模态框标题
systemModalTitle.textContent = this.textContent + '详情';
// 根据系统类型设置内容
var content = '';
if (system === 'navigation') {
content = `
<div class="system-data-panel active">
<div class="system-data-item">
<span class="system-data-label">GPS定位精度</span>
<span class="system-data-value">2.1 m</span>
</div>
<div class="system-data-item">
<span class="system-data-label">陀螺仪状态</span>
<span class="system-data-value">正常</span>
</div>
<div class="system-data-item">
<span class="system-data-label">罗经航向</span>
<span class="system-data-value">245.2°</span>
</div>
<div class="system-data-item">
<span class="system-data-label">AIS连接</span>
<span class="system-data-value">在线</span>
</div>
<div class="system-data-item">
<span class="system-data-label">GPS卫星数量</span>
<span class="system-data-value">12</span>
</div>
<div class="system-data-item">
<span class="system-data-label">最后定位时间</span>
<span class="system-data-value">14:29:45</span>
</div>
</div>
`;
} else if (system === 'communication') {
content = `
<div class="system-data-panel active">
<div class="system-data-item">
<span class="system-data-label">卫星通信</span>
<span class="system-data-value">正常</span>
</div>
<div class="system-data-item">
<span class="system-data-label">信号强度</span>
<span class="system-data-value">85%</span>
</div>
<div class="system-data-item">
<span class="system-data-label">数据传输率</span>
<span class="system-data-value">512 kbps</span>
</div>
<div class="system-data-item">
<span class="system-data-label">最后通信</span>
<span class="system-data-value">14:28:15</span>
</div>
<div class="system-data-item">
<span class="system-data-label">通信延迟</span>
<span class="system-data-value">320 ms</span>
</div>
<div class="system-data-item">
<span class="system-data-label">数据包丢失率</span>
<span class="system-data-value">0.2%</span>
</div>
</div>
`;
} else if (system === 'sonar') {
content = `
<div class="system-data-panel active">
<div class="system-data-item">
<span class="system-data-label">多波束状态</span>
<span class="system-data-value">运行中</span>
</div>
<div class="system-data-item">
<span class="system-data-label">最大探测深度</span>
<span class="system-data-value">4500 m</span>
</div>
<div class="system-data-item">
<span class="system-data-label">声波频率</span>
<span class="system-data-value">12 kHz</span>
</div>
<div class="system-data-item">
<span class="system-data-label">数据质量</span>
<span class="system-data-value">良好</span>
</div>
<div class="system-data-item">
<span class="system-data-label">声波发射功率</span>
<span class="system-data-value">85%</span>
</div>
<div class="system-data-item">
<span class="system-data-label">最后扫描时间</span>
<span class="system-data-value">14:27:30</span>
</div>
</div>
`;
} else if (system === 'sampling') {
content = `
<div class="system-data-panel active">
<div class="system-data-item">
<span class="system-data-label">CTD采水器</span>
<span class="system-data-value">就绪</span>
</div>
<div class="system-data-item">
<span class="system-data-label">浮游生物网</span>
<span class="system-data-value">部署中</span>
</div>
<div class="system-data-item">
<span class="system-data-label">沉积物采样</span>
<span class="system-data-value">待命</span>
</div>
<div class="system-data-item">
<span class="system-data-label">样本数量</span>
<span class="system-data-value">24</span>
</div>
<div class="system-data-item">
<span class="system-data-label">最后采样时间</span>
<span class="system-data-value">14:25:10</span>
</div>
<div class="system-data-item">
<span class="system-data-label">样本存储温度</span>
<span class="system-data-value">4.2°C</span>
</div>
</div>
`;
}
systemModalContent.innerHTML = content;
systemModal.style.display = 'flex';
});
});
// 地图控制按钮事件处理
document.getElementById('toggleSatellite').addEventListener('click', function () {
if (map.hasLayer(seaMapLayer)) {
map.removeLayer(seaMapLayer);
satelliteLayer.addTo(map);
} else if (map.hasLayer(terrainLayer)) {
map.removeLayer(terrainLayer);
satelliteLayer.addTo(map);
}
});
document.getElementById('toggleTerrain').addEventListener('click', function () {
if (map.hasLayer(seaMapLayer)) {
map.removeLayer(seaMapLayer);
terrainLayer.addTo(map);
} else if (map.hasLayer(satelliteLayer)) {
map.removeLayer(satelliteLayer);
terrainLayer.addTo(map);
}
});
document.getElementById('resetView').addEventListener('click', function () {
if (map.hasLayer(satelliteLayer)) {
map.removeLayer(satelliteLayer);
}
if (map.hasLayer(terrainLayer)) {
map.removeLayer(terrainLayer);
}
seaMapLayer.addTo(map);
map.setView([18.0, 115.0], 5);
});
// 按钮事件处理
document.getElementById('showWeatherChart').addEventListener('click', function () {
var container = document.getElementById('weatherChartContainer');
var dataGrid = this.closest('.panel').querySelector('.data-grid');
container.classList.toggle('chart-visible');
if (container.classList.contains('chart-visible')) {
dataGrid.style.display = 'none';
this.textContent = '隐藏图表';
} else {
dataGrid.style.display = 'grid';
this.textContent = '显示图表';
}
});
document.getElementById('showHydroChart').addEventListener('click', function () {
var container = document.getElementById('hydroChartContainer');
var dataGrid = this.closest('.panel').querySelector('.data-grid');
container.classList.toggle('chart-visible');
if (container.classList.contains('chart-visible')) {
dataGrid.style.display = 'none';
this.textContent = '隐藏图表';
} else {
dataGrid.style.display = 'grid';
this.textContent = '显示图表';
}
});
document.getElementById('dataDownloadBtn').addEventListener('click', function () {
document.getElementById('downloadModal').style.display = 'flex';
});
document.getElementById('dataPlaybackBtn').addEventListener('click', function () {
document.getElementById('playbackPanel').style.display = 'flex';
});
document.getElementById('weatherChartBtn').addEventListener('click', function () {
document.getElementById('weatherChartModal').style.display = 'flex';
});
document.getElementById('hydroChartBtn').addEventListener('click', function () {
document.getElementById('hydroChartModal').style.display = 'flex';
});
document.getElementById('closePlayback').addEventListener('click', function () {
document.getElementById('playbackPanel').style.display = 'none';
});
// 关闭模态框
document.querySelectorAll('.close-btn').forEach(function (btn) {
btn.addEventListener('click', function () {
document.querySelectorAll('.modal').forEach(function (modal) {
modal.style.display = 'none';
});
});
});
// 点击模态框外部关闭
window.addEventListener('click', function (event) {
document.querySelectorAll('.modal').forEach(function (modal) {
if (event.target === modal) {
modal.style.display = 'none';
}
});
});
// 每5秒更新一次数据
setInterval(updateData, 5000);
// 初始数据更新
updateData();
// 时间轴拖动功能
function initTimeline() {
// 确保DOM已加载完成
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', createTimeline);
} else {
createTimeline();
}
}
// 修改时间轴创建函数
function createTimeline() {
const timeline = document.querySelector('.timeline');
if (!timeline) {
console.error('时间轴容器未找到');
return;
}
// 清空时间轴容器
timeline.innerHTML = '';
// 获取当前时间并设置时间轴默认位置
const now = new Date();
const hours = now.getHours();
const minutes = now.getMinutes();
const currentTimePercent = ((hours * 60 + minutes) / (24 * 60)) * 100;
// 创建时间轴基础元素
const progress = document.createElement('div');
progress.className = 'timeline-progress';
progress.style.width = currentTimePercent + '%';
const track = document.createElement('div');
track.className = 'timeline-track';
// 添加基础元素到时间轴
timeline.appendChild(progress);
timeline.appendChild(track);
// 生成24小时时间标记 (每3小时一个标记)
for (let i = 0; i < 24; i += 3) {
const marker = document.createElement('div');
marker.className = 'time-marker';
marker.style.left = (i / 24) * 100 + '%';
const label = document.createElement('div');
label.className = 'time-label';
label.textContent = i.toString().padStart(2, '0') + ':00';
label.style.left = '50%';
marker.appendChild(label);
timeline.appendChild(marker);
}
// 添加当前时间指示器
const currentTimeMarker = document.createElement('div');
currentTimeMarker.className = 'current-time-indicator';
currentTimeMarker.style.left = currentTimePercent + '%';
timeline.appendChild(currentTimeMarker);
// 创建拖动按钮(使用图片)
const handle = document.createElement('div');
handle.className = 'timeline-handle';
handle.style.left = currentTimePercent + '%';
timeline.appendChild(handle);
// 创建船舶图标
const shipIcon = document.createElement('div');
shipIcon.className = 'ship-icon';
shipIcon.style.left = currentTimePercent + '%';
timeline.appendChild(shipIcon);
// 添加拖动事件
addDragEvents(handle, progress, shipIcon);
}
function addDragEvents(handle, progress, shipIcon) {
let isDragging = false;
// 鼠标按下事件
handle.addEventListener('mousedown', function (e) {
isDragging = true;
e.preventDefault();
});
// 鼠标移动事件
document.addEventListener('mousemove', function (e) {
if (!isDragging) return;
const timeline = document.querySelector('.timeline');
const timelineRect = timeline.getBoundingClientRect();
let posX = e.clientX - timelineRect.left;
// 限制拖动范围
posX = Math.max(0, Math.min(posX, timelineRect.width));
// 计算百分比位置
const percent = (posX / timelineRect.width) * 100;
// 更新拖动按钮位置
handle.style.left = percent + '%';
// 更新进度条
progress.style.width = percent + '%';
// 更新船舶图标位置
shipIcon.style.left = percent + '%';
});
// 鼠标释放事件
document.addEventListener('mouseup', function () {
isDragging = false;
});
// 触摸事件支持(移动端)
handle.addEventListener('touchstart', function (e) {
isDragging = true;
e.preventDefault();
});
document.addEventListener('touchmove', function (e) {
if (!isDragging) return;
const timeline = document.querySelector('.timeline');
const timelineRect = timeline.getBoundingClientRect();
let posX = e.touches[0].clientX - timelineRect.left;
// 限制拖动范围
posX = Math.max(0, Math.min(posX, timelineRect.width));
// 计算百分比位置
const percent = (posX / timelineRect.width) * 100;
// 更新拖动按钮位置
handle.style.left = percent + '%';
// 更新进度条
progress.style.width = percent + '%';
// 更新船舶图标位置
shipIcon.style.left = percent + '%';
});
document.addEventListener('touchend', function () {
isDragging = false;
});
}
// 页面加载完成后初始化时间轴
initTimeline();
// 窗口大小改变时重新初始化时间轴
window.addEventListener('resize', function () {
setTimeout(initTimeline, 100); // 延迟执行以确保DOM已更新
});
// 初始化日期时间
function initDateTime() {
function updateDateTime() {
const now = new Date();
const dateStr = now.getFullYear() + '年' +
(now.getMonth() + 1) + '月' +
now.getDate() + '日';
const timeStr = now.toTimeString().substr(0, 8);
document.getElementById('current-date').textContent = dateStr;
document.getElementById('current-time').textContent = timeStr;
}
updateDateTime();
setInterval(updateDateTime, 1000);
}
</script>
</body>
</html>