前言

如今的制造行业,基于数据进行生产策略制定与管理已经成为一种趋势,特别是 工业4.0 的浪潮下,数据战略已经成为很多制造企业的优先战略,而数据可视化以更直观的方式,帮助指导决策,成为数据分析传递信息的重要工具。通过数据可视化系统助力实现数据驱动的工业世界,为 工业4.0 提供更加灵活、敏捷、高效、个性化的数据支撑。今天就给大家带来一个采用 Hightopo 的 HT for Web 产品实现了一个水泥工厂可视化系统。

系统预览

本案例共有七个子系统:

  • 数据概况 -- 展示全厂年月时间单位的各项数据概况
  • 窑系统运行 -- 用窑工艺流程动画展示窑系统实时运行状态
  • 系统运行情况 -- 用动画流程图展示整个系统运行情况
  • 生料质量控制 -- 用图表和流程图展示各种生料的配比情况
  • 熟料质量控制 -- 用动画流程图展示各种熟料的配比情况
  • 煤粉质量控制 -- 用图表和流程图对煤粉质量进行监控
  • 智能物流 -- 通过 3D 场景实时监控进出厂车辆,和各项原料运输情

子系统页面切换

切换不同子系统时,左侧菜单和顶部标题是不需要切换的,所以我们把需要切换的内容部分别放在不同的 Block 中,Block 类型,本身不绘制任何内容,用于作为其它节点的父节点,可以与子节点同步大小,当它隐藏或显示时,所有子节点都会跟着隐藏或显示。所以当我们切换子系统时只需要控制对应的 Block 显示隐藏,而不需要去加载切换多张图纸。

流向地图

在数据概况页面中,流向地图展示年度水泥向各地区的销售情况,这里我们用 Shape 类型绘制线段来连接源地和汇地,用流动效果表示销售关系。流动效果只需引入 HT 的 ht-flow.js 插件,即可通过简单的属性设置实现,代码如下:

// 获取线段的父节点
this.flowParent = dm.getDataByTag('saleFlowParent');
// 遍历得到所有线段
this.flowParent.eachChild(child => {
// 开启流动,设置流动样式
child.s({
// 开启流动
'flow': true,
// 设置流动组中最大元素的尺寸
'flow.element.max': 4,
// 设置流动组中的元素的渐变阴影中心颜色
'flow.element.shadow.begincolor': '#49e5fe',
// 设置流动组中的最大元素的渐变阴影尺寸
'flow.element.shadow.max': 16,
// 设置流动组中的元素的渐变阴影边缘颜色
'flow.element.shadow.endcolor': 'rgba(73, 229, 254, 0)',
});
});

窑系统动画

在窑系统运行页面中,窑工艺流程动画很直观的展示了窑系统实时运行状态。画面中火焰、水和熟料在传送带上运输的动画效果,为了在性能较差的设备上也能流畅运行,我通过切换不同矢量图形的方式实现。这里用到了 HT 矢量中状态机制,先绘制多个不同的矢量组件,每个组件都可以定义状态来决定自己在哪个状态下显示,只要通过 data.s('state') 修改节点状态就可以实现如下效果:

使用一个定时器,不断地改变节点的状态值,相关代码如下:

this._stateTimer = setInterval(() => {
stateNodes.forEach(node => {
this.stateAnimation(node);
});
}, 180);
//切换状态
stateAnimation(node) {
let stateIndex = (node.a('stateIndex') || 0) % stateEnum.length,
state = stateEnum[stateIndex].value;
node.s('state', state);
node.a('stateIndex', ++stateIndex);
}

流程图动画

流程图中流动线同样是使用 ht-flow.js 插件实现。由于图纸上的线段比较多,我把不同的线段分组放在不同的 Block 下,遍历其子节点设置样式,代码如下:

  //设置流动属性
setNodeFlow (data, value) {
if (data instanceof ht.Block) {
data.eachChild(child => {
this.setNodeFlow(child, value);
});
}
else if (data.getDisplayName() === 'line'){
data.s({
'flow': value,
'flow.element.max': 4,
'flow.element.count': 1,
'flow.count': 5,
'flow.step': 10
});
}
}
//设置虚线流动属性
setNodeDashFlow(data, value) {
if (data instanceof ht.Block) {
data.eachChild(child => {
this.setNodeDashFlow(child, value);
});
}
else if (data.getDisplayName() === 'border'){
if (value) {
data.s({
'shape.dash.flow': true,
'shape.dash': true
});
}
else {
data.s({
'shape.dash.flow': false,
'shape.dash': false
});
}
}
}

为了使动画看起来更顺畅,我给一些节点加上透明度动画,设置节点透明度的代码如下:

//设置节点透明度
setNodeOpacity (data, value = 0.5) {
if (data instanceof ht.Block) {
data.eachChild(child => {
this.setNodeOpacity(child, value);
});
}
else {
data.s('opacity', value);
}
}

接下来只需要依次执行动画:

//开始流程图动画
start() {
let {eo, eoInput, eoLine1, eoKind, eoCalu} = this;
//工况输入透明度动画
this.gv.enableFlow(30);
this.setNodeOpacity(eo);
this.setNodeFlow(eo, false);
(new Promise((resolve, reject) => {
this.animtion = startAnim({
frames: 16,
interval: 5,
finishFunc: () => {resolve()},
action: (v, t) => {
this.setNodeOpacity(eoInput, 0.5 + 0.5 * v);
}
});
})).then(() => {
//连线连线透明动画,流动
return new Promise((resolve, reject) => {
this.animtion = startAnim({
frames: 12,
interval: 10,
finishFunc: () => {
this.setNodeFlow(eoLine1, true);
this.timer = setTimeout(() => {resolve()}, 1500);
},
action: (v, t) => {
this.setNodeOpacity(eoLine1, 0.5 + 0.5 * v);
}
});
})
}).then(() => {
//软计算透明动画
return new Promise(resolve => {
this.animtion = startAnim({
frames: 16,
interval: 5,
finishFunc: () => {resolve()},
action: (v, t) => {
this.setNodeOpacity(eoKind, 0.5 + 0.5 * v);
this.setNodeOpacity(eoCalu, 0.5 + 0.5 * v);
}
});
});
}).then(() => {
//软计算透明虚线流动
return new Promise(resolve => {
this.setNodeDashFlow(eoKind, true);
this.setNodeDashFlow(eoCalu, true);
this.timer = setTimeout(() => {
this.setNodeDashFlow(eoKind, false);
this.setNodeDashFlow(eoCalu, false);
resolve();
}, 3000);
});
}).then(() => {
......
})
}

智能物流

前面六个子系统均为 2D 界面,而智能物流页面则是嵌入了一个 3D 场景。实现方式是通过定义 HT 矢量 JSON 的 renderHTML 函数属性,可实现在 GraphView 拓扑图上,嵌入任意第三方 HTML DOM 元素。不过这里也要注意一点,HT 的图纸是 Canvas 实现的,renderHTML 的 DOM 元素一定在 Canvas 之上,使用 renderHTML 的 DOM 与常规 Canvas 上绘制的图元不可能有层级控制可能性。下面展示一下 renderHTML 函数属性里的代码:

renderHTML : function (data, gv, cache) {
// 避免重复创建g3d
if (!cache.g3d) {
// 创建 3D 视图组件
var g3d = cache.g3d = new ht.graph3d.Graph3dView();
// 布局函数,根据图元的位置信息摆放HTML元素
g3d.layoutHTML = function () {
gv.layoutHTML(data, g3d, true);
};
// 阻止事件冒泡
g3d.getView().addEventListener('mousedown', function (event) {
event.stopPropagation();
});
g3d.getView().addEventListener('touchstart', function (event) {
event.stopPropagation();
});
}
// 获取图元自定义属性sceneURL的值
var sceneURL = data.a('sceneURL');
// 获取图元自定义属性onPostDeserialize的值
var onPostDeserialize = data.a('onPostDeserialize');
// 当图元自定义属性sceneURL改变时,清除旧dataModel,反序列化新的sceneURL
if (cache.g3d.sceneURL !== sceneURL) {
cache.g3d.dm().clear();
cache.g3d.sceneURL = sceneURL;
if (sceneURL) {
cache.g3d.deserialize(sceneURL, function (json, dm, g3d, datas) {
// 在反序列化后的回调函数中,执行onPostDeserialize函数
onPostDeserialize && onPostDeserialize(json, dm, g3d, datas);
});
}
}
return cache.g3d;
}

