Javascript &引用;口吃;使用d3.behavior.drag()和transform时拖动

Javascript &引用;口吃;使用d3.behavior.drag()和transform时拖动,javascript,d3.js,Javascript,D3.js,我试图使用d3.js的d3.behavior.drag()drag事件来更新我的数据模型(不立即设置元素位置),然后运行我的“draw”函数根据更新的模型更新所有元素。此外,我在包含组元素上使用translatetransform,以移动与拖动对象关联的所有元素(我从下面链接的示例中删除了额外的元素)。这会导致被拖动的元素在拖动时结巴,拖得越快,情况就越糟 看 下面是示例的代码: blocks = [ { x: 0, y: 0 } ]; drag = d3.behavior.drag()

我试图使用d3.js的
d3.behavior.drag()
drag
事件来更新我的数据模型(不立即设置元素位置),然后运行我的“draw”函数根据更新的模型更新所有元素。此外,我在包含组元素上使用translate
transform
,以移动与拖动对象关联的所有元素(我从下面链接的示例中删除了额外的元素)。这会导致被拖动的元素在拖动时结巴,拖得越快,情况就越糟

下面是示例的代码:

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()​;

您在
rect
元素上调用
drag
,但您正在转换它的父元素:
g
元素

问题在于,拖动组件使用鼠标相对于父对象的位置来确定新的
d3.event.x
d3.event.y
。因此,如果在用户拖动时移动父对象(即
变换
),事情就会变得一团糟

解决方案是在移动的同一个元素上调用
拖动
;在这种情况下,
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);
}

请参阅更正的小提琴:

Nautat为您的案例提供了很好的解决方案

我的案子稍微复杂一点。我的数据绑定在我要转换的g节点下面。在这种情况下,我不能简单地移动。调用(拖动)到g级

我提交了一个pull请求,以使基础坐标空间可定制:
我和达尔文有同样的问题。拖动处理程序位于附加了D3数据的子对象上,但转换需要应用于父组(而不是D3)

我通过将origin函数设置为返回x:0,y:0,然后在事件中使用x值而不是dx来解决这个问题

e、 g

在D3的版本4中,有一个函数允许设置其他节点来确定坐标。
var drag = d3.behavior.drag()
    .origin(function(d,i) { return {x:0, y:0}; })
    .on("drag", function (d) {  movePosition(d3.event.x);   });