天天看點

基于HTML5的網絡拓撲圖 - 裝置狀态面闆

基于HTML5的網絡拓撲圖 - 裝置狀态面闆

電信網管系統中,裝置狀态資訊的實時展示非常重要,通常會挂載一堆圖示來展示狀态或告警資訊,圖示的資訊量有限,有時需要更詳細的面闆,甚至以圖表的形式展現,本文将結合最近客戶提到的需求,使用 Qunee1.6 beta版本,實作拓撲圖中裝置資訊的實時顯示。

Qunee 中ui 的定制非常靈活,每個圖元節點都可以挂載多個 ui 控件,支援9X9=81種相對位置,單節點上能挂載多個 ui 元素,并進行排列和布局,另外每個 ui 元素可以綁定圖元屬性,屬性變化,ui 元素會及時更新界面。

電信網管系統中,裝置狀态資訊的實時展示非常重要,通常會挂載一堆圖示來展示狀态或告警資訊,圖示的資訊量有限,有時需要更詳細的面闆,甚至以圖表的形式展現,本文将結合最近客戶提到的需求,使用 Qunee1.6 beta版本,實作拓撲圖中裝置資訊的實時顯示。

Qunee 中ui 的定制非常靈活,每個圖元節點都可以挂載多個 ui 控件,支援9X9=81種相對位置,單節點上能挂載多個 ui 元素,并進行排列和布局,另外每個 ui 元素可以綁定圖元屬性,屬性變化,ui 元素會及時更新界面。

基于HTML5的網絡拓撲圖 - 裝置狀态面闆

需求分析

網絡裝置拓撲圖,預設裝置為普通節點,輕按兩下時展開,顯示CPU,記憶體,流量等資訊,使用柱狀圖和不同顔色的文字來展示,再輕按兩下變回普通節點 這裡需要定制節點,普通模式下,節點包含圖示和文字,展開模式下,節點主體變成一個圓角矩陣的面闆,上面分布多個元件:圖示,文字,柱狀圖等,其中柱狀圖可以參照之前 監控圖例子中的BarUI,其他都有現成的元件可用,面闆使用内置的Shape圖形,圖示依舊使用ImageUI,文字使用 LabelUI,位置分布則借助position和 anchorPosition 屬性進行設定

CPU 柱狀圖的實作

此外,還需要将 CPU 的數值與柱狀圖綁定,這裡用到Q.Element#addUI(ui, bindingProperties)函數,在第二個參數中設定資料綁定,如果有多個屬性需要綁定可以使用數組,下面的例子将cpuBar的 data 屬性與 node 的cpu屬性進行了綁定,綁定後就可以通過node.set("cpu", 0.45)這樣的方式對 ui 進行屬性設定了

以 CPU 柱狀圖為例,左邊是文字,右邊是柱狀圖,文字向右對齊,柱狀圖左對齊

基于HTML5的網絡拓撲圖 - 裝置狀态面闆

此外,還需要将 CPU 的數值與柱狀圖綁定,這裡用到Q.Element#addUI(ui, bindingProperties)函數,在第二個參數中設定資料綁定,如果有多個屬性需要綁定可以使用數組,下面的例子将cpuBar的 data 屬性與 node 的cpu屬性進行了綁定,綁定後就可以通過node.set("cpu", 0.45)這樣的方式對 ui 進行屬性設定了

CPU 柱狀圖相關代碼

var cpu = new Q.LabelUI("CPU");

cpu.position = {x: 27, y: 47};

cpu.anchorPosition = Q.Position.RIGHT_MIDDLE;
var cpuBar = new BarUI();

cpuBar.position = {x: 30, y: 47};

cpuBar.anchorPosition = Q.Position.LEFT_MIDDLE;

node.addUI(cpu);

node.addUI(cpuBar, {

    property : "cpu",

    propertyType : Q.Consts.PROPERTY_TYPE_CLIENT,

    bindingProperty : "data"

});

node.set("cpu", 0.56);

      

實際使用中我們對函數做了封裝,看起來會不太一樣,下面是節點展開時的 ui 分布設定,主體為一個140 X 120的圓角矩形,上面分布多個文本,圖示和柱狀圖

