Web 组态运用之用户数据 ARPU 分析图

前言

做为企业的发展,经过运营的有效管理,增长收入、下降成本,取得更好的经济效益,是核心所在,在电信企业一样如此。电信企业的利润大致上是由业务收入和成本决定的,而收入和成本又可进一步分别分解表达为不一样的形式,其中在每用户平均收入(ARPU)的比对上,能够很清楚地分析出各个时间段的流量对比,而且相应地制定出对策。实现上能够经过 2D 的形式来展现相应的流程,而 Hightopo(如下简称 HT )的 HT for Web 产品上提供了丰富的 2D 组态 可帮助咱们快速上手,本系统的 ARPU 分析图也是经过 HT 搭建而成。html

界面简介及效果预览

经过 HT 的 2D 组态矢量图标绘制了三个水池,而且经过管道的水滴动画,串联起了动画流程。node

代码实现

1、水池动画的实现

矢量图适用于不少场合,其特色是放大后图像不会失真,能够适应不一样分辨率的屏幕都不会模糊,不只能够实现完美的跨平台,在大屏展现上的效果就不言而喻了。而 HT 的 2D 组态上有一套完整的矢量图标,例如系统里所实现的水池,是经过 ht.Default.setImage() 注册一个自定义的矢量图标 pool,而这个矢量图标是经过 comps 定义了几个 type 为 shpe 的自定义图形,咱们能够经过 points 和 segments 来定义出想要的效果,而这是对应于 ht.Shape 里的属性,points 是绘制矢量图形的点,而 segments 是描述点链接的样式。经过自定义的方式绘制出矢量图标 pool 后,咱们还须要对所需用到的波动移动坐标作数据绑定,方便后续来控制水波的水平移动,对于所需控制的变量咱们给它起了一个属性名称 offsetX,对应的是所绘制的 comps 组件里各个自定义图形 shape 所涉及的矩形区域 rect 的横坐标 x。json

绘制其中一个自定义矢量图形 shape 的具体实现代码以下:dom

ht.Default.setImage('pool', {
  dataBindings: [
    {
      attr: 'offsetX',
      valueType: 'Number',
      defaultValue: 0
    }
  ],
  width: 800,
  height: 200,
  clip: true,
  comps: [
    {
      type: 'shape',
      background: 'rgb(51, 153, 255)',
      rect: {
        func: function(data, view) {
          var x = data.a('offsetX') || 0;
          return [250 - x, 140, 300, 60];
        },
        value: [250, 140, 300, 60]
      },
      points: [250, 148, 290, 163, 333, 140, 421, 148, 510, 157, 550, 150, 550, 150, 550, 200, 250, 200],
      segments: [1, 4, 4, 2, 2]
    },
    ...
  ]
});

 绘制成的图形叠加在一块儿的效果:函数

水池的水波晃动实现的实质是绘制的各个自定义矢量图形 shape 的横坐标错位平移来达到一种水波的效果,咱们能够经过不限定其平移的活动范围来看一下这个原理实现的效果:动画

很显然对于平移没有边界限定是不行的,经过对于边界限定了一个范围,并在这个范围内定义了一个动画对象 anim,而后经过 HT 的动画函数ht.Default.startAnim()来启动这个动画效果:this

// 水池晃动动画
updatePoolDeep(pools) {
    // 设置每次位置水池晃动波纹偏移的值
    let offsetDlt = 2;
    // 设置水池晃动波纹动画对象
    let anim = {
        frames: Infinity,
        interval: 50,
        action: () => {
            pools.each((p) => {
                // 设置水池晃动波纹偏移方向
                let offsetFlag = p.a('offsetFlag') || 1;
                // 根据偏移方向取水池晃动波纹偏移值
                let offset = (p.a('offsetX') || 0) + offsetDlt * offsetFlag;
                // 对水池晃动波纹限定边界
                if (offset > 50) {
                    offset = 50;
                    offsetFlag = -1;
                } else if (offset < -50) {
                    offset = -50;
                    offsetFlag = 1;
                }
                // 对水池晃动波纹的偏移值和偏移方向进行数据绑定设置值
                p.a('offsetX', offset);
                p.a('offsetFlag', offsetFlag);
            });
        }
    };
    // 开启动画
    ht.Default.startAnim(anim);
}

为了使水池里面的效果更加地真实一点,咱们在矢量图标的上面注册绘制了一张水纹的矢量图片,最后实现的水池晃动效果以下:spa

2、水滴流动效果的实现

在各类行业的业务需求上,2D 视图的流动效果是必不可少的,不只能够用来表述活动的流程次序,也能够表达出两两互相关联的效果。其实现的方式也多种多样,而本系统是采用本身封装了一个在矩形管道内随机生成水滴的流动效果动画。经过构造一个流动类,类里面定义了基本的一些建立水滴节点、初始化水滴位置以及水滴动画的进行。

