基于Web组态软件(HTforWeb)实现水泥工厂数据可视化系统 点击:750 | 回复:0



iotopo

    
  • 精华:0帖
  • 求助:0帖
  • 帖子:4帖 | 4回
  • 年度积分:0
  • 历史总积分:70
  • 注册:2020年1月08日
发表于:2020-04-15 15:13:11
楼主

前言

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

系统预览

 系统实现

本案例共有七个子系统:

**数据概况** -- 展示全厂年月时间单位的各项数据概况

**窑系统运行** -- 用窑工艺流程动画展示窑系统实时运行状态

**系统运行情况** -- 用动画流程图展示整个系统运行情况

**生料质量控制** -- 用图表和流程图展示各种生料的配比情况

**熟料质量控制** -- 用动画流程图展示各种熟料的配比情况

**煤粉质量控制** -- 用图表和流程图对煤粉质量进行监控

**智能物流** -- 通过 3D 场景实时监控进出厂车辆,和各项原料运输情

子系统页面切换

子系统画面切换.png

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

流向地图

流向地图.gif

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

```javascript

// 获取线段的父节点

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)',

    });

});

```

 窑系统动画

窑系统动画.gif

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

火焰效果.gif

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


```javascript

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 下,遍历其子节点设置样式,代码如下:

流动动画.gif

```javascript

  //设置流动属性

  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

            });

        }

    }

}

```

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

```javascript

//设置节点透明度

setNodeOpacity (data, value = 0.5) {

    if (data instanceof ht.Block) {

        data.eachChild(child => {

            this.setNodeOpacity(child, value);

        });

    }

    else {

        data.s('opacity', value);

    }

}

```

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

```javascript

//开始流程图动画

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 函数属性里的代码:


```javascript

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场景.gif

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

```javascript

 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






楼主最近还看过


热门招聘
相关主题

官方公众号

智造工程师