拖动多个未分组在`g`标记中的元素? [英] Drag multiple elements that aren't grouped in a `g` tag?

查看:78
本文介绍了拖动多个未分组在`g`标记中的元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用D3的拖动行为将圆形元素拖动到使用circleGroup.call(force.drag)进行强制布局,其中force.drag是拖动行为,而circleGroup是所有圆形元素的选择.这对于拖动单个元素效果很好.

I'm using D3's drag behavior to drag circle elements in a force layout with circleGroup.call(force.drag), where force.drag is a drag behavior and circleGroup is a selection of all circle elements. This works fine for dragging a single element.

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

How can I drag an arbitrary selection of multiple circle elements all at once?

请注意,因为选择必须是任意的,所以我认为我不能只将要拖动的内容分组到<g>标记中.

Note that because the selection must be arbitrary, I don't think I can just just group the ones I want to drag together in a <g> tag.

我查看了这些

I've looked at these questions and still haven't been able to get it working.

推荐答案

您可以执行以下操作……这不是强制布局,但是您应该能够轻松地将其扩展到该范围.

You could do something like this... It's not a force layout, but you should be able to extend it to that pretty easily.

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

Click on a circle to select it, and then click and drag somewhere else to move them around.

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

Basically, I'm keeping track of the index of the selected circles in an array, and updating the corresponding data in the drag handler. After the data is updated, I then modify the cx and cy attributes of the selected circles.

注意:drag处理程序附加到覆盖整个SVG的透明rect上,并且我使用CSS样式来获取事件,并将pointer-events: all;应用于rect.

Note: the drag handler is attached to a transparent rect that covers the entire SVG, and I'm using CSS styles to get the events to cascade to the respective SVG elements correctly with pointer-events: all; applied to the 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;
        }

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="vis"></div>

这篇关于拖动多个未分组在`g`标记中的元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