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();
这部分我想额外聊一下几个点
<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: </span> '
+ '<span >' + cpu + '%</span>'
+ '<br>' +
'<span >MEM: </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 当前所在的属性组件中。
UI 库是一款功能强大的界面组件库,基于 HT 核心包的优秀框架和 HTML5 先进的 Canvas 机制,具有易上手、高性能、易扩展、组件丰富、跨平台等特点。弹出框容器 ht.ui.Popover 和 ToolTip 类似,可以在宿主组件周围显示一些提示信息。在使用时需要引入 ht-ui.js 文件。
在这个例子中,添加了三个 UI 中的 Button 组件,并分别设置了三种不同的 Popover。
// 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 插件的,接下来我还是以 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 界面。除此之外,也许你还会有其他想展示的东西。