I use a transform when panning, copied from several examples.
zoom = d3.behavior.zoom()
.x(this.xScale)
.scaleExtent([0.5, 2])
.on("zoom", zoomFunction(this))
.on("zoomend", zoomEndFunction(this));
svg = histogramContainer.append("svg")
.attr('class', 'chart')
.attr('width', width)
.attr('height', height)
.call(zoom)
.append('g')
.attr('transform', 'translate(' + this.margin.left + ' , ' +
(height - this.margin.bottom) + ')');
function zoomFunction(scope) {
return function() {
var that = scope;
that.xDelta = d3.event.translate[0];
that.zoomScale = d3.event.scale;
// some other code removed for simplicity
svg.selectAll(".stackedBar").attr("transform", "translate(" +
that.xDelta + ",0)scale(" +
that.zoomScale + ", 1)");
};
}
The problem is that since new elements enter after the pan then 'old' elements have the transform attribute applied but the new elements don't.
This breaks future panning because the old elements will be transformed from where the pre-zoom xScale drew them while the new elements will be transformed from the zoom-adjusted xScale.
It seems to me that I could redraw the old elements with the zoom-adjusted xScale, though I'm unsure when and how to do that "behind the scenes".
Alternatively I could draw the new elements with the old xScale and apply the same transform on them that the old elements have. This seems messier since elements will come and go and I'll have to keep track of the 'current transform'. My gut tells me "too much state".