3D场景嵌入后,接下来实现水泥厂内的车辆动画。根据后台传来车辆进入工厂的数据,我们创建运载不同原料的车辆模型,让它们沿着不同的路径抵达对应的厂房。同样是用 Shape 类型事先绘制好路径,根据 Shape 的 Points 和 Segments 信息,实现车辆沿着路径行驶动画。相关代码如下:

 carAnimation(car, path, duration) {
// 车辆行驶动画
ht.Default.startAnim({
duration: duration,
easing: Easing.easeNone,
action: function (v, t) {
// 设置偏移量
let offset = Math.floor(v * 100);
// 根据偏移量得到在路径上的点坐标
let position = ht.Default.getPercentPositionOnPoints(path.getPoints(), path.getSegments(), offset);
// 根据偏移量得到在路径上的点于路径切线角度
let angle = ht.Default.getPercentAngle(path.getPoints(), path.getSegments(), offset);
// 设置车辆位置坐标及旋转角度
car.setX(position.x);
car.setY(position.y);
car.setRotationY(Math.PI / 2 - angle);
},
});
}

总结

工业互联网是工业发展的必经之路,我们国家是一个工业大国,正处在工业转型升级的关键时刻,面临着人工成本上升、原材料价格波动、贸易竞争日益加剧等问题,迫切需要提高效率、降低生产成本。只有坚定不移地推动工业互联网落地,加快更多企业的数字化转型和智能化改造,才有能让在全球化竞争中立于不败之地。可视化作为智能化数字化的最后一环,让复杂抽象的数据变得真正可知可感,帮助决策者发现规律,洞悉未来,为企业提速增效。

还有更多的可视化案例可以参考:https://www.hightopo.com/demos/index.html

基于 HTML5 WebGL 的 水泥工厂可视化系统的更多相关文章

  1. 基于 HTML5 WebGL 的地铁站 3D 可视化系统

    前言 工业互联网,物联网,可视化等名词在我们现在信息化的大背景下已经是耳熟能详,日常生活的交通,出行,吃穿等可能都可以用信息化的方式来为我们表达,在传统的可视化监控领域,一般都是基于 Web SCAD ...

  2. 基于 HTML5 + WebGL 的地铁 3D 可视化系统

    前言 工业互联网,物联网,可视化等名词在我们现在信息化的大背景下已经是耳熟能详,日常生活的交通,出行,吃穿等可能都可以用信息化的方式来为我们表达,在传统的可视化监控领域,一般都是基于 Web SCAD ...

  3. 基于 HTML5 WebGL 的智慧楼宇可视化系统

    前言 可视化的智慧楼宇在 21 世纪是有急迫需求的,中国被世界称为"基建狂魔",全球高层建筑数量位居首位,所以对于楼宇的监控是必不可少.智慧楼宇可视化系统更多突出的是管理方面的功能 ...

  4. 基于 HTML5 WebGL 的发动机 3D 可视化系统

    前言     工业机械产品大多体积庞大.运输成本高,在参加行业展会或向海外客户销售时,如果没有实物展示,仅凭静态.简单的图片说明书介绍,无法让客户全面了解产品,不仅工作人员制作麻烦,客户看得也费力.如 ...

  5. 基于 HTML5 WebGL 的高炉炼铁厂可视化系统

    前言       在当今 工业4.0 新时代的推动下,不仅迎来了 工业互联网 的发展,还开启了 5G 时代的新次元.而伴随着带宽的提升,网络信息飞速发展,能源管控上与实时预警在工业互联网中也占着举足轻 ...

  6. 基于 HTML5 + WebGL 的无人机 3D 可视化系统

    前言 近年来,无人机的发展越发迅速,既可民用于航拍,又可军用于侦察,涉及行业广泛,也被称为“会飞的照相机”.但作为军事使用,无人机的各项性能要求更加严格.重要.本系统则是通过 Hightopo 的   ...

  7. 基于 HTML5 WebGL 的挖掘机 3D 可视化应用

    前言 在工业互联网以及物联网的影响下,人们对于机械的管理,机械的可视化,机械的操作可视化提出了更高的要求.如何在一个系统中完整的显示机械的运行情况,机械的运行轨迹,或者机械的机械动作显得尤为的重要,因 ...

  8. 基于 HTML5 WebGL 的加油站 3D 可视化监控

    前言 随着数字化,工业互联网,物联网的发展,我国加油站正向有人值守,无人操作,远程控制的方向发展,传统的人工巡查方式逐渐转变为以自动化控制为主的在线监控方式,即采用数据采集与监控系统 SCADA.SC ...

  9. 基于 HTML5 + Canvas 实现的 PID 可视化系统

    前言 随着工业物联网和互联网技术的普及和发展,人工填料的方式已经逐渐被机械设备取代.工业厂商减小误操作.提升设备安全以及追求高效率等制造特点对设备的要求愈加高标准.严要求.同时机械生产以后还需遵从整个 ...

