3D 可視化,就是把複雜抽象的數據信息,以合適的視覺元素及視角去呈現,方便系統的展現、維護和管理。而在可視化系統的搭建選擇上,所呈現的風格樣式效果多種多樣,各自所突出的適用場合也不盡相同。對於科技風格上的體現, 線框模式 多是最具備表明性意義的實現方式之一。 機房數據可視化 的管控維護的實現上,在 工業互聯網 的推進下,體現的維護數據和系統搭建也愈來愈多樣化,而 Hightopo(如下簡稱 HT )的 HT for Web 產品上的有着豐富的組態化可供選擇,本文將介紹如何運用 HT 豐富的 2/3D 組態 搭建出一個線框樓宇可視化機房的解決方案。html
主頁面的呈現上以線框的科技風格爲主的大樓設計,大樓環繞着數字飛昇的光柱,場外分佈着車流穿梭效果和停車場的模擬實現,其中數據中心上有着許多個設備的展現處理以及設備的預警處理,主體辦公大樓側邊並列呈現着樓層的分佈——辦公樓層場景以及機房樓層場景;切換到內場景中的機房場景,展現了機房設備羣的排列,單擊選中機櫃會視角轉化到此設備上,而且虛化周圍設備,展現出所點擊的機櫃信息,同時還具有一鍵切換查看機櫃的利用率信息;另一個內場景辦公室,則起到了展現平常辦公的應用場景,能夠添加維護的信息數據來管理。node
縱觀在工業互聯網的推進下,機房可視化系統的發展是極爲重要的一環。而3D可視化做爲一個可進行交互式、帶有多種視覺模擬體驗的機房管理平臺,其具備機房資產、能源、環境等管理功能,對機房全方面集中監控、統一管理。這是做爲機房內部數據監控的重要一環,而總體的風格搭建上,外部建築和設備採用的是科技風格的線框模式,在效果展現上能夠更爲的酷炫,交互體驗上也能夠增值加分。算法
在千篇一概的場景建築建模中,大部分都是實景上的搭建,感官上不一樣於科技風格的數字化展現來的震撼和酷炫,線框模式就很好地詮釋了這一風格。dom
3D 可視化數據中心機房集中監控管理系統對機房實現遠程集中監控管理,實時動態呈現設備告警信息及設備參數,快速定位出故障設備,使維護和管理從人工被動看守的方式向計算機集中控制和管理的模式轉變。函數
在 3D 場景風格中,有着不少實現的方式選擇,而線框風格是最爲體現科技感的一種實現方式。場景建築以及設備主體以線框風格展現,其中數據中心上的設備也會對應處理預警事件的展現。動畫
線框模式是對於模型建模 obj 的一種特殊處理,機制封裝在 HT 自己裏面,而咱們在開啓線框模式的同時,能夠選定一些建模風格上的限制,例如模型 obj 的四邊面或者三邊面就會影響到線框裏線的繪製方式,這裏經過合併三邊面,而且開啓顯示四邊面來起到線框風格上的簡潔體現:ui
// 控制是否載入 obj 的四邊面,否的話經過算法合併三角面 ht.Style['wf.loadQuadWireframe'] = false; // 控制是否顯示四邊面 ht.Style['wf.combineTriangle'] = true;
在風格基調肯定後,在主體大樓場景作還須要作一些簡單的事件機制處理,例如模型選中狀態的表現和設備預警信息彈窗的顯示。this
模型狀態的體現是開啓了模型選中的外框高亮顯示:spa
// 開啓模型選中高亮線框寬度爲1 g3d.getHighlightHelper().mode = 1;
開啓了模型選中高亮後,咱們能夠很清晰地體現出所點擊的模型,搭配上點擊事件的處理,設備信息彈窗的展現,在交互體驗上就會有一種很友好的效果展現。對於設備信息的彈窗展現,是先經過對設備進行綁定標籤,而後經過這個惟一的標籤在數據模型 dataModel 去找到這個設備,而後彈出相對應的彈窗信息或者預警事件。設計
// 根據惟一標識標籤從數據模型中獲取節點信息 this.equipmentPanel = g3dDm.getDataByTag('equipmentPanel'); this.alarmEquipmentPanel = g3dDm.getDataByTag('alarmEquipmentPanel'); this.buildingPanel = g3dDm.getDataByTag('buildingPanel'); handleInteractive(e) { // 獲取事件類型 kind 和事件處理節點 data const {kind, data} = e; if (kind === 'clickData') { let tag = data.getTag(); if (!tag) return; if (tag === 'equipment') { // 獲取所點擊設備的位置信息 var p3d = data.getPosition3d(); // 設備位置信息上對應空間座標 Y 軸上設定增長20的高度 p3d[1] = p3d[1] + 20; // 獲取設備面板 var panel = this.equipmentPanel; // 設備面板顯示展現 panel.s('3d.visible',true); // 設置設備面板座標 panel.setPosition3d(p3d); // 隱藏大樓面板和預警面板 this.buildingPanel.s('3d.visible',false); this.alarmPlane.s('3d.visible',false); } if (tag === 'alarmEquipment') { // 獲取所點擊設備的位置信息 var p3d = data.getPosition3d(); // 設備位置信息上對應空間座標 Y 軸上設定增長20的高度 p3d[1] = p3d[1] + 20; // 獲取預警面板 var panel = this.alarmEquipmentPanel; // 預警面板顯示展現 panel.s('3d.visible',true); // 設置預警面板座標 panel.setPosition3d(p3d); // 隱藏大樓面板和設備面板 this.buildingPanel.s('3d.visible',false); this.equipmentPanel.s('3d.visible',false); } if(tag === 'building'){ // 顯示大樓面板 this.equipmentPanel.s('3d.visible',true); // 隱藏設備面板 this.alarmEquipmentPanel.s('3d.visible',false); // 隱藏預警面板 this.buildingPanel.s('3d.visible',false); } } // 點擊背景則隱藏全部面板信息 if(kind === 'clickBackground'){ this.equipmentPanel.s('3d.visible',false); this.alarmEquipmentPanel.s('3d.visible',false); this.buildingPanel.s('3d.visible',false); } }
在 3D 場景中有着許多動畫的集合,能夠經過簡單清晰地體現出場景中一些所需的元素,例如車流穿梭、數字飛昇以及停車場停放的效果,能夠給靜態的場景添加活力。
經過標識獲取到對應的數字、車流和光柱節點,而後經過簡單封裝的動畫函數驅動實現出以上的效果狀態:
// 遍歷數據模型獲取所要尋找的標識節點作相應的動畫 g3dDm.each((data) => { // 獲取節點標識 let tag = data.getTag(); if (tag === 'num') { // 數字飛昇動畫 animNum(data); } else if (tag === 'car') { // 設置車輛節點的初始 uv 偏移 data.s('top.uv.offset', [1, 0]); // 車輛穿梭動畫 animCar(data); } else if (tag === 'light') { //光柱飛昇動畫 animLight(data); } });
而全部動畫效果的實現,都是基於 HT 封裝的 ht.Default.startAnim() 動畫函數,支持 Frame-Based 和 Time-Based 兩種方式的動畫,本可視化系統中採起的是後面一種實現方式,經過 duration 對於動畫時間的控制和 easing 讓用戶自定義,經過數學公式控制動畫,如勻速變化,先慢後快等效果。基於動畫函數的實現上,對各自展現節點的效果表現上,又封裝了三個函數作對應的處理。
數字飛昇動畫效果實現的封裝函數爲:
function animNum(data) { // 設置節點大小的範圍隨機數處理 var temp3 = 16 - 8 * (Math.random()); // 設置動畫運行時間的範圍隨機數處理 var temp4 = 1200 + Math.random() * 2000; // 設置節點在空間座標 Y 軸上的範圍隨機高度 var temp5 = 400 + Math.random() * 200; // 開啓動畫函數 ht.Default.startAnim({ duration: temp4, easing: function (t) { return t * t }, action: function (v, t) { // 獲取節點的位置座標信息 var p3d = data.getPosition3d(); // 設置節點的新位置座標信息 data.setPosition3d(p3d[0], temp5 - temp5 * v, p3d[2]); // 設置節點的大小信息 data.setSize3d(temp3, temp3, temp3); }, // 動畫函數結束後繼續回調此動畫函數 finishFunc: function () { animNum(data); } }); }
車輛穿梭動畫效果實現的封裝函數爲:
function animCar(data) { // 開啓動畫函數 ht.Default.startAnim({ duration: 5000, easing: function (t) { return t }, action: function (v, t) { // 判斷節點的頂面貼圖是否爲所需的對應信息貼圖 if (data.s('top.image') === 'symbols/htdesign/填充/飛光漸變 2.png') { // 獲取節點的 uv 偏移信息 var offsetX = data.s('top.uv.offset')[0]; // 設置偏移新值到節點上 offsetX = (offsetX - 0.01) % 1; data.s('top.uv.offset', [offsetX, 0]); } }, // 動畫函數結束後繼續回調此動畫函數 finishFunc: function () { animCar(data); } }); }
而光柱的實現方式上也是與數字飛昇的效果同樣,經過在隨機的範圍位置座標內經過設定不一樣的時間差隨機生成,來造成與數字飛昇爲對立面的光柱降低效果,與線框建築的科技風格融爲一體,很好地詮釋了總體風格的展現,這裏對於光柱的動畫就再也不多加贅述了。
相對應的是,停車場隨機停放的效果展現,不一樣於以上的動畫視覺展現,自己仍是具備其效果意義的,能夠對接真實的數據進行對整個停車場的車輛安放作可視化的數據維護和管理,而咱們這裏的實現上,則很好地模擬了這一事件的處理方式,也是經過一個簡單的封裝函數來體現停車場的動畫效果:
function animPark(data) { // 設置隨機值來體現車輛隨機停放的信息 var temp = Math.random(); // 根據隨機值判斷車輛安放的狀態 if (temp<0.15) { data.s('all.color','rgb(255,184,77)'); } else if (temp>0.6) { data.s('all.color','rgba(0,153,255,0.10)'); } ht.Default.startAnim({ duration: 2000, easing: function (t) { return t }, action: function (v, t) { }, // 動畫函數結束後繼續回調此動畫函數 finishFunc: function () { animPark(data); } }); }
機房的實現上,經過點擊機櫃轉移鎖定視角後展現機櫃的內部信息,而且虛化周圍設備的狀態,雙擊背景則會返回到初始的視角而且恢復默認狀態;其次,經過按鈕觸發顯示機櫃的利用率色塊展現,能夠很全面地觀察到各個機櫃的內部消耗信息,方便總體機房的維護和管理。
在機櫃的點擊事件處理上,先使得總體的機房機櫃所有開啓透明而且下降透明度達到總體虛化的效果,而後經過點擊事件的處理,獲取到節點信息,此時運用到封裝好的開門動畫函數,開門後虛化掉這個機櫃的外殼後,顯示展現機櫃的內部設備信息;雙擊背景則恢復以前所作的效果處理操做,視角轉移到默認機房視角。
在點擊事件監聽後,經過 HT 封裝的視角轉移函數 flyTo() 鎖定到對應的機櫃:
g3d.flyTo(data, { direction: [0, 10, 10], animation: true, ratio: 0.9, });
對於門的開啓動畫,首先是將門設置對應的機櫃爲父節點,經過點擊事件的監聽處理後,根據多點擊的節點,將對應的門節點和旋轉角度信息,去調用門的封裝動畫函數:
// 傳入節點和旋轉角度信息 export function animDoor(data, x) { // 開啓動畫函數 ht.Default.startAnim({ duration: 1200, easing: function (t) { return t }, // 動畫執行函數,根據傳入的角度信息作旋轉角度的動畫 action: function (v, t) { data.setRotation3d(0,-v * x,0); }, finishFunc: function () { // 設置門的父節點機櫃透明度爲0.1 data.getParent().s('shape3d.opacity', 0.1); // 遍歷門的父節點機櫃並設置透明度爲0.1 data.getParent().eachChild(function (data) { data.s('shape3d.opacity', 0.1); }) } }); }
對於雙擊背景的視角返回處理,是經過 HT 封裝的相機移動函數 moveCamera(),能夠根據所要到達的視角中心(center)和眼睛(eye),經過開啓動畫函數達到一種視角切換的過渡效果:
g3d.moveCamera([1294, 898, 1671], [0, 0, 0], true);
對於機櫃所佔用的能耗和處理能力,能夠經過機櫃利用率來體現,這樣不只能直觀地體現每個機櫃的使用狀況,還能經過反饋的使用狀況,即時對一些負載的機櫃或者是低使用率的機櫃,作出智能調整,使其機櫃羣達到最大效率化的工做狀態。而具體的實現方法是經過在機櫃羣上動態生成,佔用機櫃高度比例大小的節點,經過隨機取值的方式,而且約定能耗顏色的顯示,來體現出機櫃當前的利用率信息。
loadCapacityNode(g3dDm, cabinetList) { cabinetList.forEach((data) => { // 建立新的利用率容量節點 var node = new ht.Node(); // 生成隨機數 var randomNumber = Math.random() * 100; // 經過隨機數值來體現對應的機櫃利用率顏色的變化 var color; if (randomNumber <= 30) { color = 'rgb(51,153,255)'; } else if (randomNumber > 30 && randomNumber < 60) { color = 'rgb(240,225,19)'; } else { color = 'rgb(242,83,75)'; } // 設置利用率容量節點的位置信息 node.p3(data.p3()); // 設置利用率容量節點的錨點信息 node.setAnchor3d(data.getAnchor3d()); // 設置利用率容量節點的高度信息 node.s3(data.getWidth(), data.getTall() * (randomNumber/100), data.getHeight()); // 設置利用率容量節點的一些基本屬性 node.s({ '3d.visible': false, '3d.movable': false, 'all.color': color, 'wf.visible': true, 'wf.color': 'rgb(247,247,247)' }); // 設置容量節點爲機櫃,方便返回房間視角的時候遍歷機櫃節點一併隱藏 g3dDm.add(node); this.capacityList.push(node); }) }
線框風格只是科技風格上效果展現的一種形態,HT 自身經過數年來的行業積累,總結出了許多的風格基調設定和對應的行業應用場合,加上自身豐富的組態化快速搭建上,順應工業互聯網的浪潮,能夠推進實現許多行業上的解決方案,例如數字孿生的衍生,新基建的可視化系統等普遍的行業上都有涉及,在多種多樣的行業領域上,相信 HT 必定帶你發掘不同的工業互聯網!
2019 咱們也更新了數百個工業互聯網 2D/3D 可視化案例集,在這裏你能發現許多新奇的實例,也能探索許多好玩的效果實現和工業互聯網的展現:https://mp.weixin.qq.com/s/ZbhB6LO2kBRPrRIfHlKGQA
同時,你也能夠查看更多案例及效果:https://www.hightopo.com/demos/index.html