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

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!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>