随机推荐

  1. 免ROOT卸载手机自带软件详细教程

    一.准备条件 1.电脑一台 2.手机一部 3.WiFi 二.下载所需资源 微信扫码进入搜索,选择安卓软件卸载工具 根据图中提示,按照自己的系统进行下载 三.下载完后解压(以Windows为例),解压后 ...

  2. docker学习之路

    环境 : ubuntu 16.4 下载docker 首先使用命令行下载 docker wget -qO- https://get.docker.com/ | sh 启动 下载完成之后进行一个启动,但是 ...

  3. 程序员过关斩将-- 喷一喷坑爹的面向UI编程

    摒弃面向UI编程 为何喷起此次话题,因为前不久和我们首席架构师沟通,谈起程序设计问题,一不小心把UI扯进来,更把那些按照UI来编程的后台工程师也扯了进来.今天特意百度了一下(其实程序员应该去googl ...

  4. MATLAB神经网络(2)之R练习

    1. AMORE 1.1 newff newff(n.neurons, learning.rate.global, momentum.global, error.criterium, Stao, hi ...

  5. Django中使用CORS实现跨域请求

    跨域请求: ​    请求url包含协议.网址.端口,任何一种不同都是跨域请求. 1.安装cors模块 pip install django-cors-headers2.添加应用 INSTALLED_ ...

  6. Spark实战--搭建我们的Spark分布式架构

    Spark的分布式架构 如我们所知,spark之所以强大,除了强大的数据处理功能,另一个优势就在于良好的分布式架构.举一个例子在Spark实战--寻找5亿次访问中,访问次数最多的人中,我用四个spar ...

  7. 【分布式锁】02-使用Redisson实现公平锁原理

    前言 前面分析了Redisson可重入锁的原理,主要是通过lua脚本加锁及设置过期时间来保证锁执行的原子性,然后每个线程获取锁会将获取锁的次数+1,释放锁会将当前锁次数-1,如果为0则表示释放锁成功. ...

  8. C语言-转义字符

    %d   十进制有符号整数 %u   十进制无符号整数 %f    浮点数 %s   字符串 %c   单个字符 %p   指针的值 %e   指数形式的浮点数 %X   无符号以十六进制表示的整数 ...

  9. php 调用curl_init失败

    当你在开发微信公众号,微信小程序的时候,往往会遇到困难 进入服务器,输入 tail -f /var/log/apache2/error.log 看看apache2的日志 就因为php 的curl扩展没 ...

  10. Windows主机与centOS虚拟机之间"ping不通"

    为什么要遇到这个问题 这是我重新安装centOS7.5虚拟机之后遇到的问题——我需要安装一个SecureCRT工具,结果主机与虚拟机没有ping通. 在安装这个工具之前需要进行主机与虚拟机的相互pin ...