【问题标题】:Animate building a graph in Cytoscape.js在 Cytoscape.js 中动画构建图形
【发布时间】:2016-12-14 16:01:35
【问题描述】:

您好,我想学习如何在 Cytoscape.js 中制作图形动画。对我来说,这意味着,用户将选择一种布局算法,然后从根节点开始,一条边将从该节点开始增长,最终指向图中下一个节点的方向,然后该节点将从一个小节点增长点,并且该过程将重复。这最终会为正在构建的整个图表设置动画。我认为这与Images and Breadthfirst Layout Demo 正好相反。

谁能帮我想出一个策略来做到这一点?我在想我需要用我的节点列表布局一个无头图,并使用这些位置在 html 容器中显示的主图中显示动画。

感谢您的帮助

【问题讨论】:

    标签: cytoscape.js


    【解决方案1】:

    如果您在初始化时拥有所有元素,只需将它们全部放入图表中即可。您可以将它们最初隐藏在样式表中,然后通过动画逐个显示它们。

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

    【讨论】:

      【解决方案2】:

      这是我最终使用的,使用 maxkfranz 建议的 play promise 会更好,而不是延迟。

      /****************************************************************************************************    
       * 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                  
      };  
      

      【讨论】:

        猜你喜欢
        • 2015-11-13
        • 1970-01-01
        • 2015-12-15
        • 1970-01-01
        • 2016-01-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多