(edit: well, my supposition ended up being wrong, see the other answer)
Two years after this very interesting question was posted I had a glimpse of the probable solution to this mystery. However, a good deal of supposition remains: only Mike Bostock, the author of that code, has the real answer (provided that he still remembers why he did it that way).
As OP mentioned, this thisArg in the map function is irrelevant:
x.domain(s.map(x2.invert, x2));
//this bit here -----------^
That's because the invert method of the scale needs no this value.
However, if we look some dozen lines further down at that same code, we'll find this:
context.select(".brush").call(brush.move, x.range().map(t.invertX, t));
And here we find thisArg again:
x.range().map(t.invertX, t)
//thisArg ---------------^
The reason for this, if we look at the source code for invertX, is that invertX needs a value to use as this:
invertX: function(x) {
return (x - this.x) / this.k;
}
And here comes my supposition: invert and invertX are quite similar names and, even despite Bostock had invented them and had written countless D3 codes, he confused the two and set the thisArg for x2.invert, which although being unnecessary didn't break the code, and went unnoticed by the author.
One extra argument in favour of this supposition is that, in both cases, he used the object as the thisArg. Compare:
x2.invert, x2
| |
t.invertX, t