基於 HTML5 Canvas 的拓撲組件 ToolTip 應用


前言

ToolTip 效果是網頁制作中常見的使用特效。當用戶將鼠標懸浮在某個控件上時,ToolTip 顯示並向用戶展示相應的提示信息;當鼠標離開時,ToolTip 隱藏。一般情況下,我們使用 ToolTip 只是顯示一句話或幾個字,其實我們還可以展示很多信息。而今天的重點則是通過 Hightopo 的 HT for Web 產品來制作多種樣式的 ToolTip。

首頁地址:https://www.hightopo.com/index.html

實現方式

HT 共有八種具有可配置 ToolTip 功能的的視圖組件,分別是 ht.graph.GraphView、ht.graph3d.Graph3dView、ht.widget.ListView、ht.widget.PropertyView、ht.widget.TableView、ht.widget.TreeView、ht.widget.TreeTableView、ht.widget.Toolbar。

ht.Data 是 HT 最基礎的數據類型,用戶可將業務信息存儲在 Data 對象屬性上,目前提供了 Node、Edge、Column等子類應用於不同視圖組件中,本文中會用 data 來統稱。

顯示基礎的文本信息

首先建立一個視圖組件(這里我們以 ht.graph.GraphView 為例,其余組件基本與之相同),通過調用組件的 enableToolTip() 方法可以啟用 ToolTip 功能,之后創建一個測試用的 node,並調用它的 setToolTip() 方法設置它的 ToolTip 要顯示的內容。這樣就可以實現上圖中的效果,當我的鼠標移動到圖標上,ToolTip 就會顯示出來。具體實現代碼如下:

var dataModel = new ht.DataModel();
// 建立視圖組件
var graphView = new ht.graph.GraphView(dataModel);     
dataModel.setBackground('black');
// 開啟 ToolTip
graphView.enableToolTip();                             

var node = new ht.Node();
node.setPosition(600, 150);
node.setImage('symbols/ht.json');
// 設置 ToolTip 內容
node.setToolTip('HT for Web');                         
dataModel.add(node);

graphView.addToDOM();

 

這部分我想額外聊一下幾個點

  • 在使用 HT 默認設置的 ToolTip 格式時,通過 setToolTip() 設置好的內容,無論內容多長都會顯示為一行,“\n” 換行符和 “\r” 回車符將不會起到作用。
  • 在使用 HT 默認設置的 ToolTip 格式時,如果開啟了 ToolTip,但是並沒有對目標進行相應的設置,那么將不會顯示 ToolTip。
  • enableToolTip() 為開啟,diableToolTip() 為關閉,上圖中我通過右上角的按鈕調用這兩個方法進行了 ToolTip 的開啟和關閉,需要注意的是 ToolTip 默認是處於關閉狀態的。
  • node 可以通過 getToolTip() 方法來查看當前已設置的 ToolTip 內容。
  • 在 ht.Default 對象中包含了六個 ToolTip 的配置參數,如果想要更改這些配置,需要通過全局的 htconfig 變量名指定,由於 HT 系統只在初始化時讀取 htconfig 的配置信息,因此 htconfig 必須在引入 ht.js 包之前初始化好,運行狀態時修改 htconfig 變量不會再起作用,示例代碼如下:
<script>
    htconfig = {
        Default: {
            // 組件的ToolTip顯示的延遲間隔
            toolTipDelay: 100,              
            // 組件的ToolTip顯示的情況下,如果鼠標移動到新的位置時,ToolTip是否實時持續跟進
            toolTipContinual: true,
            // ToolTip的背景顏色
            toolTipBackground: 'yellow',     
            // ToolTip的文字顏色
            toolTipLabelColor: '#000',       
            // ToolTip的文字字體
            toolTipLabelFont: '12px arial, sans-serif',    
            // ToolTip的陰影顏色
            toolTipShadowColor: 'rgba(0,0,0,0.35)'         
        }
    };
</script> 
<script src="js/ht.js"></script>     

 

顯示自定義內容

