Skip to content

Crossed facet custom sort degrades when the child has an independent discrete scale with range steps #9882

Description

@domoritz

Custom facet sorting (row/column with sort: {field, op} or a sort array) silently degrades to encounter order in one remaining configuration: a crossed facet (both row and column) where the child view has an independent discrete scale sized by range steps.

This is the last known gap after #9818, which fixed crossed-facet custom sort in the general case (#5937, #8675, vega/altair#3481, vega/altair#3588). None of those issues hit this path; filing this so it isn't rediscovered later as "the facet sort bug is back".

Example

{
  "data": {"url": "data/cars.json"},
  "facet": {
    "row": {"field": "Origin", "sort": {"field": "Horsepower", "op": "median"}},
    "column": {"field": "Cylinders"}
  },
  "spec": {
    "mark": "bar",
    "encoding": {
      "x": {"field": "Year", "type": "ordinal"},
      "y": {"aggregate": "count"}
    }
  },
  "resolve": {"scale": {"x": "independent"}}
}

(Triggering configuration: crossed facet + custom sort + independent discrete child scale without a fixed size, so layout needs range-step sizing.)

Root cause

When the child has an independent discrete scale with range steps, facet layout needs per-row/column cardinalities, so assembleRowColumnHeaderData sources row_domain/column_domain from the crossed dataset (grouped by row × column) instead of the per-channel aggregates. That crossed aggregate doesn't carry sort.field, so sort metadata is null and both headers and cells (consistently, post-#9818) fall back to encounter order.

Adding the sort field to the crossed aggregate is not sufficient: a row sort by median(x) must be computed grouped by row only; re-aggregating per-cell medians gives op-of-op semantics, which is wrong for non-decomposable ops.

Proposed direction

Keep the crossed dataset for cardinalities, but join sort metadata in from separate row-only/column-only aggregates; i.e., extend the lookup machinery introduced in #9818 to this data path.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions