SPB Git forge
38commits 1branches 0releases
338.7 MBsize
maindefault branch
6 h agolast push
HTML 53.9% TypeScript 44.5% JavaScript 0.6% SQL 0.5%
1.8 KB · 34 lines tsx
Raw Blame History
1"use client";23import { ColumnChart } from "@/components/ui/charts";4import { fmtInt, fmtMw } from "@/lib/format";56/** Facilities opened per published opening year; MW in the tooltip only when published for that year. */7export function OpeningTimeline({ data }: { data: Array<{ year: number; opened: number; openedMw: number | null }> }) {8  const rows = [...data].filter((d) => Number.isFinite(d.year)).sort((a, b) => a.year - b.year);9  const first = rows[0]!.year;10  const last = Math.max(rows[rows.length - 1]!.year, new Date().getUTCFullYear());11  const byYear = new Map(rows.map((r) => [r.year, r]));12  const span = last - first + 1;13  const filled: Array<{ label: string; value: number; secondary: number | null }> = [];14  for (let y = first; y <= last; y++) {15    const r = byYear.get(y);16    filled.push({ label: String(y), value: r?.opened ?? 0, secondary: r?.openedMw ?? null });17  }18  const data2 = span > 30 ? rows.map((r) => ({ label: String(r.year), value: r.opened, secondary: r.openedMw })) : filled;19  const mwYears = rows.filter((r) => r.openedMw !== null).length;20  return (21    <div>22      <ColumnChart data={data2} height={150} format={(v) => fmtInt(v)} color="var(--st-operational)" ariaLabel="Facilities opened per year" />23      <ul className="mt-2 flex flex-wrap gap-x-3 gap-y-1 text-[11.5px] text-ink-3">24        {rows.slice(-6).map((r) => (25          <li key={r.year} className="figure">26            {r.year}: {fmtInt(r.opened)} opened{r.openedMw !== null ? ` · ${fmtMw(r.openedMw)}` : ""}27          </li>28        ))}29      </ul>30      <p className="mt-1.5 text-[11px] text-ink-4">{mwYears ? `${mwYears} of ${rows.length} years carry a published MW figure.` : "No opening year carries a published MW figure."} Facilities without a published opening date are not charted.</p>31    </div>32  );33}34