fix(compare): a no-results school no longer blanks the trend chart
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m8s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 13s
PR Checks / Build Frontend (no push) (pull_request) Successful in 49s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 54s
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m8s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 13s
PR Checks / Build Frontend (no push) (pull_request) Successful in 49s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 10s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 54s
Adding a school with no performance data to a comparison made every school's trend line disappear until that school was removed. Root cause: /api/compare returns such a school with a single phantom yearly_data row (the dim_school LEFT JOIN) whose year is null. In buildCompareChart, Math.trunc(null) is 0, so the axis was seeded at year 0; fillAcademicYears then walked 0, 101, 202, … and hit its 50-step cap long before reaching the real years, leaving every school's series mapped entirely to null. Fix: ignore yearly rows without a real numeric year when building the axis and the per-school year map. Regression test added. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,17 @@
|
||||
|
||||
import type { ComparisonData } from './types';
|
||||
|
||||
/**
|
||||
* A yearly row only counts once it carries a real academic year. A school with
|
||||
* no performance data still comes back from /api/compare with a single phantom
|
||||
* row (the dim_school LEFT JOIN) where `year` is null — and Math.trunc(null) is
|
||||
* 0, which would seed the axis at year 0 and, via fillAcademicYears, blow past
|
||||
* every real year and blank all schools' lines. Drop those rows up front.
|
||||
*/
|
||||
function hasYear(row: { year: number }): boolean {
|
||||
return typeof row.year === 'number' && Number.isFinite(row.year);
|
||||
}
|
||||
|
||||
/** 201819 → 201920 (academic-year arithmetic on YYYYYY codes). */
|
||||
function nextAcademicYear(year: number): number {
|
||||
const start = Math.floor(year / 100);
|
||||
@@ -66,14 +77,19 @@ export function buildCompareChart(
|
||||
nationalByYear?: Record<number, number | null | undefined>,
|
||||
): CompareChart {
|
||||
const rawYears = schools.flatMap(
|
||||
(s) => comparisonData[String(s.urn)]?.yearly_data.map((d) => Math.trunc(d.year)) ?? [],
|
||||
(s) =>
|
||||
comparisonData[String(s.urn)]?.yearly_data.filter(hasYear).map((d) => Math.trunc(d.year)) ??
|
||||
[],
|
||||
);
|
||||
const years = fillAcademicYears(rawYears);
|
||||
|
||||
const schoolDatasets: CompareChartSeries[] = schools.map((school, schoolIndex) => {
|
||||
const rows = comparisonData[String(school.urn)]?.yearly_data ?? [];
|
||||
const byYear = new Map<number, Record<string, unknown>>();
|
||||
for (const row of rows) byYear.set(Math.trunc(row.year), row as unknown as Record<string, unknown>);
|
||||
for (const row of rows) {
|
||||
if (!hasYear(row)) continue;
|
||||
byYear.set(Math.trunc(row.year), row as unknown as Record<string, unknown>);
|
||||
}
|
||||
return {
|
||||
label: school.school_name,
|
||||
data: years.map((year) => {
|
||||
|
||||
Reference in New Issue
Block a user