HAHS.
Back to Catalog

Brush and Link

interaction

Also known as: brushing, brush selection, rubber band selection, region select

Enable explorationFilter / focusShow relationship NumericalTemporalCategorical

Description

Brush and link is a coordinated selection technique in which the user drags to define a rectangular (or sometimes free-form) region on a chart, selecting all data marks that fall within that region. The selected set is then highlighted in the current view and, critically, in all linked views that share the same underlying data. This tight coupling between brushing in one view and highlighting in another is one of the most powerful techniques in multi-view visualization.

The concept traces back to the work of Becker and Cleveland (1987) on “brushing scatterplots” and was formalized in systems like XGobi and GGobi. The key insight is that patterns invisible in one projection of the data often become visible when the user isolates a subset via brushing in another projection. For example, brushing a cluster in a scatterplot of (x1, x2) might reveal that those points form a distinct band in a parallel coordinates plot of all dimensions.

Brushing is fundamentally different from click-to-select because it operates on spatial regions rather than individual marks. This makes it natural for continuous data spaces (scatterplots, time series) where the user’s analytical question is “what happens in this range?” rather than “tell me about this specific point.” D3.js provides a first-class brush module (d3-brush) that handles all the pointer event management, and most modern visualization libraries offer equivalent primitives.

Brush And Link — try it yourself

When to Use

  • When the user needs to select a contiguous subset of points in a scatterplot, time series, or histogram.
  • When coordinated views are available and the analytical value comes from seeing how a subset in one view maps to other views.
  • When the data is continuous and the natural selection unit is a range (of time, of values) rather than individual items.
  • For exploratory data analysis tasks where the user does not know in advance which subsets are interesting.
  • As a precursor to computing summary statistics, fitting models, or exporting data for a selected subset.

When NOT to Use

  • When the chart has very few marks (under 10-15) — click-to-select is simpler and more precise.
  • When the data is purely categorical with no meaningful spatial ordering to brush over.
  • On small mobile screens where a drag gesture is likely to conflict with scroll or pan.
  • When the brush region would always select all-or-nothing due to the chart’s visual density.

How It Works

  1. The user presses and drags on the chart surface, creating a visible rectangular overlay (the “brush extent”).
  2. The system performs hit-testing to determine which data marks fall within (or intersect) the brush extent.
  3. Selected marks are visually emphasized (full opacity, bold stroke); non-selected marks are dimmed.
  4. In linked views, the same data items are highlighted, even though their spatial positions differ.
  5. The user can resize or move the brush by dragging its edges or interior. The selection updates in real time.
  6. Releasing the brush (or clicking outside it) may either persist the selection or clear it, depending on the implementation.

Variations

  • 1D brush: A horizontal or vertical brush that selects a range along one axis. Common on time-series charts and histograms.
  • 2D brush: A rectangular brush that selects on both axes simultaneously. Standard for scatterplots.
  • Lasso brush: Free-form drawing to select an irregular region. More expressive but harder to adjust.
  • Multi-brush: Multiple brush regions can coexist, selecting the union (or intersection) of covered data.
  • Snap brush: The brush snaps to bin boundaries (e.g., histogram bars) rather than arbitrary pixel positions.
  • Transient brush: The brush disappears on mouse-up and the selection is applied as a filter.

Code Reference

// D3.js 2D brush on a scatterplot with linked highlighting
const brush = d3.brush()
  .extent([[0, 0], [width, height]])
  .on("brush end", ({ selection }) => {
    if (!selection) {
      svg.selectAll("circle").style("opacity", 0.8);
      return;
    }
    const [[x0, y0], [x1, y1]] = selection;
    svg.selectAll("circle").style("opacity", d =>
      x(d.xVal) >= x0 && x(d.xVal) <= x1 &&
      y(d.yVal) >= y0 && y(d.yVal) <= y1 ? 1 : 0.1
    );
  });

svg.append("g").call(brush);