[Frontend][全域功能] Loading 圖示更換 | [系統監控] 電梯 urn 全域變數建置 | [儀錶板] 連動 urn | [系統監控] 移動時建築物半透明 | 電梯變色程序放入

This commit is contained in:
dev01 2022-12-07 18:59:53 +08:00
parent c68068909b
commit 063ba840e6
7 changed files with 287 additions and 130 deletions

View File

@ -12,7 +12,7 @@
<div class="p-3 bg-primary-300 rounded overflow-hidden position-relative text-white mb-g">
<div class="">
<h3 class="display-4 d-block l-h-n m-0 fw-500">
<span id="todayUseElec"></span>
<span id="todayUseElec">--</span>
<small class="m-0 l-h-n">今日用電量 kWH</small>
</h3>
</div>
@ -23,7 +23,7 @@
<div class="p-3 bg-warning-400 rounded overflow-hidden position-relative text-white mb-g">
<div class="">
<h3 class="display-4 d-block l-h-n m-0 fw-500">
<span id="yesUseElec"></span>
<span id="yesUseElec">--</span>
<small class="m-0 l-h-n">昨日用電量</small>
</h3>
</div>
@ -74,7 +74,7 @@
<div class="p-3 bg-success-200 rounded overflow-hidden position-relative text-white mb-g">
<div class="">
<h3 class="display-4 d-block l-h-n m-0 fw-500">
<span id="insPower"></span>
<span id="insPower">--</span>
<small class="m-0 l-h-n">即時功率</small>
</h3>
</div>
@ -347,13 +347,15 @@
let loadedCnt = 0;
/* let batch = new baja.comm.Batch();*/
startPageLoading();
//// 今日用電量
// 今日用電量
getElectricMeterDayDataByBaja(devNum + "_KWH", "Mitsubishi_Sup", today, tomorrow, (data) => {
$("#todayUseElec").text(data?.data[0]?.sum || 0);
let result = data?.data[0]?.sum;
result = result ? parseFloat(result).toFixed(2) : 0;
$("#todayUseElec").text(result);
chkBajaLoaded();
})
//// 今日用電量 (每小時)
// 今日用電量 (每小時)
getElectricMeterHourDataByBaja(devNum + "_KWH", "Mitsubishi_Sup", yesterday, tomorrow, (data) => {
let todayData = data.data.filter(x => x.timestamp.$date.$year == getTimeByType("year") && x.timestamp.$date.$month == getTimeByType("month") && x.timestamp.$date.$day == getTimeByType("date"));
@ -364,11 +366,13 @@
// 昨日用電量
getElectricMeterDayDataByBaja(devNum + "_KWH", "Mitsubishi_Sup", yesterday, today, (data) => {
$("#yesUseElec").text(data?.data[0]?.sum || 0);
let result = data?.data[0]?.sum;
result = result ? parseFloat(result).toFixed(2) : 0;
$("#yesUseElec").text(result);
chkBajaLoaded();
})
//// 本週與上週用電量 (每天)
// 本週與上週用電量 (每天)
getElectricMeterDayDataByBaja(devNum + "_KWH", "Mitsubishi_Sup", prevTwoWeek, tomorrow, (data) => {
let curDay = (new Date()).getDay() == 0 ? 7 : (new Date()).getDay();
let curWeekData = data.data.filter(x => strToDate(displayDate(new Date(), "date"), null, 0 - (curDay - 1)) <= strToDate(x.timestamp.$cEncStr));
@ -378,11 +382,12 @@
chkBajaLoaded();
})
//// 電表即時功率
// 電表即時功率
getElectricMeterNoweDataByBaja(devPath, (data) => {
console.log(data)
data = data.data;
$("#insPower").text(data.filter(x => x.name == "P")[0]?.value);
let result = data.filter(x => x.name == "P")[0]?.value;
result = result ? parseFloat(result).toFixed(2) : 0;
$("#insPower").text(result);
chkBajaLoaded();
})
@ -436,7 +441,7 @@
borderColor: color.success._500,
pointColor: color.success._500,
pointBackgroundColor: color.main1,
data: todayData?.data.map(x => x.sum || YT.Math.Random(100, 1000)),
data: todayData?.data.map(x => x.sum),
order: 1,
},
{
@ -448,7 +453,7 @@
borderColor: color.info._100,
pointColor: color.info._100,
pointBackgroundColor: color.info._100,
data: yesData?.data.map(x => x.sum || YT.Math.Random(100, 1000)),
data: yesData?.data.map(x => x.sum),
order: 2,
}
]
@ -514,7 +519,7 @@
borderColor: color.success._500,
pointColor: color.success._500,
pointBackgroundColor: color.success._500,
data: curWeekData.map(x => x.sum || YT.Math.Random(100, 1000)),
data: curWeekData.map(x => x.sum),
order: 1,
},
{
@ -526,7 +531,7 @@
borderColor: color.info._100,
pointColor: color.info._100,
pointBackgroundColor: color.info._100,
data: prevWeekData.map(x => x.sum || YT.Math.Random(100,1000)),
data: prevWeekData.map(x => x.sum),
order: 2,
}
]
@ -705,6 +710,8 @@
function show3DModel() {
launchViewer('dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6dGEzaHFzZmZ6cWJub3V4a3BsZGt1a3NldzRzajIxdzUtYmltc19tb2RlbHMvJUUzJTgwJTkwJUU1JThGJUIwJUU1JThDJTk3JUU0JUI4JUFEJUU4JThGJUIxJUU1JUE0JUE3JUU2JUE4JTkzJUUzJTgwJTkxQVJDMjAyMjEyMDEubndk');
launchViewer(pageAct.urn, (viewer, nodeIds) => {
console.log("nodeIds",nodeIds)
});
}
</script>

