Skip to content

Legend

The legend turns a layer's symbology into a swatch. Logic lives in app/src/core/legend/introspect.ts; rendering in app/widgets/legend/LegendWidget.tsx.

The swatch model

legendForSymbology(symbology, geometryType) returns a LegendSwatch:

Kind Produced by Renders
single simple symbology One swatch shaped by geometryType (dot / line / square)
categories a match expression (or a categories override) A labeled swatch list
gradient an interpolate expression (or a gradient override) A continuous bar
hidden legend: { kind: 'hidden' } Nothing
unknown un-introspectable raw paint A neutral "custom" marker

The swatch shape is driven by the detected geometryType, not by symbology fields — so a stray radius on a polygon layer can't pick the wrong shape.

Introspection

For raw symbology without an explicit legend override, the introspector reads the paint:

  1. findColorExpression looks for the first array-valued color paint (circle-colorfill-colorline-color).
  2. If it's a ['match', ['get', prop], val, color, …, fallback], it extracts category entries.
  3. If it's an ['interpolate', …, ['get', prop], stop, color, …], it extracts gradient stops.
  4. Anything else → unknown (the legend shows a "custom" marker; the author can add an explicit override).

An explicit legend override on raw symbology always wins over introspection.

What the widget renders

LegendWidget filters to layers that are visible, have kit symbology, and aren't hideFromLegend. (Raster layers and default-styled Esri vector layers have no introspectable symbology, so they're skipped — covered by the same "no symbology" check.) It then sorts: raw symbologies first, then point → line → polygon, stable within each bucket by declared order.

A layer's symbology.description (a raw field) renders as a muted subtitle under the layer name in category/gradient legends.

Hiding a layer

  • legend: { kind: 'hidden' } on raw symbology → produces a hidden swatch (raw only).
  • hideFromLegend: true on the layer → filtered out before introspection (any symbology kind). This is the universal switch; it's copied into LayerMetadata and checked in the widget's filter.