/** * Deep Analysis Renderers v1.0 * 渲染: Raman功能表 · PACDARES · 宫位互影响 · Vargottama · 频率 · 三角验证 · Raman评级 */ import { PLANET_CN, PLANET_SYMBOLS, SIGNS_CN, SIGNS } from './jyotish-engine.js'; import { RAMAN_TABLES, HOUSE_DOMAINS } from './analysis-deep.js'; import { t, signName, planetName, houseLabel } from './i18n.js'; import { escapeHtml, safeNumber } from './security.js'; const $ = id => document.getElementById(id); const ARGALA_TARGETS = ['Sun', 'Moon', 'Mars', 'Mercury', 'Jupiter', 'Venus', 'Saturn', 'Rahu', 'Ketu']; // ============================================================================ // 1. Raman 功能吉凶星表 // ============================================================================ export function renderFunctionalNature(ascSign) { const c = $('raman-fn-table'); if (!c) return; const t = RAMAN_TABLES[ascSign]; if (!t) { c.innerHTML = '

无数据

'; return; } const FN_LABEL = { best_benefic: { text: '最佳吉星', cls: 'fn-best' }, benefic: { text: '吉星', cls: 'fn-good' }, yogakaraka: { text: 'Yogakaraka', cls: 'fn-yk' }, neutral: { text: '中性', cls: 'fn-neutral' }, malefic: { text: '凶星', cls: 'fn-bad' }, worst: { text: '最凶', cls: 'fn-worst' }, }; const mkBadges = (list, key) => list.map(p => `${escapeHtml(PLANET_SYMBOLS[p]||'')} ${escapeHtml(PLANET_CN[p])}` ).join(''); let html = `
最佳吉星
${mkBadges(t.best,'best_benefic')}
`; if (t.yk) html += `
Yogakaraka
${escapeHtml(PLANET_SYMBOLS[t.yk]||'')} ${escapeHtml(PLANET_CN[t.yk])}
`; html += `
吉星
${mkBadges(t.good,'benefic')}
`; html += `
中性
${mkBadges(t.neutral,'neutral')}
`; html += `
凶星
${mkBadges(t.bad,'malefic')}
`; if (t.worst.length) html += `
最凶
${mkBadges(t.worst,'worst')}
`; html += `
Maraka
${mkBadges(t.maraka,'worst')}
`; c.innerHTML = html; } // ============================================================================ // 2. PACDARES 八维分析 // ============================================================================ export function renderPACDARES(pac) { const c = $('pacdares-grid'); if (!c) return; const SECTIONS = [ { key:'P', title:'P · Position 位置', icon:'P', desc:'行星本位:落宫·星座·状态·功能属性' }, { key:'A', title:'A · Aspect 相位', icon:'A', desc:'行星接收的相位影响' }, { key:'C', title:'C · Conjunction 合相', icon:'C', desc:'同宫行星合相关系与能量污染' }, { key:'D', title:'D · Dhana 财富', icon:'D', desc:'财富Yoga检测' }, { key:'Ar', title:'Ar · Arishta 凶象', icon:'!', desc:'凶象检测' }, { key:'R', title:'R · Raja 王者', icon:'R', desc:'Raja Yoga & Yogakaraka' }, { key:'E', title:'E · Exchange 互换', icon:'E', desc:'Parivartana 宫主星互换' }, { key:'S', title:'S · Special 特殊', icon:'S', desc:'逆行·燃烧·入旺·落陷' }, ]; let html = ''; for (const s of SECTIONS) { const items = pac[s.key] || []; const count = items.length; html += `
${s.icon}${s.title}${count}
${s.desc}
`; if (count === 0) { html += `
未检测到
`; } else { html += `
`; for (const it of items) html += renderPACItem(s.key, it); html += `
`; } html += `
`; } c.innerHTML = html; } function renderPACItem(key, it) { switch(key) { case 'P': return `
${escapeHtml(PLANET_SYMBOLS[it.planet]||'')} ${escapeHtml(it.pcn)}${escapeHtml(it.scn)} H${escapeHtml(it.house)} ${escapeHtml(it.status||'')} ${it.retro?'℞':''} ${it.combust?'[燃]':''}${fnLabel(it.fn)}主管H${escapeHtml((it.hr || []).join('/'))}
`; case 'A': return `
${escapeHtml(PLANET_SYMBOLS[it.planet]||'')} ${escapeHtml(it.pcn)} (H${escapeHtml(it.house)})${(it.received || []).map(r=>`${escapeHtml(PLANET_CN[r.from])} ${escapeHtml(r.type)} → ${escapeHtml(r.impact)}`).join('')}
`; case 'C': return `
${escapeHtml(it.p1cn)} + ${escapeHtml(it.p2cn)}H${escapeHtml(it.house)}${it.pollution?'[!] 能量污染':''}${fnLabel(it.f1)}${fnLabel(it.f2)}
`; case 'D': return `
${escapeHtml(it.type)}${escapeHtml(it.lcn)}H${escapeHtml(it.house)}${escapeHtml(it.str)}
`; case 'Ar': return `
${escapeHtml(it.type)}${escapeHtml(it.desc)}
`; case 'R': return `
${escapeHtml(it.type)}${escapeHtml(it.lcn)}H${escapeHtml(it.house)}${escapeHtml(it.str)}
`; case 'E': return `
${escapeHtml(it.type)} (${escapeHtml(it.nature)})${escapeHtml(it.desc)}
`; case 'S': return `
${escapeHtml(it.type)}${escapeHtml(it.desc)}
`; default: return ''; } } function fnCls(fn) { return fn==='yogakaraka'?'yk':fn==='best_benefic'?'best':fn==='benefic'?'good':fn==='malefic'?'bad':fn==='worst'?'worst':'neut'; } function fnLabel(fn) { return fn==='yogakaraka'?'YK':fn==='best_benefic'?'大吉':fn==='benefic'?'吉':fn==='malefic'?'凶':fn==='worst'?'大凶':'中'; } // ============================================================================ // 3. Argala / Virodhargala 干预分析 // ============================================================================ export function renderArgala(argala) { const c = $('argala-section'); if (!c) return; if (!argala || Object.keys(argala).length === 0) { c.innerHTML = '
未取得 Argala 数据
'; return; } const entries = ARGALA_TARGETS .map(pn => ({ planet: pn, ...(argala[pn] || {}) })) .filter(item => item.argala_on_this || item.virodha_on_this) .sort((a, b) => Math.abs(safeNumber(b.net_score)) - Math.abs(safeNumber(a.net_score))); const supported = entries.filter(item => item.net_assessment === 'supported' || item.net_assessment === 'strongly_supported').length; const blocked = entries.filter(item => item.net_assessment === 'blocked').length; const neutral = entries.length - supported - blocked; const cards = entries.slice(0, 9).map(item => renderArgalaCard(item)).join(''); c.innerHTML = `
${supported}被支持
${blocked}被阻挡
${neutral}中性
读法