var w = 140, h = 120, r = 10;
var shape = Q.Shapes.getRect(-w/2, -h/2, w, h, r, r);
this.image = shape;
var gradient = new Q.Gradient(Q.Consts.GRADIENT_TYPE_LINEAR, ["#F4F4F4", "#FFFFFF", "#DFDFDF", "#E9E9E9"]);

gradient.angle = Math.PI / 2;
this.setStyle(Q.Styles.SHAPE_FILL_GRADIENT, gradient);
this.setStyle(Q.Styles.SHAPE_STROKE, 0);
this.setStyle(Q.Styles.SHAPE_OUTLINE, 1);
this.setStyle(Q.Styles.SHAPE_OUTLINE_STYLE, "#C9C9C9");
this.setStyle(Q.Styles.LAYOUT_BY_PATH, false);
function addUIAt(node, ui, x, y, bindingProperty, value){

    ui.syncSelection = false;

    ui.zIndex = 1;

    ui.position = {x: x, y: y};

    ui.anchorPosition = Q.Position.LEFT_TOP;

    ui.fontSize = 10;

    var binding;

    if(bindingProperty){

        binding = {

            property : bindingProperty,

            propertyType : Q.Consts.PROPERTY_TYPE_CLIENT,

            bindingProperty : "data"

        }

    }

    node.addUI(ui, binding);

    return ui;

}
var icon = new Q.ImageUI(image);

icon.size = this.iconSize;

addUIAt(this, icon, 15, 12, "icon").anchorPosition = Q.Position.CENTER_MIDDLE;

addUIAt(this, new Q.LabelUI(name), 30, 5);

addUIAt(this, new Q.LabelUI(id), 30, 22).color = "#D00";

addUIAt(this, new Q.LabelUI("CPU"), 27, 47).anchorPosition = Q.Position.RIGHT_MIDDLE;

addUIAt(this, new Q.LabelUI("MEM"), 27, 65).anchorPosition = Q.Position.RIGHT_MIDDLE;

addUIAt(this, new BarUI(), 30, 47, "cpu").anchorPosition = Q.Position.LEFT_MIDDLE;

addUIAt(this, new BarUI(), 30, 65, "memory").anchorPosition = Q.Position.LEFT_MIDDLE;

addUIAt(this, new Q.LabelUI("Incoming:"), 71, 90).anchorPosition = Q.Position.RIGHT_MIDDLE;

addUIAt(this, new Q.LabelUI("Outgoing:"), 71, 106).anchorPosition = Q.Position.RIGHT_MIDDLE;
var ui = addUIAt(this, new Q.LabelUI(), 75, 90, "incoming");

ui.anchorPosition = Q.Position.LEFT_MIDDLE;

ui.color = "#C20";

ui = addUIAt(this, new Q.LabelUI(), 75, 106, "outgoing");

ui.anchorPosition = Q.Position.LEFT_MIDDLE;

ui.color = "#C20";

      

大體效果

基于HTML5的網絡拓撲圖 - 裝置狀态面闆

進一步封裝

接下來進一步封裝,實作普通模式和展開模式切換,并增加滑鼠互動,輕按兩下進行切換 這裡我們繼承 Node,定義了一個CustomServerNode類,并增加了showDetail屬性,預設為 true 表示展開狀态,設定為 false 時則隐藏所有挂載的 ui,并設定image為圖檔,保留 image 和預設文本标簽

showDetail屬性定義

Object.defineProperties(CustomServerNode.prototype, {

    showDetail: {

        get: function(){

            return this._showDetail;

        },

        set: function(show){

            if(this._showDetail == show){

                return;

            }

            this._showDetail = show;

            this.image = show ? this.shape : this.get("image");

            this.name = show ? "輕按兩下合并" : (this.get("name") + "\n" + this.get("id"));

            var uis = this.bindingUIs;

            if(uis){

                uis.forEach(function(ui){

                    ui.ui.visible = show;

                })

                this.invalidate();

            }

        }

    }

})

      

增加輕按兩下互動

graph.ondblclick = function(evt){

    var element = evt.getData();

    if(element){

        element.showDetail = !element.showDetail;

    }

}

      

運作效果

基于HTML5的網絡拓撲圖 - 裝置狀态面闆

線上示範

http://demo.qunee.com/#VOIP Demo