我试图实现D3拖拽行为,我没有找到一个例子。
下面的代码创建了几行,每行都有一个矩形,圆形和椭圆形,并为圆圈启用了拖动功能。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Drag many</title>
<style media="screen">
.active {
stroke: #000;
stroke-width: 2px;
}
</style>
</head>
<body>
<svg width=1000 height=500></svg>
<script src="https://d3js.org/d3.v4.min.js" charset="utf-8"></script>
<script type="text/javascript">
var svg=d3.select("svg"),
mainGroup = svg.append("g");
var squareData = [
{x:25, y:23, width:15, height:15},
{x:25, y:63, width:15, height:15}
];
var circleData = [
{cx:60, cy:30, r:10},
{cx:60, cy:70, r:10}
];
var ellipseData = [
{cx:90, cy:30, rx:10, ry:15},
{cx:90, cy:70, rx:10, ry:15}
];
var squareGroup = mainGroup.append("g");
squareGroup.selectAll(null)
.data(squareData)
.enter().append("rect")
.attr("class", (d,i)=>`rectGroup row_${i+1}`)
.attr("x", d=>d.x)
.attr("y", d=>d.y)
.attr("width", d=>d.width)
.attr("height", d=>d.height)
.attr("fill", "blue");
circleGroup = mainGroup.append("g");
circleGroup.selectAll(null)
.data(circleData)
.enter().append("circle")
.attr("class", (d,i)=>`circleGroup row_${i+1}`)
.attr("cx", d=>d.cx)
.attr("cy", d=>d.cy)
.attr("r", d=>d.r)
.attr("fill", "red")
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
ellipseGroup = mainGroup.append("g");
ellipseGroup.selectAll(null)
.data(ellipseData)
.enter().append("ellipse")
.attr("class", (d,i)=>`ellipseGroup row_${i+1}`)
.attr("cx", d=>d.cx)
.attr("cy", d=>d.cy)
.attr("rx", d=>d.rx)
.attr("ry", d=>d.ry)
.attr("fill", "green");
function dragstarted(d){
d3.select(this).classed("active", true);
}
function dragended(d){
d3.select(this).classed("active", false);
}
function dragged(d){
//var dx = d3.event.x - d3.select(this).attr("cx")
d3.select(this).attr("cx", d.x = d3.event.x);
// I really need to move all the elements in this row here,
// with the circle being the pivot...
}
</script>
</body>
</html>
&#13;
我想修改圆圈的拖动行为,用它拉动整行,而不是单独移动。
我怎样才能做到这一点?
答案 0 :(得分:1)
看起来你给每一行一个类而不是:
function dragged(d){d3.select(this).attr("cx", d.x = d3.event.x);}
获取该行的类(来自代码的外观,它应该是第二个类):var thisRow = d3.select(this).attr("class").split()[1];
.split()将拆分空格,这就是让类列表吐出结果的方式。
让班级移动所有课程后:
d3.selectAll("." + thisRow).attr("cx", d.x = d3.event.x);
答案 1 :(得分:0)
我不确定是否有更好的方法可以找到row
,但是我是如何使用@pmkroeker
function dragged(d){
var deltaX = d3.event.x - d3.select(this).attr("cx");
d3.select(this).attr("cx", d.x = d3.event.x); // move the circle
// find the row
var row = d3.select(this).attr("class").split(/\s+/).filter(s=>s.startsWith("row_"))[0];
// grab other elements of the row and move them as well
d3.selectAll("."+row).filter(".rectGroup").attr("x", d=>d.x = d.x+deltaX);
d3.selectAll("."+row).filter(".ellipseGroup").attr("cx", d=>d.cx = d.cx+deltaX);
}