I would like to use a D3.js brush to allow users to select a range of values on an axis. By default, clicking outside the brush clears it, so that no range is selected.
d3 brush by design calls 'brushmove()' once a user presses a mouse on the brush element (i.e. on 'mousedown.brush' event). If effectively leads to resetting the previous brush extent.
A possible workaround is to replace the original mousedown.brush handler with the custom one. The custom handler will only call the original handlers once the mouse was moved after initial mousedown.
var brushNode = chart.append("g")
.call(brush);
brushNode
.selectAll("rect")
.attr("y", -10)
.attr("height", 10);
// store the reference to the original handler
var oldMousedown = brushNode.on('mousedown.brush');
// and replace it with our custom handler
brushNode.on('mousedown.brush', function () {
brushNode.on('mouseup.brush', function () {
clearHandlers();
});
brushNode.on('mousemove.brush', function () {
clearHandlers();
oldMousedown.call(this);
brushNode.on('mousemove.brush').call(this);
});
function clearHandlers() {
brushNode.on('mousemove.brush', null);
brushNode.on('mouseup.brush', null);
}
})
See the demo.