当我拖动元素切换/更改其位置时,如何防止svg的“g”元素在其他“g”元素上重叠。 以下是代码的链接。
https://jsfiddle.net/3jxqgjcL/
var group = svg.selectAll('g')
.data(rectangles)
.enter().append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")")
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
group.append("rect")
.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; })
.attr("height", 60)
.attr("width", 300)
.style("fill", function(d, i) { return color(i); });
group.append("text")
.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; })
.attr("text-anchor", "start")
.style("fill", "steelblue")
.text("Close");
function dragstarted(d) {
d3.select(this).raise().classed("active", true);
}
function dragged(d) {
d3.select(this).select("text")
.attr("y", d.y = d3.event.y);
d3.select(this).select("rect")
.attr("y", d.y = d3.event.y);
}
function dragended(d) {
d3.select(this).classed("active", false);
}
答案 0 :(得分:1)
你的问题并不完全清楚。我假设通过防止svg的“g”元素重叠,当你释放其中一个时,你想要重新排列组。
在这种情况下,您可以获取<g>
函数中的所有dragended
元素,对它们进行排序并根据它们的索引进行翻译:
function dragended(d) {
d3.select(this).classed("active", false);
var theseGroups = svg.selectAll(".groups").sort(function(a, b) {
return d3.ascending(a.y, b.y);
});
theseGroups.attr("transform", function(d, i) {
return "translate(" + margin.left / 2 + "," + (d.y = barHeight * i) + ")";
})
}
这是一个演示:
var margin = {
top: 10,
right: 10,
bottom: 30,
left: 10
},
width = 500 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom
distance = 0, barHeight = 75, i = 0;
function yAxis() {
if (i == 0) {
i++;
return 2;
} else {
distance = parseInt(barHeight) * i;
i++;
return distance;
}
}
var rectangles = d3.range(5).map(function() {
return {
x: 5,
y: Math.round(yAxis())
};
});
var color = d3.scaleOrdinal(d3.schemeCategory10);
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
var group = svg.selectAll('g')
.data(rectangles)
.enter().append("g")
.attr("class", "groups")
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")"
})
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
group.append("rect")
.attr("height", 60)
.attr("width", 300)
.style("fill", function(d, i) {
return color(i);
});
group.append("text")
.attr("text-anchor", "start")
.style("fill", "steelblue")
.text("Close");
function dragstarted(d) {
d3.select(this).raise().classed("active", true);
}
function dragged(d) {
d3.select(this).attr("transform", "translate(" + margin.left / 2 + "," + (d.y = d3.event.y) + ")");
}
function dragended(d) {
d3.select(this).classed("active", false);
var theseGroups = svg.selectAll(".groups").sort(function(a, b) {
return d3.ascending(a.y, b.y);
});
theseGroups.attr("transform", function(d, i) {
return "translate(" + margin.left / 2 + "," + (d.y = barHeight * i) + ")";
})
}
svg {
border: 1px solid #000;
}
<script src="https://d3js.org/d3.v4.min.js"></script>