While playing with the brush event yesterday, I noticed that when I click and clear the brush, the line chart of the focus area stays the same. I would expect it to reset to the full dataset. So I added the reset component in the brushed function.
Reset after clearing the selection

function brushed(event) {
if (event.selection === null) {
xScale.domain(d3.extent(dataset, xAccessor))
//reset the domain
focus.select(".x-axis")
.call(d3.axisBottom().scale(xScale))
//generate the x-axis
line.attr("d", endLineGenerator(dataset))
//generate the line
} else {
... //previous code in this function
}
}
Adding Handle
This improvement is to add a visual cue for dragging the brush. I saw this Brush Handles example by Mike Bostock on Observable. Why not add one? 🙂

Brush handles are created by “d3.arc( )”; we are actually drawing two half circles. We need a left one and a right one. We used the identifier “w” for the left handle and “e” for the right handle. This distinction allows us to apply different shapes to each handle based on its type. Here, we will have different “startAngle” and “endAngle”.

const handle = context.selectAll(".custom-handle")
.data([{ type: "w" }, { type: "e" }])
.enter().append("path")
.attr("class", "custom-handle")
.attr("fill", "#666")
.attr("fill-opacity", 0.8)
.attr("stroke", "#000")
.attr("stroke-width", 1.5)
.attr("cursor", "ew-resize")
.attr("d", d3.arc()
.innerRadius(0)
.outerRadius(chartHeight2 / 2)
.startAngle(d => { return d.type === "w" ? Math.PI : 0; })
.endAngle(d => { return d.type === "w" ? 2 * Math.PI: Math.PI; }))
.attr("display", "none")
The handle is initially set to invisible. Later, when we have the selection, we will change it to (“display”, null) and translate our handles to the correct position – the left side and the right side of the brush.
// Only set handle positions if they're defined
if (typeof s0 !== "undefined" && typeof s1 !== "undefined") {
handle.attr("display", null)
.attr("transform", (d, i) =>
`translate(${i === 0 ? s0 : s1},
${chartHeight2 / 2 + 2.5})`)
//+2.5 because I added 5 to the x-axis as well
}