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.

1366 lines
47 KiB
JavaScript

9 months ago
import { drawAxis, drawAxis2D, draw2DText } from './draw.js';
import { loadOption, GIL1, GIL2, GIL3, GIL4, CPD, CPD1 } from './echartsOptions.js';
let renderer, scene, camera, controls, renderer2D, scene2D, camera2D, controls2D;
//let socket = null;
let axis = new THREE.Group();
let axis2D = new THREE.Group();
let initAxis = 80;//正值最大值
let maxNum = [];//上一次的最大值
let minNum = 0;//负值最大值
let planes = [];//截断面
let i18n;
let viewType = 1;//窗口显示状态1初始状态PRPSorPRPD只显示一个且可以切换 2半屏状态3其他窗口半屏状态
const paramsStr = window.location.search
const params = new URLSearchParams(paramsStr)
let viewIndex = params.get('viewIndex') || 0;//视窗序号
let productId = params.get('productId') || 2;//产品id
let deviceId = params.get('deviceId') || '50100001_1';//设备id
let win;//窗口序列
let isReconnect = false;
let socket;
let token = 'c9343e83005e1f2b458d66628ddff98b'
let url = `ws://192.168.1.88:8844/messaging/${token}`
9 months ago
//const stats = new Stats();
//document.body.appendChild(stats.dom);
let box2D6 = document.getElementById('box2D6');
let box2D6chart = '';
let maxRange = 100;
let clearHistory = 30;
// //打点统计次数颜色
let realTime = {
channelFiltering: 0,//频段过滤 //必填
switch: 1,//开关1、启动、0、关闭 //必填
mapCategory: 3,//图谱类型1、PRPS、2、PRPD、3、PRPS/PRPD //必填
monitorType: 1,// GIS 1 GIL故障定位 2 GIL局放 3 电缆 4 //必填
cumulativeDot: 1,//累计打点时长 默认1秒-1则无限累计 //必填
correlationDenoising: 0,//关联降噪1、启动、0、关闭 //不必填
adaptiveNoise: 0,//自适应降噪1、启动、0、关闭 //不必填
groundNoise: 0,//手动降噪 //不必填
migrationPhase: 0,//偏移相位//不必填
waveSwitch: 0,//录播开关1、开始、0、停止 //不必填
atlasType: 1,
}
//电缆局放1 PRPS/PRPD 2 折现图
let atlasType = 1;
// monitorType GIS 1 GIL故障定位 2 GIL局放 3 电缆 4
// atlasType 1 PRPS/PRPD 2 飞行模式/脉冲数据 3 连续模式
const lut = new THREE.Lut();
lut.addColorMap('axis', [[0.0, 0x00ee00], [0.25, 0xeeee00], [0.75, 0xee0000], [1.0, 0x4e0211]],);
lut.setColorMap('axis', 500)
let meshList = new THREE.Group();//图例柱子
const dummy = new THREE.Object3D();
meshList.name = 'chartsMesh';
let pointsList = new THREE.Group();//图例散点
pointsList.name = 'chartsPoint';
let axisTextGroup = new THREE.Group();
axisTextGroup.name = 'axisText';
let axisTextGroup2D = new THREE.Group();
axisTextGroup2D.name = 'axisText';
// 周期,相位 柱子数
let period = 50, phase = 128, count = period * phase;
const geometry = new THREE.BoxGeometry(0.6, 1, 2.5);
geometry.computeVertexNormals()
//非光泽表面的材质,没有镜面高光
//const initInstancedMesh = new THREE.InstancedMesh(geometry, new THREE.MeshLambertMaterial(), count);
//最佳性能材质
const initInstancedMesh = new THREE.InstancedMesh(geometry, new THREE.MeshBasicMaterial(), count);
initInstancedMesh.name = 'initInstancedMesh';
/* prpd初始Instanced点 */
let initInstancedPoints,//prpd实例
pointPositions, pointColors,//PRPS位置及颜色的集合
pointsGeometry = new THREE.BufferGeometry(),
pointCount;
//pointsGeometry = new THREE.BoxGeometry(0, 0.8, (360 / initAxis) * 0.8,),// prpd位置属性数组
//pointsGeometry.computeVertexNormals()
let counter = 1;
const switchFun = {
showHistory: {
open() {
initTrendChart()
},
close() {
}
}
};
$('.switch').on('click', function () {
$(this).toggleClass('active');
if ($(this).hasClass('active')) {
console.log('开关已打开');
} else {
console.log('开关已关闭');
}
});
9 months ago
$('#setting-btn').click(function () {
$(this).toggleClass('ready')
$('#setting').toggle()
})
9 months ago
//菜单展示隐藏
$('#show').click(function () {
$('.LinkANC').toggle();
$('#associated-noise-box').toggle()
$('.eventList').toggle();
$('#record-btn-box').toggle();
$('.refreshtitle').toggle();
$('#total').toggle();
$('.noisy-slide-box').toggle();
$('#addPointNumDiv').toggle();
$(this).toggleClass('ready')
})
//prps or prpd 切换
$('#prps').click(function () {
updateParams('mapCategory', $(this), 1)
$('#box3D1').toggle();
$('#box2D1').toggle();
$('#prpd').toggleClass('ready')
})
$('#prpd').click(function () {
updateParams('mapCategory', $(this), 2)
$('#box2D1').toggle();
$('#box3D1').toggle();
$('#prps').toggleClass('ready')
})
//暂停or开启
$('#start').click(function () {
updateParams('switch', $(this))
})
//图谱放大缩小
$('.scale').click(function () {
if ($(this).hasClass('big')) {
maxRange = maxRange + 25;
$('.small').removeClass('ready')
if (maxRange == 100) {
$(this).toggleClass('ready')
}
} else {
maxRange = maxRange - 25;
$('.big').removeClass('ready')
if (maxRange == 25) {
$(this).toggleClass('ready')
}
}
drawAxis((maxRange / 100) * initAxis, 0);
clearPoints()
let constant = (360 / (maxRange)) * maxRange + 1
planes[0].constant = constant
})
//自适应降噪
$('#adaptive-noise').click(function () {
if (!realTime.adaptiveNoise) {//groundNoise
$(".noisy-slide").slider({ value: -80 });
$(".noisy-slide span").attr('data-content', '底噪' + ' ' + -80);
$(".noisy-slide").slider({ disabled: true });
realTime.groundNoise = 0;
} else {
$(".noisy-slide").slider({ disabled: false });
}
updateParams('adaptiveNoise', $(this))
})
//关联传感器降噪
$('#associated-noise').click(function () {
updateParams('correlationDenoising', $(this))
})
// 录播按钮点击
$('.record-btn-box').click(function () {
let $this = $(this).children();
if (socket) {
//初始状态没暂停clss且录播状态为停止的时候添加该class
if (!$this.hasClass('pause') && !realTime.waveSwitch) {
$this.addClass('pause')
}
$this.toggleClass('live')
$this.toggleClass('pause')
}
updateParams('waveSwitch', null)
})
$('.refresh-btn').click(function () {
$('#total').slideToggle()
})
//累计打点时间输入
$("#total-time").on("input", function () { // 使用 "input" 事件可以实现实时过滤
var currentValue = $(this).val();
var filteredValue = currentValue.replace(/[^0-9]/g, ''); // 使用正则表达式过滤非数字字符
if (currentValue !== filteredValue) {
$(this).val(filteredValue); // 如果有变化,则更新输入框的值
}
});
$('#total-time').blur(function () {
const value = $(this).val() || 1
updateParams('cumulativeDot', null, value)
if (value == 1) {
if (!$('.refresh-btn').hasClass('ready')) {
$('.refresh-btn').addClass('ready')
}
} else {
$('.refresh-btn').removeClass('ready')
}
})
//频段切换
$('#channelFiltering').on('change', function () {
let val = $(this).val();
updateParams('channelFiltering', null, val)
})
//更新socket参数
function updateParams(prams, that, value) {
if (socket) {
realTime[prams] = value || (realTime[prams] ? 0 : 1);
that && that.toggleClass('ready')
sendMessage()
}
}
loadOption();
init();
init2D();
render();
render2D();
initTrendChart();
onWindowResize()
9 months ago
function initTrendChart() {
box2D6chart = echarts.init(box2D6)
setTimeout(() => {
box2D6chart.setOption(CPD);
})
}
const generateArray = () => {
const newArray = [];
const step = 360 / phase;
for (let i = 1; i <= phase; i++) {
newArray.push([counter, (360 - parseInt(i * step)), getRandomInt(10, 65)]);
}
counter = (counter % period) + 1;
return newArray;
}
const generateArray1 = () => {
const newArray = [];
for (let i = 0; i < 4000; i++) {
newArray.push([getRandomInt(0, 360), getRandomInt(0, 80), getRandomInt(1, 15)])
}
return newArray
}
function initPointsFun() {
if (initInstancedPoints) {
pointsList.remove(initInstancedPoints);
initInstancedPoints.material.dispose()//map(i => { i.dispose() })
initInstancedPoints.geometry.dispose()//map(i => { i.disponse() })
initInstancedPoints = null;
}
let maxYPointsMap = [800, 10000, 10000, 7000];
let maxYPoints = maxYPointsMap[realTime.monitorType - 1];
pointCount = phase * maxYPoints;
pointPositions = new Float32Array(pointCount * 3) // x, y, z
pointColors = new Float32Array(pointCount * 3) // r, g, b
// 初始化点的位置和颜色
for (let i = 0; i < pointCount; i++) {
const x = i
const y = 9999
const z = 10
pointPositions[i * 3] = x
pointPositions[i * 3 + 1] = y
pointPositions[i * 3 + 2] = z
pointColors[i * 3] = Math.random()
pointColors[i * 3 + 1] = Math.random()
pointColors[i * 3 + 2] = Math.random()
}
pointsGeometry.setAttribute('position', new THREE.BufferAttribute(pointPositions, 3))
pointsGeometry.setAttribute('color', new THREE.BufferAttribute(pointColors, 3))
// 创建 ShaderMateria
const material = new THREE.PointsMaterial({ size: 2, vertexColors: true })
// 创建 Points 对象
initInstancedPoints = new THREE.Points(pointsGeometry, material)
initInstancedPoints.name = 'initInstancedPoints';
// const object1 = meshList.getObjectByName('initInstancedMesh');
// if (!object1) {
pointsList.add(initInstancedPoints);
//}
}
initCharts()
function initCharts(type) {
if (type == 'open') {
meshList.visible = true;
return;
} else if (type == 'close') {
meshList.visible = false;
let k = 1, s = 1;
for (let j = 0; j < period; j++) {
for (let i = 0; i < phase; i++) {
initInstancedMesh.getMatrixAt(k, dummy.matrix);
dummy.position.setFromMatrixPosition(dummy.matrix);
dummy.scale.setFromMatrixScale(dummy.matrix);
dummy.position.y = 99999;
dummy.scale.y = Math.abs(1);
const color = lut.getColor(Math.abs(0) / initAxis);
initInstancedMesh.setColorAt(k, color);
dummy.updateMatrix();
initInstancedMesh.setMatrixAt(k, dummy.matrix);
k++;
}
}
initInstancedMesh.instanceMatrix.needsUpdate = true;
initInstancedMesh.instanceColor.needsUpdate = true;
for (let i = 0; i < pointCount; i++) {
pointPositions[i * 3 + 1] = 9999999 // Y//移到y轴高出隐藏多余的点
}
// 通知 Three.js 更新 BufferGeometry
pointsGeometry.attributes.position.needsUpdate = true
return;
}
let k = 0, initList = [];
for (let i = 0; i < period; i++) {
initList.push(generateArray());
}
for (let j = 0; j < initList.length; j++) {
for (let i = 0; i < initList[j].length; i++) {
const [a, b, c] = initList[j][i];
dummy.position.set(j, 99999, b);
dummy.scale.y = 0;
dummy.updateMatrix();
initInstancedMesh.setMatrixAt(k, dummy.matrix);
const color = lut.getColor(Math.abs(c) / initAxis);
initInstancedMesh.setColorAt(k, color);
k++;
}
}
initInstancedMesh.instanceMatrix.needsUpdate = true;
initInstancedMesh.instanceColor.needsUpdate = true;
const object = meshList.getObjectByName('initInstancedMesh');
if (!object) {
meshList.add(initInstancedMesh);
}
initPointsFun()
}
function drawPRPD(list, clear) {
if (clear) {
if (initInstancedPoints) {
for (let i = 0; i < pointCount; i++) {
pointPositions[i * 3 + 1] = 9999999 // Y//移到y轴高出隐藏多余的点
}
// 通知 Three.js 更新 BufferGeometry
pointsGeometry.attributes.position.needsUpdate = true
}
}
const colors = [
{
color: new THREE.Color(0x50A3BA),
num: 5,
},
{
color: new THREE.Color(0x9DB578),
num: 7,
},
{
color: new THREE.Color(0xEAC736),
num: 10,
},
{
color: new THREE.Color(0xE28B4A),
num: 14,
},
];
const range = realTime.monitorType == 1 ? maxRange : false;
const max = range ? initAxis * (range / 100) : initAxis;
list.forEach((item, index) => {
// 更新颜色
const color = item[2] <= 3 ? new THREE.Color(0x0082df) : (item[2] >= 15 ? new THREE.Color(0xD94E5D) : colors.find(i => item[2] <= i.num).color);
pointPositions[index * 3] = 10 // X
pointPositions[index * 3 + 1] = item[1] > max ? max : item[1] // Y
pointPositions[index * 3 + 2] = 360 - item[0] // Z
pointColors[index * 3] = color.r //R
pointColors[index * 3 + 1] = color.g //G
pointColors[index * 3 + 2] = color.b //B
})
for (let i = list.length - 1; i < pointCount; i++) {
pointPositions[i * 3 + 1] = 9999999 // Y//移到y轴高出隐藏多余的点
}
// 通知 Three.js 更新 BufferGeometry
pointsGeometry.attributes.position.needsUpdate = true
pointsGeometry.attributes.color.needsUpdate = true
}
function drawPRPS(data) {
let k = 0;
let list = JSON.parse(JSON.stringify(data))
list = list.map((i) => ({
h: i[2],
color: lut.getColor(Math.abs((i[2]) / initAxis).toFixed(2)),
}))
for (let j = 0; j < period; j++) {
for (let i = 0; i < list.length; i++) {
initInstancedMesh.getMatrixAt(k, dummy.matrix);
dummy.position.setFromMatrixPosition(dummy.matrix);
dummy.scale.setFromMatrixScale(dummy.matrix);
if (dummy.position.x > 0) {
dummy.position.x -= 1;
} else {
let { h, color } = list[i];
dummy.position.x = 49;
dummy.position.y = h == 0 ? 99999 : h / 2;
dummy.scale.y = Math.abs(h);
initInstancedMesh.setColorAt(k, color);
}
dummy.updateMatrix();
initInstancedMesh.setMatrixAt(k, dummy.matrix);
k++;
}
}
initInstancedMesh.instanceMatrix.needsUpdate = true;
initInstancedMesh.instanceColor.needsUpdate = true;
}
9 months ago
// 在页面加载完成后执行WebSocket连接的代码
document.addEventListener('DOMContentLoaded', function () {
//initSocket()
9 months ago
// aaa()
//bbb()
});
function sendMessage() {
let ws = new WebSocket(url); // 替换成你的WebSocket服务器地址
// 当WebSocket连接打开时执行此函数
ws.onopen = function (event) {
ws.send(JSON.stringify({
"type": "sub",
"topic": `/device-message-sender/${productId}/${deviceId}`,
"parameter": {
"messageType": "INVOKE_FUNCTION",
"inputs": realTime,
"functionId": "requestPrpsData",
"headers": {
"async": true
}
},
"id": "request-id"
}))
}
}
//滑动条初始化
function LoadSlide() {
// 相位偏移滑动条
$(".cdf-slide").slider({
orientation: "horizontal",
animate: "slow",
min: -180,
max: 180,
step: 1,
value: 0,
create: function (event, ui) {
$(this).children('.ui-slider-handle').attr('data-content', '相位偏移' + ` 0 ` + '度')
},
slide: function (event, ui) {
$(this).children('.ui-slider-handle').attr('data-content', '相位偏移' + ` ${ui.value} ` + '度');
$(this).attr('data-price', ui.value);
},
change: function (event, ui) {
updateParams('migrationPhase', null, ui.value)
}
});
// 底噪滑动条
$(".noisy-slide.GIS").slider({
orientation: "vertical",
animate: "slow",
min: -80,
max: 0,
step: 1,
value: -80,
create: function (event, ui) {
$(this).children('.ui-slider-handle').attr('data-content', '底噪' + ` -80`)
},
slide(event, ui) {
$(this).children('.ui-slider-handle').attr('data-content', '底噪' + ` ${ui.value}`);
},
change: function (event, ui) {
updateParams('groundNoise', null, 80 + ui.value)
}
});
$(".noisy-slide.GIL").slider({
orientation: "vertical",
animate: "slow",
min: 0,
max: 80,
step: 1,
value: 0,
create: function (event, ui) {
$(this).children('.ui-slider-handle').attr('data-content', '底噪' + ` 0`)
},
slide(event, ui) {
$(this).children('.ui-slider-handle').attr('data-content', '底噪' + ` ${ui.value}`);
},
change: function (event, ui) {
$(this).attr('data-price', ui.value);
if ($(this).parent().parent().parent().hasClass('realdata')) {
realTime.groundNoise = ui.value;
if (socket != '' && socket != null && !$('#adaptive-noise').hasClass("ready")) {
socket.emit('realTimeSet', realTime);
}
}
}
});
}
//更新趋势图谱
function updataHistory(timestamp, realData) {
let time = timestampToTime(timestamp),
data = [[time, (realData.max).toFixed(2)]],
data1 = [[time, realData.count]],
option = box2D6chart.getOption();
if (option.xAxis[0].data.length > clearHistory) {
box2D6chart.setOption({
xAxis: [{
type: 'category',
data: [time],
}],
series: [
{ seriesIndex: 0, data },
{ seriesIndex: 1, data: data1 }
]
})
} else {
box2D6chart.setOption({
xAxis: [{
type: 'category',
data: [...box2D6chart.getOption().xAxis[0].data, time],
}]
})
box2D6chart.appendData({ seriesIndex: 0, data })
box2D6chart.appendData({ seriesIndex: 1, data: data1 })
box2D6chart.resize()
}
}
function initSocket() {
socket = new WebSocket(url); // 替换成你的WebSocket服务器地址
// 当WebSocket连接打开时执行此函数
socket.onopen = function (event) {
console.log('WebSocket连接已打开');
socket.send(JSON.stringify({
"type": "sub",
"topic": `/device/${productId}/${deviceId}/message/property/report`,
"parameter": {
"messageType": "READ_PROPERTY",
},
"id": "request-id"
}));
$('#start').addClass('ready')
$('.record-btn').addClass('ready')
$('#total-time').prop('disabled', false)
sendMessage()
LoadSlide()
};
// 当接收到服务器发送的消息时,执行此函数
socket.onmessage = function (event) {
const data = JSON.parse(event.data);
const { payload: { properties: { realData }, timestamp } } = data
console.log("🚀 data:", data)
9 months ago
if (realData?.lists2d?.length) {
drawEcharts1(null, realData.lists2d);
$('#maxValue').html(`${(realData.max).toFixed(2)}`);
$('#averageValue').html(`${(realData.avg).toFixed(2)}`);
$('#impulseQuantity').html(`${realData.count}`);
updataHistory(timestamp, realData)
}
if (realData?.lists3d?.length) {
drawEcharts1(realData.lists3d);
}
};
// 当WebSocket连接关闭时执行此函数
socket.onclose = function (event) {
console.log('WebSocket连接已关闭');
};
// 当发生错误时,执行此函数
socket.onerror = function (error) {
console.error('WebSocket错误:', error);
};
}
// 时间戳1637244864707
/* 时间戳转换为时间 */
function timestampToTime(timestamp) {
timestamp = timestamp ? timestamp : null;
let date = new Date(timestamp);//时间戳为10位需*1000时间戳为13位的话不需乘1000
let Y = date.getFullYear() + '-';
let M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
let D = (date.getDate() < 10 ? '0' + date.getDate() : date.getDate()) + ' ';
let h = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()) + ':';
let m = (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()) + ':';
let s = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds();
return Y + M + D + h + m + s;
}
function bbb() {
setTimeout(() => {
drawPRPD(generateArray1())
const now = new Date();
const hours = now.getHours();
const minutes = now.getMinutes();
const seconds = now.getSeconds();
//console.log(box2D6chart.series)
const data1 = [[`${hours}:${minutes}:${seconds}`, getRandomInt(-20, -40)], ...box2D6chart.getOption().series[0].data]
//const data2 = [[`${hours}:${minutes}:${seconds}`, getRandomInt(2000, 4400)],...box2D7chart.getOption().series[0].data]
box2D6chart.setOption({ series: [{ type: 'line', data: data1 }] });
bbb()
}, 1000)
}
function aaa() {
setTimeout(() => {
drawPRPS(generateArray());
aaa();
}, 20);
}
//aaa();
// 生成指定范围内的随机整数
function getRandomInt(min, max) {
const randomNumber = Math.random() * (max - min) + min;
const roundedNumber = randomNumber.toFixed(0);
return parseFloat(roundedNumber);
}
//电缆局放折线图更新提交
$('#form-submit').click(function () {
if ($('#realdata').attr('data-id')) {
socket.emit('getFrequencyData', { wl: $('#form-wl').val(), fltr: $('#form-fltr').val() });
}
})
//dom加载完成时
$(window).ready(function () {
$(window).scrollTop(0, 0);
let maxHeight1 = 500, maxHeight = 273
let h = $(window).height();
let w = $(window).width();
$(".loading-box").css('height', h * 0.75)
$(".loading-box-mini").css('height', h * 0.25)
$('.noisy-slide').css('height', h * 0.4)
$('.toggle--checkbox').attr('checked', 'false');
$('.record-btn').removeClass('ready');
$('#total-time').prop('disabled', true)
let isLoad = { command: 'load', win: win }
// title 国际化
window.parent.postMessage(isLoad, '*');
})
// 页面放大缩小时
$(window).resize(function () {
//window.requestAnimationFrame(function () {
9 months ago
onWindowResize()
// })
9 months ago
})
//清空Three中的Point点位
function clearPoints(type) {
// drawPRPS([], true);
drawPRPD([], true);
}
//量程切换
// 实时数据量程修改
$('#original').on('change', function () {
let val = ($(this).val() / 100) * initAxis;
if (maxRange != val) {
clearPoints();
let $this = $(this);
const max = ($this.val() / 100) * initAxis
$this.parent().addClass('is-checked').parent().addClass('is-checked').siblings().removeClass('is-checked').children().removeClass('is-checked')
$("[name='range']:checked").attr("checked", false);
$("[name='range'][value='" + $this.val() + "']").attr("checked", true);
//initAxis = val;
drawAxis(val, 0);
clearPoints()
maxRange = $this.val();
let constant = (360 / (max)) * max + 1
planes[0].constant = constant
}
})
// 打开事件列表
$('.event-btn').on('click', function () {
if ($(this).hasClass('ready')) {
var isFull = !!(document.webkitIsFullScreen || document.mozFullScreen ||
document.msFullscreenElement || document.fullscreenElement
);
if (isFull) {
var dblChoseAlert = simpleAlert({
"content": i18n.message.exitFullScreen + ` `,
"buttons": {
"确定": function () {
dblChoseAlert.close();
}
}
})
} else {
let deviceNum = $('#realdata').attr('data-deviceNum'),
channelNum = $('#realdata').attr('data-chanel'),
name = $('#realdata').attr('data-name');
let data = { command: 'eventList', win: win, deviceNum: deviceNum, channelNum: channelNum, name: name };
window.parent.postMessage(data, '*');
}
}
})
//全屏
$(".charts").on("dblclick", function () {
if (viewIndex == 88) {
window.parent.postMessage({ command: 'closeFullScreen', index: viewIndex }, '*');
} else {
window.parent.postMessage({ command: 'dblClick', index: viewIndex }, '*');
}
})
$("#prps-img").on('click', function () {
// 获取渲染器renderer的canvas然后调用todataurl方法获取数据URI
let dataUrl = renderer.domElement.toDataURL();
console.log("🚀 renderer.domElement:", renderer.domElement)
// 将DataURL转换为Blob对象
let blob = dataURLtoBlob(dataUrl);
// 创建下载链接
let link = document.createElement('a');
link.setAttribute('download', 'PRPS.png');
let url = URL.createObjectURL(blob);
console.log("🚀 url:", url)
link.href = url//.replace('http', 'https');
// 将下载链接添加到HTML页面
document.body.appendChild(link);
// 触发下载链接的单击事件
link.click();
})
function dataURLtoBlob(dataUrl) {
const arr = dataUrl.split(',');
const mime = arr[0].match(/:(.*?);/)[1];
const bstr = atob(arr[1]);
let n = bstr.length;
const u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], { type: mime });
}
$("#prpd-img").on('click', function () {
// 获取渲染器renderer的canvas然后调用todataurl方法获取数据URI
let dataUrl = renderer2D.domElement.toDataURL('image/png');
// 将DataURL转换为Blob对象
let blob = dataURLtoBlob(dataUrl);
// 创建下载链接
let link = document.createElement('a');
link.setAttribute('download', 'PRPD.png');
link.href = URL.createObjectURL(blob);
// 将下载链接添加到HTML页面
document.body.appendChild(link);
// 触发下载链接的单击事件
link.click();
})
//主页面传递事件
window.addEventListener('message', function (e) {
let data = e.data;
window.parent.postMessage(data, '*');
if (data.command == 'i18n') {
viewIndex = viewIndex ? viewIndex : data.index;
$('.phaseOffset').html('相位偏移')
$('.LinkNC').attr('title', '关联噪声传感器降噪')
$('.LinkANC').attr('title', '自适应降噪')
$('#record-btn-box').attr('title', '录波')
$('#toggle-box').attr('title', '开启/暂停')
$('.noise').html('底噪')
// $('.addPointNum').html(CumulativeRBI)
$('.eventList').attr('title', '事件列表')
$('.refreshtitle').attr('title', '刷新')
$('.channelNum .name').html('监测点' + "")
$('.maxValue .name').html('脉冲最大值' + "")
// $('.pc-tip .name').html(discharge + '')
// $('.avgValue .name').html(data.i18n.content.realTime.gil.averageValue + "")
$('.pulseNumber .name').html('脉冲数量' + "")
} else if (data.command == 'setView') {
viewType = data.viewType;
onWindowResize()
} else if (data.command == 'open') {
$('#box3D1').show();
$('#box3D2').hide();
let { id, name, equipmentId, channelNum, monitorType, ipAddress } = data;
$("#range100").click();
$('#model-tab-dl-1').click();
$('#realdata').attr('data-id', id)
$('#realdata').attr('data-name', name)
$('#realdata').attr('data-deviceNum', equipmentId)
$('#realdata').attr('data-chanel', channelNum)
atlasType = 1;
initChangeType(monitorType)
//不一致 切换图谱
if (realTime.monitorType != monitorType) {
realTime.monitorType = monitorType;
changeEcharts(monitorType);
initPointsFun();
}
initCharts('open');
if ($('#realdata').children('.echarts-btn').first().children('.toggle--knob').children('.toggle--checkbox').is(':checked')) {
// console.log("kai----"+data.win)
// console.log(data)
// console.log($('#toggle--knob1'))
$('#toggle--knob1').click()
}
win = data.win;
initRealTime();
} else if (data.command == 'close') {
if ($('#realdata').attr('data-id') == data.id) {
$('#realdata').attr('data-id', '')
$('#realdata').attr('data-name', '')
$('#realdata').attr('data-deviceNum', '')
$('#realdata').attr('data-chanel', '')
$(".noisy-slide").slider({ disabled: false });
if (!$('#realdata').children('.echarts-btn').first().children('.toggle--knob').children('.toggle--checkbox').is(':checked')) {
$('#toggle--knob1').click()
}
$('#channelNum').html('&nbsp;&nbsp;');
$('#maxValue').html("0");
$('#averageValue').html("0");
$('#impulseQuantity').html("0");
// $('#pc-number').html('0');
$('#clear').click();
$('#model-tab-dl-1').click()
$('#associated-noise').addClass('disabled');
$('#adaptive-noise').addClass('disabled');
clearPoints()
win = undefined;
initCharts('close');
}
} else if (data.command == 'historyPRPD') {
} else if (data.command == 'historyPRPS') {
}
})
function changeEcharts(type) {
upDrawAxis(0, 0, type)
if (type == 1) {
$('.unit').html('dBm')
$(".noisy-slide.GIL").fadeOut(() => {
$(".noisy-slide.GIS").fadeIn();
});
// $('.pc-tip').hide();
$('#model-tab-dl').hide();
} else if (type == 2 || type == 3) {
realTime.atlasType = 1;
$('#model-tab button:first-child').addClass('active').siblings().removeClass('active')
$('.unit').html('mV')
$(".noisy-slide.GIS").fadeOut(() => {
$(".noisy-slide.GIL").fadeIn();
});
//$('.pc-tip').hide();
$('#model-tab-dl').hide();
} else if (type == 4) {
atlasType = 1;
$('#model-tab-dl button:first-child').addClass('active').siblings().removeClass('active')
$('.unit').html('mV');
//$('.pc-tip').show();
$('#model-tab-dl').show()
}
}
function initRealTime() {
$('.associated-noise').removeClass('ready');
$('.adaptive-noise').removeClass('ready');
$("#channelFiltering").val(0);
if (realTime.monitorType == 1) {
$(".noisy-slide").slider({ value: -80 });
$(".noisy-slide span").attr('data-content', i18n.content.realTime.gis.noise1 + ' ' + -80);
} else if (realTime.monitorType == 2 || realTime.monitorType == 3) {
$(".noisy-slide").slider({ value: 0 });
$(".noisy-slide span").attr('data-content', i18n.content.realTime.gis.noise1 + ' ' + 0);
}
realTime.channelFiltering = 0;
realTime.cumulativeDot = 1;
realTime.correlationDenoising = 0;
realTime.adaptiveNoise = 0;
realTime.groundNoise = 0;
}
function downloadPng(type) {
let dataUrl = '';
// 获取渲染器renderer的canvas然后调用todataurl方法获取数据URI
if (type) {
dataUrl = renderer.domElement.toDataURL('image/png');
} else {
dataUrl = renderer2D.domElement.toDataURL('image/png');
}
// 将DataURL转换为Blob对象
let blob = new Blob([dataUrl], { type: 'image/png' });
// 创建下载链接
let link = document.createElement('a');
link.setAttribute('download', 'my_scene_image.png');
link.href = URL.createObjectURL(blob);
// 将下载链接添加到HTML页面
document.body.appendChild(link);
// 触发下载链接的单击事件
link.click();
}
//初始化绘制坐标轴文字
function drawAxisText(textMap, type) {
let setTextMap = '';
if (textMap) {
setTextMap = textMap;
} else {
let {
content: {
analyzeDiagnosis: {
analyzeDiagnosis: { amplitude }
},
},
tip: { period, phase, } } = i18n;
let inifo = {
amplitude,
period,
phase,
};
setTextMap = inifo;
}
if (type == 2 || type == 3) {
setTextMap.amplitude = 'mV';
} else if (type == 4) {
setTextMap.amplitude = 'mV';
}
let infoNum = [
{}, {
w: 60,
h: 32,
cw: 9,
ch: 8,
size: 26.3,
}, {}, {
w: 125,
h: 50,
size: 38.3,
}, {
w: 125,
h: 50,
size: 38.3,
},
{
w: 130,
h: 50,
size: 38.3,
}, {}, {}, {
w: 165,
h: 122,
size: 68.3,
},
]
let axisText = [{
type: 'text',
lang: true,
content: 'amplitude',
rotate: 90,
color: '#000000',
size: 30,
font: 'normal Bold 500px Arial,sans-serif',
xyz: [-60, minNum ? 0 : 120, 382],
},
{
type: 'text',
lang: true,
content: 'period',
xyz: [150, -180, 420],
xyz: [minNum ? 250 : 150, minNum ? -220 : -130, 420],
color: '#000000',
size: 30,
font: 'normal Bold 500px Arial,sans-serif',
},
{
type: 'text',
lang: true,
content: 'phase',
color: '#000000',
size: 30,
font: 'normal Bold 500px Arial,sans-serif',
xyz: [500, -110, 140],
},];
let axis2dText = [{
type: 'text',
lang: true,
content: 'amplitude',
rotate: 10,
color: '#000000',
size: 30,
font: 'normal Bold 500px Arial,sans-serif',
xyz: [-20, minNum ? 0 : 180, 405],
},
{
type: 'text',
lang: true,
content: 'phase',
color: '#000000',
size: 30,
font: 'normal Bold 500px Arial,sans-serif',
xyz: [0, minNum ? -265 : -87, 180],
},];
let setList = (list) => {
let newList = [];
for (let i of list) {
let str = setTextMap[i.content];
i.content = [str];
let { w, h, cw, ch, size } = infoNum[str.length - 1]
i.w = i.rotate ? h : w;
i.h = i.rotate ? w : h;
i.cw = i.rotate ? ch : cw;
i.ch = i.rotate ? cw : ch;
i.size = size;
if (i.rotate) {
i.xyz[2] = 445 + size / 2;
}
newList.push(draw2DText(i))
}
return newList
}
axisTextGroup.children.length && axisTextGroup.remove(...axisTextGroup.children)
axisTextGroup.add(...setList(axisText))
axisTextGroup2D.children.length && axisTextGroup2D.remove(...axisTextGroup2D.children)
axisTextGroup2D.add(...setList(axis2dText))
}
//根据坐标轴类型更新坐标轴
function upDrawAxis(max, min, type) {
if (!type) {
initAxis = max; minNum = min; drawAxis(initAxis, minNum);
return;
}
if (type == 1) {
initAxis = 80; minNum = 0;
drawAxis(initAxis, minNum);
} else if (type == 3 || type == 2) {
initAxis = 500; minNum = 0;
drawAxis(initAxis, minNum)
} else if (type == 4) {
initAxis = 2000; minNum = -2000;
drawAxis(initAxis, minNum);
}
drawAxisText(0, type);
// onWindowResize()
9 months ago
planes[0].constant = (360 / (initAxis)) * initAxis + 1
}
renderer.domElement.addEventListener('webglcontextlost', handleContextLost, false);
function handleContextLost(event) {
event.preventDefault();
init();
}
renderer2D.domElement.addEventListener('webglcontextlost', handleContextLost2, false);
function handleContextLost2(event) {
event.preventDefault();
init2D();
}
function handleVisibilityChange() {
if (document.hidden) {
// 页面被最小化或切换应用程序,暂停渲染并清除 InstancedMesh 相关资源
instancedMesh.dispose();
} else {
// 页面重新显示,重新创建 WebGL 上下文并重新设置 InstancedMesh
init();
}
}
//prps初始化
function init() {
let box = $('#box3D1');
let width = box.width();
let height = box.height();
9 months ago
renderer = new THREE.WebGLRenderer({ logarithmicDepthBuffer: true, antialias: true, preserveDrawingBuffer: true, });//preserveDrawingBuffer保存three.js canvas画布上的信息
renderer.localClippingEnabled = true
let constant = (360 / (initAxis)) * initAxis + 1
planes = [
new THREE.Plane(new THREE.Vector3(0, -1, 0), constant), //y轴正值截取
]
renderer.clippingPlanes = planes
renderer.setSize(width, height);//设置渲染区域尺寸
renderer.setClearColor(0xffffff, 1); //设置背景颜色
//renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
renderer.setPixelRatio(window.devicePixelRatio)//设备像素比,优化渲染效果
box?.append(renderer.domElement); //body元素中插入canvas对象
scene = new THREE.Scene();
scene.add(meshList, axis, pointsList, axisTextGroup);
/* var point = new THREE.PointLight(0xffffff);
point.position.set(600, 600, 600); //点光源位置
scene.add(point); //点光源添加到场景中
var ambient = new THREE.AmbientLight(0x444444);
scene.add(ambient); */
drawAxis(initAxis, minNum, true)
var k = width / height; //窗口宽高比
var s = 420; //三维场景显示范围控制系数,系数越大,显示的范围越大
//创建相机对象
camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1600);
camera.position.set(500, 200, 500); //设置相机位置
camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
controls = new THREE.OrbitControls(camera, renderer.domElement);
// 设置左右方向的最大、最小角度限制为 90 度和 0 度
controls.minAzimuthAngle = 0;
controls.maxAzimuthAngle = Math.PI / 2;
// 设置上下方向的最大、最小角度限制为 90 度和 0 度
controls.minPolarAngle = 0;
controls.maxPolarAngle = Math.PI / 2;
//设置放大缩小上下限
controls.minZoom = 0.5;
controls.maxZoom = 2;
//controls.enablePan = false;
//设置控制器中心点
controls.target.set(25, 0, 180);
renderer.render(scene, camera);
//controls.addEventListener('change', render);
}
//prpd初始化
function init2D() {
let box = $('#box2D1');
let width = box.width();
let height = box.height();
renderer2D = new THREE.WebGLRenderer({ logarithmicDepthBuffer: true, antialias: true, preserveDrawingBuffer: true, });//preserveDrawingBuffer保存three.js canvas画布上的信息\
renderer2D.localClippingEnabled = true
let constant = (360 / (initAxis)) * initAxis + 1
planes = [
new THREE.Plane(new THREE.Vector3(0, -1, 0), constant), //y轴正值截取
]
renderer2D.clippingPlanes = planes
renderer2D.setSize(width, height);//设置渲染区域尺寸
renderer2D.setClearColor(0xffffff, 1); //设置背景颜色
renderer2D.setPixelRatio(window.devicePixelRatio)//设备像素比,优化渲染效果
box?.append(renderer2D.domElement); //body元素中插入canvas对象
scene2D = new THREE.Scene();
const List = pointsList.clone()
scene2D.add(axis2D, List, axisTextGroup2D, pointsList)
drawAxis2D(initAxis, minNum)
// 辅助坐标系 参数250表示坐标系大小可以根据场景大小去设置
// let axisHelper = new THREE.AxesHelper(250);
// scene2D.add(axisHelper);
var k = width / height; //窗口宽高比
var s = 380; //三维场景显示范围控制系数,系数越大,显示的范围越大
//创建相机对象
camera2D = new THREE.OrthographicCamera(-s * k - 200, s * k - 200, s + 160, -s + 160, 1, 1200);
camera2D.position.set(600, 0, 0); //设置相机位置
camera2D.lookAt(scene2D.position); //设置相机方向(指向的场景对象)
controls2D = new THREE.OrbitControls(camera2D, renderer2D.domElement);
controls2D.enablePan = false//右键位移禁用
controls2D.enableZoom = false//放大缩小禁用
//设置放大缩小上下限
controls2D.minZoom = 0.5;
controls2D.maxZoom = 2;
controls2D.enableRotate = false
renderer2D.render(scene2D, camera2D);
controls2D.addEventListener('change', render2D);
}
function onWindowResize() {
if (viewType == 1 || viewType == 2) {//全功能PrpsAndPrpd
let h = $(window).height();
$(".loading-box").css('height', h * 0.65)
$(".loading-box-mini").css('height', h * 0.35)
$('.noisy-slide').css('height', h * 0.4)
$('#realdata').show();
$('.noisy-slide-box').show();
$('#echarts-text').show();
$('#addPointNumDiv').show();
$('#box3D1').show();
$('#box2D1').hide();
$('#box2D6').show();
9 months ago
} else if (viewType == 3) {//实时数据仅展示prpd
let h = $(window).height();
$(".loading-box").css('height', h)
9 months ago
$('#realdata').hide();
$('.noisy-slide-box').hide();
$('#echarts-text').hide();
$('#addPointNumDiv').hide();
$('#box3D1').hide();
$('#box2D1').show();
$('#box2D6').hide();
9 months ago
} else if (viewType == 4) {//历史趋势仅展示prps
let h = $(window).height();
$(".loading-box").css('height', h * 0.9)
$('#realdata').hide();
$('.noisy-slide-box').hide();
$('#echarts-text').hide();
$('#addPointNumDiv').hide();
$('#box3D1').hide();
$('#box2D1').show();
} else if (viewType == 5) {//历史趋势仅展示prpd
let h = $(window).height();
$(".loading-box").css('height', h * 0.9)
9 months ago
$('#realdata').hide();
$('.noisy-slide-box').hide();
$('#echarts-text').hide();
$('#addPointNumDiv').hide();
$('#box3D1').hide();
$('#box2D1').show();
}
if (echarts.getInstanceByDom(box2D6) != null) {
9 months ago
box2D6chart.resize();
}
9 months ago
let box = $('#box3D1');
let width = box.width();
let height = box.height();
//console.log("🚀 height:",width, height)
9 months ago
let k = width / height; //窗口宽高比
let s = 350; //三维场景显示范围控制系数,系数越大,显示的范围越大
camera.left = -s * k - 20;
camera.right = s * k - 20;
camera.top = s + (minNum ? -80 : 60);
camera.bottom = -s + (minNum ? -80 : 60);
camera.aspect = k;
camera.updateProjectionMatrix();
renderer.setSize(width, height);
renderer.setPixelRatio(window.devicePixelRatio)//设备像素比,优化渲染效果
let s2D = 270;
camera2D.left = -s2D * k - 200;
camera2D.right = s2D * k - 200;
camera2D.top = s2D + (minNum ? -30 : 155);
camera2D.bottom = -s2D + (minNum ? -30 : 155);
camera2D.aspect = k;
camera2D.updateProjectionMatrix();
renderer2D.setSize(width, height);
renderer2D.setPixelRatio(window.devicePixelRatio)//设备像素比,优化渲染效果
}
function render() {
// 获取摄像机的视锥体
const frustum = new THREE.Frustum();
const cameraViewProjectionMatrix = new THREE.Matrix4();
camera.updateMatrixWorld(); // 确保摄像机的世界矩阵已更新
cameraViewProjectionMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
frustum.setFromProjectionMatrix(cameraViewProjectionMatrix);
// 遍历场景中的每个对象,并根据视锥体进行剔除
scene.traverse((object) => {
if (object.isMesh) {
object.visible = frustum.intersectsObject(object);
}
});
// 更新帧率显示器
//stats.update();
renderer.render(scene, camera);
requestAnimationFrame(render)
}
function render2D() {
//scene.rotateY(0.001);//每次绕y轴旋转0.01弧度
requestAnimationFrame(render2D)
renderer2D.render(scene2D, camera2D);
}
function initChangeType(monitorType) {
gilSwitchChart(1)
cpdSwitchChart(1)
upDrawAxis(0, 0, monitorType)
if (monitorType == 1) {
//$('.avgValue').fadeOut()
$('#model-tab').fadeOut(() => {
$('#channelFiltering').fadeIn()
$('.pm-slide-box').fadeIn()
$('#associated-noise-box').fadeIn()
// $('#record-btn-box').fadeIn()
$('#toggle-box').fadeIn()
$('.noisy-slide-box').fadeIn()
$('.radiogroup').fadeIn()
$('.cdf-slide-box').fadeIn()
$('.eventList').fadeIn()
$('.refreshtitle').fadeIn()
$('#associated-noise').removeClass('disabled');
$('#adaptive-noise').removeClass('disabled');
$(".noisy-slide").slider({ disabled: false });
$("#channelFiltering").val(0);
$('.monitorType').html('UHF')
})
} else if (monitorType == 2 || monitorType == 3) {
$('#channelFiltering').fadeOut(() => {
$('#model-tab').fadeIn()
if (realTime.atlasType == 1) {
$('#model-tab button:first-child').addClass('active').siblings().removeClass('active')
} else if (realTime.atlasType == 2) {
$('#model-tab button:nth-child(2)').addClass('active').siblings().removeClass('active')
} else {
$('#model-tab button:last-child').addClass('active').siblings().removeClass('active')
$('.cdf-slide-box').fadeOut()
$('.noisy-slide-box').fadeOut()
}
})
$('.pm-slide-box').fadeOut()
$('#associated-noise-box').fadeOut()
// $('#record-btn-box').fadeOut()
// $('#toggle-box').fadeOut()
$('.radiogroup').fadeOut()
// $('.eventList').fadeOut()
$('.refreshtitle').fadeOut()
//$('.avgValue').fadeIn()
$('.avgValue .name').html(i18n.content.realTime.gil.averageValue + "")
$('.monitorType').html('AE')
$('#line-btn-box').hide();
$('#form-line').hide();
} else if (monitorType == 4) {
$('#channelFiltering').fadeOut()
$('.pm-slide-box').fadeOut()
$('#associated-noise-box').fadeOut()
// $('#record-btn-box').fadeOut()
// $('#toggle-box').fadeOut()
$('.noisy-slide-box').fadeOut()
$('.radiogroup').fadeOut()
$('.refreshtitle').fadeOut()
$('#model-tab').fadeOut()
$('.cdf-slide-box').fadeIn()
$('.eventList').fadeIn()
//$('.avgValue').fadeIn()
$('.avgValue .name').html(i18n.content.realTime.gis.averageValue + "")
$('.monitorType').html('HFCT')
}
}
// 图表绘制
function drawEcharts1(list1, list2) {
// monitorType GIS 1 GIL故障定位 2 GIL局放 3 电缆 4
// atlasType 1 PRPS/PRPD 2 飞行模式/脉冲数据 3 连续模式
if (list1?.length) {
drawPRPS(list1)
}
if (list2?.length) {
drawPRPD(list2)
}
}
export { scene, axis, meshList, pointsList, axis2D, scene2D, i18n, }