2016-08-17 6 views
0

J'utilise une disposition de force D3 et tente de réduire des nœuds enfants tout en conservant le graphique corrigé, par ex. en les changeant simplement et l'opacité de leurs liens. Cependant, je n'essaye pas de simplement réduire tous les nœuds à la fois - j'ai en fait un attribut dans chaque nœud appelé "groupe", qui peut être 1,2 ou 3.Disposition de force D3: Réduire le sous-ensemble de nœuds enfants (changement d'opacité)

Lorsque je clique sur un nœud, une info-bulle apparaît avec 3 boutons pour chacun de ces groupes - en cliquant sur le bouton correct, je voudrais que le nœud enfant de ce type s'effondre, mais tous ses enfants (des 3 groupes) s'effondrent également.

Voici le fiddle.

J'ai jusqu'à présent essayé de créer des tableaux des ids de groupe de noeuds et les ID de liaison correspondants, puis utilisez JQuery pour cacher les objets DOM, mais cela ne fonctionne pas:

function collapseNodes(node, collapseType, isCollapsed) { 
    var collapseData = minimise(node, collapseType); 
    var cNodes = collapseData.nodes, 
     cLinks = collapseData.links; 
    console.log(collapseData); 
    var newClass = isCollapsed ? "uncollapsed" : "collapsed"; 

    cNodes.forEach(function(n) { 
     d3.select(n).style("opacity", 0); 
    }); 

    cLinks.forEach(function(l) { 
     d3.select(l).style("opacity", 0); 
    }); 
} 

function minimise(node, assetMinType = "") { 
    // Function to minimise a node 
    var minNodes = []; 
    var minLinks = []; 

    if (node.group == 'asset') { 
     node.children.forEach(function(child) { 
      if (child.group == assetMinType) 
       minimiseRec(child, node.id); 
     }); 
    } 
    else { 
     minimiseRec(node, ""); 

     // We want to keep the top node and link 
     minNodes.shift(); 
     minLinks.shift(); 

    } 

    function minimiseRec(node, parentID) { 
     minNodes.push("#" + node.id); 
     minLinks.push("#parent_" + parentID + "_child_" + node.address); 

     node.children.map(function(child) { 
      minimise(child, node.id); 
     }); 
    } 

    return { nodes: minNodes, links: minLinks }; 
} 

Est-ce que quelqu'un sait comment mieux pour faire ça?

Merci.

Répondre

1

Si c'est seulement l'opacité que vous souhaitez changer c'est assez simple. Je suppose que si vous cachez un nœud enfants, vous voulez cacher les enfants de leurs enfants et ainsi de suite? Je commence par définir une variable d.hiddenNode. C'est ainsi que je peux basculer l'opacité. Je l'ai mis à faux. Et puis sur la fonction clic:

.on('click', function(d) { 
    console.log(d); 
    if(d.hiddenNode){ 
     hideChildren(d, false); 
     d.hiddenNode = false; 
    } else { 
     hideChildren(d, true); 
     d.hiddenNode = true; 
    } 

    }) 

maintenant parce que vous voulez que les enfants des enfants, etc à cacher, vous avez besoin d'une fonction récursive comme si. Celui qui cache les liens et les noeuds (j'ai commenté à expliquer):

function hideChildren(node, hide) { 

    for (var i = 0; i < node.children.length; i++) { 
    recurseChildren(node.children[i]); //loop through children to hide 
    } 

    function recurseChildren(node) { 

    nodeEnter.each(function(d) { //go through all nodes to check for children 
     if (d.index == node.index) { //if child is found 
     d3.select(this).style('opacity', function(){ 
     return hide ? 0 : 1;  //toggle opacity depending on d.hiddenNode value 
     }) //.remove(); 
     } 
    }) 

    link.each(function(d) { //same with links 
     if (d.source.index == node.index || d.target.index == node.index) { //if source or target are hidden hide the link 
     d3.select(this).style('opacity', function(){ 
     return hide ? 0 : 1;   
     }) //.remove(); 
     } 
    }) 

    if (node.children) { //if this node has children, call again but with their children 
     for (var i = 0; i < node.children.length; i++) { 
     recurseChildren(node.children[i]); 
     } 
    } 
    } 
} 

Voici le violon mis à jour: http://jsfiddle.net/thatOneGuy/3g4fqfa8/2/

EDIT

Pour le pop-up je viens de créer un div qui contient 3 groupes, 1,2,3:

<div id='groupChoice'> 
<div id='group1' class = 'group' onclick='hideGroup(1)'>1</div> 
<div id='group2' class = 'group' onclick='hideGroup(2)'>2</div> 
<div id='group3' class = 'group' onclick='hideGroup(3)'>3</div> 
</div> 

Réglez cette option cachée dans CSS:

.group{ 
    width: 50px; 
    height:50px; 
    border : 1px solid black; 
} 

#groupChoice{ 
    visibility:hidden; 
} 

J'ai changé la logique un peu, mais c'est le violon mis à jour avec le commentaire: http://jsfiddle.net/thatOneGuy/3g4fqfa8/3/

Theres un travail qui doit être fait avec les liens. Je n'ai pas assez de temps pour terminer, je suis désolé. Mais cela devrait vous aider à démarrer. Fondamentalement, lorsque vous cliquez sur un nœud, le pop up apparaît, vous avez choisi un groupe à cacher, ils sont cachés. Appuyez à nouveau sur le même noeud, choisissez un noeud à afficher. Cela a été fait super rapide, donc il y a beaucoup de mal avec, mais les bases sont les donc ça devrait aider :)

+0

Je suis désolé d'avoir assez de temps pour terminer. La logique est assez simple, il suffit de vérifier si le nœud appartient au groupe que vous souhaitez cacher et si c'est le cacher et ses enfants – thatOneGuy

+1

Merci beaucoup! – annikam