У меня возникли проблемы с библиотекой 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;
}
Недостаточно изменить данные, вам также необходимо обновить элементы DOM новыми позициями. –
@LarsKotthoff не должен принудительно выполнять функцию force.drag(), вызвав update()? – Dmitry
Функция перетаскивания не вызовет ничего. Вероятно, вы, вероятно, имеете в виду функцию «tick» обработчика силы - в принципе да, но только в том случае, если макет все еще работает. –