唐忠 發表於 2020-3-29 23:44:00

基于 HTML5 Canvas 的拓扑组件 ToolTip 应用

<h2>前言</h2>
<p>ToolTip&nbsp;效果是网页制作中常见的使用特效。当用户将鼠标悬浮在某个控件上时,ToolTip 显示并向用户展示相应的提示信息;当鼠标离开时,ToolTip 隐藏。一般情况下,我们使用 ToolTip 只是显示一句话或几个字,其实我们还可以展示很多信息。而今天的重点则是通过&nbsp;<strong>Hightopo</strong>&nbsp;的&nbsp;<strong>HT for Web&nbsp;</strong>产品来制作多种样式的 ToolTip。</p>
<p>首页地址:https://www.hightopo.com/index.html</p>
<h2>实现方式</h2>
<p>HT 共有八种具有可配置 ToolTip 功能的的视图组件,分别是&nbsp;ht.graph.GraphView、ht.graph3d.Graph3dView、ht.widget.ListView、ht.widget.PropertyView、ht.widget.TableView、ht.widget.TreeView、ht.widget.TreeTableView、ht.widget.Toolbar。</p>
<p>ht.Data 是 HT 最基础的数据类型,用户可将业务信息存储在 Data 对象属性上,目前提供了 Node、Edge、Column等子类应用于不同视图组件中,本文中会用 data 来统称。</p>
<h3>显示基础的文本信息</h3>
<p><img src="https://img2020.cnblogs.com/blog/1905962/202003/1905962-20200314001048965-1468002091.gif"></p>
<p>首先建立一个视图组件(这里我们以&nbsp;ht.graph.GraphView 为例,其余组件基本与之相同),通过调用组件的 enableToolTip() 方法可以启用 ToolTip 功能,之后创建一个测试用的 node,并调用它的 setToolTip() 方法设置它的 ToolTip 要显示的内容。这样就可以实现上图中的效果,当我的鼠标移动到图标上,ToolTip 就会显示出来。具体实现代码如下:</p>
<div class="cnblogs_code">
<pre>var dataModel = new<span> ht.DataModel();
// 建立视图组件
var graphView = new<span> ht.graph.GraphView(dataModel);   
dataModel.setBackground('black'<span>);
// 开启 ToolTip
<span>graphView.enableToolTip();                           

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

graphView.addToDOM();</span></span></span></span></span></span></span></span></pre>
</div>
<p>&nbsp;</p>
<p>这部分我想额外聊一下几个点</p>
<ul>
<li>在使用 HT 默认设置的 ToolTip 格式时,通过 setToolTip() 设置好的内容,无论内容多长都会显示为一行,“\n” 换行符和 “\r” 回车符将不会起到作用。</li>
<li>在使用 HT 默认设置的 ToolTip 格式时,如果开启了 ToolTip,但是并没有对目标进行相应的设置,那么将不会显示 ToolTip。</li>
<li>enableToolTip() 为开启,diableToolTip() 为关闭,上图中我通过右上角的按钮调用这两个方法进行了 ToolTip 的开启和关闭,需要注意的是 ToolTip 默认是处于关闭状态的。</li>
<li>node 可以通过 getToolTip() 方法来查看当前已设置的 ToolTip 内容。</li>
<li>在 ht.Default 对象中包含了六个 ToolTip 的配置参数,如果想要更改这些配置,需要通过全局的 htconfig 变量名指定,由于 HT 系统只在初始化时读取 htconfig 的配置信息,因此 htconfig 必须在引入 ht.js 包之前初始化好,运行状态时修改 htconfig 变量不会再起作用,示例代码如下:</li>
</ul>
<div class="cnblogs_code">
<pre>&lt;script&gt;<span>
    htconfig =<span> {
      Default: {
            // 组件的ToolTip显示的延迟间隔
            toolTipDelay: 100<span>,            
            // 组件的ToolTip显示的情况下,如果鼠标移动到新的位置时,ToolTip是否实时持续跟进
            toolTipContinual: true<span>,
            // ToolTip的背景颜色
            toolTipBackground: 'yellow'<span>,   
            // ToolTip的文字颜色
            toolTipLabelColor: '#000'<span>,      
            // ToolTip的文字字体
            toolTipLabelFont: '12px arial, sans-serif'<span>,   
            // ToolTip的阴影颜色
            toolTipShadowColor: 'rgba(0,0,0,0.35)'<span>         
      }
    };
