Skip to content

Instantly share code, notes, and snippets.

@d3noob
Last active January 13, 2022 22:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save d3noob/204d08d309d2b2903e12554b0aef6a4d to your computer and use it in GitHub Desktop.
Save d3noob/204d08d309d2b2903e12554b0aef6a4d to your computer and use it in GitHub Desktop.
d3.drag with grouped elements in v4

The resulting code (with some minor formatting alterations) from an answer on Stack Overflow to a question about how to group two elements and drag them using d3.drag.

Kudos (and thanks) to Dragon_Slayer for the solution.

A block for the original (not working correctly) code is here.

<!DOCTYPE html>
<meta charset="utf-8">
<style>
.active {
stroke: #000;
stroke-width: 2px;
}
.rect {
pointer-events: all;
stroke: none;
stroke-width: 40px;
}
</style>
<body>
<script src="//d3js.org/d3.v4.min.js"></script>
<script>
var margin = {top: 10, right: 10, bottom: 30, left: 10},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var rectangles = d3.range(10).map(function() {
return {
x: Math.round(Math.random() * (width)),
y: Math.round(Math.random() * (height))
};
});
var color = d3.scaleOrdinal(d3.schemeCategory20);
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
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", 30)
.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("x", d.x = d3.event.x)
.attr("y", d.y = d3.event.y);
d3.select(this).select("rect")
.attr("x", d.x = d3.event.x)
.attr("y", d.y = d3.event.y);
}
function dragended(d) {
d3.select(this).classed("active", false);
}
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment