Layer toggles: show/hide Chiron, asteroids, nodes, Lilith, PoF, minor aspects
Frontend-only filtering over the already-computed chart — wheel, tables, aspect grid/list, report and synastry views all respect the toggles; state persists in localStorage. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
9c284edc9f
commit
438b4c1b47
@ -136,6 +136,57 @@ $("#saved-charts").addEventListener("change", (e) => {
|
|||||||
});
|
});
|
||||||
fillSaved();
|
fillSaved();
|
||||||
|
|
||||||
|
/* ---------------- layer toggles ---------------- */
|
||||||
|
const LAYER_GROUPS = {
|
||||||
|
chiron: ["Chiron"],
|
||||||
|
asteroids: ["Ceres", "Pallas", "Juno", "Vesta"],
|
||||||
|
nodes: ["North Node", "South Node"],
|
||||||
|
lilith: ["Lilith"],
|
||||||
|
fortune: ["Part of Fortune"],
|
||||||
|
};
|
||||||
|
const LAYER_IDS = ["chiron", "asteroids", "nodes", "lilith", "fortune", "minor"];
|
||||||
|
|
||||||
|
function layerState() {
|
||||||
|
const st = {};
|
||||||
|
LAYER_IDS.forEach((k) => (st[k] = $("#ly-" + k).checked));
|
||||||
|
return st;
|
||||||
|
}
|
||||||
|
function hiddenBodies() {
|
||||||
|
const st = layerState();
|
||||||
|
const hidden = new Set();
|
||||||
|
for (const [k, names] of Object.entries(LAYER_GROUPS)) {
|
||||||
|
if (!st[k]) names.forEach((n) => hidden.add(n));
|
||||||
|
}
|
||||||
|
return hidden;
|
||||||
|
}
|
||||||
|
function filterChart(d) {
|
||||||
|
const hidden = hiddenBodies();
|
||||||
|
const showMinor = layerState().minor;
|
||||||
|
return {
|
||||||
|
...d,
|
||||||
|
bodies: d.bodies.filter((b) => !hidden.has(b.name)),
|
||||||
|
aspects: d.aspects.filter((a) => !hidden.has(a.a) && !hidden.has(a.b) && (showMinor || a.major)),
|
||||||
|
parallels: d.parallels.filter((p) => !hidden.has(p.a) && !hidden.has(p.b)),
|
||||||
|
interpretation: (d.interpretation || []).map((sec) => ({
|
||||||
|
...sec,
|
||||||
|
items: sec.items.filter((it) => ![...hidden].some((n) => it.title.includes(n))),
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
(function initLayers() {
|
||||||
|
let saved = {};
|
||||||
|
try { saved = JSON.parse(localStorage.getItem("nategodd-layers") || "{}"); } catch {}
|
||||||
|
LAYER_IDS.forEach((k) => { if (k in saved) $("#ly-" + k).checked = saved[k]; });
|
||||||
|
LAYER_IDS.forEach((k) =>
|
||||||
|
$("#ly-" + k).addEventListener("change", () => {
|
||||||
|
try { localStorage.setItem("nategodd-layers", JSON.stringify(layerState())); } catch {}
|
||||||
|
if (lastChart) render(lastChart, true);
|
||||||
|
if (lastSyn && !$("#syn-results").hidden) renderSynastry(lastSyn, false);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
})();
|
||||||
|
let lastSyn = null;
|
||||||
|
|
||||||
/* ---------------- tabs ---------------- */
|
/* ---------------- tabs ---------------- */
|
||||||
document.querySelectorAll("#tabs button").forEach((b) =>
|
document.querySelectorAll("#tabs button").forEach((b) =>
|
||||||
b.addEventListener("click", () => {
|
b.addEventListener("click", () => {
|
||||||
@ -148,22 +199,25 @@ document.querySelectorAll("#tabs button").forEach((b) =>
|
|||||||
$("#print-btn").addEventListener("click", () => window.print());
|
$("#print-btn").addEventListener("click", () => window.print());
|
||||||
|
|
||||||
/* ---------------- render ---------------- */
|
/* ---------------- render ---------------- */
|
||||||
function render(d) {
|
function render(d, rerender = false) {
|
||||||
$("#results").hidden = false;
|
$("#results").hidden = false;
|
||||||
const inp = d.input;
|
const inp = d.input;
|
||||||
|
const f = filterChart(d);
|
||||||
$("#chart-header").innerHTML =
|
$("#chart-header").innerHTML =
|
||||||
`<h2>${esc(inp.name) || "Natal Chart"}</h2>
|
`<h2>${esc(inp.name) || "Natal Chart"}</h2>
|
||||||
<p>${inp.date}${inp.time ? " · " + inp.time + " local" : " · time unknown (solar chart)"} · ${esc(inp.place)}
|
<p>${inp.date}${inp.time ? " · " + inp.time + " local" : " · time unknown (solar chart)"} · ${esc(inp.place)}
|
||||||
· ${inp.lat.toFixed(3)}°, ${inp.lon.toFixed(3)}° · TZ ${esc(String(inp.tz))} (UTC${inp.utc_offset >= 0 ? "+" : ""}${inp.utc_offset})
|
· ${inp.lat.toFixed(3)}°, ${inp.lon.toFixed(3)}° · TZ ${esc(String(inp.tz))} (UTC${inp.utc_offset >= 0 ? "+" : ""}${inp.utc_offset})
|
||||||
· ${d.house_system} houses · ${d.is_day_chart ? "Day" : "Night"} chart</p>`;
|
· ${d.house_system} houses · ${d.is_day_chart ? "Day" : "Night"} chart</p>`;
|
||||||
drawWheel(d);
|
drawWheel(f);
|
||||||
renderBalances(d);
|
renderBalances(d);
|
||||||
renderPositions(d);
|
renderPositions(f);
|
||||||
renderAspects(d);
|
renderAspects(f);
|
||||||
renderReport(d);
|
renderReport(f);
|
||||||
fillSynPartners();
|
if (!rerender) {
|
||||||
$("#syn-results").hidden = true;
|
fillSynPartners();
|
||||||
$("#results").scrollIntoView({ behavior: "smooth" });
|
$("#syn-results").hidden = true;
|
||||||
|
$("#results").scrollIntoView({ behavior: "smooth" });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function esc(s) { return String(s ?? "").replace(/[&<>"]/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """ }[c])); }
|
function esc(s) { return String(s ?? "").replace(/[&<>"]/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """ }[c])); }
|
||||||
@ -457,7 +511,20 @@ $("#syn-go").addEventListener("click", async () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function renderSynastry(d) {
|
function renderSynastry(d0, scroll = true) {
|
||||||
|
lastSyn = d0;
|
||||||
|
const hidden = hiddenBodies();
|
||||||
|
const showMinor = layerState().minor;
|
||||||
|
const d = {
|
||||||
|
...d0,
|
||||||
|
chart_a: { ...d0.chart_a, bodies: d0.chart_a.bodies.filter((b) => !hidden.has(b.name)) },
|
||||||
|
chart_b: { ...d0.chart_b, bodies: d0.chart_b.bodies.filter((b) => !hidden.has(b.name)) },
|
||||||
|
interaspects: d0.interaspects.filter((x) => !hidden.has(x.a) && !hidden.has(x.b) && (showMinor || x.major)),
|
||||||
|
interpretation: d0.interpretation.map((sec) => ({
|
||||||
|
...sec,
|
||||||
|
items: sec.items.filter((it) => ![...hidden].some((n) => it.title.includes(n))),
|
||||||
|
})),
|
||||||
|
};
|
||||||
$("#syn-results").hidden = false;
|
$("#syn-results").hidden = false;
|
||||||
const sc = d.scores;
|
const sc = d.scores;
|
||||||
const nameA = d.chart_a.input.name || "Chart A";
|
const nameA = d.chart_a.input.name || "Chart A";
|
||||||
@ -498,7 +565,7 @@ function renderSynastry(d) {
|
|||||||
r += "</section>";
|
r += "</section>";
|
||||||
});
|
});
|
||||||
$("#syn-report").innerHTML = r;
|
$("#syn-report").innerHTML = r;
|
||||||
$("#syn-results").scrollIntoView({ behavior: "smooth" });
|
if (scroll) $("#syn-results").scrollIntoView({ behavior: "smooth" });
|
||||||
}
|
}
|
||||||
$("#syn-print").addEventListener("click", () => window.print());
|
$("#syn-print").addEventListener("click", () => window.print());
|
||||||
|
|
||||||
|
|||||||
@ -72,6 +72,16 @@
|
|||||||
<button type="button" id="exp-png" title="download wheel as PNG">⬇ PNG</button>
|
<button type="button" id="exp-png" title="download wheel as PNG">⬇ PNG</button>
|
||||||
<button type="button" id="exp-print" title="print / save as PDF">🖨 Print</button>
|
<button type="button" id="exp-print" title="print / save as PDF">🖨 Print</button>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="layers">
|
||||||
|
<span class="layers-label">Layers:</span>
|
||||||
|
<label class="check"><input type="checkbox" checked disabled> core planets</label>
|
||||||
|
<label class="check"><input type="checkbox" id="ly-chiron" checked> Chiron</label>
|
||||||
|
<label class="check"><input type="checkbox" id="ly-asteroids" checked> asteroids</label>
|
||||||
|
<label class="check"><input type="checkbox" id="ly-nodes" checked> nodes</label>
|
||||||
|
<label class="check"><input type="checkbox" id="ly-lilith" checked> Lilith</label>
|
||||||
|
<label class="check"><input type="checkbox" id="ly-fortune" checked> Part of Fortune</label>
|
||||||
|
<label class="check"><input type="checkbox" id="ly-minor" checked> minor aspects</label>
|
||||||
|
</div>
|
||||||
<nav id="tabs">
|
<nav id="tabs">
|
||||||
<button data-tab="wheel" class="active">Wheel</button>
|
<button data-tab="wheel" class="active">Wheel</button>
|
||||||
<button data-tab="positions">Positions</button>
|
<button data-tab="positions">Positions</button>
|
||||||
|
|||||||
@ -118,6 +118,12 @@ td.dign { color: var(--gold); font-size: 12px; }
|
|||||||
#report .item p { margin: 0; color: var(--ink); }
|
#report .item p { margin: 0; color: var(--ink); }
|
||||||
#print-btn { margin-top: 10px; }
|
#print-btn { margin-top: 10px; }
|
||||||
|
|
||||||
|
#layers { display: flex; gap: 14px; align-items: center; flex-wrap: wrap; margin-bottom: 10px;
|
||||||
|
padding: 8px 12px; background: #10101c; border: 1px solid var(--line); border-radius: 8px; }
|
||||||
|
.layers-label { color: var(--dim); font-size: 11px; text-transform: uppercase; letter-spacing: 1px; }
|
||||||
|
#layers label.check { font-size: 13px; color: var(--ink); gap: 6px; }
|
||||||
|
#layers input[disabled] + * , #layers label:has(input[disabled]) { opacity: 0.55; }
|
||||||
|
|
||||||
#toolbar { display: flex; gap: 8px; margin-bottom: 12px; flex-wrap: wrap; }
|
#toolbar { display: flex; gap: 8px; margin-bottom: 12px; flex-wrap: wrap; }
|
||||||
#toolbar button { font-size: 13px; padding: 6px 12px; background: #1a1a2e; }
|
#toolbar button { font-size: 13px; padding: 6px 12px; background: #1a1a2e; }
|
||||||
#toolbar button:hover { background: #262640; }
|
#toolbar button:hover { background: #262640; }
|
||||||
@ -146,7 +152,7 @@ td.dign { color: var(--gold); font-size: 12px; }
|
|||||||
|
|
||||||
@media print {
|
@media print {
|
||||||
body { background: #fff; color: #000; font-size: 12px; }
|
body { background: #fff; color: #000; font-size: 12px; }
|
||||||
header, #form-card, #tabs, footer, #print-btn, #toolbar, #syn-picker, #syn-print { display: none !important; }
|
header, #form-card, #tabs, footer, #print-btn, #toolbar, #layers, #syn-picker, #syn-print { display: none !important; }
|
||||||
#results { border: none; background: none; }
|
#results { border: none; background: none; }
|
||||||
.tab { display: block !important; }
|
.tab { display: block !important; }
|
||||||
#report .item b, #report h4, h3 { color: #000; }
|
#report .item b, #report h4, h3 { color: #000; }
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user