&lt;/script&gt;
&lt;script src="js/ht.js"&gt;&lt;/script&gt;   </span></span></span></span></span></span></span></span></pre>
</div>
<p>&nbsp;</p>
<h3>显示自定义内容</h3>
<p>除了默认的文本信息,HT 也提供了自定义 ToolTip 的功能,大部分视图组件也有一个 getToolTip() 方法,该方法可重载返回自定义的 toolTip 文字。在下图的这个例子中,左侧部分继续使用了&nbsp;ht.graph.GraphView,右侧部分的上方则是采用了&nbsp;ht.widget.PropertyView,下方采用了&nbsp;ht.widget.FormPane。</p>
<p><img src="https://img2020.cnblogs.com/blog/1905962/202003/1905962-20200316173739032-189056438.gif"></p>
<p>首先我们先来看一下左侧部分,由于大部分组件的在 ToolTip 上的使用方法类似,所以我们还是以 GraphView 来作为代表例子。从图中我们可以看到,ToolTip 的内容变为了两行,但是在上一部分提到过使用 HT 默认设置的格式是无法对内容进行换行的。这里就是因为重载了 graphView 的 getToolTip(),getToolTip() 会传入一个交互事件 event 参数,通过 getDataAt() 方法来获取产生交互事件的 data,之后我们就可以根据 data 进行相应的设置。示例代码如下:</p>
<div class="cnblogs_code">
<pre>getColor = function<span>(value) {
    if (value &lt; 40<span>)
      return '#00A406'<span>;
    if (value &lt; 70<span>)
      return '#FFCC00'<span>;
    return '#A60000'<span>;
};

graphView.getToolTip = function<span>(e){
    var data =<span> graphView.getDataAt(e);
    if<span>(data){
      var cpu = data.a('cpu'<span>),
            mem = data.a('mem'<span>),
            html = '&lt;div style="background:#FDFDFD;padding:6px;font-size:13px;box-shadow:0 0 10px gray;"&gt;' +
                '&lt;span style="color:black"&gt;CPU:&amp;nbsp;&amp;nbsp;&lt;/span&gt; '
                + '&lt;span style="color:' + getColor(cpu)+ '"&gt;' + cpu + '%&lt;/span&gt;'
                + '&lt;br&gt;' +
                '&lt;span style="color:black"&gt;MEM:&amp;nbsp;&amp;nbsp;&lt;/span&gt;'
                + '&lt;span style="color:' + getColor(mem)+ '"&gt;' + mem + '%&lt;/span&gt;'
                + '&lt;/div&gt;'<span>;<br>      return {html: html};<br>    }<br>}; </span></span></span></span></span></span></span></span></span></span></span></span></pre>
</div>
<p>从以上代码中可以看出本例是通过 innerHTML 将自定义的 html 效果加入到了 tooltip 的 div 中从而展示了当前 data 数据绑定中的内容,鉴于 graphView 中只设置一个 data,所以重载方法中并没有对 data 作更严格的判断,只要 data 存在就会进行呈现,在正式的项目开发中可能会有多个 data 需要不同的自定义格式。在此情况下,我们可以去判断 getDataAt() 获取到的 data 是哪一个,从而对不同的 data 进行不同的设置;也可以继续使用 setToolTip(),然后对 getDataAt() 获取到的 data 调用 getToolTip(),对获取的值进行处理。</p>
<p>&nbsp;</p>
<div class="cnblogs_code">
<pre><span>propertyView.addProperties([
    {
      name: 'name'<span>,
      displayName: 'Name'<span>
    },
    {
      displayName: 'CPU'<span>,
      drawPropertyValue: function<span>(g, property, value, rowIndex, x, y, w, h, data, view) {
            drawFunc(g, data.a('cpu'<span>), x, y, w, h);
      },
      getToolTip: function<span>(data, isValue, propertyView){
            return isValue ? data.a('cpu') + '%' : 'CPU usage percentage'<span>;
      }
    },
    {
      displayName: 'MEM'<span>,
      drawPropertyValue: function<span>(g, property, value, rowIndex, x, y, w, h, data, view) {
            drawFunc(g, data.a('mem'<span>), x, y, w, h);
      },
      getToolTip: function<span>(data, isValue, propertyView){
            return isValue ? data.a('mem') + '%' : 'Memory usage percentage'<span>;
      }      
    }
]); </span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
</div>
<p>上述代码为右上方 propertyView 的部分配置代码,ht.widget.PropertyView 和其余七种组件则有些不同,它的每一个子元素 ht.Property 可以通过 getToolTip 方法设置不同的自定义内容。由于它的特殊性,getToolTip 会传入三个参数:data 代表 dataModel 中当前被选中的 data 对象,同时也是 propertyView 当前展示的 data 对象;isValue 代表当前鼠标位置是否在右侧属性值范围内,若值为 false 则代表在左侧属性名范围内;propertyView 则代表 property 当前所在的属性组件中。&nbsp;</p>
<p>&nbsp;</p>
<h3>使用 HT UI 的 Popover 插件</h3>
<p>UI 库是一款功能强大的界面组件库,基于 HT 核心包的优秀框架和 HTML5 先进的 Canvas 机制,具有易上手、高性能、易扩展、组件丰富、跨平台等特点。弹出框容器 ht.ui.Popover 和 ToolTip 类似,可以在宿主组件周围显示一些提示信息。在使用时需要引入 ht-ui.js 文件。</p>
<h4>在 HT UI 中使用 Popover 插件。</h4>
<p>&nbsp;<img src="https://img2020.cnblogs.com/blog/1905962/202003/1905962-20200325163420783-265504167.gif"></p>
<p>在这个例子中,添加了三个 UI 中的 Button 组件,并分别设置了三种不同的 Popover。</p>
<ul>
<li>第一种是通过 ht.ui.HtmlView 嵌套了一个 iframe,HtmlView 可以包装任意 HTML&nbsp;内容,如 HTML&nbsp;文本、DOM&nbsp;对象。</li>
<li>右侧的第二个例子则是通过 ht.ui.HTView&nbsp;包装了 HT&nbsp;核心包中的组件 ht.graph3d.Graph3dView。</li>
<li>最后一个例子显示的是 Echarts 的图表。与前两种使用 UI 自带的组件不同,这里我们自定义了一个 ht.ui.EchartView&nbsp;组件实现 Echarts&nbsp;的显示功能,UI 库提供了自定义组件的功能,像上图中的 Button 也可以去自己定义,不过这里我们就不详谈了。</li>
</ul>
<div class="cnblogs_code">
<pre>// htmlView
var button = new<span> ht.ui.Button();
button.setText('hover me'<span>);

