Skip to content

Commit

Permalink
draw_planets clean up complete, should be better
Browse files Browse the repository at this point in the history
  • Loading branch information
g-battaglia committed Aug 13, 2024
1 parent 11b6655 commit fa48e11
Show file tree
Hide file tree
Showing 17 changed files with 101 additions and 90 deletions.
20 changes: 20 additions & 0 deletions kerykeion/charts/draw_planets.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,26 @@ def draw_planets(
chart_type: ChartType,
second_subject_available_kerykeion_celestial_points: Union[list[KerykeionPointModel], None] = None,
):
"""
Draws the planets on a chart based on the provided parameters.
Args:
radius (int): The radius of the chart.
available_kerykeion_celestial_points (list[KerykeionPointModel]): List of celestial points for the main subject.
available_planets_setting (list[KerykeionSettingsCelestialPointModel]): Settings for the celestial points.
third_circle_radius (Union[int, float]): Radius of the third circle.
main_subject_first_house_degree_ut (Union[int, float]): Degree of the first house for the main subject.
main_subject_seventh_house_degree_ut (Union[int, float]): Degree of the seventh house for the main subject.
chart_type (ChartType): Type of the chart (e.g., "Transit", "Synastry").
second_subject_available_kerykeion_celestial_points (Union[list[KerykeionPointModel], None], optional):
List of celestial points for the second subject, required for "Transit" or "Synastry" charts. Defaults to None.
Raises:
KerykeionException: If the second subject is required but not provided.
Returns:
str: SVG output for the chart with the planets drawn.
"""
TRANSIT_RING_EXCLUDE_POINTS_NAMES = get_args(Houses)

if chart_type == "Transit" or chart_type == "Synastry":
Expand Down
136 changes: 62 additions & 74 deletions kerykeion/charts/kerykeion_chart_svg.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,11 @@ class KerykeionChartSVG:
earth: float
air: float
water: float
c1: float
c2: float
c3: float
main_radius: float
first_circle_radius: float
second_circle_radius: float
third_circle_radius: float
homedir: Path
xml_svg: Path
width: Union[float, int]
language_settings: dict
chart_colors_settings: dict
Expand All @@ -88,12 +88,6 @@ class KerykeionChartSVG:
chart_settings: dict
user: AstrologicalSubject
available_planets_setting: List[KerykeionSettingsCelestialPointModel]
points_deg_ut: list
points_deg: list
points_retrograde: list
t_points_deg_ut: list
t_points_deg: list
t_points_retrograde: list
height: float
location: str
geolat: float
Expand All @@ -109,7 +103,6 @@ def __init__(
new_settings_file: Union[Path, None] = None,
):
# Directories:
DATA_DIR = Path(__file__).parent
self.homedir = Path.home()
self.new_settings_file = new_settings_file