对于水滴节点的建立,定义了一个方法:code

createNode() {
    let node;
    // 判断水池中是否有遗留,存在则设定节点为水池删除的最后一个节点
    if (this._pool.length) {
        node = this._pool.pop();
    }
    else {
        // 建立新的水滴节点
        node = new ht.Node();
        // 设置水滴图片
        node.setImage(WATER_IMG);
    }
    // 取出流动对应的第一条管道
    let firstPath = this.option.paths[0];
    // 设置随机的偏移量
    let offset = Math.floor(Math.random() * OFFSET_MAX * 2) - OFFSET_MAX;
    // 设置水滴的位置
    node.p(this.getStartPositon(firstPath.rect, firstPath.orientation, offset));
    // 设置水滴的朝向角度
    node.setRotation(this.getRotation(firstPath.orientation));
    // 设置水滴的数据绑定
    node.a({
        // 流动管道
        pathIndex: 0,
        // 动画步进
        step: Math.random() * 2 + 3,
        // 偏移量
        offset: offset
    });
    return node;
}

流动类里定义了一个设置水滴在规定的矩形 rect 里流动的方法,其参数所表示的意义为:htm

  • rect:水滴流动的矩形范围;
  • orientation:水滴流动的朝向,TOP | BOTTOM | RIGHT | LEFT;
  • offset:水滴流动的偏移量;
getStartPositon(rect, orientation, offset) {
    // 水滴流动的矩形区域 rect 的坐标位置
    let { x, y, width, height } = rect;
    // 判断水滴朝向位置,并相应地进行位置的偏移
    switch (orientation) {
        case TOP:
            return {
                x: x + width / 2 + offset,
                y: y + height
            };
        case RIGHT:
            return {
                x: x,
                y: y + height / 2 + offset
            };
        case BOTTOM:
            return {
                x: x + width / 2 + offset,
                y: y
            };
        case LEFT:
            return {
                x: x + width,
                y: y + height / 2 + offset
            };
    }
}

根据水滴的朝向 orientation,还设置了它的旋转方法:

getRotation(orientation) {
    switch (orientation) {
        case TOP:
            return Math.PI;
        case RIGHT:
            return - Math.PI / 2;
        case BOTTOM:
            return 0;
        case LEFT:
            return Math.PI / 2;
    }
}

3、图纸叠加的实现

不少场合下,不一样于小弹窗的实现,若是须要一个模糊状态的弹窗窗口,咱们能够经过叠加一张背景透明的图纸来达到这种效果。

 

建立另一个弹窗图纸的 GraphView 取名为 g2dPop,经过点击事件来渲染加载这张图纸呈现:

其实现的监听代码逻辑以下:

// 开启主图纸事件监听
this.g2d.mi(this.handleInteractive, this);
// 开启弹窗图纸事件监听
this.g2dPop.mi(this.popHandleInteractive, this);
    
// 主图纸监听事件
handleInteractive(e) {
    const {kind, data} = e;
    // 监听事件为点击图元
    if (kind === 'clickData') {
        // 获取图元标签
        let tag = data.getTag();
        if (!tag) return;
        // 判断图元的标签
        if (tag.indexOf('poolClick') >= 0) {
            // 反序列化弹窗图纸
            ht.Default.xhrLoad('displays/pop.json', json => {
                if (!json) return;
                this.g2dPopDm.deserialize(json);
            });
        }
    }
}

// 弹窗监听事件
popHandleInteractive(e) {
    const {kind, data} = e;
    // 监听事件为点击图元
    if (kind === 'clickData') {
        // 获取图元标签
        let tag = data.getTag();
        if (!tag) return;
        // 判断图元的标签
        if (tag === 'back') {
            // 清除弹窗图纸
            this.g2dPopDm.clear();
        }
    }
}

总结

2D 组态上实现的矢量图标能够运用在许多的场合,不只能够在电信企业表达用户数据流量的水池效果,在不少工业上的工艺流程也能够得以体现,例如 PID-进料系统可视化界面,丰富的 2D 组态能够搭建许多好玩的场景,HT 自身丰富的 2D 组态 更是能帮助用户快速上手实现不同的可视化系统!

2019 咱们也更新了数百个工业互联网 2D/3D 可视化案例集,在这里你能发现许多新奇的实例,也能发掘出不同的工业互联网:https://mp.weixin.qq.com/s/ZbhB6LO2kBRPrRIfHlKGQA

同时,你也能够查看更多案例及效果:https://www.hightopo.com/demos/index.html

相关文章
相关标签/搜索