2

前言

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 还能做些什么后就联系我们吧。


hightopo
5.5k 声望3k 粉丝

Everything you need to create cutting-edge 2D and 3D visualization