Skip to content

Chart-type-aware row cap: chartRowCap(type) replaces flat CHART_ROW_CAP=500 #109

Description

@BorisTyshkevich

Problem. CHART_ROW_CAP (src/core/chart-data.js:19, currently 500) is one flat constant applied to every chart type in buildChartData() (src/core/chart-data.js:236, rows.slice(0, CHART_ROW_CAP)), and surfaced via the "first 500 of N rows" note in src/ui/results.js:912-916. The number was picked by eyeballing at design time (commit 2c2dc45, comment: "plots past this get unreadable") — there's no readability model behind it, and a single cap is the wrong shape regardless of the number:

  • Pie is unreadable well before 500 — legible slice count tops out around 20-30 regardless of monitor width.
  • Bar/column are bound by minimum bar+gap width for legible category ticks — this scales with canvas width, but a fixed 500 doesn't reflect that.
  • Line/area are point-density bound, not label-bound — a wide canvas can plot several thousand points before individual points become indistinguishable. 500 is needlessly conservative here (the report that prompted this: a 1.4K-row result only plotted its first 500 points on a line chart).

Scope (this issue — pure lookup, no aggregation-order change).

  • Add to src/core/chart-data.js:
    export const CHART_ROW_CAPS = { pie: 30, hbar: 500, bar: 1000, line: 5000, area: 5000 };
    export function chartRowCap(type) {
      return CHART_ROW_CAPS[type] ?? 500;
    }
  • buildChartData() uses rows.slice(0, chartRowCap(cfg.type)) instead of the flat constant.
  • src/ui/results.js's truncation note uses chartRowCap(cfg.type) instead of CHART_ROW_CAP, and re-renders (existing rerender() path already re-runs on type change) so switching chart type re-slices and updates the note.
  • Update tests/unit/chart-data.test.js:234 (currently asserts 500 labels) and tests/unit/results.test.js:680 (currently asserts 'first 500 of') for the new per-type values; add a test that switching chart type on an oversized result changes both the slice length and the note text.

Explicitly out of scope (see #111). buildChartData() currently slices raw rows before aggregating (chart-data.js:236, then the per-category sums/groups maps below it) — correct for results that are already one-row-per-category (typical GROUP BY output), but for un-pre-aggregated results this caps input rows, not output categories, and can silently drop or short-total categories that only appear later in row order. That's a correctness issue, not a readability one, and needs a different fix shape (aggregate over all rows, then keep top-N categories) — tracked separately so this issue stays a same-day pure-lookup change.

Acceptance.

  • Each chart type has its own row cap instead of one flat 500 (CHART_ROW_CAPS / chartRowCap).
  • Switching chart type on an oversized result re-slices to that type's cap and updates the truncation note accordingly.
  • Existing tests updated for the new per-type caps; new test covers the type-switch note change.
  • npm test green at the per-file coverage gate.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    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