2015-05-19 9 views
3

Я построил регулярную «сетку», которая размещает узлы в равномерно расположенных точках по сетке. Затем, рандомизируя linkDistance, я могу «разжечь» сетку, чтобы она была менее регулярной.«Пиннинговые» узлы в графике, ориентированном на D3

Я хотел бы «прикрепить» все граничные точки так, чтобы они не двигались, оставляя только внутренние точки, на которые воздействует силовая компоновка.

Мое понимание заключалось в том, что, поскольку это обычная квадратная сетка, любые точки с весом менее 4 будут «краевой» точкой и, следовательно, должны быть закреплены.

Я полагаю, что вес вычисляется только после того, как узлы и ссылки, которые были добавлены к макету силы, поэтому я forEach ING через nodes массив, после добавления его в макет силы и условно установки fixed собственности на основе по весу.

Затем я повторно использую имущество nodes и start Моделирование.

Неплохо. В примере я прикрепляю ВСЕ точки перемещения.

force = d3.layout.force() 
       .size([w, h ]) 
       .nodes(nodes) 
       .links(links) 
       .linkDistance(function(d){ return Math.random() * GRID_SPACING; }) 
       .linkStrength(1) 
       .charge(0) 
       .gravity(0) 
       .friction(.5) 
       .on("tick", function() { 
        d3links.attr("x1", function(d) { return d.source.x; }) 
         .attr("y1", function(d) { return d.source.y; }) 
         .attr("x2", function(d) { return d.target.x; }) 
         .attr("y2", function(d) { return d.target.y; }); 

        d3nodes.attr("cx", function(d) { return d.x; }) 
         .attr("cy", function(d) { return d.y; }); 
       }); 

      // "Pin" all the edge nodes. 
      nodes.forEach(function(node){ 
       if (node.weight < 4){ 
        node.fixed = true; 
       } 
      }); 

      force.nodes(nodes).start(); 

ответ

1

Ваша проницательность хорошая! Но времени это все ...
«Старт» событие срабатывает после того, как вес был инициализирован так это должно работать ...

force = d3.layout.force() 
    .size([w, h]) 
    .nodes(nodes) 
    .links(links) 
    .linkDistance(function (d) { return Math.random() * GRID_SPACING; }) 
    .linkStrength(1) 
    .charge(0) 
    .gravity(0) 
    .friction(.5) 
    .on("tick", function() { 
     d3links.attr("x1", function (d) { return d.source.x; }) 
       .attr("y1", function (d) { return d.source.y; }) 
       .attr("x2", function (d) { return d.target.x; }) 
       .attr("y2", function (d) { return d.target.y; }); 

     d3nodes.attr("cx", function (d) { return d.x; }) 
       .attr("cy", function (d) { return d.y; }); 
    }) 
    .on("start", function() { 
     // "Pin" all the edge nodes. 
     nodes.forEach(function (node) { 
      if (node.weight < 4) { 
       node.fixed = true; 
      } 
     }); 
    }) 


force.nodes(nodes).start(); 

(Если вы хотите включить поведение сопротивления, то вам нужно будет повторно -fix после dragend также.)

+0

Это было! Поэтому я предполагаю, что весы не вычисляются до тех пор, пока не начнется макет силы. В моем коде я не начинал макет, поэтому весы были не определены, поэтому ни один из узлов не соответствовал моим критериям «закрепления». Странно, что это не ошибка. –

+0

Не нужно угадывать @TomAuger, просто прочитайте код d3, его довольно прямолинейный в этом модуле. ;) –