拖动多个不在“g”标签中分组的元素?

时间:2015-02-19 05:30:57

标签: javascript svg d3.js

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

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

请注意,因为选择必须是任意的,所以我认为我不能将我想要在<g>标记中拖动的那些分组。

我看过these questions但仍无法让它发挥作用。


1 个答案:

答案 0 :(得分:2)

你可以做这样的事情......这不是一种力量布局,但是你应该能够很容易地扩展它。

单击一个圆圈将其选中,然后单击并拖动到其他位置以移动它们。

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

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

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