881 lines
25 KiB
HTML
881 lines
25 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>
|
||
<style>
|
||
* {
|
||
margin: 0;
|
||
padding: 0;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
body {
|
||
font-family: 'Microsoft YaHei', Arial, sans-serif;
|
||
height: 100vh;
|
||
overflow: hidden;
|
||
background: #0a0e27;
|
||
color: #fff;
|
||
}
|
||
|
||
/* 整体布局 */
|
||
.container {
|
||
display: grid;
|
||
grid-template-columns: 1fr 30%;
|
||
grid-template-rows: 60px 1fr 200px;
|
||
height: 100vh;
|
||
gap: 2px;
|
||
background: #000;
|
||
}
|
||
|
||
/* 顶部标题栏 */
|
||
.header {
|
||
grid-column: 1 / 3;
|
||
background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 0 30px;
|
||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
|
||
}
|
||
|
||
.header-title {
|
||
font-size: 24px;
|
||
font-weight: bold;
|
||
letter-spacing: 2px;
|
||
}
|
||
|
||
.header-info {
|
||
display: flex;
|
||
gap: 30px;
|
||
font-size: 14px;
|
||
color: #a8d5ff;
|
||
}
|
||
|
||
.header-info span {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 5px;
|
||
}
|
||
|
||
/* 控制按钮 */
|
||
.header-controls {
|
||
display: flex;
|
||
gap: 10px;
|
||
align-items: center;
|
||
}
|
||
|
||
.control-btn {
|
||
background: rgba(79, 195, 247, 0.2);
|
||
border: 1px solid #4fc3f7;
|
||
color: #4fc3f7;
|
||
padding: 8px 16px;
|
||
border-radius: 5px;
|
||
cursor: pointer;
|
||
font-size: 14px;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.control-btn:hover {
|
||
background: rgba(79, 195, 247, 0.3);
|
||
border-color: #64b5f6;
|
||
color: #64b5f6;
|
||
transform: translateY(-2px);
|
||
box-shadow: 0 4px 8px rgba(79, 195, 247, 0.3);
|
||
}
|
||
|
||
.control-btn:active {
|
||
transform: translateY(0);
|
||
}
|
||
|
||
.control-btn svg {
|
||
width: 16px;
|
||
height: 16px;
|
||
}
|
||
|
||
/* 左侧数字孪生区域 */
|
||
.main-view {
|
||
grid-column: 1;
|
||
grid-row: 2;
|
||
background: #0a0e27;
|
||
position: relative;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.main-view iframe {
|
||
width: 100%;
|
||
height: 100%;
|
||
border: none;
|
||
display: block;
|
||
}
|
||
|
||
/* 右侧属性面板 */
|
||
.property-panel {
|
||
grid-column: 2;
|
||
grid-row: 2 / 4;
|
||
background: linear-gradient(180deg, #1a1f3a 0%, #0f1329 100%);
|
||
padding: 20px;
|
||
overflow-y: auto;
|
||
border-left: 1px solid #2a3f5f;
|
||
}
|
||
|
||
.panel-title {
|
||
font-size: 18px;
|
||
margin-bottom: 20px;
|
||
padding-bottom: 10px;
|
||
border-bottom: 2px solid #2a5298;
|
||
color: #4fc3f7;
|
||
}
|
||
|
||
.property-item {
|
||
margin-bottom: 15px;
|
||
padding: 15px;
|
||
background: rgba(42, 63, 95, 0.3);
|
||
border-radius: 5px;
|
||
border-left: 3px solid #4fc3f7;
|
||
}
|
||
|
||
.property-label {
|
||
font-size: 12px;
|
||
color: #8ba9c7;
|
||
margin-bottom: 5px;
|
||
}
|
||
|
||
.property-value {
|
||
font-size: 16px;
|
||
color: #fff;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.status-indicator {
|
||
display: inline-block;
|
||
width: 8px;
|
||
height: 8px;
|
||
border-radius: 50%;
|
||
margin-right: 8px;
|
||
animation: pulse 2s infinite;
|
||
}
|
||
|
||
.status-normal {
|
||
background: #4caf50;
|
||
}
|
||
|
||
.status-warning {
|
||
background: #ff9800;
|
||
}
|
||
|
||
@keyframes pulse {
|
||
|
||
0%,
|
||
100% {
|
||
opacity: 1;
|
||
}
|
||
|
||
50% {
|
||
opacity: 0.5;
|
||
}
|
||
}
|
||
|
||
/* 底部数据面板 */
|
||
.data-panel {
|
||
grid-column: 1;
|
||
grid-row: 3;
|
||
background: linear-gradient(180deg, #1a1f3a 0%, #0f1329 100%);
|
||
padding: 15px 20px;
|
||
border-top: 1px solid #2a3f5f;
|
||
overflow-y: auto;
|
||
}
|
||
|
||
.data-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||
gap: 15px;
|
||
}
|
||
|
||
.data-card {
|
||
background: rgba(42, 63, 95, 0.3);
|
||
padding: 15px;
|
||
border-radius: 5px;
|
||
border: 1px solid #2a5298;
|
||
transition: transform 0.2s;
|
||
}
|
||
|
||
.data-card:hover {
|
||
transform: translateY(-2px);
|
||
border-color: #4fc3f7;
|
||
}
|
||
|
||
.data-card-title {
|
||
font-size: 12px;
|
||
color: #8ba9c7;
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
.data-card-value {
|
||
font-size: 20px;
|
||
font-weight: bold;
|
||
color: #4fc3f7;
|
||
}
|
||
|
||
.data-card-unit {
|
||
font-size: 12px;
|
||
color: #8ba9c7;
|
||
margin-left: 5px;
|
||
}
|
||
|
||
/* 滚动条样式 */
|
||
::-webkit-scrollbar {
|
||
width: 8px;
|
||
height: 8px;
|
||
}
|
||
|
||
::-webkit-scrollbar-track {
|
||
background: #0a0e27;
|
||
}
|
||
|
||
::-webkit-scrollbar-thumb {
|
||
background: #2a5298;
|
||
border-radius: 4px;
|
||
}
|
||
|
||
::-webkit-scrollbar-thumb:hover {
|
||
background: #4fc3f7;
|
||
}
|
||
|
||
/* 图表容器 */
|
||
.chart-container {
|
||
margin: 20px 0;
|
||
padding: 15px;
|
||
background: rgba(42, 63, 95, 0.2);
|
||
border-radius: 8px;
|
||
border: 1px solid #2a5298;
|
||
}
|
||
|
||
.chart-title {
|
||
font-size: 14px;
|
||
color: #4fc3f7;
|
||
margin-bottom: 15px;
|
||
font-weight: bold;
|
||
}
|
||
|
||
/* 进度条图表 */
|
||
.progress-bar-chart {
|
||
margin: 10px 0;
|
||
}
|
||
|
||
.progress-label {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
font-size: 12px;
|
||
color: #8ba9c7;
|
||
margin-bottom: 5px;
|
||
}
|
||
|
||
.progress-bar-bg {
|
||
width: 100%;
|
||
height: 20px;
|
||
background: rgba(0, 0, 0, 0.3);
|
||
border-radius: 10px;
|
||
overflow: hidden;
|
||
position: relative;
|
||
}
|
||
|
||
.progress-bar-fill {
|
||
height: 100%;
|
||
background: linear-gradient(90deg, #4fc3f7, #2196f3);
|
||
border-radius: 10px;
|
||
transition: width 0.3s ease;
|
||
position: relative;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.progress-bar-fill::after {
|
||
content: '';
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
|
||
animation: shimmer 2s infinite;
|
||
}
|
||
|
||
@keyframes shimmer {
|
||
0% {
|
||
transform: translateX(-100%);
|
||
}
|
||
|
||
100% {
|
||
transform: translateX(100%);
|
||
}
|
||
}
|
||
|
||
/* 环形图表 */
|
||
.ring-chart {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 20px;
|
||
margin: 15px 0;
|
||
}
|
||
|
||
.ring-svg {
|
||
width: 80px;
|
||
height: 80px;
|
||
transform: rotate(-90deg);
|
||
}
|
||
|
||
.ring-background {
|
||
fill: none;
|
||
stroke: rgba(0, 0, 0, 0.3);
|
||
stroke-width: 8;
|
||
}
|
||
|
||
.ring-progress {
|
||
fill: none;
|
||
stroke: url(#gradient);
|
||
stroke-width: 8;
|
||
stroke-linecap: round;
|
||
transition: stroke-dashoffset 0.5s ease;
|
||
}
|
||
|
||
.ring-info {
|
||
flex: 1;
|
||
}
|
||
|
||
.ring-value {
|
||
font-size: 24px;
|
||
font-weight: bold;
|
||
color: #4fc3f7;
|
||
}
|
||
|
||
.ring-label {
|
||
font-size: 12px;
|
||
color: #8ba9c7;
|
||
margin-top: 5px;
|
||
}
|
||
|
||
/* 折线图样式 */
|
||
.line-chart {
|
||
height: 120px;
|
||
display: flex;
|
||
align-items: flex-end;
|
||
gap: 4px;
|
||
padding: 10px 0;
|
||
}
|
||
|
||
.line-bar {
|
||
flex: 1;
|
||
background: linear-gradient(to top, #2196f3, #4fc3f7);
|
||
border-radius: 3px 3px 0 0;
|
||
transition: height 0.3s ease;
|
||
position: relative;
|
||
min-height: 10px;
|
||
}
|
||
|
||
.line-bar:hover {
|
||
background: linear-gradient(to top, #4fc3f7, #64b5f6);
|
||
cursor: pointer;
|
||
}
|
||
|
||
/* 温度计样式 */
|
||
.thermometer {
|
||
display: flex;
|
||
gap: 15px;
|
||
align-items: center;
|
||
padding: 10px 0;
|
||
}
|
||
|
||
.thermometer-bar {
|
||
width: 30px;
|
||
height: 150px;
|
||
background: rgba(0, 0, 0, 0.3);
|
||
border-radius: 15px;
|
||
position: relative;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.thermometer-fill {
|
||
position: absolute;
|
||
bottom: 0;
|
||
left: 0;
|
||
right: 0;
|
||
background: linear-gradient(to top, #f44336, #ff9800, #4caf50);
|
||
border-radius: 15px;
|
||
transition: height 0.5s ease;
|
||
}
|
||
|
||
.thermometer-info {
|
||
flex: 1;
|
||
}
|
||
|
||
.thermometer-value {
|
||
font-size: 32px;
|
||
font-weight: bold;
|
||
color: #4fc3f7;
|
||
}
|
||
|
||
.thermometer-desc {
|
||
font-size: 12px;
|
||
color: #8ba9c7;
|
||
margin-top: 5px;
|
||
}
|
||
</style>
|
||
</head>
|
||
|
||
<body>
|
||
<div class="container">
|
||
<!-- 顶部标题栏 -->
|
||
<div class="header">
|
||
<div class="header-title">江南造船厂数字孪生平台</div>
|
||
<div class="header-info">
|
||
<span>
|
||
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
|
||
<path
|
||
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" />
|
||
</svg>
|
||
系统状态: 正常运行
|
||
</span>
|
||
<span>
|
||
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
|
||
<path
|
||
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z" />
|
||
</svg>
|
||
当前时间: <span id="current-time"></span>
|
||
</span>
|
||
<span>
|
||
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
|
||
<path
|
||
d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z" />
|
||
</svg>
|
||
上海市 江南造船厂
|
||
</span>
|
||
</div>
|
||
<div class="header-controls">
|
||
<button class="control-btn" id="refresh-btn" title="刷新数字孪生">
|
||
<svg viewBox="0 0 24 24" fill="currentColor">
|
||
<path d="M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z"/>
|
||
</svg>
|
||
刷新
|
||
</button>
|
||
<button class="control-btn" id="fullscreen-btn" title="全屏数字孪生">
|
||
<svg viewBox="0 0 24 24" fill="currentColor">
|
||
<path d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"/>
|
||
</svg>
|
||
全屏
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 左侧数字孪生主视图 -->
|
||
<div class="main-view">
|
||
<iframe src="index.html" title="江南造船厂数字孪生"></iframe>
|
||
</div>
|
||
|
||
<!-- 右侧属性面板 -->
|
||
<div class="property-panel">
|
||
<h3 class="panel-title">实时监控面板</h3>
|
||
|
||
<!-- 设备基础信息 -->
|
||
<div class="property-item">
|
||
<div class="property-label">设备名称</div>
|
||
<div class="property-value">龙门吊 #3</div>
|
||
</div>
|
||
|
||
<div class="property-item">
|
||
<div class="property-label">设备状态</div>
|
||
<div class="property-value">
|
||
<span class="status-indicator status-normal"></span>
|
||
运行中
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 设备利用率环形图 -->
|
||
<div class="chart-container">
|
||
<div class="chart-title">设备利用率</div>
|
||
<div class="ring-chart">
|
||
<svg class="ring-svg" viewBox="0 0 100 100">
|
||
<defs>
|
||
<linearGradient id="gradient" x1="0%" y1="0%" x2="100%" y2="0%">
|
||
<stop offset="0%" style="stop-color:#4fc3f7;stop-opacity:1" />
|
||
<stop offset="100%" style="stop-color:#2196f3;stop-opacity:1" />
|
||
</linearGradient>
|
||
</defs>
|
||
<circle class="ring-background" cx="50" cy="50" r="40"></circle>
|
||
<circle class="ring-progress" cx="50" cy="50" r="40" stroke-dasharray="251.2" stroke-dashoffset="62.8"
|
||
id="utilization-ring"></circle>
|
||
</svg>
|
||
<div class="ring-info">
|
||
<div class="ring-value" id="utilization-value">75%</div>
|
||
<div class="ring-label">当前利用率</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 负载进度条 -->
|
||
<div class="chart-container">
|
||
<div class="chart-title">负载状态</div>
|
||
<div class="progress-bar-chart">
|
||
<div class="progress-label">
|
||
<span>当前负载</span>
|
||
<span id="load-value">45.8 吨</span>
|
||
</div>
|
||
<div class="progress-bar-bg">
|
||
<div class="progress-bar-fill" style="width: 38%;" id="load-bar"></div>
|
||
</div>
|
||
<div class="progress-label" style="margin-top: 5px;">
|
||
<span>最大: 120.0 吨</span>
|
||
<span id="load-percent">38%</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 能耗温度计 -->
|
||
<div class="chart-container">
|
||
<div class="chart-title">实时能耗</div>
|
||
<div class="thermometer">
|
||
<div class="thermometer-bar">
|
||
<div class="thermometer-fill" style="height: 62%;" id="power-fill"></div>
|
||
</div>
|
||
<div class="thermometer-info">
|
||
<div class="thermometer-value" id="power-value">185</div>
|
||
<div class="thermometer-desc">kW / 300 kW</div>
|
||
<div class="thermometer-desc" style="margin-top: 10px;">
|
||
<span class="status-indicator status-warning"></span>
|
||
中等负荷
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 24小时运行趋势 -->
|
||
<div class="chart-container">
|
||
<div class="chart-title">24小时运行趋势</div>
|
||
<div class="line-chart" id="trend-chart">
|
||
<div class="line-bar" style="height: 60%;" data-value="60"></div>
|
||
<div class="line-bar" style="height: 75%;" data-value="75"></div>
|
||
<div class="line-bar" style="height: 55%;" data-value="55"></div>
|
||
<div class="line-bar" style="height: 80%;" data-value="80"></div>
|
||
<div class="line-bar" style="height: 70%;" data-value="70"></div>
|
||
<div class="line-bar" style="height: 85%;" data-value="85"></div>
|
||
<div class="line-bar" style="height: 65%;" data-value="65"></div>
|
||
<div class="line-bar" style="height: 90%;" data-value="90"></div>
|
||
<div class="line-bar" style="height: 75%;" data-value="75"></div>
|
||
<div class="line-bar" style="height: 68%;" data-value="68"></div>
|
||
<div class="line-bar" style="height: 78%;" data-value="78"></div>
|
||
<div class="line-bar" style="height: 82%;" data-value="82"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 运行时长进度 -->
|
||
<div class="chart-container">
|
||
<div class="chart-title">今日运行时长</div>
|
||
<div class="progress-bar-chart">
|
||
<div class="progress-label">
|
||
<span>已运行</span>
|
||
<span id="runtime-value">6.5 小时</span>
|
||
</div>
|
||
<div class="progress-bar-bg">
|
||
<div class="progress-bar-fill" style="width: 65%;" id="runtime-bar"></div>
|
||
</div>
|
||
<div class="progress-label" style="margin-top: 5px;">
|
||
<span>计划: 10.0 小时</span>
|
||
<span>65%</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 其他信息 -->
|
||
<div class="property-item">
|
||
<div class="property-label">维护状态</div>
|
||
<div class="property-value">良好</div>
|
||
</div>
|
||
|
||
<div class="property-item">
|
||
<div class="property-label">上次维护</div>
|
||
<div class="property-value">2025-10-01</div>
|
||
</div>
|
||
|
||
<div class="property-item">
|
||
<div class="property-label">操作人员</div>
|
||
<div class="property-value">张三 (工号: 2024001)</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 底部数据面板 -->
|
||
<div class="data-panel">
|
||
<div class="data-grid">
|
||
<div class="data-card">
|
||
<div class="data-card-title">实时产能</div>
|
||
<div>
|
||
<span class="data-card-value">1,245</span>
|
||
<span class="data-card-unit">件/日</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="data-card">
|
||
<div class="data-card-title">设备利用率</div>
|
||
<div>
|
||
<span class="data-card-value">87.5</span>
|
||
<span class="data-card-unit">%</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="data-card">
|
||
<div class="data-card-title">在线设备</div>
|
||
<div>
|
||
<span class="data-card-value">24/28</span>
|
||
<span class="data-card-unit">台</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="data-card">
|
||
<div class="data-card-title">当前作业人员</div>
|
||
<div>
|
||
<span class="data-card-value">156</span>
|
||
<span class="data-card-unit">人</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="data-card">
|
||
<div class="data-card-title">今日能耗</div>
|
||
<div>
|
||
<span class="data-card-value">3,842</span>
|
||
<span class="data-card-unit">kWh</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="data-card">
|
||
<div class="data-card-title">安全预警</div>
|
||
<div>
|
||
<span class="data-card-value" style="color: #4caf50;">0</span>
|
||
<span class="data-card-unit">项</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="data-card">
|
||
<div class="data-card-title">完工进度</div>
|
||
<div>
|
||
<span class="data-card-value">68.3</span>
|
||
<span class="data-card-unit">%</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="data-card">
|
||
<div class="data-card-title">质量合格率</div>
|
||
<div>
|
||
<span class="data-card-value">99.2</span>
|
||
<span class="data-card-unit">%</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
// 更新当前时间
|
||
function updateTime() {
|
||
const now = new Date();
|
||
const timeString = now.toLocaleString('zh-CN', {
|
||
year: 'numeric',
|
||
month: '2-digit',
|
||
day: '2-digit',
|
||
hour: '2-digit',
|
||
minute: '2-digit',
|
||
second: '2-digit',
|
||
hour12: false
|
||
});
|
||
document.getElementById('current-time').textContent = timeString;
|
||
}
|
||
|
||
updateTime();
|
||
setInterval(updateTime, 1000);
|
||
|
||
// 更新环形图
|
||
function updateRingChart(percent) {
|
||
const ring = document.getElementById('utilization-ring');
|
||
const valueText = document.getElementById('utilization-value');
|
||
const circumference = 251.2;
|
||
const offset = circumference - (percent / 100) * circumference;
|
||
ring.style.strokeDashoffset = offset;
|
||
valueText.textContent = percent + '%';
|
||
}
|
||
|
||
// 更新负载进度条
|
||
function updateLoadBar(current, max) {
|
||
const percent = ((current / max) * 100).toFixed(1);
|
||
document.getElementById('load-value').textContent = current.toFixed(1) + ' 吨';
|
||
document.getElementById('load-percent').textContent = percent + '%';
|
||
document.getElementById('load-bar').style.width = percent + '%';
|
||
}
|
||
|
||
// 更新能耗
|
||
function updatePower(power, max) {
|
||
const percent = ((power / max) * 100).toFixed(0);
|
||
document.getElementById('power-value').textContent = power;
|
||
document.getElementById('power-fill').style.height = percent + '%';
|
||
}
|
||
|
||
// 更新运行时长
|
||
function updateRuntime(hours, max) {
|
||
const percent = ((hours / max) * 100).toFixed(0);
|
||
document.getElementById('runtime-value').textContent = hours.toFixed(1) + ' 小时';
|
||
document.getElementById('runtime-bar').style.width = percent + '%';
|
||
}
|
||
|
||
// 更新趋势图
|
||
function updateTrendChart() {
|
||
const bars = document.querySelectorAll('.line-bar');
|
||
bars.forEach(bar => {
|
||
const currentHeight = parseInt(bar.style.height);
|
||
const variation = (Math.random() - 0.5) * 10;
|
||
let newHeight = currentHeight + variation;
|
||
newHeight = Math.max(20, Math.min(95, newHeight));
|
||
bar.style.height = newHeight + '%';
|
||
});
|
||
}
|
||
|
||
// 模拟数据更新
|
||
function updateChartData() {
|
||
// 更新环形图(设备利用率)
|
||
const currentUtil = parseInt(document.getElementById('utilization-value').textContent);
|
||
const newUtil = Math.max(60, Math.min(95, currentUtil + (Math.random() - 0.5) * 5));
|
||
updateRingChart(Math.round(newUtil));
|
||
|
||
// 更新负载
|
||
const currentLoad = parseFloat(document.getElementById('load-value').textContent);
|
||
const newLoad = Math.max(30, Math.min(100, currentLoad + (Math.random() - 0.5) * 3));
|
||
updateLoadBar(newLoad, 120);
|
||
|
||
// 更新能耗
|
||
const currentPower = parseInt(document.getElementById('power-value').textContent);
|
||
const newPower = Math.max(150, Math.min(250, currentPower + (Math.random() - 0.5) * 10));
|
||
updatePower(Math.round(newPower), 300);
|
||
|
||
// 更新运行时长(缓慢增加)
|
||
const currentRuntime = parseFloat(document.getElementById('runtime-value').textContent);
|
||
const newRuntime = Math.min(10, currentRuntime + 0.01);
|
||
updateRuntime(newRuntime, 10);
|
||
|
||
// 更新趋势图
|
||
updateTrendChart();
|
||
}
|
||
|
||
// 模拟底部数据面板更新
|
||
function updateDataPanel() {
|
||
const cards = document.querySelectorAll('.data-card-value');
|
||
cards.forEach(card => {
|
||
const currentValue = parseFloat(card.textContent);
|
||
if (!isNaN(currentValue)) {
|
||
// 随机小幅波动
|
||
const variation = (Math.random() - 0.5) * 2;
|
||
const newValue = (currentValue + variation).toFixed(1);
|
||
card.textContent = newValue;
|
||
}
|
||
});
|
||
}
|
||
|
||
// 每3秒更新一次图表数据
|
||
setInterval(updateChartData, 3000);
|
||
|
||
// 每5秒更新一次数据面板
|
||
setInterval(updateDataPanel, 5000);
|
||
|
||
// 监听来自Unity的消息
|
||
window.addEventListener('message', function (event) {
|
||
console.log('收到iframe消息:', event.data);
|
||
// 这里可以根据Unity发送的消息更新界面数据
|
||
// 例如:根据Unity发送的设备数据更新图表
|
||
if (event.data && event.data.type === 'equipment') {
|
||
if (event.data.utilization) updateRingChart(event.data.utilization);
|
||
if (event.data.load) updateLoadBar(event.data.load, 120);
|
||
if (event.data.power) updatePower(event.data.power, 300);
|
||
}
|
||
});
|
||
|
||
// 刷新按钮功能
|
||
document.getElementById('refresh-btn').addEventListener('click', function() {
|
||
const iframe = document.querySelector('.main-view iframe');
|
||
const btn = this;
|
||
|
||
// 添加旋转动画
|
||
btn.style.transition = 'transform 0.6s ease';
|
||
btn.style.transform = 'rotate(360deg)';
|
||
|
||
// 刷新iframe
|
||
iframe.src = iframe.src;
|
||
|
||
// 动画结束后重置
|
||
setTimeout(() => {
|
||
btn.style.transform = 'rotate(0deg)';
|
||
}, 600);
|
||
});
|
||
|
||
// 全屏按钮功能
|
||
document.getElementById('fullscreen-btn').addEventListener('click', function() {
|
||
const mainView = document.querySelector('.main-view');
|
||
const btn = this;
|
||
|
||
if (!document.fullscreenElement) {
|
||
// 进入全屏
|
||
if (mainView.requestFullscreen) {
|
||
mainView.requestFullscreen();
|
||
} else if (mainView.webkitRequestFullscreen) {
|
||
mainView.webkitRequestFullscreen();
|
||
} else if (mainView.msRequestFullscreen) {
|
||
mainView.msRequestFullscreen();
|
||
}
|
||
} else {
|
||
// 退出全屏
|
||
if (document.exitFullscreen) {
|
||
document.exitFullscreen();
|
||
} else if (document.webkitExitFullscreen) {
|
||
document.webkitExitFullscreen();
|
||
} else if (document.msExitFullscreen) {
|
||
document.msExitFullscreen();
|
||
}
|
||
}
|
||
});
|
||
|
||
// 监听全屏状态变化,更新按钮
|
||
document.addEventListener('fullscreenchange', function() {
|
||
const btn = document.getElementById('fullscreen-btn');
|
||
if (!document.fullscreenElement) {
|
||
// 退出全屏状态
|
||
btn.innerHTML = `
|
||
<svg viewBox="0 0 24 24" fill="currentColor">
|
||
<path d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"/>
|
||
</svg>
|
||
全屏
|
||
`;
|
||
btn.title = '全屏数字孪生';
|
||
} else {
|
||
// 全屏状态
|
||
btn.innerHTML = `
|
||
<svg viewBox="0 0 24 24" fill="currentColor">
|
||
<path d="M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z"/>
|
||
</svg>
|
||
退出全屏
|
||
`;
|
||
btn.title = '退出全屏';
|
||
}
|
||
});
|
||
|
||
// 兼容不同浏览器的全屏事件
|
||
document.addEventListener('webkitfullscreenchange', function() {
|
||
document.dispatchEvent(new Event('fullscreenchange'));
|
||
});
|
||
document.addEventListener('mozfullscreenchange', function() {
|
||
document.dispatchEvent(new Event('fullscreenchange'));
|
||
});
|
||
document.addEventListener('MSFullscreenChange', function() {
|
||
document.dispatchEvent(new Event('fullscreenchange'));
|
||
});
|
||
</script>
|
||
</body>
|
||
|
||
</html> |