工业互联网可视化系统风格的抉择:线框模式之 3D 数据中心机房的实现
// 控制是否载入 obj 的四边面,否的话通过算法合并三角面
ht.Style['wf.loadQuadWireframe'] = false;
// 控制是否显示四边面
ht.Style['wf.combineTriangle'] = true;
在风格基调确定后,在主体大楼场景做还需要做一些简单的事件机制处理,例如模型选中状态的表现和设备预警信息弹窗的显示。
模型状态的体现是开启了模型选中的外框高亮显示:
// 开启模型选中高亮线框宽度为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);
}
}
// 遍历数据模型获取所要寻找的标识节点做相应的动画
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);
}
});
}
- direction:默认undefined,眼睛处于目标的方向(相对目标,受到目标自身旋转影响),例如[0,1,5]在目标正面的斜向上;
- animation:默认false,是否使用动画,可以设置为true或者false或者animation动画对象;
- ratio:默认0.8,浮点类型,表示眼睛跟中心的距离动态计算(例如 0.8 表示眼睛在上述方向上动态计算距离以将目标包围盒的8个角全部适配到屏幕80%范围内);
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),通过开启动画函数达到一种视角切换的过渡效果:
- eye:相机位置坐标;
- center:中心点位置坐标;
- anim:默认 false,是否使用动画,可以设置为true或者false或者animation动画对象;
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);
})
}
工业互联网可视化系统风格的抉择:线框模式之 3D 数据中心机房的实现的更多相关文章
- TWaver可视化编辑器的前世今生(四)电力 云计算 数据中心
插播一则广告(长期有效) TWaver需要在武汉招JavaScript工程师若干 要求:对前端技术(JavasScript.HTML.CSS),对可视化技术(Canvas.WebGL)有浓厚的兴趣基础 ...
- python工业互联网应用实战17—前后端分离模式之django template vs jquery3
上一章节我们完成了"CRUD"的后面3个功能点,新增由于改动较大我们专门增加本章来阐述,主要是完成技术栈切换后,会发现模板的代码判断过多,逻辑过于复杂.对未来存在的扩展和维护友好性 ...
- python工业互联网应用实战18—前后端分离模式之jquery vs vue
前面我们分三章来说明了使用django template与jquery的差别,通过jquery如何来实现前后端的分离,同时再9章节使用vue.js 我们浅尝辄止的介绍了JQuery到vue的切换,由于 ...
- 分享数百个 HT 工业互联网 2D 3D 可视化应用案例
过去的 2018 年,我们认为是国内工业互联网可视化的元年,图扑软件作为在工业可视化领域的重度参与者,一线见证了众多 HTML5/Web 化.2D/3D 化的项目在工业界应用落地,我们觉得有必要在此分 ...
- 分享数百个 HT 工业互联网 2D 3D 可视化应用案例之 2019 篇
继<分享数百个 HT 工业互联网 2D 3D 可视化应用案例>2018 篇,图扑软件定义 2018 为国内工业互联网可视化的元年后,2019 年里我们与各行业客户进行了更深度合作,拓展了H ...
- 数百个 HT 工业互联网 2D 3D 可视化应用案例分享 - 2019 篇
继<分享数百个 HT 工业互联网 2D 3D 可视化应用案例>2018 篇,图扑软件定义 2018 为国内工业互联网可视化的元年后,2019 年里我们与各行业客户进行了更深度合作,拓展了H ...
- 2019-分享数百个 HT 工业互联网 2D 3D 可视化应用案例分享
继<分享数百个 HT 工业互联网 2D 3D 可视化应用案例>2018 篇,图扑软件定义 2018 为国内工业互联网可视化的元年后,2019 年里我们与各行业客户进行了更深度合作,拓展了H ...
- 浅谈工业4.0背景下的空中数据端口,无人机3D 可视化系统的应用
前言 近年来,无人机的发展越发迅速,既可民用于航拍,又可军用于侦察,涉及行业广泛,把无人机想象成一个“会飞的传感器”,无人机就成了工业4.0的一个空中数据端口,大至地球物理.气象.农业数据.小至个人位 ...
- 基于 HTML5 的工业互联网 3D 可视化应用
工业企业中生产线处于高速运转,由工业设备所产生.采集和处理的数据量远大于企业中计算机和人工产生的数据,生产线的高速运转则对数据的实时性要求也更高.破解这些大数据就是企业在新一轮制造革命中赢得竞争力的钥 ...
随机推荐
- JavaScript面向对象的作用域链(转载)
JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走遍天下都不怕... 一.“JavaScript中无块级作用域” 在Java或C# ...
- socket编程-多个客户端向服务器发送人脸照片,服务器返回识别结果(服务器使用多线程)...
recognition.py import numpy as np import face_recognition import os class recognition: def __init__( ...
- Python自动化运维一之psutil
1.1系统性能信息模块psutil 1.1.1下载安装psutil 1. wget https://pypi.python.org/packages/source/p/psutil/psutil- ...
- C++编程入门题目--No.5
题目: 输入三个整数x,y,z,请把这三个数由小到大输出. 程序分析: 我们想办法把最小的数放到x上,先将x与y进行比较,如果x>y则将x与y的值进行交换, 然后再用x与z进行比较,如果x> ...
- ACM-ICPC 2019 山东省省赛 C Wandering Robot
这个题额,我觉的是一道水题,思维题,需要考虑的情况比较多,题意一个机器人给一条指令,循环n遍,问此过程中离原点最远距离. 考虑最远距离可能出现的的情况. 每次循环之后距离至少为0: 1.假设他每一次循 ...
- FZU 1894 志愿者选拔
Problem 1894 志愿者选拔 Accept: 2308 Submit: 7003 Time Limit: 1500 mSec Memory Limit : 32768 KB Problem D ...
- codeforce 227D Naughty Stone Piles (贪心+递归+递推)
Description There are n piles of stones of sizes a1, a2, -, an lying on the table in front of you. D ...
- 记一次真实的线上事故:一个update引发的惨案!
目录 前言 项目背景介绍 要命的update 结语 前言 从事互联网开发这几年,参与了许多项目的架构分析,数据库设计,改过的bug不计其数,写过的sql数以万计,从未出现重大纰漏,但常在河边走,哪 ...
- 也谈解决Combobox绑定数据后取值出现System.Data.DataRowView的问题
刚才遇到一个怪现象:同一个窗口,同一张表,通过第一个Combobox值的改变,动态绑定第二个Combobox,结果出现一个怪现象,第一个Combobox有的值改变第二个Combobox一切正常,有几个 ...
- MySQL升级-CentOS6.8
在腾讯云购买的服务器自带的MySQL是5.1版本的,相对于最新版的5.7差了很多特性,在平时的项目练习中使用到了MySQL也会遇到一些奇葩的错误,很有必要升级到至少5.5版本以上. 步骤: 1.备份数 ...