2015-11-12 6 views
1

j'ai créé 3 groupes de cercles chacun dans une présentation différente de la force:noeuds de cercle Connexion de groupes differect mises en force avec des lignes

(function() { 
    /****** Functions ******* 
    ************************/ 
    var rand = function (min, max) { 
     return Math.floor(Math.random() * (max - min + 1)) + min; 
    }; 

    /****** Variables ******* 
    ************************/ 
    var i, 
     color, 
     width = 400, 
     height = 400, 
     forces = [], 
     coords, 
     _linksData, _nodesData, 
     mainContainer; 

    /** Coordinates of groups **/ 
    coords = [ 
     [0, 0], 
     [width, 0], 
     [width * 2, 0], 
    ]; 

    color = d3.scale.category10(); 

    /****** Main SVG container ******* 
    *********************************/ 
    mainContainer = d3.select("#main-container").append("svg") 
     .attr("width", 1165) 
     .attr("height", 650) 
     .append("g"); 

    for (i = 0; i < 3; i++) { 
     forces[i] = d3.layout.force(); 

     (function() { 
      /****** Generate Random Data for one Group ******* 
      *************************************************/ 

      /** Random amount of circles with random radius **/ 
      _nodesData = d3.range(rand(25, 45)).map(function (d, i) { 
       return { 
        id  : i, 
        radius : rand(6, 18) 
       } 
      }); 

      /** 
      Add children to group with 0 radius in order to have d3 
      position it in center and put all other circles in its orbit 
      **/ 
      _nodesData.push({ 
       children : d3.range(_nodesData.length), 
       radius : 0 
      }); 

      /** Add links **/ 
      _linksData = d3.layout.tree().links(_nodesData); 


      /****** Create Group Container ******* 
      *************************************/ 
      var groupContainer = mainContainer.append("g") 
       .attr('class', 'group') 
       .attr('id', 'group' + i) 
       .attr('transform', 'translate(' + coords[i][0] + ',' + coords[i][1] + ')') 
       .on('mouseenter', function() { 
        var index = d3.select(this).attr('id').replace('group', ''); 
        // console.log(index); 
        forces[index].alpha(.25); 
       }); 

      var nodesObjects = groupContainer.selectAll(".node"); 
      var linksObjects = groupContainer.selectAll(".link") 

      /****** Force Layout ******/ 
      forces[i].linkDistance(function() { 
        return rand(110, 130) 
       }) 
       .charge(function() { 
        return -rand(150, 200) 
       }) 
       .gravity(0.1 + 1/rand(10, 50)) 
       .size([width, height]) 
       .on("tick", tick) 
       .nodes(_nodesData) 
       .links(_linksData) 
       .start(); 

      /****** links ******/ 
      // linksObjects = linksObjects.data(_linksData) 
      //  .enter() 
      //  .append("line").attr('class', 'link') 
      // 
      // ; 

      /****** Create nodes ******/ 
      nodesObjects = nodesObjects.data(_nodesData, function (d) { 
        return d.id; 
       }) 
       .enter().append("g") 
       .attr("class", "node") 
       .on('mouseover', function() { 
        d3.select(this).moveToFront(); 
       }); 


      /****** Create circles ******/ 
      nodesObjects.append("circle") 
       .attr("r", function (d) { 
        return d.radius; 
       }).style("fill", color(i)); 


      function tick() { 
       linksObjects.attr({ 
        x1 : function (d) { 
         return d.source.x; 
        }, 
        y1 : function (d) { 
         return d.source.y; 
        }, 
        x2 : function (d) { 
         return d.target.x; 
        }, 
        y2 : function (d) { 
         return d.target.y; 
        } 
       }); 

       nodesObjects.attr("transform", function (d) { 
        return "translate(" + d.x + "," + d.y + ")"; 
       }); 
      } 

     })(); 
    } 
}()) 

http://jsfiddle.net/dmitrychuba/h69wqvcy/2/

Résultat:

QUESTION

Existe-t-il un moyen d'ajouter des lignes reliant des cercles et garder des cercles sur ses positions?

Précision: les lignes doivent être connectées à des cercles, à savoir mettre à jour leurs positions quand les cercles se déplace

http://jsfiddle.net/dmitrychuba/h69wqvcy/2/

MISE À JOUR

Il a été réalisé par l'ajout de lignes mise en page et la mise à jour leurs positions sur tick even

+1

Absolument. Je donnerais à chaque ligne une classe que vous pouvez déduire des données du noeud source et du noeud cible qui l'identifie de façon unique, de sorte qu'il puisse être sélectionné en ne connaissant que la source ou la cible. Il suffit alors de faire exactement cela et de mettre à jour les coordonnées de chaque côté dans la fonction «tick» du handler. –

+0

C'est exactement ce que je viens de faire, qui a résolu le problème. Merci – Dmitry

Répondre

0

Concernant votre question afin d'éviter que les cercles ne bougent:

Vous pouvez appeler force.alpha(0) pour arrêter le mouvement après un certain temps, puis resume() la disposition sur mouseout. Peut-être que cela peut fonctionner pour vous en fonction de ce que vous voulez faire: http://jsfiddle.net/h69wqvcy/3/

  var groupContainer = mainContainer.append("g") 
       .attr('class', 'group') 
       .attr('id', 'group' + i) 
       .attr('transform', 
       'translate(' + coords[i][0] + ',' + coords[i][1] + ')') 
       .on('mouseenter', function() { 
        var index = d3.select(this).attr('id').replace('group', ''); 
        // console.log(index); 
        forces[index].alpha(0.25); 
        setTimeout(function() { 
         forces[index].alpha(0); 
        }, 1000); 
       }) 
       .on('mouseout', function() { 
        var index = d3.select(this).attr('id').replace('group', ''); 
        // console.log(index); 
        forces[index].resume(); 
       });  

Vous devriez ALSE effacer le délai d'attente si mouseout a lieu avant l'expiration du délai.

+0

Je ne pense pas que c'est la question - OP demande comment mettre à jour les positions des lignes que les cercles se déplacent. –

+0

peut-être que j'ai mal compris la question. Ce serait bien que le PO clarifie la question une fois de plus. – kmandov