2017-08-07 1 views
1

Ich versuche, ein Diagramm zu erstellen, das beim Laden der Seite alle Knoten im Diagramm aus dem Stammknoten wie einen Baum erweitert, wie das Gegenteil von this example. Der Graph ist ohne Zyklen und einen vordefinierten Wurzelknoten gerichtet.Erweitern von Knoten mit Cytoscape

Momentan verberge ich alle Knoten in der Grafik. Ich führe dann ein DFS vom Wurzelknoten aus. Bei jedem Kindknoten verschiebe ich ihn an den Ort des Elternknotens und möchte dann .animate() mit seiner ursprünglichen Position als Ziel ausführen, so dass es eine glatte Animation gibt. Wie im Code zu sehen ist, pausiert die .animate() - Funktion den Rest des Programms nicht. Irgendein Rat?

var cy = cytoscape({ 
 
    container: document.getElementById('cy'), 
 

 
    boxSelectionEnabled: false, 
 
    autounselectify: true, 
 

 
    style: cytoscape.stylesheet() 
 
    .selector('node') 
 
     .css({ 
 
     'content': 'data(id)' 
 
     }) 
 
    .selector('edge') 
 
     .css({ 
 
     'curve-style': 'bezier', 
 
     'target-arrow-shape': 'triangle', 
 
     'width': 4, 
 
     'line-color': '#ddd', 
 
     'target-arrow-color': '#ddd', 
 
     }), 
 

 
    elements: { 
 
    nodes: [ 
 
     { data: { id: 'a' } }, 
 
     { data: { id: 'b' } }, 
 
     { data: { id: 'c' } }, 
 
     { data: { id: 'd' } }, 
 
     { data: { id: 'e' } } 
 
     ], 
 

 
     edges: [ 
 
     { data: { id: 'ae', weight: 1, source: 'a', target: 'e' } }, 
 
     { data: { id: 'ab', weight: 3, source: 'a', target: 'b' } }, 
 
     { data: { id: 'bc', weight: 5, source: 'b', target: 'c' } }, 
 
     { data: { id: 'cd', weight: 2, source: 'c', target: 'd' } }, 
 
     ] 
 
    }, 
 

 
    layout: { 
 
    name: 'breadthfirst', 
 
    directed: true, 
 
    padding: 10, 
 
    roots: '#a', 
 
    } 
 
}); // cy init 
 

 
var root_id = 'a' 
 

 
//get root 
 
var root = cy.$('#'+root_id)[0] 
 

 
//empty collection 
 
var collection = cy.collection() 
 

 
//hide all nodes except root 
 
cy.ready(function(event){ 
 
    collection = collection.add(cy.nodes('node[id!="'+root_id+'"]')) 
 
    collection = collection.add(cy.nodes().connectedEdges()); 
 
    collection.style('visibility', 'hidden') 
 
}); 
 

 

 
var visited_nodes = [root]; 
 
function dfs(node) { 
 
    //visit node 
 
    visited_nodes.push(node) 
 
    
 
    //for each neighbor w ov f 
 
    neighbors = cy.$('#'+node.id()).outgoers('edge') 
 
    neighbors.forEach(function (next) { 
 
    var next_node = cy.$('#'+next.data().target) 
 
    if (visited_nodes.indexOf(next_node) < 0){ 
 
     //visit each unvisited node 
 
     //we will move the target node to the source node, then use .animate() to move the target node back to it's original location 
 
     source_id = next.data('source') 
 
     target_id = next.data('target') 
 
     var node_to_move = cy.$('#' + next.data('target'))[0] 
 
     
 
     //record the x and y coordinates to avoid messing around for objects. temporary. 
 
     var start_position_x = cy.$('#' + next.data('source')).position().x 
 
     var start_position_y = cy.$('#' + next.data('source')).position().y 
 
     var end_position_x = cy.$('#' + next.data('target')).position().x 
 
     var end_position_y = cy.$('#' + next.data('target')).position().y 
 
     
 
     //move the target node to its start position 
 
     node_to_move.position('x',start_position_x) 
 
     node_to_move.position('y',start_position_y) 
 
     node_to_move.style('visibility', 'visible') 
 

 
     //then animate the target node moving to it's original position 
 
     node_to_move.animate(
 
     { 
 
     position: {end_position_x, end_position_y} 
 
     }, 
 
     { 
 
     duration: 1000, 
 
     complete: function(){ 
 
      node_to_move.style('visibility', 'visible') 
 
      // if (e !== undefined){ 
 
      // e.style('visibility', 'visible') 
 
      // } 
 
     } 
 
     }) 
 

 
     //DOESNT WORK WITH THESE COMMENTED OUT, DOES WITH THEM COMMENTED IN/ 
 
     //I think this means it is a timing problem, with the dsf moving forward without the nodes getting moved 
 
     // node_to_move.position('x',end_position_x) 
 
     // node_to_move.position('y',end_position_y) 
 
     
 
     dfs(next_node)  
 
    } 
 
    }) 
 
}
body { 
 
    font: 14px helvetica neue, helvetica, arial, sans-serif; 
 
} 
 

 
#cy { 
 
    height: 100%; 
 
    width: 100%; 
 
    position: absolute; 
 
    left: 0; 
 
    top: 0; 
 
} 
 

 
#eat { 
 
    position: absolute; 
 
    left: 1em; 
 
    top: 1em; 
 
    font-size: 1em; 
 
    z-index: -1; 
 
    color: #c88; 
 
}
<!DOCTYPE html> 
 
<!-- This code is for demonstration purposes only. You should not hotlink to Github, Rawgit, or files from the Cytoscape.js documentation in your production apps. --> 
 
<html> 
 
<head> 
 
<link href="style.css" rel="stylesheet" /> 
 
<meta charset=utf-8 /> 
 
<meta name="viewport" content="user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui"> 
 
<title>Images</title> 
 
<script src="cube/node_modules/cytoscape/dist/cytoscape.js"></script> 
 
</head> 
 
<body> 
 
<div id="cy"></div> 
 
<!-- Load appplication code at the end to ensure DOM is loaded --> 
 
<script src="expand.js"></script> 
 
</body> 
 
</html>

Antwort

0

lief Sie die Animationen in der gleichen Zeit. Kettenanimationen unter Verwendung von Versprechen, z. node1.animation().play().promise().then(node2.animation().play.promise()).then(...)

+0

Wie würden Sie .animate() innerhalb des dfs-Stacks verketten? Sie haben nicht wirklich die Liste der Knoten bis zum Ende, es sei denn, Sie schlagen vor, nur dfs zu tun, um die Bestellung zu erhalten, und dann die Verkettung + Versprechungsmethode? – bluepanda

+0

Verketten Sie die Versprechen. Sie können '.then()' überall. – maxkfranz

Verwandte Themen