View File

@ -861,7 +861,7 @@
var subSeviceData = []; //每個設備訂閱點位值
var floList = []; //每個樓層
var elevObj = null; //左側 2D 電梯物件
var viewer3DNodeIds = [12115, 12109, 12103];
var viewer3DNodeIds = [];
var elev3DBind = {};
var elev3DOption = {};
var elev3DObj = [];
@ -992,10 +992,10 @@
let subData = subSeviceData.filter(x => x.device_number == devNum)[0];
if (subData) {
// 左側 3D 電梯 nodeID 與 device_number match
if (Object.keys(elev3DBind).indexOf(devNum) == -1) {
elev3DBind[devNum] = viewer3DNodeIds[Object.keys(elev3DBind).length];
}
//// 左側 3D 電梯 nodeID 與 device_number match
//if (Object.keys(elev3DBind).indexOf(devNum) == -1 && viewer3DNodeIds.length != 0) {
// elev3DBind[devNum] = viewer3DNodeIds[Object.keys(elev3DBind).length];
//}
// 左側 3D 電梯 Viewer Option 設置
/*elev3DOption.nodes = Object.keys(elev3DBind).map(x => elev3DBind[x]);*/
elev3DOption.nodeId = elev3DBind[devNum];
@ -1015,7 +1015,7 @@
}
}
})
debugger
if (isFirstLoad3D == false && elev3DObj.length != 0) {
let elevObj = elev3DObj.filter(x => x.nodeId == elev3DBind[devNum])[0];
if (!elevObj.id) {
@ -2403,9 +2403,13 @@
//載入3D模型
function load3DModel() {
launchViewer('dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6LW1vZGVsX3Rlc3QxMTIxLyVFMyU4MCU5MCVFNSU4RiVCMCVFNSU4QyU5NyVFNCVCOCVBRCVFOCU4RiVCMSVFNSVBNCVBNyVFNiVBOCU5MyVFMyU4MCU5MUFSQ18yMDIyMTIwNS5ud2Q', (viewer) => {
$.each(viewer3DNodeIds, function (idx, node) {
launchViewer(pageAct.urn, (viewer, nodeIds) => {
nodeIds = Array.from(nodeIds);
$.each(nodeIds, (idx, item) => {
elev3DBind[item[0]] = item[1];
})
nodeIds = nodeIds.map(x => x[1]);
$.each(nodeIds, function (idx, node) {
let options = {
element: $("#forgeViewer"),
viewer: viewer,

View File

@ -63,53 +63,99 @@ label[id$='-error'].error {
/* checkbox switch */
input.toggle:checked::before {
content: '';
position: absolute;
top: 2px;
left: 24px;
display: block;
border-radius: 25px;
width: 20px;
height: 20px;
background: #3f8635;
content: '';
position: absolute;
top: 2px;
left: 24px;
display: block;
border-radius: 25px;
width: 20px;
height: 20px;
background: #3f8635;
}
input.toggle::before {
content: '';
position: absolute;
top: 2px;
left: 3px;
display: block;
border-radius: 25px;
width: 20px;
height: 20px;
background: #656565;
transition: 0.2s;
content: '';
position: absolute;
top: 2px;
left: 3px;
display: block;
border-radius: 25px;
width: 20px;
height: 20px;
background: #656565;
transition: 0.2s;
}
input.toggle {
cursor:pointer;
appearance: none;
position:relative;
width: 48px;
height: 24px;
background: #464646;
border-radius: 50px;
align-content: center;
cursor: pointer;
appearance: none;
position: relative;
width: 48px;
height: 24px;
background: #464646;
border-radius: 50px;
align-content: center;
}
input.toggle:checked {
background: #97c193;
background: #97c193;
}
.loading-bg {
background: #0000009c;
background-repeat: no-repeat;
opacity:0;
opacity: 0;
width: 100%;
height: 100vh;
position: fixed;
z-index: 2000;
}
.lds-ring {
display: inline-block;
position: relative;
width: 25px;
height: 25px;
margin-right:0.8rem;
}
.lds-ring div {
top: -4px;
box-sizing: border-box;
display: block;
position: absolute;
width: 25px;
height: 25px;
margin: 6px;
border: 6px solid #fff;
border-radius: 50%;
animation: lds-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
border-color: #fff transparent transparent transparent;
}
.lds-ring div:nth-child(1) {
animation-delay: -0.45s;
}
.lds-ring div:nth-child(2) {
animation-delay: -0.3s;
}
.lds-ring div:nth-child(3) {
animation-delay: -0.15s;
}
@keyframes lds-ring {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
@keyframes flashing-c {
0% {
color: var(--flash-color-1);
@ -437,7 +483,7 @@ input.toggle:checked {
}
.bg-orange {
background-color:#ffa100;
background-color: #ffa100;
}
/* text color */
@ -488,13 +534,3 @@ input.toggle:checked {
.t-yellow {
color: var(--yt-yellow-1);
}
.custom-select-ri {
-moz-appearance: none;
-webkit-appearance: none;
appearance: none;
}
.custom-radio-input {
vertical-align: middle;
}

View File

@ -2167,7 +2167,7 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
} else {
isValidLogin();
}
showMainSys();
$(loadEle).Loading("close");
}
@ -2177,6 +2177,7 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
function isValidLogin() {
$("#app").load("_dashboard.html", loadCallback);
showMainSys();
getBuiList();
getSysMonBtnList();
checkDevState();
@ -2216,7 +2217,7 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
} else {
let strHtml = ``;
$.each(res.data, (index, buiObj) => {
strHtml += `<a id="buiBtn${buiObj.building_tag}" class="dropdown-item" href="javascript:;">${buiObj.full_name}</a>`;
strHtml += `<a id="buiBtn${buiObj.building_tag}" data-urn="${buiObj.urn_3D}" class="dropdown-item" href="javascript:;">${buiObj.full_name}</a>`;
})
$("#buiList").append(strHtml).droSetItem(); //droSetItem 預設第一筆 active
}
@ -2299,6 +2300,7 @@ License: You must have a valid license purchased only from wrapbootstrap.com (li
onEvent("active:change", "#buiList", function (e, actEle) {
if (actEle) {
pageAct.buiTag = $(actEle).prop("id").split("buiBtn")[1];
pageAct.urn = $(actEle).data("urn");
}
})

View File

@ -63,8 +63,8 @@ function launchViewer(urn, callback) {
Autodesk.Viewing.Document.load(documentId, onDocumentLoadSuccess, onDocumentLoadFailure);
$("#forgeViewer").on("autodesk:loaded", function () {
callback ? callback(viewer) : "";
$("#forgeViewer").on("autodesk:loaded", function (e,nodeIds) {
callback ? callback(viewer, nodeIds) : "";
})
@ -140,22 +140,11 @@ class elevator3D {
setTreeFrag = function (callback) {
let tree = this.viewer.model.getData().instanceTree;
let nodeId = this.nodeId;
//tree.enumNodeChildren(nodeId, (node) => {
// nodeId = node;
// tree.enumNodeFragments(nodeId, (frag) => {
// this.fragProxy = this.viewer.impl.getFragmentProxy(this.viewer.model, frag);
// this.fragProxy.getAnimTransform();
// let fragPosition = new THREE.Vector3(0, 0, 0);// 一樓0 二樓15 三樓 26
// this.fragProxy.position = fragPosition
// this.fragProxy.updateAnimTransform()
// });
//})
if (nodeId) {
let childCnt = tree.getChildCount(nodeId);
let curIdx = 1;
this.fragProxys.filter(x => x.nodeId == nodeId).forEach((x) => {
let idx = this.fragProxys.indexOf(x);
this.fragProxys.splice(idx,1);
@ -207,16 +196,28 @@ class elevator3D {
if (!fragProxy) {
return;
}
changeColor(nodeId);
console.log("movStatus:" + movStatus, "fragProxy.position.z:" + fragProxy.position.z.roundDecimal(2), "targetFloorZ:" + this.targetFloorZ.roundDecimal(2))
//if ((movStatus == 2 && fragProxy.position.z.roundDecimal(2) < this.targetFloorZ.roundDecimal(2)) ||
// (movStatus == 1 && fragProxy.position.z.roundDecimal(2) > this.targetFloorZ.roundDecimal(2)) ||
// fragProxy.position.z.roundDecimal(2) == this.targetFloorZ.roundDecimal(2)) {
// this.movStatus = 0;
// recoverTransparentBuilding();
// hideColor(nodeId);
// return;
//}
if (fragProxy.position.z > this.targetFloorZ) {
movStatus = 2
}
else if (fragProxy.position.z < this.targetFloorZ) {
movStatus = 1
}
//if (movStatus == 0) {
// recoverTransparentBuilding();
// return;
//}
if (movStatus == 0) {
return;
if (fragProxy.position.z.roundDecimal(2) > this.targetFloorZ.roundDecimal(2)) {
this.movStatus = 2;
}
else if (fragProxy.position.z.roundDecimal(2) < this.targetFloorZ.roundDecimal(2)) {
this.movStatus = 1;
}
tree.enumNodeFragments(nodeId, (frag) => {
@ -236,12 +237,23 @@ class elevator3D {
}, true);
this.viewer.impl.sceneUpdated(true);
setTransparentBuilding();
let movElevator = $(this.ele)[0]._elevator3D.filter(x => x.nodeId == this.nodeId)[0]?.obj.movElevator.bind(this);
console.log("fragProxyZ:" + fragProxyZ, "targetFloorZ:" + this.targetFloorZ)
if (movStatus == 2) {
if (fragProxyZ >= this.targetFloorZ) {
requestAnimationFrame(() => {
movElevator();
});
} else {
this.movStatus = 0;
recoverTransparentBuilding();
hideColor(nodeId);
return;
}
}
else if (movStatus == 1) {
@ -249,9 +261,14 @@ class elevator3D {
requestAnimationFrame(() => {
movElevator();
});
} else {
this.movStatus = 0;
recoverTransparentBuilding();
hideColor(nodeId);
return;
}
}
//let fragPosition = new THREE.Vector3(position);// 一樓0 二樓15 三樓 26
@ -276,49 +293,69 @@ function onDocumentLoadSuccess(doc, eleOption) {
// });
viewer.addEventListener(Autodesk.Viewing.GEOMETRY_LOADED_EVENT, function () {
//var instanceTree = viewer.model.getData().instanceTree;
//var allDbIdsStr = Object.keys(instanceTree.nodeAccess.dbIdToIndex);
//var domElem = document.getElementById('all_id');
//domElem.innerText = allDbIdsStr;
//let nodes = eleOption.nodes ?? [];
//let element = eleOption.element ?? "";
//$(element)[0]._elevator3D = [];
//$.each(nodes, function (idx, node) {
// let options = {
// element: $(element),
// viewer: viewer,
// nodeId: node,
// floorHeight: eleOption.floorHeight ?? [],
// inited: function () {
// if (idx == nodes.length - 1) {
// $(element).trigger("autodesk:loaded");
// }
// }
// }
// let elevator3DObj = new elevator3D(options);
//})
$("#forgeViewer").trigger("autodesk:loaded");
//let tree = viewer.model.getData().instanceTree;
//let nodeId = 10952;
//console.log("tree", tree)
//tree.enumNodeFragments(nodeId, function (frag) {
// fragProxy = viewer.impl.getFragmentProxy(viewer.model, frag);
// fragProxy.getAnimTransform();
// let fragPosition = new THREE.Vector3(0, 0, 0);// 一樓0 二樓15 三樓 26
// fragProxy.position = fragPosition
// fragProxy.updateAnimTransform()
//});
//viewer.impl.sceneUpdated(true);
//$("#forgeViewer").trigger("autodesk:loaded");
let instanceTree = viewer.model.getData().instanceTree;
console.log(instanceTree.nodeAccess)
allDbIdsStr = Object.keys(instanceTree.nodeAccess.dbIdToIndex);
getNodeIdByDbIds(allDbIdsStr, (nodeIds) => {
$("#forgeViewer").trigger("autodesk:loaded", nodeIds );
});
});
}
function getNodeIdByDbIds(allDbIdsStr,callback) {
let curDbId = 0;
let tagId = 0;
let _parentId = 0;
let _childId = 0;
let evelMap = new Map();
let finTimeout = null;
allDbIdsStr.forEach((dbId) => {
curDbId = parseInt(dbId);
viewer.getProperties(curDbId, function (e) {
e.properties.forEach(function (item, idx) {
if (item.displayName == "tag_id" && e.name == "【電梯】") {
tagId = e.dbId;
viewer.getProperties(tagId, function (e2) {
e2.properties.forEach(function (item2, idx2) {
if (item2.displayName == "child") {
_parentId = item2.displayValue;
viewer.getProperties(_parentId, function (e3) {
//var childIdArr = new Array();
/*childIdArr.push(_parentId)*/
//e3.properties.forEach(function (item3, idx3) {
// if (item3.displayName == "child") {
// _childId = item3.displayValue;
// childIdArr.push(_childId);
// }
//});
evelMap.set(item.displayValue, e3.dbId)
console.log("map: " + evelMap);
clearTimeout(finTimeout)
finTimeout = setTimeout(() => {
callback ? callback(evelMap) : "";
}, 10)
})
}
});
})
}
});
})
})
return evelMap;
}
function setElevatorFloor(floor) {
if (floor == 0)
targetFloorZ = 0;
@ -471,3 +508,64 @@ async function loadHeatmaps(model) {
const floorName = "01 - Entry Level";
dataVizExtn.renderSurfaceShading(floorName, sensorType, getSensorValue);
}
function setTransparentBuilding() {
//allDbIdsStr.forEach((dbId) => {
// setTransparency(dbId, 0.2);
//})
for (var i = 0; i < allDbIdsStr.length; i++) {
setTransparency(parseInt(allDbIdsStr[i]), 0.2);
}
}
function recoverTransparentBuilding() {
//allDbIdsStr.forEach((dbId) => {
// setTransparency(dbId, 1);
//})
for (var i = 0; i < allDbIdsStr.length; i++) {
setTransparency(parseInt(allDbIdsStr[i]), 1);
}
}
//設定模型 透明度
function setTransparency(nodeId, opacity) {
var model = viewer.model;
//var nodeId = 1633;
var fragList = viewer.model.getFragmentList();
var fragIds = []
model.getData().instanceTree.enumNodeFragments(
nodeId, (fragId) => {
fragIds.push(fragId)
});
fragIds.forEach((fragId) => {
//获取材质
var material = fragList.getMaterial(fragId);
if (material) {
//设置透明度
material.opacity = opacity;//0.5;
material.transparent = true;
//标记更新
material.needsUpdate = true;
}
})
//更新viewer
viewer.impl.invalidate(true, true, true);
}
function changeColor(nodeId) {//電梯變綠色
var color = new THREE.Vector4(0, 1, 0, 1);
viewer.setThemingColor(nodeId, color);
}
function hideColor(nodeId) {//顏色改成透明
var color = new THREE.Vector4(0, 1, 0, 0);
viewer.setThemingColor(nodeId, color);
}

View File

@ -29,6 +29,10 @@ $.fn.SetDropDown = function (eleObj, divObj) {
$("#" + eleObj.dropdownId).find(".dropdown-item-checkbox input:checked").trigger("click", "init");
}
Number.prototype.roundDecimal = function (precision) {
return Math.round(Math.round(this * Math.pow(10, (precision || 0) + 1)) / 10) / Math.pow(10, (precision || 0));
}
Array.prototype.Distinct = function () {
return this.filter((value, index, self) => { return self.indexOf(value) === index; });
}

View File

@ -55,10 +55,16 @@ YT.Alert.Error = function (text) {
}
YT.Alert.Tip = function (text, type = null, color = null) {
YT.Alert.Tip = function (text, type = null,isLoading = true, color = null) {
let ranId = Math.floor(Math.random() * 100000);
let iconHtml = "";
if (isLoading) {
iconHtml = `<div class="lds-ring"><div></div><div></div><div></div><div></div></div>`;
} else {
iconHtml = `<span class="material-icons fs-3">error</span>`;
}
$("body").append(`<div id='tip-alert-${ranId}' class='alert alert-dismissible yt-alert shadow-lg fade show' role = 'alert' style='display:none;'>
<span class="material-icons fs-3">error</span><strong id="alert-text-${ranId}">${text}</strong></div>`)
${iconHtml}<strong id="alert-text-${ranId}">${text}</strong></div>`)
alertIdArray.push("tip-alert-" + ranId);
alertIdArray.length > 2 ? alertIdArray.shift() : ""