Skip to content

Deck.gl Polygon legend labels share endpoints (cosmetic / ambiguous range labels) #40786

@alex-poor

Description

@alex-poor

Bug description

The deck.gl Polygon chart legend renders bucket labels with shared endpoints, so consecutive bins appear to overlap. With default settings (no manual break points), the legend shows e.g.:

1 - 81
81 - 212
212 - 369

Every interior breakpoint (81, 212, …) appears in two adjacent labels — once as an upper bound, once as a lower bound — which reads as overlapping ranges and is confusing.

This is a cosmetic / UX-clarity issue, not a correctness bug. The underlying binning and coloring are correct: colors are assigned with d3's scaleThreshold, which treats each breakpoint as a half-open cut point, so a value of exactly 81 lands in exactly one bucket (81–212). No polygon is double-counted or mis-colored. Only the legend label text is ambiguous.

Root cause

In superset-frontend/plugins/preset-chart-deckgl/src/utils.ts, getBuckets() builds each label by pairing adjacent breakpoints:

const range = `${breakPoints[i]} - ${breakPoints[i + 1]}`;

This always reuses each interior breakpoint in two labels. The color scale (getBreakPointColorScaler, same file) uses scaleThreshold, which is half-open and unambiguous — so the labels misrepresent the (correct) bucketing logic.

Scope

  • Affects the deck.gl Polygon layer only — it is the only chart in the frontend that renders a discrete numeric-range legend (scaleThreshold appears nowhere else in superset-frontend).
  • Country Map / World Map avoid this by using a continuous linear color scale with no discrete-range legend.
  • ECharts charts use categorical legends (names, not ranges), so they are unaffected.
  • Independent of the Number of buckets vs Bucket break points controls — setting explicit break points changes where the bins are, but labels still share endpoints.

Expected behavior

Legend bins should read as a clean, non-overlapping partition. There is no existing internal convention to match (Polygon is the only discrete-range legend), so candidate formats:

  1. Edge-operator notation (common GIS/choropleth convention — ArcGIS, Datawrapper): < 81, 81 – 212, 212 – 369, > 369
  2. Interval notation: [1, 81), [81, 212), [212, 369]
  3. Render the boundary number once between touching swatches (gradient-bar style) rather than as isolated a - b rows.

Note: simply incrementing the lower bound (82 - 212) is not correct in general — breakpoints and metric values can be fractional, so a value like 81.5 would fall into a labeling gap.

How to reproduce

  1. Create a deck.gl Polygon chart with a numeric metric.
  2. Leave Bucket break points empty (use default Number of buckets).
  3. Observe the legend — adjacent bins share endpoints (1 - 81, 81 - 212, …).

Superset version

master / latest (also observed on 5.0+).

Related (different) issues

No existing open issue/PR covers the shared-endpoint label formatting.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions