拖动多个未分组在`g`标记中的元素? [英] Drag multiple elements that aren't grouped in a `g` tag?
问题描述
我正在使用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
处理程序中更新相应的数据.数据更新后,我然后修改所选圆的cx
和cy
属性.
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屋!