Argala 看“结果能否被打开”:2/4/11 宫形成资源、基础、收益干预;12/10/3 宫形成 Virodhargala 阻挡。这里按行星主题展示净支持或净阻碍。

${cards}
`; } function renderArgalaCard(item) { const cls = item.net_assessment === 'strongly_supported' ? 'argala-strong' : item.net_assessment === 'supported' ? 'argala-supported' : item.net_assessment === 'blocked' ? 'argala-blocked' : 'argala-neutral'; const support = (item.argala_on_this || []).slice(0, 3).map(a => `${escapeHtml(planetName(a.source))} · ${escapeHtml(a.house_from)}宫 · ${escapeHtml(a.effect)}` ).join(''); const blockers = (item.virodha_on_this || []).slice(0, 3).map(v => `${escapeHtml(planetName(v.source))} 阻挡${escapeHtml(v.blocks_argala_from)}宫Argala` ).join(''); const label = { strongly_supported: '强支持', supported: '支持', blocked: '受阻', neutral: '中性', }[item.net_assessment] || '中性'; return `
${escapeHtml(PLANET_SYMBOLS[item.planet] || '')} ${escapeHtml(planetName(item.planet))} ${escapeHtml(label)} ${safeNumber(item.net_score) >= 0 ? '+' : ''}${escapeHtml(item.net_score ?? 0)}
Argala${support || '无主要干预'}
Virodha${blockers || '无明显阻挡'}
`; } // ============================================================================ // 4. 宫位互影响矩阵 // ============================================================================ export function renderHouseInfluence(matrix) { const c = $('house-influence-grid'); if (!c) return; let html = ''; for (const h of matrix) { const vd = h.verdict; const vc = vd==='强力'?'vd-strong':vd==='吉'?'vd-good':vd==='中'?'vd-neut':vd==='弱'?'vd-weak':'vd-afflicted'; html += `
H${escapeHtml(h.house)}${escapeHtml(h.scn)}主: ${escapeHtml(h.lcn)}
${safeNumber(h.total)>0?'+':''}${escapeHtml(h.total)}
${escapeHtml(h.verdict)}
`; for (const it of h.items) { const ic = it.sc > 0 ? 'hi-pos' : it.sc < 0 ? 'hi-neg' : 'hi-zero'; html += `
${escapeHtml(it.src)}${safeNumber(it.sc)>0?'+':''}${escapeHtml(it.sc)}
`; } html += `
`; } c.innerHTML = html; } // ============================================================================ // 4. Vargottama 检测 // ============================================================================ export function renderVargottama(vgList) { const c = $('vargottama-section'); if (!c) return; if (!vgList.length) { c.innerHTML = '
未检测到 Vargottama 行星
'; return; } let html = '
'; for (const v of vgList) { html += `
${escapeHtml(PLANET_SYMBOLS[v.planet]||'')} ${escapeHtml(v.pcn)}Vargottama${escapeHtml(v.d1)}
`; } html += '
'; html += '
Vargottama:行星在本命盘(D1)和九分盘(D9)落入同一星座,能量倍增。无论吉凶,该行星能量都会被放大。
'; c.innerHTML = html; } // ============================================================================ // 5. 行星频率分析 // ============================================================================ export function renderFrequency(freq) { const c = $('frequency-grid'); if (!c) return; let html = ''; for (const [pn, f] of Object.entries(freq)) { const lc = f.pct>=50?'freq-vhigh':f.pct>=40?'freq-high':f.pct>=30?'freq-mid':'freq-low'; const pct = Math.max(0, Math.min(100, safeNumber(f.pct))); html += `
${escapeHtml(PLANET_SYMBOLS[pn]||'')} ${escapeHtml(f.pcn)}${pct}%
${escapeHtml(f.topScn)} (${escapeHtml(f.count)}/${16})
${escapeHtml(f.level)}
${(f.dist || []).map(d=>`${escapeHtml(d.scn)} ${escapeHtml(d.p)}%`).join(' · ')}
`; } c.innerHTML = html; } // ============================================================================ // 6. D1 × D9 × D10 三角验证 // ============================================================================ export function renderTriangle(tri) { const c = $('triangle-table'); if (!c) return; let html = ``; for (const t of tri) { const vc = t.verdict.includes('双重强势')?'tri-best':t.verdict.includes('未兑现')?'tri-break':t.verdict.includes('反击')?'tri-comeback':t.verdict.includes('双重弱势')?'tri-worst':'tri-ok'; html += ``; } html += '
行星D1D1状态D9D9状态D10D10状态Vg判定
${escapeHtml(PLANET_SYMBOLS[t.planet]||'')} ${escapeHtml(t.pcn)}${escapeHtml(t.d1sign)}${escapeHtml(t.d1st)}${escapeHtml(t.d9sign)}${escapeHtml(t.d9st)}${escapeHtml(t.d10sign)}${escapeHtml(t.d10st)}${t.vargottama?'✓':'—'}${escapeHtml(t.verdict)}
'; c.innerHTML = html; } function stCls(st) { return st==='入旺'||st==='入庙'?'st-good':st==='落陷'?'st-bad':'st-neut'; } // ============================================================================ // 7. Raman 宫位评级(六步法) // ============================================================================ function sanitizeRamanDetail(detail) { return String(detail || '') .replace(/\(undefined\)/g, '(缺星座)') .replace(/\bundefined\b/g, '缺资料'); } export function renderRamanGrades(scores) { const c = $('raman-grades-grid'); if (!c) return; let html = ''; for (const s of scores) { const gc = s.grade==='A'?'grade-a':s.grade==='B'?'grade-b':s.grade==='C'?'grade-c':s.grade==='D'?'grade-d':'grade-f'; const domain = HOUSE_DOMAINS[s.house]; html += `
H${escapeHtml(s.house)}${escapeHtml(s.scn)}${escapeHtml(s.grade)}
${escapeHtml(domain?domain.name:'')}
+${escapeHtml(s.pos)} / -${escapeHtml(s.neg)} = ${safeNumber(s.net)>0?'+':''}${escapeHtml(s.net)}
宫主: ${escapeHtml(s.lcn)}
`; for (const d of s.details) html += `
${escapeHtml(sanitizeRamanDetail(d))}
`; html += '
'; } c.innerHTML = html; } // ============================================================================ // 8. Trikona-Kendra 三方四正映射渲染 // ============================================================================ export function renderTrikonaKendra(data) { const c = document.getElementById('trikona-kendra-grid'); if (!c || !data) return; const { houseLords, trikonaConnections, kendraConnections, crossConnections, overallRating, hasRaja } = data; let html = `
${overallRating}
`; // 关键宫位宫主星一览 html += `
关键宫位宫主星
`; const keyHouses = [1, 4, 5, 7, 9, 10]; const houseTag = { 1: '命宫', 4: '家庭', 5: '创意', 7: '婚姻', 9: '命运', 10: '事业' }; const groupTag = h => [1,5,9].includes(h) ? '三方' : '四正'; for (const h of keyHouses) { const hl = houseLords[h]; const tag = houseTag[h] || ''; const grp = groupTag(h); html += `
H${h} ${tag} ${grp}
${escapeHtml(hl.lord_cn)} (${escapeHtml(hl.lord)})
→ H${escapeHtml(hl.lordInHouse || '?')} ${escapeHtml(hl.lordStatus || '')} ${hl.lordRetro ? '℞' : ''}
`; } html += '
'; // 三方连接 if (trikonaConnections.length > 0) { html += `
Trikona 三方连接 (1-5-9)
`; for (const conn of trikonaConnections) { const qClass = conn.quality === 'excellent' ? 'tk-exc' : conn.quality === 'strong' ? 'tk-str' : 'tk-good'; html += `
${conn.quality === 'excellent' ? '★' : conn.quality === 'strong' ? '◆' : '→'} ${escapeHtml(conn.desc)}
`; } html += '
'; } else { html += `
Trikona 三方连接 (1-5-9)
三方宫主星之间无直接连接
`; } // 四正连接 if (kendraConnections.length > 0) { html += `
Kendra 四正连接 (1-4-7-10)
`; for (const conn of kendraConnections) { const qClass = conn.quality === 'excellent' ? 'tk-exc' : conn.quality === 'strong' ? 'tk-str' : 'tk-good'; html += `
${conn.quality === 'excellent' ? '★' : conn.quality === 'strong' ? '◆' : '→'} ${escapeHtml(conn.desc)}
`; } html += '
'; } else { html += `
Kendra 四正连接 (1-4-7-10)
四正宫主星之间无直接连接
`; } // 三方×四正交叉 if (crossConnections.length > 0) { html += `
Trikona × Kendra 交叉连接 (Raja Yoga)
`; for (const conn of crossConnections) { const qClass = conn.quality === 'maha-raja' ? 'tk-maha' : 'tk-raja'; html += `
${conn.quality === 'maha-raja' ? '★★' : '★'} ${escapeHtml(conn.desc)}
`; } html += '
'; } else { html += `
Trikona × Kendra 交叉连接
三方与四正之间无交叉 Raja Yoga 连接
`; } c.innerHTML = html; }