fix(chart): Sripati Bhava from the real sidereal MC; Bhava chart and tables (T5, BUG-1077)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
This commit is contained in:
Jesse_Chen
2026-09-28 15:38:24 +08:00
co-authored by Claude Opus 5.5
parent 3f6bcb081a
commit c35e0195e1
16 changed files with 743 additions and 9 deletions
@@ -37,7 +37,8 @@ export function ChartPageRoute() {
* the natal packet that is already on the page, so they request nothing.
*/
function chartTypeLayer(id: ChartTypeId): ChartViewLayer | null {
if (id === "D1" || id === "MOON" || id === "BHAVA") return null;
if (id === "D1" || id === "MOON") return null;
if (id === "BHAVA") return "bhava";
if (id === "TRANSIT") return "transit";
return "varga";
}
@@ -6,6 +6,7 @@ import { VedicChartSvg } from "@/components/personal-report/vedic-chart-svg";
import type {
ChartViewFailureStatus,
ChartViewAscendantRow,
ChartViewBhavaOk,
ChartViewOk,
ChartViewPlanetRow,
ChartViewTransitOk,
@@ -236,6 +237,64 @@ function TransitTable({ transit }: { transit: ChartViewTransitOk }) {
);
}
function BhavaTables({ bhava }: { bhava: ChartViewBhavaOk }) {
return (
<>
<div className="chart-page-planet-table-wrap">
<table className="chart-page-planet-table">
<caption>Bhava · {bhava.houseSystem}</caption>
<thead>
<tr>
<th scope="col">行星</th>
<th scope="col">黄道经度</th>
<th scope="col">星座宫</th>
<th scope="col">Bhava 宫</th>
<th scope="col">换宫</th>
</tr>
</thead>
<tbody>
{bhava.rows.map((row) => {
const key = planetGlyphKey(row.name);
return (
<tr key={row.name} className={row.shifted ? "is-shifted" : undefined}>
<th scope="row">
<PlanetCell name={row.name} label={row.label} abbr={key ? PLANET_ABBR[key] : "—"} />
</th>
<td className="chart-page-planet-num">{row.signLabel} {formatDegreeMinutes(row.degreeInSign)}</td>
<td className="chart-page-planet-mid">{row.rashiHouse}宫</td>
<td className="chart-page-planet-mid">{row.bhavaHouse}宫</td>
<td className="chart-page-planet-mid">{row.shifted ? "是" : "否"}</td>
</tr>
);
})}
</tbody>
</table>
</div>
<div className="chart-page-planet-table-wrap">
<table className="chart-page-planet-table">
<caption>宫头与宫界</caption>
<thead>
<tr>
<th scope="col">宫</th>
<th scope="col">宫头</th>
<th scope="col">起点(sandhi)</th>
</tr>
</thead>
<tbody>
{bhava.cusps.map((cusp) => (
<tr key={cusp.house}>
<th scope="row">{cusp.house}宫</th>
<td className="chart-page-planet-num">{cusp.signLabel} {formatDegreeMinutes(cusp.degreeInSign)}</td>
<td className="chart-page-planet-num">{cusp.sandhiSignLabel} {formatDegreeMinutes(cusp.sandhiDegreeInSign)}</td>
</tr>
))}
</tbody>
</table>
</div>
</>
);
}
/** Chart, parameter table and boundary line, then the chart type's own table. */
function VedicLayout({ view, chart, ariaLabel, ascendantHouse, children }: {
view: ChartViewOk;
@@ -287,6 +346,18 @@ function ChartTypeBody({ view, vargaId, pending, failure }: {
</VedicLayout>
);
}
if (vargaId === "BHAVA") {
const bhava = view.bhava;
if (bhava.status !== "ok") return <LayerWaiting pending={pending} failure={failure} copy={CHART_VIEW_COPY.waitingChart} />;
return (
<VedicLayout view={view} chart={bhava.chart} ariaLabel="Bhava 北印度盘 Sripati 不等宫">
<div className="chart-page-varga-table-block">
<p className="chart-page-note chart-page-table-note">{CHART_VIEW_COPY.bhavaNote}</p>
<BhavaTables bhava={bhava} />
</div>
</VedicLayout>
);
}
if (vargaId === "TRANSIT") {
const transit = view.transit;
if (transit.status !== "ok") return <LayerWaiting pending={pending} failure={failure} copy={CHART_VIEW_COPY.waitingChart} />;