HAHS.
Back to Catalog

Hover Highlight

interaction

Also known as: mouseover emphasis, hover focus, highlight on hover

Enable explorationProvide detailFilter / focus CategoricalNumericalTemporal

Description

Hover highlight is a rapid, reversible interaction in which the system visually emphasizes the data element under the cursor while simultaneously de-emphasizing (dimming, desaturating, or shrinking) all other elements. This creates an immediate figure-ground separation that helps the viewer isolate one mark from its context without any explicit selection action.

The technique is closely related to what Yi et al. (2007) call the “select” interaction intent — marking something as interesting so it can be examined more closely. But unlike a click-based selection, hover highlight is completely transient: the emphasis vanishes the moment the cursor moves away. This zero-commitment cost makes it one of the most fluid ways to scan through a dataset, letting the viewer rapidly “try on” different focal points.

Hover highlight is especially powerful when combined with linked views. Hovering over a bar in one chart can highlight the corresponding points in a scatterplot and the corresponding row in a table. This cross-view highlighting, sometimes called “brushing and linking” in its simplest form, was pioneered in systems like Brushing Scatterplots (Becker & Cleveland, 1987) and remains a cornerstone of coordinated multiple views.

Hover Highlight — try it yourself

When to Use

  • When the chart has many overlapping or adjacent marks and the viewer needs to visually isolate one element.
  • In multi-series line charts where lines cross and it is hard to trace a single series.
  • In linked/coordinated views where highlighting in one view should propagate to others.
  • In network diagrams to show a node’s immediate neighbors.
  • When the viewer needs to compare one element against the backdrop of the full distribution.

When NOT to Use

  • On touch-only devices where hover is unavailable (use tap-to-select instead).
  • When every element is already visually distinct and easy to identify without hover.
  • In very dense displays (e.g., 50,000-point scatterplots) where individual mark highlighting is meaningless — use brush selection instead.
  • When the de-emphasis of non-hovered elements would obscure critical context the viewer needs to maintain.

How It Works

  1. The user moves the cursor over a data mark (or a legend entry, axis label, or other selectable element).
  2. The system identifies the target mark and any related marks (e.g., all marks in the same group or series).
  3. The target mark is visually emphasized: increased opacity, a brighter fill, a bold stroke, a size increase, or an outline glow.
  4. All other marks are de-emphasized: reduced opacity (commonly to 0.1-0.3), desaturated color, or thinner stroke.
  5. When the cursor moves away, all marks return to their default visual state.

The de-emphasis step (sometimes called “dimming” or “fog”) is as important as the emphasis. Without it, the highlighted mark does not stand out in a dense chart.

Variations

  • Single-mark highlight: Only the hovered mark changes. Simplest implementation.
  • Group highlight: Hovering one mark highlights all marks in the same category or series. Common in grouped bar charts and multi-line charts.
  • Legend-driven highlight: Hovering over a legend swatch highlights the entire corresponding series.
  • Connected highlight: In network or hierarchical visualizations, hovering a node highlights its edges and neighbors.
  • Cross-view highlight: Hovering in one view highlights corresponding elements in all linked views.
  • Inverse highlight (spotlight): Instead of dimming others, a semi-transparent overlay covers the entire chart except the hovered region.

Code Reference

// D3.js hover highlight with opacity dimming
svg.selectAll("circle")
  .on("mouseover", function (event, d) {
    svg.selectAll("circle")
      .transition().duration(100)
      .style("opacity", c => c.group === d.group ? 1 : 0.15);
  })
  .on("mouseout", () => {
    svg.selectAll("circle")
      .transition().duration(200)
      .style("opacity", 0.8);
  });