Expand All @@ -118,8 +111,6 @@ def __init__(
else:
self.output_directory = self.homedir

self.xml_svg = DATA_DIR / "templates/chart.xml"

self.parse_json_settings(new_settings_file)
self.chart_type = chart_type

Expand Down Expand Up @@ -147,14 +138,16 @@ def __init__(
natal_aspects_instance = NatalAspects(self.user, new_settings_file=self.new_settings_file)
self.aspects_list = natal_aspects_instance.relevant_aspects

# TODO: If not second should exit
if self.chart_type == "Transit" or self.chart_type == "Synastry":
if not second_obj:
raise KerykeionException("Second object is required for Transit or Synastry charts.")

# Kerykeion instance
self.t_user = second_obj

# Aspects
self.aspects_list = SynastryAspects(self.user, self.t_user, new_settings_file=self.new_settings_file).relevant_aspects

self.t_available_kerykeion_celestial_points = []
for body in available_celestial_points_names:
self.t_available_kerykeion_celestial_points.append(self.t_user.get(body))
Expand All @@ -171,13 +164,30 @@ def __init__(
self.geolat = self.user.lat
self.geolon = self.user.lng

logging.info(f"{self.user.name} birth location: {self.location}, {self.geolat}, {self.geolon}")

if self.chart_type == "Transit":
self.t_name = self.language_settings["transit_name"]

self.template = None


# Default radius for the chart
self.main_radius = 240

# Set circle radii based on chart type
if self.chart_type == "ExternalNatal":
self.first_circle_radius, self.second_circle_radius, self.third_circle_radius = 56, 92, 112
else:
self.first_circle_radius, self.second_circle_radius, self.third_circle_radius = 0, 36, 120

# Initialize element points
self.fire = 0.0
self.earth = 0.0
self.air = 0.0
self.water = 0.0

# Calculate element points from planets
self._calculate_elements_points_from_planets()

def set_output_directory(self, dir_path: Path) -> None:
"""
Sets the output direcotry and returns it's path.
Expand Down Expand Up @@ -211,11 +221,10 @@ def _draw_zodiac_circle_slices(self, r):
str: The SVG string representing the zodiac circle.
"""
sings = get_args(Sign)

output = ""
for i, sing in enumerate(sings):
output += draw_zodiac_slice(
c1=self.c1,
c1=self.first_circle_radius,
chart_type=self.chart_type,
seventh_house_degree_ut=self.user.houses_degree_ut[6],
num=i,
Expand All @@ -231,6 +240,7 @@ def _calculate_elements_points_from_planets(self):
Calculate chart element points from a planet.
TODO: Refactor this method.
Should be completely rewritten. Maybe even part of the AstrologicalSubject class.
The points should include just the standard way of calculating the elements points.
"""

zodiac = (
Expand Down Expand Up @@ -296,9 +306,6 @@ def _draw_all_aspects_lines(self, r, ar):

def _draw_all_transit_aspects_lines(self, r, ar):
out = ""

self.aspects_list = SynastryAspects(self.user, self.t_user, new_settings_file=self.new_settings_file).relevant_aspects

for aspect in self.aspects_list:
out += draw_aspect_line(
r=r,
Expand All @@ -307,7 +314,6 @@ def _draw_all_transit_aspects_lines(self, r, ar):
color=self.aspects_settings[aspect["aid"]]["color"],
seventh_house_degree_ut=self.user.seventh_house.abs_pos
)

return out

def _create_template_dictionary(self) -> ChartTemplateDictionary:
Expand All @@ -317,52 +323,38 @@ def _create_template_dictionary(self) -> ChartTemplateDictionary:
Returns:
ChartTemplateDictionary: A dictionary with template data for the chart.
"""
# Initialize element points
self.fire = 0.0
self.earth = 0.0
self.air = 0.0
self.water = 0.0

# Calculate element points from planets
self._calculate_elements_points_from_planets()

# Default rotation
rotation = "0"

# Initialize template dictionary
template_dict: ChartTemplateDictionary = dict() # type: ignore
radius = 240

# Set chart dimensions
template_dict["chart_height"] = self.height
template_dict["chart_width"] = self.width

# Set chart name
template_dict["stringName"] = f"{self.user.name}:" if self.chart_type in ["Synastry", "Transit"] else f'{self.language_settings["info"]}:'

# Set viewbox based on chart type
template_dict['viewbox'] = self.chart_settings["basic_chart_viewBox"] if self.chart_type in ["Natal", "ExternalNatal"] else self.chart_settings["wide_chart_viewBox"]

# Set circle radii based on chart type
if self.chart_type == "ExternalNatal":
self.c1, self.c2, self.c3 = 56, 92, 112
else:
self.c1, self.c2, self.c3 = 0, 36, 120

# Generate rings and circles based on chart type
if self.chart_type in ["Transit", "Synastry"]:
template_dict["transitRing"] = draw_transit_ring(radius, self.chart_colors_settings["paper_1"], self.chart_colors_settings["zodiac_transit_ring_3"])
template_dict["degreeRing"] = draw_transit_ring_degree_steps(radius, self.user.seventh_house.abs_pos)
template_dict["first_circle"] = draw_first_circle(radius, self.chart_colors_settings["zodiac_transit_ring_2"], self.chart_type)
template_dict["second_circle"] = draw_second_circle(radius, self.chart_colors_settings['zodiac_transit_ring_1'], self.chart_colors_settings['paper_1'], self.chart_type)
template_dict['third_circle'] = draw_third_circle(radius, self.chart_colors_settings['zodiac_transit_ring_0'], self.chart_colors_settings['paper_1'], self.chart_type)
template_dict["makeAspects"] = self._draw_all_transit_aspects_lines(radius, radius - 160)
template_dict["transitRing"] = draw_transit_ring(self.main_radius, self.chart_colors_settings["paper_1"], self.chart_colors_settings["zodiac_transit_ring_3"])
template_dict["degreeRing"] = draw_transit_ring_degree_steps(self.main_radius, self.user.seventh_house.abs_pos)
template_dict["first_circle"] = draw_first_circle(self.main_radius, self.chart_colors_settings["zodiac_transit_ring_2"], self.chart_type)
template_dict["second_circle"] = draw_second_circle(self.main_radius, self.chart_colors_settings['zodiac_transit_ring_1'], self.chart_colors_settings['paper_1'], self.chart_type)
template_dict['third_circle'] = draw_third_circle(self.main_radius, self.chart_colors_settings['zodiac_transit_ring_0'], self.chart_colors_settings['paper_1'], self.chart_type)
template_dict["makeAspectGrid"] = draw_aspect_transit_grid(self.language_settings["aspects"], self.aspects_list, self.planets_settings, self.aspects_settings)

template_dict["makeAspects"] = self._draw_all_transit_aspects_lines(self.main_radius, self.main_radius - 160)
else:
template_dict["transitRing"] = ""
template_dict["degreeRing"] = draw_degree_ring(radius, self.c1, self.user.seventh_house.abs_pos, self.chart_colors_settings["paper_0"])
template_dict['first_circle'] = draw_first_circle(radius, self.chart_colors_settings["zodiac_radix_ring_2"], self.chart_type, self.c1)
template_dict["second_circle"] = draw_second_circle(radius, self.chart_colors_settings["zodiac_radix_ring_1"], self.chart_colors_settings["paper_1"], self.chart_type, self.c2)
template_dict['third_circle'] = draw_third_circle(radius, self.chart_colors_settings["zodiac_radix_ring_0"], self.chart_colors_settings["paper_1"], self.chart_type, self.c3)
template_dict["makeAspects"] = self._draw_all_aspects_lines(radius, radius - self.c3)
template_dict["degreeRing"] = draw_degree_ring(self.main_radius, self.first_circle_radius, self.user.seventh_house.abs_pos, self.chart_colors_settings["paper_0"])
template_dict['first_circle'] = draw_first_circle(self.main_radius, self.chart_colors_settings["zodiac_radix_ring_2"], self.chart_type, self.first_circle_radius)
template_dict["second_circle"] = draw_second_circle(self.main_radius, self.chart_colors_settings["zodiac_radix_ring_1"], self.chart_colors_settings["paper_1"], self.chart_type, self.second_circle_radius)
template_dict['third_circle'] = draw_third_circle(self.main_radius, self.chart_colors_settings["zodiac_radix_ring_0"], self.chart_colors_settings["paper_1"], self.chart_type, self.third_circle_radius)
template_dict["makeAspectGrid"] = draw_aspect_grid(self.chart_colors_settings['paper_0'], self.available_planets_setting, self.aspects_list)

# Set chart dimensions
template_dict["chart_height"] = self.height
template_dict["chart_width"] = self.width
template_dict["makeAspects"] = self._draw_all_aspects_lines(self.main_radius, self.main_radius - self.third_circle_radius)

# Set chart title
if self.chart_type == "Synastry":
Expand All @@ -372,9 +364,6 @@ def _create_template_dictionary(self) -> ChartTemplateDictionary:
else:
template_dict["stringTitle"] = self.user.name

# Set chart name
template_dict["stringName"] = f"{self.user.name}:" if self.chart_type in ["Synastry", "Transit"] else f'{self.language_settings["info"]}:'

# Set bottom left corner information
template_dict["bottomLeft0"] = f"{self.user.zodiac_type if self.user.zodiac_type == 'Tropic' else self.user.zodiac_type + ' ' + self.user.sidereal_mode}"
template_dict["bottomLeft1"] = f"{self.user.houses_system_name}"
Expand Down Expand Up @@ -431,11 +420,8 @@ def _create_template_dictionary(self) -> ChartTemplateDictionary:
for aspect in self.aspects_settings:
template_dict[f"orb_color_{aspect['degree']}"] = aspect['color']

# Set configuration rotation
template_dict["cfgRotate"] = rotation

# Drawing functions
template_dict["makeZodiac"] = self._draw_zodiac_circle_slices(radius)
template_dict["makeZodiac"] = self._draw_zodiac_circle_slices(self.main_radius)

# Draw houses grid and cusps
if self.chart_type in ["Transit", "Synastry"]:
Expand All @@ -448,15 +434,15 @@ def _create_template_dictionary(self) -> ChartTemplateDictionary:
)

template_dict["makeHouses"] = draw_houses_cusps_and_text_number(
r=radius,
r=self.main_radius,
first_subject_houses_list_ut=self.user.houses_degree_ut,
standard_house_cusp_color=self.chart_colors_settings["houses_radix_line"],
first_house_color=self.planets_settings[12]["color"],
tenth_house_color=self.planets_settings[13]["color"],
seventh_house_color=self.planets_settings[14]["color"],
fourth_house_color=self.planets_settings[15]["color"],
c1=self.c1,
c3=self.c3,
c1=self.first_circle_radius,
c3=self.third_circle_radius,
chart_type=self.chart_type,
second_subject_houses_list_ut=self.t_user.houses_degree_ut,
transit_house_cusp_color=self.chart_colors_settings["houses_transit_line"],
Expand All @@ -471,15 +457,15 @@ def _create_template_dictionary(self) -> ChartTemplateDictionary:
)

template_dict["makeHouses"] = draw_houses_cusps_and_text_number(
r=radius,
r=self.main_radius,
first_subject_houses_list_ut=self.user.houses_degree_ut,
standard_house_cusp_color=self.chart_colors_settings["houses_radix_line"],
first_house_color=self.planets_settings[12]["color"],
tenth_house_color=self.planets_settings[13]["color"],
seventh_house_color=self.planets_settings[14]["color"],
fourth_house_color=self.planets_settings[15]["color"],
c1=self.c1,
c3=self.c3,
c1=self.first_circle_radius,
c3=self.third_circle_radius,
chart_type=self.chart_type,
)

Expand All @@ -489,24 +475,23 @@ def _create_template_dictionary(self) -> ChartTemplateDictionary:
available_kerykeion_celestial_points=self.available_kerykeion_celestial_points,
available_planets_setting=self.available_planets_setting,
second_subject_available_kerykeion_celestial_points=self.t_available_kerykeion_celestial_points,
radius=radius,
radius=self.main_radius,
main_subject_first_house_degree_ut=self.user.houses_degree_ut[0],
main_subject_seventh_house_degree_ut=self.user.houses_degree_ut[6],
chart_type=self.chart_type,
third_circle_radius=self.c3,
third_circle_radius=self.third_circle_radius,
)
else:
template_dict["makePlanets"] = draw_planets(
available_planets_setting=self.available_planets_setting,
chart_type=self.chart_type,
radius=radius,
radius=self.main_radius,
available_kerykeion_celestial_points=self.available_kerykeion_celestial_points,
third_circle_radius=self.c3,
third_circle_radius=self.third_circle_radius,
main_subject_first_house_degree_ut=self.user.houses_degree_ut[0],
main_subject_seventh_house_degree_ut=self.user.houses_degree_ut[6],
)


# Draw elements percentages
template_dict["elements_percentages"] = draw_elements_percentages(
self.language_settings['fire'],
Expand Down Expand Up @@ -557,8 +542,11 @@ def makeTemplate(self, minify: bool = False) -> str:
"""Creates the template for the SVG file"""
td = self._create_template_dictionary()

DATA_DIR = Path(__file__).parent
xml_svg = DATA_DIR / "templates/chart.xml"

# read template
with open(self.xml_svg, "r", encoding="utf-8", errors="ignore") as f:
with open(xml_svg, "r", encoding="utf-8", errors="ignore") as f:
template = Template(f.read()).substitute(td)

# return filename
Expand Down
2 changes: 1 addition & 1 deletion kerykeion/charts/templates/chart.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
>
<title>$stringTitle | Kerykeion</title>
<!--- Main Chart -->
<g kr:node="Main_Chart" transform="rotate($cfgRotate)">
<g kr:node="Main_Chart">

<g kr:node="Main_Text">
<rect class="background-rectangle" x="0" y="0" width="$chart_width" height="$chart_height" style="fill: $paper_color_1" />
Expand Down
1 change: 0 additions & 1 deletion kerykeion/kr_types/chart_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ class ChartTemplateDictionary(TypedDict):
orb_color_150: str
orb_color_180: str

cfgRotate: str
cfgTranslate: str
makeZodiac: str
makeHouses: str
Expand Down
8 changes: 6 additions & 2 deletions kerykeion/kr_types/settings_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,14 @@ class KerykeionSettingsAspectModel(SubscriptableBaseModel):
degree: int = Field(title="Aspect Degrees", description="The degree of the aspect")
name: str = Field(title="Aspect Name", description="The name of the aspect")
is_active: bool = Field(title="Aspect is Active", description="Is the aspect active?")
visible_grid: bool = Field(title="Aspect Visible Grid", description="Is the aspect visible in the grid?")
is_major: bool = Field(title="Aspect is Major", description="Is the aspect major?")
is_minor: bool = Field(title="Aspect is Minor", description="Is the aspect minor?")
orb: int = Field(title="Aspect Orb", description="The orb of the aspect")
color: str = Field(title="Aspect Color", description="The color of the aspect")

# Deprecated: Not used anymore
visible_grid: bool = Field(title="Aspect Visible Grid", description="Is the aspect visible in the grid?")


# Language Settings
class KerykeionLanguageCelestialPointModel(SubscriptableBaseModel):
Expand Down Expand Up @@ -145,9 +147,11 @@ class KerykeionLanguageModel(SubscriptableBaseModel):

class KerykeionGeneralSettingsModel(SubscriptableBaseModel):
axes_orbit: int = Field(title="Axes Orbit", description="The orbit of the axes in the chart")
planet_in_zodiac_extra_points: int = Field(title="Planet in Zodiac Extra Points", description="The extra points of the planet in the zodiac")
language: str = Field(title="Language", description="The language of the chart")

# Deprecated: Should be removed
planet_in_zodiac_extra_points: int = Field(title="Planet in Zodiac Extra Points", description="The extra points of the planet in the zodiac")

class KerykeionChartSettingsModel(SubscriptableBaseModel):
basic_chart_viewBox: str = Field(title="Basic Chart ViewBox", description="The viewbox of the basic chart")
wide_chart_viewBox: str = Field(title="Wide Chart ViewBox", description="The viewbox of the wide chart")
Expand Down
2 changes: 1 addition & 1 deletion tests/charts/John Lennon - ExternalNatal Chart.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit fa48e11

Please sign in to comment.