我正在使用D3的drag behavior来拖动包含circleGroup.call(force.drag)
的力布局中的圆形元素,其中force.drag
是拖动行为,circleGroup
是所有圈子的选择元素。这适用于拖动单个元素。
如何一次拖动多个圆形元素的任意选择?
请注意,因为选择必须是任意的,所以我认为我不能将我想要在<g>
标记中拖动的那些分组。
答案 0 :(得分:2)
你可以做这样的事情......这不是一种力量布局,但是你应该能够很容易地扩展它。
单击一个圆圈将其选中,然后单击并拖动到其他位置以移动它们。
基本上,我正在跟踪数组中所选圆圈的索引,并更新drag
处理程序中的相应数据。数据更新后,我会修改所选圈子的cx
和cy
属性。
注意: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;
}