2013-06-21 3 views
0

Я пытаюсь заставить мою сеть D3 замерзнуть после того, как она достигнет красивого макета (альфа достигает 0). Я хочу, чтобы сила полностью остановилась, даже когда узел перетаскивается (пользователь должен иметь возможность вручную изменять узлы). Я думаю, что знаю, как сделать вторую часть этого, изменив функции, которые вызываются на mousedown и mouseup для узлов. Тем не менее, я не могу получить исходный макет и замораживание для работы.D3: Показать расположение сети, затем остановить силу

Я рассмотрел примеры для "static" force layouts, где сеть отображается только после завершения компоновки. Тем не менее, я хочу, чтобы сеть отображалась по мере достижения стабильной компоновки. Я добавил это в конце функции, которая втягивает сети:

while (force.alpha() >0.005) { 
    force.tick(); 
} 
force.stop(); 

С этим дополнением, сеть не отображается, пока не доберется до force.stop(). Кто-нибудь знает, как я могу отобразить его, пока он «тикает»?

EDIT: Вот моя реализация функции tick:

function tick(e) { 

console.log(force.alpha()); 
if (force.alpha() <0.05) { 
    force.stop(); 
} 
var h = svgH; 

if (e.alpha < 0.05) { 
    var q = d3.geom.quadtree(nodes), 
    i = 0, 
    n = nodes.length; 

    while (++i < n) { 
     q.visit(collide(nodes[i], e.alpha)); 
    } 
} 


path.attr("d", function(d) { 

    // Total difference in x and y from source to target 
    diffX = d.target.x - d.source.x; 
    diffY = d.target.y - d.source.y; 

    // Length of path from center of source node to center of target node 
    pathLength = Math.sqrt((diffX * diffX) + (diffY * diffY)); 

    // x and y distances from center to outside edge of target node 
    offsetX = (diffX * d.target.radius)/pathLength; 
    offsetY = (diffY * d.target.radius)/pathLength; 

    if (d.target.y < d.source.y) { 
     var avgY = (d.target.y + d.source.y)/2; 

     if (d.target.fixed != true) { 
      d.target.y = avgY; 
     } 
     if (d.source.fixed != true) { 
      d.source.y = avgY; 
     } 
    } 

    return "M" + d.source.x + "," + d.source.y + "L" + (d.target.x - offsetX) + "," + (d.target.y - offsetY); 
}); 

// Keep circles within bounds of screen 
var r = 6; 
circle.attr("cx", function(d) { return d.x = Math.max(r + d.radius, Math.min(w - r, d.x)); }) 
     .attr("cy", function(d) { 
      return d.y = Math.max(d.radius, Math.min(h - d.radius, d.y)); 
     }); 

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

ответ

0

Проверить состояние остановки в обработчике события tick - таким образом, вы можете перерисовать сеть на каждом тике и остановиться.

+0

Я добавил эту проверку в начале обработчика 'tick': if (force.alpha() <0.005) {force.stop(); } '. Я также печатаю альфа прямо перед проверкой. 'stop()' устанавливает альфа-значение в ноль, но по какой-то причине моя сеть продолжает дрейфовать, даже когда alpha равна нулю ... может ли это быть так, как я реализовал функцию tick? – FrancesKR

+0

Возможно. Если вы продемонстрируете свою реализацию, я смогу судить об этом лучше :) –

+0

Я добавил реализацию к своему сообщению (я использую 0,05 вместо 0,005). Странно то, что как только он достигает стабильной сети, каждый раз, когда я его беспокою, после этого он будет «повторно нагреваться», а затем замораживается после альфа <0,05. Это первый раз, когда это не работает. – FrancesKR