zoukankan      html  css  js  c++  java
  • 基于 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() 设置好的内容,无论内容多长都会显示为一行,“ ” 换行符和 “ ” 回车符将不会起到作用。
    • 在使用 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,  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,
            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 还能做些什么后就联系我们吧。

  • 相关阅读:
    vue-router(路由)详细教程
    vue路由对象($route)参数简介
    this.$router.push相关的vue-router的导航方法
    es6 Promise.reject()方法
    百度阿里网易大疆等大小厂前端校招面筋 | 掘金技术征文
    Vue 脱坑记
    (尚016)Vue指令(11个自带指令+自定义指令)
    (尚015)Vue过滤器(对显示的数据进行格式化)
    (尚014)Vue过渡与动画
    (尚013)Vue的生命周期
  • 原文地址:https://www.cnblogs.com/xhload3d/p/12571377.html
Copyright © 2011-2022 走看看