SPB Git forge
3commits 1branches 0releases
417.0 KBsize
maindefault branch
10 days agolast push
TypeScript 66.5% Python 30.9% JavaScript 1.4% CSS 0.7%
2.2 KB · 34 lines tsx
Raw Blame History
1import { Bars, StackedBars } from '@/components/charts/charts';2import { fmtInt, num } from '@/lib/format';3import type { LaunchTimeline } from '@/lib/types';45const REGION_LABELS = { us: 'United States', russia_cis: 'Russia / Kazakhstan', china: 'China', other: 'Other / unknown site' };67/** Launches per year by launch-site region + monthly cadence for the last 36 months. Server-rendered SVG. */8export function LaunchTimelineCharts({ timeline }: { timeline: LaunchTimeline }) {9  const years = timeline.years.map((y) => ({ x: String(y.year), us: num(y.us) ?? 0, russia_cis: num(y.russia_cis) ?? 0, china: num(y.china) ?? 0, other: num(y.other) ?? 0 }));10  const months = timeline.months.map((m) => ({ x: m.month.slice(0, 7), y: num(m.launches) ?? 0 }));11  const lastYear = timeline.years[timeline.years.length - 1];12  const totalLaunches = timeline.years.reduce((s, y) => s + (num(y.launches) ?? 0), 0);13  const totalPayloads = timeline.years.reduce((s, y) => s + (num(y.payloads) ?? 0), 0);14  return (15    <div className="grid gap-8 lg:grid-cols-[minmax(0,3fr)_minmax(0,2fr)]">16      <div className="min-w-0">17        <div className="mb-2 flex items-baseline justify-between gap-3">18          <p className="eyebrow">Launches per year by launch-site region</p>19          <p className="tnum text-xs text-ink-3">{fmtInt(totalLaunches)} launches · {fmtInt(totalPayloads)} payloads since {timeline.years[0]?.year ?? '—'}</p>20        </div>21        <StackedBars data={years} keys={['us', 'russia_cis', 'china', 'other']} labels={REGION_LABELS} title="Orbital launches per year by launch-site region" height={220} xTicks={10} />22      </div>23      <div className="min-w-0">24        <div className="mb-2 flex items-baseline justify-between gap-3">25          <p className="eyebrow">Monthly cadence · last 36 months</p>26          {lastYear && <p className="tnum text-xs text-ink-3">{fmtInt(lastYear.launches)} launches in {lastYear.year}</p>}27        </div>28        <Bars data={months} title="Launches per month over the last 36 months" height={220} xTicks={6} highlightLast color="var(--series-2)" />29        <p className="mt-1 text-2xs text-ink-3">The last bar is the current month (partial).</p>30      </div>31    </div>32  );33}34