2015-05-07 2 views
1

У меня возникли проблемы с библиотекой d3.D3: Возможно ли предотвратить выход объекта из границ?

У меня есть несколько узлов с включенной функцией force.drag(). Я хочу, чтобы они остались внутри какого-нибудь сквайра. Я пытался этот подход:

var force = d3.layout.force() 
    .size([w, h]) 
    .charge(-40) 
    .linkDistance(getLinkDistance) 
    .gravity(0.01); 

var drag = force.drag() 
    .on("dragstart", onDragStart) 
    .on("drag", onDrag);  

function onDragStart(d) { 
    d.fixed = true; 
} 

function onDrag(d) { 
    if (d.x < 0) 
    d.x = 0; 
    if (d.x > w) 
    d.x = w; 
    if (d.y < 0) 
    d.y = 0; 
    if (d.y > h) 
    d.y = h; 
} 

var newNodes = gnodes.enter().append("svg:g") 
     .attr("class", "node") 
     .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }) 
     .call(drag); 

К сожалению, функция перетаскивания, кажется, игнорирует это, и объект все еще находится в состоянии выйти за пределы и становятся невидимыми. Как я могу предотвратить функцию перетаскивания для перемещения объектов за пределы моих границ? Чтобы прояснить, только объект перетаскивания должен оставаться внутри сквайра, остальные могут сбрасывать все, что захотят.

Обновление:

я частично решить эту проблему путем добавления события dragend и отпуская узел там, если координаты не так. Теперь узел вернется извне экрана, по крайней мере. Тем не менее я не могу манипулировать его координатами.

var drag = force.drag() 
    .on("dragstart", onDragStart) 
    .on("dragend", onDragEnd); 


function onDragStart(d) { 
    d.fixed = true; 
} 

function onDragEnd(d) { 
    if (d.x < 0 || d.x > w || d.y < 0 || d.y > h) 
    d.fixed = false; 
} 
+1

Недостаточно изменить данные, вам также необходимо обновить элементы DOM новыми позициями. –

+0

@LarsKotthoff не должен принудительно выполнять функцию force.drag(), вызвав update()? – Dmitry

+0

Функция перетаскивания не вызовет ничего. Вероятно, вы, вероятно, имеете в виду функцию «tick» обработчика силы - в принципе да, но только в том случае, если макет все еще работает. –

ответ

1

Просто решил, что. Появляется координаты px и py:

var drag = force.drag() 
    .on("dragstart", onDragStart) 
    .on("drag", onDrag); 

function validate(x, a, b) { 
    if (x < a) x = a; 
    if (x > b) x = b; 
    return x; 
} 

function onDragStart(d) { 
    d.fixed = true; 
} 

function onDrag(d) { 
    d.px = validate(d.px, 0, w); 
    d.py = validate(d.py, 0, h); 
} 
Смежные вопросы