除了默認的文本信息,HT 也提供了自定義 ToolTip 的功能,大部分視圖組件也有一個 getToolTip() 方法,該方法可重載返回自定義的 toolTip 文字。在下圖的這個例子中,左側部分繼續使用了 ht.graph.GraphView,右側部分的上方則是采用了 ht.widget.PropertyView,下方采用了 ht.widget.FormPane。

首先我們先來看一下左側部分,由於大部分組件的在 ToolTip 上的使用方法類似,所以我們還是以 GraphView 來作為代表例子。從圖中我們可以看到,ToolTip 的內容變為了兩行,但是在上一部分提到過使用 HT 默認設置的格式是無法對內容進行換行的。這里就是因為重載了 graphView 的 getToolTip(),getToolTip() 會傳入一個交互事件 event 參數,通過 getDataAt() 方法來獲取產生交互事件的 data,之后我們就可以根據 data 進行相應的設置。示例代碼如下:

getColor = function(value) {
    if (value < 40)
        return '#00A406';
    if (value < 70)
        return '#FFCC00';
    return '#A60000';
};

graphView.getToolTip = function(e){
    var data = graphView.getDataAt(e);
    if(data){
        var cpu = data.a('cpu'),
            mem = data.a('mem'),
            html = '<div >' + 
                '<span >CPU:&nbsp;&nbsp;</span> ' 
                + '<span >' + cpu + '%</span>'
                + '<br>' +
                '<span >MEM:&nbsp;&nbsp;</span>' 
                + '<span >' + mem + '%</span>'
                + '</div>';
return {html: html};
}
};

從以上代碼中可以看出本例是通過 innerHTML 將自定義的 html 效果加入到了 tooltip 的 div 中從而展示了當前 data 數據綁定中的內容,鑒於 graphView 中只設置一個 data,所以重載方法中並沒有對 data 作更嚴格的判斷,只要 data 存在就會進行呈現,在正式的項目開發中可能會有多個 data 需要不同的自定義格式。在此情況下,我們可以去判斷 getDataAt() 獲取到的 data 是哪一個,從而對不同的 data 進行不同的設置;也可以繼續使用 setToolTip(),然后對 getDataAt() 獲取到的 data 調用 getToolTip(),對獲取的值進行處理。

 

propertyView.addProperties([
    {
        name: 'name',
        displayName: 'Name'
    },
    {
        displayName: 'CPU',
        drawPropertyValue: function(g, property, value, rowIndex, x, y, w, h, data, view) {
            drawFunc(g, data.a('cpu'), x, y, w, h);
        },
        getToolTip: function(data, isValue, propertyView){
            return isValue ? data.a('cpu') + '%' : 'CPU usage percentage';
        }
    },
    {
        displayName: 'MEM',
        drawPropertyValue: function(g, property, value, rowIndex, x, y, w, h, data, view) {
            drawFunc(g, data.a('mem'), x, y, w, h);
        },
        getToolTip: function(data, isValue, propertyView){
            return isValue ? data.a('mem') + '%' : 'Memory usage percentage';
        }        
    }
]); 

上述代碼為右上方 propertyView 的部分配置代碼,ht.widget.PropertyView 和其余七種組件則有些不同,它的每一個子元素 ht.Property 可以通過 getToolTip 方法設置不同的自定義內容。由於它的特殊性,getToolTip 會傳入三個參數:data 代表 dataModel 中當前被選中的 data 對象,同時也是 propertyView 當前展示的 data 對象;isValue 代表當前鼠標位置是否在右側屬性值范圍內,若值為 false 則代表在左側屬性名范圍內;propertyView 則代表 property 當前所在的屬性組件中。 

 

使用 HT UI 的 Popover 插件

UI 庫是一款功能強大的界面組件庫,基於 HT 核心包的優秀框架和 HTML5 先進的 Canvas 機制,具有易上手、高性能、易擴展、組件豐富、跨平台等特點。彈出框容器 ht.ui.Popover 和 ToolTip 類似,可以在宿主組件周圍顯示一些提示信息。在使用時需要引入 ht-ui.js 文件。

在 HT UI 中使用 Popover 插件。

 

