diff --git a/scripts/chart_renderer.py b/scripts/chart_renderer.py new file mode 100644 index 00000000..6bec524b --- /dev/null +++ b/scripts/chart_renderer.py @@ -0,0 +1,238 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +南印度占星盘图可视化渲染器 v1.0 + +生成南印度风格 (4×4方格) 的可视化星盘SVG。 +支持:D1(本命)/D9(Navamsa)/D10(Dasamsa)等分盘 +""" + +from typing import Dict, List, Optional + +SIGNS = ['Aries', 'Taurus', 'Gemini', 'Cancer', 'Leo', 'Virgo', + 'Libra', 'Scorpio', 'Sagittarius', 'Capricorn', 'Aquarius', 'Pisces'] + +# 南印度盘星座固定布局(从左上角顺时针读数) +# 星座位置固定不变,行星散布其中 +SOUTH_INDIAN_GRID = [ + # Row 0: Pisces, Aries, Taurus, Gemini + [11, 0, 1, 2], + # Row 1: Aquarius, (CENTER), (CENTER), Cancer + [10, -1, -1, 3], + # Row 2: Capricorn, (CENTER), (CENTER), Leo + [9, -1, -1, 4], + # Row 3: Sagittarius, Scorpio, Libra, Virgo + [8, 7, 6, 5], +] + +PLANET_SYMBOLS = { + 'Sun': '☉', 'Moon': '☽', 'Mars': '♂', 'Mercury': '☿', + 'Jupiter': '♃', 'Venus': '♀', 'Saturn': '♄', + 'Rahu': '☊', 'Ketu': '☋', 'Asc': 'Asc', +} + +PLANET_COLORS = { + 'Sun': '#E65100', 'Moon': '#1565C0', 'Mars': '#C62828', + 'Mercury': '#2E7D32', 'Jupiter': '#F9A825', 'Venus': '#6A1B9A', + 'Saturn': '#37474F', 'Rahu': '#00695C', 'Ketu': '#BF360C', +} + +SIGN_NAMES_CN = { + 'Aries': '白羊', 'Taurus': '金牛', 'Gemini': '双子', 'Cancer': '巨蟹', + 'Leo': '狮子', 'Virgo': '处女', 'Libra': '天秤', 'Scorpio': '天蝎', + 'Sagittarius': '射手', 'Capricorn': '摩羯', 'Aquarius': '水瓶', 'Pisces': '双鱼', +} + +SIGN_ABBREV = { + 'Aries': 'Ar', 'Taurus': 'Ta', 'Gemini': 'Ge', 'Cancer': 'Cn', + 'Leo': 'Le', 'Virgo': 'Vi', 'Libra': 'Li', 'Scorpio': 'Sc', + 'Sagittarius': 'Sg', 'Capricorn': 'Cp', 'Aquarius': 'Aq', 'Pisces': 'Pi', +} + +CELL_SIZE = 80 +PADDING = 10 +GRID_OFFSET_X = 50 +GRID_OFFSET_Y = 50 +SVG_WIDTH = GRID_OFFSET_X * 2 + CELL_SIZE * 4 +SVG_HEIGHT = GRID_OFFSET_Y * 2 + CELL_SIZE * 4 + 60 + + +def render_south_indian_chart(planets: Dict, asc_sign: str, title: str = "D1 — Rashi Chart") -> str: + """ + 生成南印度风格星盘SVG字符串。 + + Args: + planets: {planet: sign_name} 或 {planet: {'sign': name, 'degree': float}} + asc_sign: 上升星座名称 + title: 图表标题 + + Returns: + 完整SVG字符串 + """ + lines = [] + lines.append(f'') + return '\n'.join(lines) + + +def render_html_report(birth_data: Dict, chart_data: Dict, analysis: Dict, + title: str = "印度占星分析报告") -> str: + """ + 生成完整的HTML分析报告。 + + Args: + birth_data: {'name': str, 'date': str, 'time': str, 'place': str} + chart_data: 星盘数据(用于生成图表) + analysis: 分析结果 {'career': {...}, 'relationship': {...}, 'remedies': {...}, ...} + title: 报告标题 + + Returns: + 完整HTML字符串 + """ + html = f''' + +
+ + +评估:{c.get("assessment", "")}
' + if c.get('fields'): + html += '推荐领域:
'
+ for f in c['fields'][:5]:
+ perc = int(f.get('score', 0) / max(1, max(x.get('score', 0) for x in c['fields'] or [{'score': 1}])) * 100)
+ color = '#1a237e' if perc > 70 else '#283593' if perc > 40 else '#5c6bc0'
+ html += f'{f["field"]} '
+ html += '
评估:{r.get("assessment", "")}
' + if r.get('partnership_style'): + for s in r['partnership_style'][:1]: + html += f'Venus:{s.get("expression", "")}
' + html += '{rem.get("summary", "")}
' + recs = rem.get('recommendations', {}) + if recs.get('gems'): + html += '宝石建议:
'
+ for g in recs['gems'][:3]:
+ html += f'{g["planet"]}: {g["gem"]} '
+ html += '
咒语建议:
'
+ for m in recs['mantras'][:3]:
+ html += f'{m["mantra"]} × {m["repetitions"]} '
+ html += '