做爲企業的發展,經過運營的有效管理,增長收入、下降成本,取得更好的經濟效益,是核心所在,在電信企業一樣如此。電信企業的利潤大致上是由業務收入和成本決定的,而收入和成本又可進一步分別分解表達爲不一樣的形式,其中在每用戶平均收入(ARPU)的比對上,能夠很清楚地分析出各個時間段的流量對比,而且相應地制定出對策。實現上能夠經過 2D 的形式來展現相應的流程,而 Hightopo(如下簡稱 HT )的 HT for Web 產品上提供了豐富的 2D 組態 可幫助咱們快速上手,本系統的 ARPU 分析圖也是經過 HT 搭建而成。html
經過 HT 的 2D 組態矢量圖標繪製了三個水池,而且經過管道的水滴動畫,串聯起了動畫流程。node
矢量圖適用於不少場合,其特色是放大後圖像不會失真,能夠適應不一樣分辨率的屏幕都不會模糊,不只能夠實現完美的跨平臺,在大屏展現上的效果就不言而喻了。而 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
在各類行業的業務需求上,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
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; } }
不少場合下,不一樣於小彈窗的實現,若是須要一個模糊狀態的彈窗窗口,咱們能夠經過疊加一張背景透明的圖紙來達到這種效果。
建立另一個彈窗圖紙的 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