Accepted answer

As I understand, the problem is that dragging working with circles but not with groups, for some reason

You are manipulating the nodes on drag with cx and cy properties. g elements do not have these, so this will not achieve what you want, even if node contained groups rather than circles:

  node.attr("cx", function(d) { return d.x; })
      .attr("cy", function(d) { return d.y; })

As noted,node = g.append("circle") means that you aren't actually manipulating the g elements anyways, which is why your circles move on tick or drag.

Instead, keep node a selection of g elements, and manipulate the transform property:

  // the group representing each node:
  node = node.enter().append("g").merge(node);

  // the circle for each group
  .classed('node', true).attr('id', id)
  .attr("r", 25).attr("fill", function(d) { return color(; });

  // the text for each group
  .classed('text', true)
  .attr("text-anchor", "start")
  .attr("dx", 6).text(id).merge(node);

Then, on click or drag events, just update the transform:


  node.attr("transform",function(d) { return "translate("+d.x+","+d.y+")" ;});


  d.x = d3.event.x;
  d.y = d3.event.y;"transform",function(d) { return "translate("+d.x+","+d.y+")" ;});

Here's an updated fiddle.

More Query from same tag