2015-11-12 1 views
1

я создал 3 группы кругов каждый в разной компоновкой силы:Connect круг узлы differect групп силы-макеты с линиями

(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/

Результат:

ВОПРОС

Есть ли способ добавить линии, соединяющие круги и держать круги на своих позициях?

Разъяснение: линии должны быть подключены к кругам, т.е. обновить свои позиции, когда круги движется

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

UPDATE

Это было достигнуто за счет добавления линии расположения и обновляют свои позиции на tick event

+1

Абсолютно. Я бы дал каждой строке класс, который вы можете получить из данных источника и целевого узла, который однозначно идентифицирует его, чтобы его можно было выбрать, зная только источник или цель. Тогда все, что вам нужно, это сделать именно так и обновить координаты с обоих концов в функции обработчика 'tick' соответствующего макета силы. –

+0

Это именно то, что я только что сделал, и это решило проблему. Спасибо – Dmitry

ответ

0

Что касается вашего вопроса, чтобы предотвратить перемещение кругов:

Вы можете позвонить force.alpha(0), чтобы остановить движение через некоторое время, а затем resume() макет на mouseout. Может быть, это может работать для вас в зависимости от того, что вы хотите сделать: 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(); 
       });  

Вы должны ALSE очистить тайм-аут, если MouseOut происходит до истечения тайм-аута.

+0

Я не думаю, что это вопрос - ОП спрашивает, как обновить позиции линий по мере перемещения кругов. –

+0

Возможно, я неправильно понял вопрос. Было бы неплохо, если бы ОП еще раз разъяснил вопрос. – kmandov

Смежные вопросы