Skip to main content
A highlight emphasizes the observations that match a predicate by dimming the ones that don’t. You describe what to match, not which pixels to paint, so the highlight follows the data through re-sorts, filters and updates.

Predicates

The first argument to highlight() is a predicate: a test against your post-transform columns. A field predicate names a variable and a comparison:
Ordered operators (gt, gte, lt, lte, range) need a numeric or date column. Using one on a text column is an INVALID_PREDICATE_OPERATOR warning that drops the whole highlight; the chart still renders without it. Naming a column the data doesn’t have (UNKNOWN_VARIABLE) does the same, and one bad leaf inside an and or or drops the highlight it belongs to. Both arrive as diagnostics.
There is no neq here; write { not: { variable: 'region', eq: 'EU' } } instead. The neq operator on transform.filter belongs to a separate comparison vocabulary. Combine predicates with and, or and not:

Scope

By default a highlight matches single observations. The scope option widens each match to a larger unit:

Scoping to one layer

In a multi-layer chart (bars plus a trend line, say), bind the highlight to one layer: give the layer an id and name it with layerId. Observations in other layers are never tested, so a Q4 highlight on the bars leaves the trend line alone:
Omit layerId to test the predicate against every layer. A layer you never name gets an id at resolve time, so scoping is the one case where naming it yourself matters.

Combining highlights

Multiple highlight() calls accumulate, and the engine unions their matches: an observation matched by any highlight is emphasized. Two separate highlights behave like an or:
The union is exactly an or, so this equals a single highlight with an or predicate: the same observations match and the result is the same:
Use one or predicate when the two conditions are one idea. Use two highlights when they are independent and you may toggle them separately.

Styling the de-emphasis

Every non-matched observation carries the dimmed style state, and one stylesheet entry decides what that state looks like. The built-in stylesheet dims to alpha: 0.4. Put your own entry in overrides, where it decides the cascade:
alpha lowers the opacity of non-matched observations; saturation: 0 drains their color to gray. SetHighlightDimStyleCommand makes the same choice as a command, for a picker in an editing UI. It writes exactly that entry:
'dim' writes the built-in alpha: 0.4 out in full; 'desaturate' writes { saturation: 0, alpha: 0.6 }. readHighlightDimStyle(spec) reads the current choice back, to select the right item in the picker.

Highlight commands

highlight() has a one-for-one command mirror: The id is settled when the command is constructed, so RemoveHighlightCommand can address a highlight that was added without one.
  • Styling — the stylesheet the dimmed entries live in, and the where condition that takes this same predicate language
  • Mappings & aesthetics — the variables a predicate can name
  • Transforms — predicates run against post-transform columns