拖动未分组在 `g` 标签中的多个元素?

Drag multiple elements that aren't grouped in a `g` tag?

我正在使用 D3 的 drag behavior 在强制布局中使用 circleGroup.call(force.drag) 拖动圆形元素,其中 force.drag 是拖动行为,circleGroup 是选择所有圆形元素。这适用于拖动单个元素。

如何一次拖动任意选择的多个圆形元素?

请注意,因为选择必须是任意的,我不认为我可以将我想拖在一起的那些放在一个 <g> 标签中。

我查看了 these questions,但仍然无法正常工作。


你可以做这样的事情......这不是强制布局,但你应该能够很容易地将它扩展到那样。

点击圆圈 select,然后点击并拖动到其他地方移动它们。

基本上,我跟踪数组中 selected 圆圈的索引,并更新 drag 处理程序中的相应数据。数据更新后,我再修改select圈子的cxcy属性。

注意:drag 处理程序附加到覆盖整个 SVG 的透明 rect,我正在使用 CSS 样式让事件级联到相应的pointer-events: all; 正确应用于 rect.

的 SVG 元素

 var width = 500,
   height = 500;

 var data = d3.range(10).map(function(d) {
   return {
     x: parseInt(Math.random() * width),
     y: parseInt(Math.random() * height),
     r: parseInt(Math.random() * 10 + 10)
   }
 });

 var selectedNodes = [],
   selectedData = [];

 var drag = d3.behavior.drag()
   .on("drag", dragged)

 var vis = d3.select("#vis").append("svg")
   .attr("width", width)
   .attr("height", height);

 var dragRect = vis.append("rect")
   .attr("class", "drag")
   .attr("width", width)
   .attr("height", height)
   .call(drag);

 var nodes = vis.selectAll("circle.node")
   .data(data)
   .enter().append("circle")
   .attr("class", "node")
   .attr("r", function(d) {
     return d.r;
   })
   .attr("cx", function(d) {
     return d.x;
   })
   .attr("cy", function(d) {
     return d.y;
   })
   .on("click", clicked);

 function dragged(d) {
   selectedData.forEach(function(i) {
     data[i].x += d3.event.dx;
     data[i].y += d3.event.dy;
   });

   d3.selectAll("circle.node.selected")
     .attr("cx", function(d) {
       return d.x;
     })
     .attr("cy", function(d) {
       return d.y;
     });
 }

 function clicked(d, i) {
   var j = selectedData.indexOf(i);

   if (j === -1) {
     selectedData.push(i);
     d3.select(this).classed("selected", true);
   } else {
     selectedData.splice(j, 1);
     d3.select(this).classed("selected", false);
   }
 }
        rect.drag {
          fill: none;
          pointer-events: all;
        }
        circle.node {
          fill: #000;
        }
        circle.node:hover {
          cursor: pointer;
        }
        circle.node.selected {
          fill: #f00;
        }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="vis"></div>