zoukankan      html  css  js  c++  java
  • TWaver HTML5之树形布局

    转眼间春节假期已经过完,作为一个职业的程序猿,不知道大家有没有这样的感觉,一天不碰电脑,总觉得生活少点什么。今天是春节后上班的第三天,给大家分享一下我们前段时间的一个需求,需求是这样的:界面中的网元分为不同的域,比如一级域,二级域,三级域,….N级域,而且不同域之间会有连线。对于这个需求,按照常规的想法,使用group岂不是很简单,一级域是一个group,二级域也是一个group,二级域的group是一级域的父亲,以此类推。但是这样有个问题,如果域比较多,会造成group的过度嵌套,界面中group多了之后,不仅用户体验下降,而且会严重影响性能,所以倒不如直接用树,可以很直观的体现各个域之间的层级关系。
    Screen Shot 2015-02-27 at 10.14.31
    下面是布局的代码,代码很简单,相信熟悉twaver的人很容易看懂。

    function layoutRing(){    
        //setup all group rings.
        var groups={};    
        box.forEach(function(data){
          if(data instanceof twaver.Node){
            var node=data;
            node.setClient('x', node.getLocation().x);
            node.setClient('y', node.getLocation().y);
            var groupName=data.getClient('group');
            if(!groups[groupName]){
              groups[groupName]=[];
            }
            var rings=groups[groupName];
            var level=parseInt(node.getClient('level'));
            if(rings.length<=level){
              rings.push([]);
            }
            var ring=rings[level];
            ring.push(node);
          }
        });
     
        cleanConnections();
        layouter.doLayout('topbottom');   
         
        for(var groupName in groups){
          //get this group bounds.
          var x1=undefined, y1=undefined, x2=undefined, y2=undefined;
          var rings=groups[groupName];
          for(var level=0;level<rings.length; level++){
            var ring=rings[level];
            for(var index=0;index<ring.length;index++){
              var node=ring[index];   
              x1=x1 ? Math.min(x1, node.getLocation().x) : node.getLocation().x;
              y1=y1 ? Math.min(y1, node.getLocation().y) : node.getLocation().y;
              x2=x2 ? Math.max(x2, node.getLocation().x) : node.getLocation().x;
              y2=y2 ? Math.max(y2, node.getLocation().y) : node.getLocation().y;
     
              var target=box.getDatas().get(Math.floor(Math.random()*box.size()));
              if(target instanceof twaver.Node && target!==node){
                var connection=new twaver.Link(node, target);
                connection.setStyle('link.width',0.2);
                connection.setStyle('link.color', '#aaaaaa');
                connection.setClient('connection',true);
                connection.setClient('angle', (target.getClient('angle')+node.getClient('angle'))/2);
                box.add(connection);
              }
            }
          }
          var width=x2-x1;
          var height=y2-y1;           
     
          //layout each ring for this group.
          for(var level=0;level<rings.length; level++){
            var ring=rings[level];
            for(var index=0;index<ring.length;index++){
              var node=ring[index];   
              var radius=node.getLocation().y-y1;
              var range=Math.PI*2;        
              var angle=(node.getLocation().x-x1)/width * range;
              if(level>1 && (level==rings.length-1 || rings.length<4)){
                angle=node.getParent().getClient('angle')+(angle-node.getParent().getClient('angle'))/3;
              }
              var x=radius*Math.cos(angle);
              var y=radius*Math.sin(angle);
                       
              node.setLocation(node.getClient('x'),node.getClient('y'));
              node.setClient('angle', angle);                     
              move(node, x, y);
            }
          }
        }   
       }
    

      

    布局中的可以加入动画效果,提升用户体验,关于动画的相关文档可以参考文档:Screen Shot 2015-02-27 at 10.53.11

    function move(node, x, y){
        var x0=node.getClient('x');
        var y0=node.getClient('y');
        new twaver.Animate({
              from: { x: x0, y: y0 },
              to: { x: x, y: y },
              type: 'point',
              delay: 100,
              dur: 1000,
              easing: 'easeNone',
              onUpdate: function (value) {
                node.setLocation(value.x, value.y);
              }
            }).play();      
       }

    如果有对这个示例感兴趣的朋友,可以发邮件索取相关代码,邮箱地址:jack.shangguan@servasoft.com

  • 相关阅读:
    Silverlight生命周期概述
    NVolecity 处理DataTable 小记
    Adobe CS6 安装的时候,安装到AdobeHelp 死掉的解决方法
    验证视图状态 MAC 失败。如果此应用程序由网络场或群集承载,请确保 配置指定了相同的 validationKey 和验证算法。不能在群集中使用 AutoGenerate 的解决办法
    为什么要写博客
    [原创]SQL发音考证(搜寻SQL86标准)
    [转载]《暗时间》:为什么你应该(从现在开始就)写博客
    [转载]《暗时间》:书写是为了更好的思考
    [原创]手把手教你写网络爬虫(1):网易云音乐歌单
    javascript简单的日历实现《转》
  • 原文地址:https://www.cnblogs.com/twaver/p/4329276.html
Copyright © 2011-2022 走看看