Accepted answer

The following seems to work as desired

var zoom = d3.zoom().on("zoom", zoomed).scaleExtent([1 / 2, 8]);

function zoomed() {
  g.attr("transform", d3.event.transform); // updated for d3 v4

var svg ="#chart").append("svg")
    .on("touchmove mousemove", moved)
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + + margin.bottom)

var g = svg.append("g");, d3.zoomIdentity.translate(400, 200).scale(0.4));

I'm still not sure what the problem was. Going back to the original code, the transform was correctly applied to g and the transformation erased this without explanation.

One difference is that I define g seperately, maybe that is related.

More Query from same tag