在這個例子中,添加了三個 UI 中的 Button 組件,並分別設置了三種不同的 Popover。

  • 第一種是通過 ht.ui.HtmlView 嵌套了一個 iframe,HtmlView 可以包裝任意 HTML 內容,如 HTML 文本、DOM 對象。
  • 右側的第二個例子則是通過 ht.ui.HTView 包裝了 HT 核心包中的組件 ht.graph3d.Graph3dView。
  • 最后一個例子顯示的是 Echarts 的圖表。與前兩種使用 UI 自帶的組件不同,這里我們自定義了一個 ht.ui.EchartView 組件實現 Echarts 的顯示功能,UI 庫提供了自定義組件的功能,像上圖中的 Button 也可以去自己定義,不過這里我們就不詳談了。
// htmlView
var button = new ht.ui.Button();
button.setText('hover me');

var htmlView = new ht.ui.HtmlView();
htmlView.setContent('<iframe border="0"  src="http://www.hightopo.com"></iframe>');

var popover = new ht.ui.Popover();
popover.setContentView(htmlView);
button.setPopover(popover1, 'hover');

button.addToDOM(window, { x: 70, y: 20, width: 80, height: 24 });

這里我只貼出了第一種的完整代碼作為示例。首先我們定義了一個 button 對象作為宿主組件,然后定義一個 htmlView 並調用它的 setContent 方法去包裝要顯示的內容,最后將其加入到 popover 中,設置給 button。如果需要點擊顯示的話,也可以將 hover 改為 click。

 在 HT 中使用 Popover 插件

 在 HT 中也是可以使用 Popover 插件的,接下來我還是以 graphView 為例來介紹一下。

上圖內容是在 graphView 中添加了兩個 node,並為它們設置了內容相同的兩個 Popover。和在 UI 中不同,Popover 並沒有通過宿主調用 setPopover 進行配置,而是緩存在了 node 的私有變量 _popover 上,通過控制 Popover 的 hide() 和 show() 進行隱藏和顯示。

function getScreenRect(graphView, node) {
    var tx = graphView.tx(),
        ty = graphView.ty(),
        zoom = graphView.getZoom(),
        pos = node.getPosition(),
        width = node.getWidth() * zoom,
        height = node.getHeight() * zoom;

    return {
        x: tx + pos.x * zoom - width / 2,
        y: ty + pos.y * zoom - height / 2,
        width: width,
        height: height
    }
}

function init() {
    graphView = new ht.graph.GraphView();
    dataModel = graphView.dm();

    node1 = new ht.Node();
    node1.setPosition(200, 100);
    node1.setName('Device1');
    node1._popover = createPopover('top');
    dataModel.add(node1);

    graphView.getView().addEventListener('mousemove', function (e) {
        var oldHoverNode = graphView._hoverNode;
        var newNode = graphView.getDataAt(e);
        if (oldHoverNode !== newNode) {
            if (oldHoverNode) {
                oldHoverNode._popover.hide();
            }
            if (newNode && newNode._popover) {
                var newPopover = newNode._popover;
                var rect = getScreenRect(graphView, newNode);
                newPopover.setMaster(rect);
                newNode._popover.show();
            }
            graphView._hoverNode = newNode;
        }
    });

    graphView.addToDOM();
}

通過 getView() 可以獲取到拓撲組件的根層 div,對其監聽鼠標移動事件,當鼠標移動到一個新節點上就會顯示其 Popover,同時對原節點的 Popover 進行隱藏,之后在 graphView 上添加私有變量進行記錄。在事件監聽中 Popover 調用了 setMaster() 方法,並傳入了當前節點的矩形范圍,這是因為 Popover 需要根據宿主的矩形范圍進行定位顯示。

總結

ToolTip 的使用大多數情況下是顯示一張圖片的名稱,或是一個 logo 的作用。但 HT 除了提供 ToolTip 的基本功能,還給予了擴展的空間,可以顯示一個圖表,也可以顯示一個 3D 界面。除此之外,也許你還會有其他想展示的東西。如果你感興趣,就請點擊文章開頭的鏈接,看一看 HT 還能做些什么后就聯系我們吧。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM