Подтвердить что ты не робот

"Заикание" при использовании d3.behavior.drag() и преобразование

Я пытаюсь использовать событие d3.js d3.behavior.drag() drag для обновления моей модели данных (без установки позиции элемента сразу), затем запустите мою функцию "рисования", чтобы обновить все элементы на основе обновленной модели. Кроме того, я использую перевод transform в содержащем элементе группы, чтобы переместить все элементы, связанные с перетаскиваемым объектом (я удалил дополнительные элементы из приведенного ниже примера). Это заставляет затянутые элементы заикаться, когда они перетаскиваются, что ухудшается, тем быстрее вы его перетаскиваете.

Смотрите этот урезанный пример в jsFiddle.

Здесь код примера:

blocks = [
  { x: 0, y: 0 }
];

drag = d3.behavior.drag()
  .origin(Object)
  .on("drag", function(d) {
    d.x = d3.event.x;
    d.y = d3.event.y;
    draw();
  });

svg = d3.select("body")
  .append("svg:svg")
  .attr("width", 600)
  .attr("height", 600);

function draw() {
  g = svg.selectAll("g")
    .data(blocks);

  gEnter = g.enter().append("g");

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

  gEnter.append("rect")
    .attr("height", 100)
    .attr("width", 100)
    .call(drag);
}

draw()​;
4b9b3361

Ответ 1

Вы вызываете drag в элементе rect, но вы преобразуете его родительский элемент: g.

Проблема заключается в том, что компонент drag использует местоположение мыши относительно родителя для определения новых d3.event.x и d3.event.y. Итак, если вы перемещаете (т.е. transform) родительский элемент во время перетаскивания пользователя, все становится беспорядочным.

Решение состоит в вызове drag для того же элемента, который вы перемещаете; в этом случае элемент g:

function draw() {
  g = svg.selectAll("g")
    .data(blocks);

  gEnter = g.enter().append("g")
    .call(drag);

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

  gEnter.append("rect")
    .attr("height", 100)
    .attr("width", 100);
}

См. исправленный скрипт: http://jsfiddle.net/EMNGq/14/

Ответ 2

У меня была такая же проблема, как у Дарвина. Обработчик перетаскивания находится на дочернем объекте, у которого есть D3 Data, но преобразование должно быть применено к родительской группе (а не d3).

Я решил это, установив функцию origin для возврата x: 0, y: 0 и затем используя значение x в событии, а не dx.

например

var drag = d3.behavior.drag()
    .origin(function(d,i) { return {x:0, y:0}; })
    .on("drag", function (d) {  movePosition(d3.event.x);   });

Ответ 3

Nautat предоставил хорошее решение для вашего дела.

Мой случай немного сложнее. Мои данные связаны ниже g- node Я хочу преобразовать. В этом случае я не могу просто переместить .call(перетащить) на g-уровень.

Я отправил запрос на растяжение, чтобы сделать базовое пространство координат настраиваемым: https://github.com/mbostock/d3/pull/1055