I am nesting a lot of elements inside of a g element like so:
...
I have a similar sort of issue (http://jsfiddle.net/j8RZN/1/), except the suggested workaround does not seem to be helping.
userBox.data([userBox]).call(d3.behavior.drag() //makes the box to move
//titleBox.data([userBox]).call(d3.behavior.drag() //does not make the box move
.on("dragstart", function() {})
.on("drag", function(d, i) {
console.log('box being dragged');
d.attr("transform", "translate(" + (d3.event.x) + "," + (d3.event.y) + ")");
})
.on("dragend", function() {}));
circleDrag.call(d3.behavior.drag()
.on("dragstart", function() {})
.on("drag", function(d, i) {
d3.event.sourceEvent.stopPropagation();
console.log('small rectangle being dragged');
})
.on("dragend", function() {}));
An SVG <g> element does not have a size or area; it is a transparent container for all its descendants, and cannot intercept events for other elements (unless you are adding an event listener to be triggered during the 'capture phase').
As a parent element, events bubble up to it; likely what you are seeing is that whatever event you're using to trigger the drag start (mousedown?) on the <rect> is also bubbling up to the <g> and starting a concurrent drag of that.
To fix this, you want to stop your event from bubbling. In your event handler for the mousedown (or whatever) on the <rect> add:
function startDrag(evt){
// whatever your code is here
evt.stopPropagation();
}
Without your actual code (or better, a pared-down test case) it's hard to know for sure, or help you further.
Edit Here's a working version of your simple example: http://jsfiddle.net/ZrCQE/2/
Specifically, apparently d3.event is not the event itself, but an object with a sourceEvent property that references the actual event.
var dragGroup = d3.behavior.drag()
.on('dragstart', function() {
console.log('Start Dragging Group');
}).on('drag', function(d, i) {
d.x += d3.event.dx;
d.y += d3.event.dy;
d3.select(this).attr("transform", "translate("+d.x+","+d.y+")");
});
var dragCircle = d3.behavior.drag()
.on('dragstart', function(){
d3.event.sourceEvent.stopPropagation();
console.log('Start Dragging Circle');
})
.on('drag', function(d,i){
d.cx += d3.event.dx;
d.cy += d3.event.dy;
d3.select(this).attr('cx', d.cx).attr('cy', d.cy)
});
var svg = d3.select('body').append('svg').attr('viewBox','-50 -50 300 300');
var g = svg.selectAll('g').data([{x:10,y:10}])
.enter().append('g').call(dragGroup);
g.append('rect').attr('width', 100).attr('height', 100);
g.selectAll('circle').data([{cx: 90,cy:80}])
.enter().append('circle')
.attr('cx', function(d){ return d.cx })
.attr('cy', function(d){ return d.cy })
.attr('r', 30)
.call(dragCircle);