{{ theme.skipToContentLabel || 'Skip to content' }}

Chart Config Sync — Single Source of Truth

Date: 2026-02-13 Goal: Ensure export pages automatically support any chart added to the main data pages.

Problem

Chart definitions are duplicated:

  • Dust Ranger: CHART_CONFIGS in DustRangerChartDashboard.tsx (10 charts) vs chartOptions in export.tsx (10 charts) — currently in sync but can drift
  • Dust Levels: Charts hardcoded inline in index.tsx vs chartOptions in export.tsx — already out of sync (export missing Road Corrugation charts)

When a developer adds a new chart to the main page, they must remember to also add it to the export page.

Solution

Create a shared chart config per feature that both the main page and export page consume.

Dust Ranger: src/features/dust-ranger/config/chartConfig.ts

typescript
export interface DustRangerChartConfig {
  key: string;
  label: string;
  icon: string;
  defaultSelected: boolean;  // for export page
  /** Dynamic label parts that depend on dataType */
  labelFn?: (dataType: DataType) => string;
}

export const DUST_RANGER_CHART_CONFIGS: DustRangerChartConfig[] = [
  { key: "timeSeries", label: "Time Series", icon: "solar:chart-2-linear", defaultSelected: true, labelFn: (dt) => `${dt === "mc" ? "Mass" : "Number"} Concentration Over Time ${dt === "mc" ? "(MC)" : "(NC)"}` },
  { key: "hourlyAverage", label: "Hourly Average", icon: "solar:clock-circle-linear", defaultSelected: true, labelFn: (dt) => `Hourly Average Patterns ${dt === "mc" ? "(MC)" : "(NC)"}` },
  // ... all 10 charts
];

Main page (DustRangerChartDashboard.tsx): imports DUST_RANGER_CHART_CONFIGS, uses key/label/icon for toggle buttons.

Export page (dust-ranger-data/export.tsx): imports DUST_RANGER_CHART_CONFIGS, maps to ChartOption[] using key/labelFn/defaultSelected.

Dust Levels: src/features/dust-levels/config/chartConfig.ts

typescript
export interface DustLevelChartConfig {
  key: string;
  label: string;
  icon: string;
  defaultSelected: boolean;
  /** Whether this chart is per-geofence (duplicated when "All" selected) */
  perGeofence: boolean;
}

export const DUST_LEVEL_CHART_CONFIGS: DustLevelChartConfig[] = [
  { key: "dustLevelTemp", label: "Dust Levels", icon: "solar:chart-2-linear", defaultSelected: true, perGeofence: true },
  { key: "weeklyAverage", label: "Weekly Average", icon: "solar:calendar-linear", defaultSelected: true, perGeofence: true },
  { key: "monthlyAverage", label: "Monthly Average", icon: "solar:calendar-linear", defaultSelected: true, perGeofence: true },
  { key: "weeklyRoadBumps", label: "Weekly Road Corrugation Count", icon: "solar:road-linear", defaultSelected: false, perGeofence: true },
  { key: "monthlyRoadBumps", label: "Monthly Road Corrugation Count", icon: "solar:road-linear", defaultSelected: false, perGeofence: true },
  { key: "dustDistribution", label: "Data Distribution & Threshold Selection", icon: "solar:pie-chart-linear", defaultSelected: false, perGeofence: false },
  { key: "dustlocUsage", label: "Dustloc Usage", icon: "solar:graph-linear", defaultSelected: true, perGeofence: false },
];

Tasks

Task 1: Create Dust Ranger chart config

New file: src/features/dust-ranger/config/chartConfig.ts

  • Extract chart definitions from DustRangerChartDashboard.tsx
  • Add defaultSelected and labelFn fields

Task 2: Update DustRangerChartDashboard to use shared config

Modify: src/features/dust-ranger/components/DustRangerChartDashboard.tsx

  • Import DUST_RANGER_CHART_CONFIGS
  • Remove local CHART_CONFIGS

Task 3: Update Dust Ranger export page to use shared config

Modify: src/app/(admin)/(pages)/dust-ranger-data/export.tsx

  • Import DUST_RANGER_CHART_CONFIGS
  • Derive chartOptions from shared config using labelFn(dataType)

Task 4: Create Dust Levels chart config

New file: src/features/dust-levels/config/chartConfig.ts

  • Define all charts including Road Corrugation charts

Task 5: Update Dust Levels export page to use shared config + add missing charts

Modify: src/app/(admin)/(pages)/dust-levels/export.tsx

  • Import DUST_LEVEL_CHART_CONFIGS
  • Derive chartOptions from shared config
  • Add Road Corrugation chart rendering (Weekly + Monthly, per-geofence aware)

Task 6: Update Dust Levels main page to use shared config (optional)

Modify: src/app/(admin)/(pages)/dust-levels/index.tsx

  • Use config for data-export-key attributes (lighter touch — main page has complex inline rendering)

Task 7: Verify and lint

  • npx tsc --noEmit
  • pnpm lint