拖动未分组在 `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圈子的cx
和cy
属性。
注意: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>
我正在使用 D3 的 drag behavior 在强制布局中使用 circleGroup.call(force.drag)
拖动圆形元素,其中 force.drag
是拖动行为,circleGroup
是选择所有圆形元素。这适用于拖动单个元素。
如何一次拖动任意选择的多个圆形元素?
请注意,因为选择必须是任意的,我不认为我可以将我想拖在一起的那些放在一个 <g>
标签中。
我查看了 these questions,但仍然无法正常工作。
你可以做这样的事情......这不是强制布局,但你应该能够很容易地将它扩展到那样。
点击圆圈 select,然后点击并拖动到其他地方移动它们。
基本上,我跟踪数组中 selected 圆圈的索引,并更新 drag
处理程序中的相应数据。数据更新后,我再修改select圈子的cx
和cy
属性。
注意:drag
处理程序附加到覆盖整个 SVG 的透明 rect
,我正在使用 CSS 样式让事件级联到相应的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;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="vis"></div>