Skip to content

buildChartSeries' pivot branch writes the category key onto every bucket, so framework#4033's hasNoCategoryKey guard can never fire for a pivoted chart #4507

Description

@yinlianghui

Measured while implementing #4497 (PR #4506); filed unassigned rather than widened into that card's ruled surface.

What

hasNoCategoryKey (plugin-charts' AdvancedChartImpl) exists to catch the framework#4033 shape — a dimension grouped by but never projected, so no row carries the category key at all. Instead of drawing an axis with no marks, it renders an explanatory placeholder naming the missing key:

!rows.some((row) => row != null && typeof row === 'object' && key in row)

That predicate reads props.data, which for a dataset-bound chart is buildChartSeries' output. The pivot branch always writes the key onto every bucket it creates:

if (!byX.has(xId)) byX.set(xId, { [xKey]: /* … */ });

so key in row is unconditionally true downstream, and the guard cannot fire for a 2-dimension/1-measure chart regardless of what the query returned.

Effect

A pivoted chart whose first dimension was never projected collapses every row into one unnamed bucket and draws an axis with an empty category label — the exact silent shape framework#4033 introduced the placeholder to eliminate. The single-dimension branch is unaffected: it passes rows through, so key-absent rows stay key-absent and the guard sees them.

Status

Pre-existing and unchanged by #4497 — that card deliberately kept the key-absent shape out of the pivot's bucket (isNullCategory requires key in row), so a never-projected dimension is not relabelled (None), which would state something false about the data. Pinned as a measured limit in packages/core/src/utils/chart-series.nullCategory.test.ts, case "does NOT bucket a row that lacks the category key ENTIRELY".

Shape of a fix (not prescriptive)

Either the pivot preserves key-absence (omit [xKey] from a bucket whose source rows never carried it, so the existing guard sees it), or hasNoCategoryKey learns the pivot's shape. The first keeps one guard with one meaning; the second spreads the pivot's internals into the renderer. Needs its own measurement of how a dataset query actually reports an unprojected dimension in a 2-dimension grouping.

Observation-class: nothing a user hits unless a dataset groups by a dimension it does not project, which is itself the framework#4033 defect.


Generated by Claude Code

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