Files
SIPAIIS_WMS_JSSW/src/main/webapp/jsp/bigScreen2.jsp
2026-03-12 01:43:29 +08:00

882 lines
28 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<title>区域管线大屏展示</title>
<script type="text/javascript" src="<%=request.getContextPath()%>/node_modules/jquery/dist/jquery.min.js"></script>
<script type="text/javascript" src="<%=request.getContextPath()%>/JS/echarts3.0.js"></script>
<!-- 天地图 API -->
<script type="text/javascript" src="http://api.tianditu.gov.cn/api?v=4.0&tk=f423193014cde7bf44b224c6ab2b1210"></script>
<!-- <script
type="text/javascript"
src="../../node_modules/jquery/dist/jquery.min.js"
></script> -->
<!-- <script type="text/javascript" src="../../JS/echarts3.0.js"></script> -->
<style>
body,
html {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
overflow: auto; /* Allow scrolling if window is smaller */
background-color: #030829;
}
.screen-container {
width: 6500px;
height: 1800px;
/* background-image: url("../../IMG/screen2.png"); */
background-image: url('<%=request.getContextPath()%>/IMG/screen2.png');
background-size: 100% 100%;
background-repeat: no-repeat;
position: relative;
}
.stat-card {
position: absolute;
top: 257px;
/* left: 1910px; */
width: 200px;
height: 71px;
color: rgba(255, 255, 255, 1);
font-family: Gilroy;
font-weight: 500;
font-size: 60px;
}
.card-1 {
left: 1910px;
}
.card-2 {
left: 2832px;
}
.card-3 {
left: 3754px;
}
.ring-chart-wrapper {
position: absolute;
top: 563px;
left: 1880px;
width: 662px;
height: 455px;
}
.pie-chart-wrapper-2 {
position: absolute;
top: 563px;
left: 2572px;
width: 662px;
height: 455px;
}
.gauge-chart-wrapper-3 {
position: absolute;
top: 563px;
left: 3264px;
width: 662px;
height: 455px;
}
.gauge-chart-wrapper-4 {
position: absolute;
top: 563px;
left: 3956px;
width: 662px;
height: 455px;
}
.bar-chart-wrapper-5 {
position: absolute;
top: 1158px;
left: 1881px;
width: 1353px;
height: 592px;
}
.bar-chart-wrapper-6 {
position: absolute;
top: 1158px;
left: 3265px;
width: 1353px;
height: 592px;
}
.ring-chart-bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0.4;
mix-blend-mode: normal;
/* border: 1px solid rgba(27, 126, 242, 1); */
box-sizing: border-box;
/* background: rgba(27, 126, 242, 0.6); */
}
#ring-chart-content,
#pie-chart-content-2,
#gauge-chart-content-3,
#gauge-chart-content-4,
#bar-chart-content-5,
#bar-chart-content-6 {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
/* 全屏提示遮罩 */
.fullscreen-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.9);
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
cursor: pointer;
}
.fullscreen-overlay .tip-content {
text-align: center;
color: #fff;
}
.fullscreen-overlay .tip-content h2 {
font-size: 48px;
margin-bottom: 20px;
color: #46F2FF;
}
.fullscreen-overlay .tip-content p {
font-size: 24px;
color: #7ef3ff;
}
.fullscreen-overlay .tip-content .icon {
font-size: 80px;
margin-bottom: 20px;
}
</style>
</head>
<body>
<!-- 全屏提示遮罩 -->
<%-- <div class="fullscreen-overlay" id="fullscreenOverlay" onclick="enterFullscreen()">--%>
<%-- <div class="tip-content">--%>
<%-- <div class="icon">🖥️</div>--%>
<%-- <h2>点击进入全屏展示</h2>--%>
<%-- <p>按 ESC 键可退出全屏</p>--%>
<%-- </div>--%>
<%-- </div>--%>
<div class="screen-container">
<div id="map-container" style="position: absolute; top: 280px; left: 70px; width: 1760px; height: 1470px; background-color: white;"></div>
<div class="stat-card card-1">53829.5</div>
<div class="stat-card card-2">2495</div>
<div class="stat-card card-3">2460</div>
<div class="ring-chart-wrapper">
<div class="ring-chart-bg"></div>
<div id="ring-chart-content"></div>
</div>
<div class="pie-chart-wrapper-2">
<div class="ring-chart-bg"></div>
<div id="pie-chart-content-2"></div>
</div>
<div class="gauge-chart-wrapper-3">
<div class="ring-chart-bg"></div>
<div id="gauge-chart-content-3"></div>
</div>
<div class="gauge-chart-wrapper-4">
<div class="ring-chart-bg"></div>
<div id="gauge-chart-content-4"></div>
</div>
<div class="bar-chart-wrapper-5">
<div class="ring-chart-bg"></div>
<div id="bar-chart-content-5"></div>
</div>
<div class="bar-chart-wrapper-6">
<div class="ring-chart-bg"></div>
<div id="bar-chart-content-6"></div>
</div>
</div>
<script>
// ==================== 天地图初始化 ====================
var contextPath = "<%=request.getContextPath()%>";
var map = null;
var pipelineOverlays = [];
// 初始化天地图
function initTiandituMap() {
// 创建地图实例
map = new T.Map("map-container");
// 放大地图级别 (15比13更放大)
map.centerAndZoom(new T.LngLat(121.34, 30.74), 15);
map.enableScrollWheelZoom();
// 设置暗色主题 - 切换为卫星影像底图
map.setMapType(TMAP_SATELLITE_MAP);
// 添加控件
var scale = new T.Control.Scale();
map.addControl(scale);
var zoom = new T.Control.Zoom();
map.addControl(zoom);
// 隐藏地图类型切换控件,保持暗色主题
setTimeout(function() {
var mapTypeCtrl = document.querySelector(".TMAP_maptype");
if (mapTypeCtrl) {
mapTypeCtrl.style.display = "none";
}
}, 500);
console.log("[天地图] 初始化完成 - 暗色主题缩放级别15");
// 加载管道数据
loadPipelineData();
}
// 加载管道数据
function loadPipelineData() {
$.ajax({
url: contextPath + '/jsp/z_bigScreen/geo.json',
type: 'GET',
dataType: 'json',
success: function(data) {
if (data && data.features) {
var pipelines = data.features.map(function(feature) {
var attr = feature.attributes || {};
var geom = feature.geometry || {};
var paths = geom.paths || null;
var lengthM = attr.Shape_Leng ? (attr.Shape_Leng * 111000).toFixed(2) : '-';
return {
id: attr.FID,
name: '管线-' + attr.FID,
length: lengthM,
elevation: attr.Elevation || 0,
color: attr.Color || 6,
layer: attr.Layer || 'WS_LINE',
paths: paths
};
});
renderPipelines(pipelines);
console.log("[管道数据] 加载完成,共", pipelines.length, "条");
}
},
error: function(xhr, status, error) {
console.error("[管道数据] 加载失败:", error);
}
});
}
// 渲染管道到地图
function renderPipelines(pipelines) {
// 先清除之前的管线
clearPipelines();
pipelines.forEach(function(item) {
if (!item.paths || !item.paths.length) return;
var pathsArray = item.paths;
// 如果 paths 的第一个元素不是数组,说明是单路径格式,需要包装
if (!Array.isArray(pathsArray[0]) || !Array.isArray(pathsArray[0][0])) {
pathsArray = [pathsArray];
}
// 按颜色区分管线 (Color === 6 为深蓝色,其他为深红色)
var lineColor = item.color === 6 ? '#0066cc' : '#0ea6c1';
// 渲染每条路径
pathsArray.forEach(function(pathCoords) {
if (!pathCoords || pathCoords.length < 2) return;
var points = pathCoords.map(function(p) {
return new T.LngLat(p[0], p[1]);
});
var polyline = new T.Polyline(points, {
color: lineColor,
weight: 8,
opacity: 1
});
map.addOverLay(polyline);
pipelineOverlays.push(polyline);
// 信息窗口
var infoHtml = '<div style="font-size:13px;line-height:1.5;">' +
'<strong style="color:#007bff;">管线 #' + item.id + '</strong><br>' +
'名称: ' + (item.name || '-') + '<br>' +
'管长: ' + (item.length || '-') + ' m<br>' +
'高程: ' + (item.elevation || 0).toFixed(2) + ' m' +
'</div>';
var infoWindow = new T.InfoWindow(infoHtml, { offset: new T.Point(0, 0) });
polyline.addEventListener('click', function(e) {
map.openInfoWindow(infoWindow, e.lnglat);
});
});
});
console.log("[管线渲染] 完成,共渲染", pipelineOverlays.length, "条管线段");
}
// 清除管道覆盖物
function clearPipelines() {
pipelineOverlays.forEach(function(overlay) {
map.removeOverLay(overlay);
});
pipelineOverlays = [];
}
// ==================== 数据统一管理 ====================
var pageData = {
// 统计卡片数据
statCards: {
card1: 100,
card2: 200,
card3: 400,
},
// 饼图1数据 - 管线类型统计
pieChart1: [
{ value: 335, name: "II级钢筋混凝土管 承插接口" },
{ value: 310, name: "焊接钢管 焊接接口" },
{ value: 274, name: "高密度聚乙烯双壁波纹管" },
{ value: 235, name: "聚乙烯PE管" },
{ value: 200, name: "II级钢筋混凝土管" },
{ value: 180, name: "高密度聚乙烯缠绕管" },
{ value: 150, name: "焊接钢管 焊接连接" },
{ value: 140, name: "高密度聚乙烯中空壁缠绕管" },
{ value: 130, name: "钢筋混凝土管" },
{ value: 110, name: "球墨铸铁管" },
{ value: 100, name: "预应力钢筒混凝土管" }
],
// 饼图2数据 - 管线类型统计2
pieChart2: [
{ value: 335, name: "II级钢筋混凝土管 承插接口" },
{ value: 310, name: "焊接钢管 焊接接口" },
{ value: 274, name: "高密度聚乙烯双壁波纹管" },
{ value: 235, name: "聚乙烯PE管" },
{ value: 200, name: "II级钢筋混凝土管" },
{ value: 180, name: "高密度聚乙烯缠绕管" },
{ value: 150, name: "焊接钢管 焊接连接" },
{ value: 140, name: "高密度聚乙烯中空壁缠绕管" },
{ value: 130, name: "钢筋混凝土管" },
{ value: 110, name: "球墨铸铁管" },
{ value: 100, name: "预应力钢筒混凝土管" }
],
// 仪表盘数据
gaugeCharts: {
gauge3: 53829.5,
gauge4: 12345.6
},
// 柱状图数据
barCharts: {
bar5: [
// 3000, 4500, 1500, 5000, 23000, 1500, 15000, 3000, 4000, 5000, 2000,
// 1000, 500, 2563, 4000
],
bar6: [
// 2000, 3000, 1000, 4000, 18000, 1000, 12000, 2000, 3000, 4000, 1500,
// 800, 400, 2000, 3000
]
},
// 柱状图X轴数据
barXAxis: [
// "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15"
]
};
// 更新统计卡片显示
function updateStatCards() {
$(".card-1").text(pageData.statCards.card1);
$(".card-2").text(pageData.statCards.card2);
$(".card-3").text(pageData.statCards.card3);
}
// 从接口获取数据并更新页面(示例方法,供后期调用)
function fetchDataFromApi(apiUrl) {
$.ajax({
url: apiUrl,
type: "GET",
dataType: "json",
success: function(response) {
// 假设接口返回的数据格式如下:
// {
// statCards: { card1: xxx, card2: xxx, card3: xxx },
// pieChart1: [...],
// pieChart2: [...],
// gaugeCharts: { gauge3: xxx, gauge4: xxx },
// barCharts: { bar5: [...], bar6: [...] }
// }
if (response) {
// 更新数据
if (response.statCards) pageData.statCards = response.statCards;
if (response.pieChart1) pageData.pieChart1 = response.pieChart1;
if (response.pieChart2) pageData.pieChart2 = response.pieChart2;
if (response.gaugeCharts) pageData.gaugeCharts = response.gaugeCharts;
if (response.barCharts) pageData.barCharts = response.barCharts;
if (response.barXAxis) pageData.barXAxis = response.barXAxis;
// 刷新页面
refreshPage();
}
},
error: function(xhr, status, error) {
console.error("获取数据失败:", error);
}
});
}
// 刷新页面所有图表
function refreshPage() {
updateStatCards();
initPieChart();
initPieChart2();
initGaugeChart("gauge-chart-content-3", pageData.gaugeCharts.gauge3);
initGaugeChart("gauge-chart-content-4", pageData.gaugeCharts.gauge4);
initBarChart("bar-chart-content-5", pageData.barCharts.bar5);
initBarChart("bar-chart-content-6", pageData.barCharts.bar6);
}
// 进入全屏函数
function enterFullscreen() {
var elem = document.documentElement;
if (elem.requestFullscreen) {
elem.requestFullscreen();
} else if (elem.webkitRequestFullscreen) {
elem.webkitRequestFullscreen();
} else if (elem.msRequestFullscreen) {
elem.msRequestFullscreen();
}
document.getElementById('fullscreenOverlay').style.display = 'none';
}
// 监听全屏状态变化
document.addEventListener('fullscreenchange', function() {
var overlay = document.getElementById('fullscreenOverlay');
if (!document.fullscreenElement) {
overlay.style.display = 'flex';
}
});
document.addEventListener('webkitfullscreenchange', function() {
var overlay = document.getElementById('fullscreenOverlay');
if (!document.webkitFullscreenElement) {
overlay.style.display = 'flex';
}
});
// 获取管道统计数据
function fetchPipelineStats() {
$.ajax({
url: "<%=request.getContextPath()%>/pipeline/pipelineData/getStatistics.do",
type: "GET",
dataType: "json",
success: function(response) {
console.log("管道统计数据:", response);
if (response && response.success) {
// 更新统计卡片
$(".card-1").text(response.totalLength || 0);
$(".card-2").text(response.totalCount || 0);
$(".card-3").text(response.totalCount || 0);
// 更新仪表盘数据
pageData.gaugeCharts.gauge3 = response.totalLength || 0;
pageData.gaugeCharts.gauge4 = response.totalLength || 0;
// 更新饼图数据 - 材质长度比例
if (response.materialLengthRatio && response.materialLengthRatio.length > 0) {
pageData.pieChart1 = response.materialLengthRatio.map(function(item) {
return {
name: item.material,
value: item.length
};
});
}
// 更新饼图数据 - 材质数量比例
if (response.materialCountRatio && response.materialCountRatio.length > 0) {
pageData.pieChart2 = response.materialCountRatio.map(function(item) {
return {
name: item.material,
value: item.count
};
});
}
// 更新柱状图数据 - 管径长度分布
if (response.diameterLengthRatio && response.diameterLengthRatio.length > 0) {
// 取前15个数据
var topData = response.diameterLengthRatio.slice(0, 15);
pageData.barCharts.bar5 = topData.map(function(item) {
return item.length;
});
pageData.barXAxis = topData.map(function(item) {
return item.diameter;
});
}
// 更新柱状图数据 - 管径数量分布
if (response.diameterCountRatio && response.diameterCountRatio.length > 0) {
var topData = response.diameterCountRatio.slice(0, 15);
pageData.barCharts.bar6 = topData.map(function(item) {
return item.count;
});
}
// 重新渲染图表
initPieChart();
initPieChart2();
initGaugeChart("gauge-chart-content-3", pageData.gaugeCharts.gauge3);
initGaugeChart("gauge-chart-content-4", pageData.gaugeCharts.gauge4);
initBarChart("bar-chart-content-5", pageData.barCharts.bar5);
initBarChart("bar-chart-content-6", pageData.barCharts.bar6);
}
},
error: function(xhr, status, error) {
console.error("获取管道统计数据失败:", error);
}
});
}
$(document).ready(function () {
// 初始化天地图
initTiandituMap();
// 初始化统计数据
updateStatCards();
// 初始化图表
initPieChart();
initPieChart2();
initGaugeChart("gauge-chart-content-3", pageData.gaugeCharts.gauge3);
initGaugeChart("gauge-chart-content-4", pageData.gaugeCharts.gauge4);
initBarChart("bar-chart-content-5", pageData.barCharts.bar5);
initBarChart("bar-chart-content-6", pageData.barCharts.bar6);
// 获取管道统计数据
fetchPipelineStats();
// Double click to toggle fullscreen
$("body").on("dblclick", function () {
launchIntoFullscreen(document.documentElement);
});
});
function initPieChart() {
var chartDom = document.getElementById("ring-chart-content");
var myChart = echarts.init(chartDom);
var option = {
color: [
"#5470c6",
"#91cc75",
"#fac858",
"#ee6666",
"#73c0de",
"#3ba272",
"#fc8452",
"#9a60b4",
"#ea7ccc",
"#00d4ff",
"#ffb700",
"#2bff89",
"#915eff",
"#ff7f00",
],
tooltip: {
trigger: "item",
formatter: "{b}: {c}m ({d}%)"
},
series: [
{
name: "管线类型统计",
type: "pie",
radius: "55%",
center: ["50%", "50%"],
avoidLabelOverlap: true,
label: {
show: true,
position: "outside",
formatter: "{b}\n{d}%",
fontSize: 32,
lineHeight: 40,
align: "left",
color: "#fff",
fontWeight: "bold",
},
labelLine: {
show: true,
length: 30,
length2: 40,
lineStyle: {
type: "solid",
width: 2,
},
},
data: pageData.pieChart1,
},
],
};
myChart.setOption(option);
}
function initPieChart2() {
var chartDom = document.getElementById("pie-chart-content-2");
var myChart = echarts.init(chartDom);
var option = {
color: [
"#5470c6",
"#91cc75",
"#fac858",
"#ee6666",
"#73c0de",
"#3ba272",
"#fc8452",
"#9a60b4",
"#ea7ccc",
"#00d4ff",
"#ffb700",
"#2bff89",
"#915eff",
"#ff7f00",
],
tooltip: {
trigger: "item",
formatter: "{b}: {c}条 ({d}%)"
},
series: [
{
name: "管线类型统计2",
type: "pie",
radius: "55%",
center: ["50%", "50%"],
avoidLabelOverlap: true,
label: {
show: true,
position: "outside",
formatter: "{b}\n{d}%",
fontSize: 32,
lineHeight: 40,
align: "left",
color: "#fff",
fontWeight: "bold",
},
labelLine: {
show: true,
length: 30,
length2: 40,
lineStyle: {
type: "solid",
width: 2,
},
},
data: pageData.pieChart2,
},
],
};
myChart.setOption(option);
}
function initGaugeChart(domId, value) {
var chartDom = document.getElementById(domId);
var myChart = echarts.init(chartDom);
var option = {
series: [
{
type: "gauge",
startAngle: 180,
endAngle: 0,
min: 0,
max: 300,
splitNumber: 6,
radius: "90%",
center: ["50%", "70%"],
axisLine: {
lineStyle: {
width: 40,
color: [
[
1,
new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: "rgba(65, 108, 243, 1)" },
{ offset: 1, color: "rgba(0, 68, 160, 1)" },
]),
],
],
},
},
pointer: {
show: true,
length: "60%",
width: 6,
itemStyle: {
color: "#00d4ff",
},
},
axisTick: {
show: false,
},
splitLine: {
show: false,
},
axisLabel: {
color: "#00d4ff",
fontSize: 20,
distance: -80,
formatter: function (value) {
return value;
},
},
detail: {
show: true,
offsetCenter: [0, "40%"],
fontSize: 30,
color: "#fff",
formatter: "{value} m",
},
data: [
{
value: value,
name: "",
},
],
},
],
};
// Adjust value if it exceeds max for visual representation (optional)
// For now, we just set the data value as is, but if it's large like 53829.5,
// the pointer will be pegged at max.
// If the gauge is just a visual indicator and the number is what matters:
// Let's set the gauge pointer to max if value > 300
if (value > 300) {
option.series[0].data[0].value = 300; // Pointer at max
option.series[0].detail.formatter = value + " m"; // Show real value
}
myChart.setOption(option);
}
function initBarChart(domId, data) {
var chartDom = document.getElementById(domId);
var myChart = echarts.init(chartDom);
// Find max value for markPoint (example logic)
var maxVal = Math.max(...data);
var minVal = Math.min(...data);
var option = {
grid: {
top: "20%",
left: "3%",
right: "4%",
bottom: "3%",
containLabel: true,
},
tooltip: {
trigger: "axis",
},
xAxis: {
type: "category",
data: pageData.barXAxis,
axisLine: {
lineStyle: { color: "#2C3E50" },
show: true,
// lineStyle: {
// color: 'rgba(255, 255, 255, 0.3)'
// }
},
axisLabel: {
color: "#B7C9E2",
fontSize: 40,
},
// axisTick: {
// show: false
// }
},
yAxis: {
type: "value",
// name: "长度(m)",
// nameTextStyle: {
// color: '#B7C9E2',
// padding: [0, 0, 40, 2300],
// fontSize: 40,
// },
splitNumber: 5,
axisLine: { show: false },
axisTick: { show: false },
axisLabel: {
color: "#B7C9E2",
fontSize: 40,
},
splitLine: {
lineStyle: {
color: "rgba(255,255,255,0.15)",
type: "dashed",
},
},
},
dataZoom: [{ type: "inside" }],
series: [
{
data: data,
type: "bar",
barWidth: "40%",
itemStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: "#46F2FF" },
{ offset: 1, color: "#0B4DB5" },
]),
shadowColor: "rgba(0, 0, 0, 0.3)",
shadowBlur: 10,
},
},
emphasis: {
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: "#6af8ff" },
{ offset: 1, color: "#1560d6" },
]),
},
},
},
],
};
myChart.setOption(option);
}
function launchIntoFullscreen(element) {
if (element.requestFullscreen) {
element.requestFullscreen();
} else if (element.mozRequestFullScreen) {
element.mozRequestFullScreen();
} else if (element.webkitRequestFullscreen) {
element.webkitRequestFullscreen();
} else if (element.msRequestFullscreen) {
element.msRequestFullscreen();
}
}
function exitFullscreen() {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
}
}
</script>
</body>
</html>