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

17

Я пытаюсь использовать событие d3.js d3.behavior.drag() drag для обновления моей модели данных (без установки позиции элемента немедленно), а затем запустить мою функцию «draw» для обновления всех элементов на основе обновленной модели. Кроме того, я использую перевод 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()​;
    
задан tlrobinson 26.10.2012 в 00:51
источник

3 ответа

31

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

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

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

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);
}

См. исправленный Fiddle: Ссылка

    
ответ дан nautat 26.10.2012 в 03:47
источник
  • В версии 4 D3 есть функция контейнера, которая позволяет установить другой узел для определения координат. –  user2393229 23.01.2018 в 20:28
5

У меня была такая же проблема, как у Дарвина. Обработчик перетаскивания находится на дочернем объекте, у которого есть 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);   });
    
ответ дан avowkind 25.05.2013 в 01:11
источник
3

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

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

Я отправил запрос на растяжение, чтобы сделать базовое пространство координат настраиваемым: Ссылка

    
ответ дан Antonin Hildebrand 05.02.2013 в 21:16
источник