var htmlView = new<span> ht.ui.HtmlView();
htmlView.setContent('&lt;iframe border="0" style="width: 400px; height: 300px; margin: 0; padding: 0; border: 0;" src="http://www.hightopo.com"&gt;&lt;/iframe&gt;'<span>);

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

button.addToDOM(window, { x: 70, y: 20, width: 80, height: 24<span> });<br></span></span></span></span></span></span></span></pre>
</div>
<p>这里我只贴出了第一种的完整代码作为示例。首先我们定义了一个 button 对象作为宿主组件,然后定义一个 htmlView 并调用它的 setContent 方法去包装要显示的内容,最后将其加入到 popover 中,设置给 button。如果需要点击显示的话,也可以将 hover 改为 click。</p>
<h4>&nbsp;在 HT 中使用 Popover 插件</h4>
<p>&nbsp;在 HT 中也是可以使用 Popover 插件的,接下来我还是以 graphView 为例来介绍一下。</p>
<p><img src="https://img2020.cnblogs.com/blog/1905962/202003/1905962-20200318195814830-519010806.gif"></p>
<p>上图内容是在 graphView 中添加了两个 node,并为它们设置了内容相同的两个 Popover。和在 UI 中不同,Popover 并没有通过宿主调用 setPopover 进行配置,而是缓存在了 node 的私有变量 _popover 上,通过控制 Popover 的 hide() 和 show() 进行隐藏和显示。</p>
<div class="cnblogs_code">
<pre>function<span> getScreenRect(graphView, node) {
    var tx =<span> graphView.tx(),
      ty =<span> graphView.ty(),
      zoom =<span> graphView.getZoom(),
      pos =<span> node.getPosition(),
      width = node.getWidth() *<span> zoom,
      height = node.getHeight() *<span> zoom;

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

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

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

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

    graphView.addToDOM();
}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></pre>
</div>
<p>通过 getView() 可以获取到拓扑组件的根层 div,对其监听鼠标移动事件,当鼠标移动到一个新节点上就会显示其 Popover,同时对原节点的 Popover 进行隐藏,之后在 graphView 上添加私有变量进行记录。在事件监听中 Popover 调用了 setMaster() 方法,并传入了当前节点的矩形范围,这是因为 Popover 需要根据宿主的矩形范围进行定位显示。</p>
<h2>总结</h2>
<p>ToolTip 的使用大多数情况下是显示一张图片的名称,或是一个 logo 的作用。但 HT 除了提供 ToolTip 的基本功能,还给予了扩展的空间,可以显示一个图表,也可以显示一个 3D 界面。除此之外,也许你还会有其他想展示的东西。如果你感兴趣,就请点击文章开头的链接,看一看 HT 还能做些什么后就联系我们吧。</p><br><br>
来源:https://www.cnblogs.com/htdaydayup/p/12532916.html
頁: [1]
查看完整版本: 基于 HTML5 Canvas 的拓扑组件 ToolTip 应用