2016-10-17 14 views
1

嗨,我想了解如何在Cytoscape.js中动画构建图形。对我而言,这意味着用户会选择一种布局算法,然后从根节点开始,一个边将从该节点开始增长,最终最终指向图中下一个节点的方向,然后该节点将从一个小的点,并且过程会重复。这最终会使正在构建的整个图形动画化。我认为这与Images and Breadthfirst Layout Demo恰恰相反。动画在Cytoscape.js中构建图形

任何人都可以帮我找出一个策略吗?我想我需要用我的节点列表来布局无头图,并使用这些位置来显示html容器中显示的主图中的动画。

感谢您的帮助

回答

1

如果你有初始化所有的元素,只是把他们都在图中。你可以让他们最初隐藏你的样式表,并且你可以用动画逐个显示它们。

我会使用.animation()而不是.animate(),因为您可以使用返回的animation对象及其播放承诺。您可以创建一系列承诺作为您的时间表。

+0

谢谢,这是有道理的,我会给它一个镜头 – Boo

0

下面是我最终使用的方法,它可以更好地使用玩家承诺,如maxkfranz所示,而不是延迟。

/****************************************************************************************************  
* https://gist.github.com/maxkfranz/aedff159b0df05ccfaa5 
* method will animate the graph building, from parent to child 
* 
*/ 
animateGraphBuilding = function(nodes){ 

    var delay = 0;  
    var size = nodes.length; 
    var duration = (200000/size); 
    mod = $('#animationSpeed').val()/2; 
    if(mod < 1){ 
     mod = 1; 
     $('#animationSpeed').val(mod); 
    }else if(mod > 100){ 
     mod = 100; 
     $('#animationSpeed').val(mod); 

    } 

    duration /= mod; 

    var visitedMap = {};//used to ensure nodes are only animated once 

    for(var index = 0; index < size; ++index){ 
     visitedMap[nodes[index].data('id')] = 0; 
    } 
    var nodesCopy = nodes.clone();//store original rendered positions 

    //loop through the list of nodes and then, 
    //Find connected nodes and then, 
    //loop through connected nodes and animated from parent to original position 
    for(var i = 0; i < nodes.length; ++i){ 
     var cNode = nodes[i];     
     var nextNodes = cNode.connectedEdges(
       function(){ 
        return this.source().same(cNode); 
       } 
      ).targets();                   

     for (var index = 0; index < nextNodes.length; ++index){ 
      var nNode = nextNodes[index]; 

      (function(currentNode, x, copyNode, nextNode){   

       if(nextNode != null && x != 0 && visitedMap[nextNode.data('id')] < 1){ 
        ++visitedMap[nextNode.data('id')]; 
        //console.log('currentNode: ' + currentNode.data('id')+ ', x: ' + x + ', nextNode: ' + nextNode.data('id')); 

        var position = nextNode.renderedPosition();     
        nextNode.renderedPosition(copyNode.renderedPosition());   

        nextNode.delay(delay, function(){ 
         nextNode.style("visibility", "visible");       
        }).animate( {     
          renderedPosition: position //to this position        
         }, { 
          duration: duration, 
          complete: function(){/*do nothiing*/} 
         }                 
        );     
       }else if (nextNode != null && visitedMap[nextNode.data('id')] < 1){ 

        ++visitedMap[nextNode.data('id')]; 
        var position = nextNode.renderedPosition();     
        nextNode.renderedPosition(copyNode.renderedPosition());   

        nextNode.delay(delay, function(){ 
         currentNode.style("visibility", "visible"); //show the root node 
         nextNode.style('visibility', 'visible');      
        }).animate( {     
          renderedPosition: position,//to this position        
         }, { 
          duration: duration, 
          complete: function(){/*do nothing*/}      
         }          
        );           
       }   

       delay += duration; 

      })(cNode, i, nodesCopy[i], nNode);      
     } //end inner for, iterates through children nodes 
    } // end of outter for, iterates through all nodes     
};