kerykeion 4.14.3__py3-none-any.whl → 4.14.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of kerykeion might be problematic. Click here for more details.

@@ -5,24 +5,21 @@
5
5
 
6
6
 
7
7
  import logging
8
+ from typing import get_args
8
9
 
9
10
  from kerykeion.settings.kerykeion_settings import get_settings
10
11
  from kerykeion.aspects.synastry_aspects import SynastryAspects
11
12
  from kerykeion.aspects.natal_aspects import NatalAspects
12
13
  from kerykeion.astrological_subject import AstrologicalSubject
13
- from kerykeion.kr_types import KerykeionException, ChartType
14
+ from kerykeion.kr_types import KerykeionException, ChartType, KerykeionPointModel, Sign
14
15
  from kerykeion.kr_types import ChartTemplateDictionary
15
16
  from kerykeion.kr_types.settings_models import KerykeionSettingsCelestialPointModel
16
17
  from kerykeion.charts.charts_utils import (
17
- degreeDiff,
18
- sliceToX,
19
- sliceToY,
20
18
  draw_zodiac_slice,
21
19
  convert_latitude_coordinate_to_string,
22
20
  convert_longitude_coordinate_to_string,
23
21
  draw_aspect_line,
24
22
  draw_elements_percentages,
25
- convert_decimal_to_degree_string,
26
23
  draw_transit_ring_degree_steps,
27
24
  draw_degree_ring,
28
25
  draw_transit_ring,
@@ -32,8 +29,11 @@ from kerykeion.charts.charts_utils import (
32
29
  draw_aspect_grid,
33
30
  draw_houses_cusps_and_text_number,
34
31
  draw_aspect_transit_grid,
35
- draw_moon_phase
32
+ draw_moon_phase,
33
+ draw_house_grid,
34
+ draw_planet_grid,
36
35
  )
36
+ from kerykeion.charts.draw_planets import draw_planets
37
37
  from pathlib import Path
38
38
  from scour.scour import scourString
39
39
  from string import Template
@@ -74,11 +74,11 @@ class KerykeionChartSVG:
74
74
  earth: float
75
75
  air: float
76
76
  water: float
77
- c1: float
78
- c2: float
79
- c3: float
77
+ main_radius: float
78
+ first_circle_radius: float
79
+ second_circle_radius: float
80
+ third_circle_radius: float
80
81
  homedir: Path
81
- xml_svg: Path
82
82
  width: Union[float, int]
83
83
  language_settings: dict
84
84
  chart_colors_settings: dict
@@ -88,22 +88,10 @@ class KerykeionChartSVG:
88
88
  chart_settings: dict
89
89
  user: AstrologicalSubject
90
90
  available_planets_setting: List[KerykeionSettingsCelestialPointModel]
91
- transit_ring_exclude_points_names: List[str]
92
- points_deg_ut: list
93
- points_deg: list
94
- points_sign: list
95
- points_retrograde: list
96
- houses_sign_graph: list
97
- t_points_deg_ut: list
98
- t_points_deg: list
99
- t_points_sign: list
100
- t_points_retrograde: list
101
- t_houses_sign_graph: list
102
91
  height: float
103
92
  location: str
104
93
  geolat: float
105
94
  geolon: float
106
- zodiac: tuple
107
95
  template: str
108
96
 
109
97
  def __init__(
@@ -115,7 +103,6 @@ class KerykeionChartSVG:
115
103
  new_settings_file: Union[Path, None] = None,
116
104
  ):
117
105
  # Directories:
118
- DATA_DIR = Path(__file__).parent
119
106
  self.homedir = Path.home()
120
107
  self.new_settings_file = new_settings_file
121
108
 
@@ -124,8 +111,6 @@ class KerykeionChartSVG:
124
111
  else:
125
112
  self.output_directory = self.homedir
126
113
 
127
- self.xml_svg = DATA_DIR / "templates/chart.xml"
128
-
129
114
  self.parse_json_settings(new_settings_file)
130
115
  self.chart_type = chart_type
131
116
 
@@ -139,58 +124,20 @@ class KerykeionChartSVG:
139
124
 
140
125
  self.available_planets_setting.append(body)
141
126
 
142
- # House cusp points are excluded from the transit ring.
143
- self.transit_ring_exclude_points_names = [
144
- "First_House",
145
- "Second_House",
146
- "Third_House",
147
- "Fourth_House",
148
- "Fifth_House",
149
- "Sixth_House",
150
- "Seventh_House",
151
- "Eighth_House",
152
- "Ninth_House",
153
- "Tenth_House",
154
- "Eleventh_House",
155
- "Twelfth_House"
156
- ]
157
-
158
127
  # Available bodies
159
- available_celestial_points = []
128
+ available_celestial_points_names = []
160
129
  for body in self.available_planets_setting:
161
- available_celestial_points.append(body["name"].lower())
162
-
163
- # Make a list for the absolute degrees of the points of the graphic.
164
- self.points_deg_ut = []
165
- for planet in available_celestial_points:
166
- self.points_deg_ut.append(self.user.get(planet).abs_pos)
167
-
168
- # Make a list of the relative degrees of the points in the graphic.
169
- self.points_deg = []
170
- for planet in available_celestial_points:
171
- self.points_deg.append(self.user.get(planet).position)
130
+ available_celestial_points_names.append(body["name"].lower())
172
131
 
173
- # Make list of the points sign
174
- self.points_sign = []
175
- for planet in available_celestial_points:
176
- self.points_sign.append(self.user.get(planet).sign_num)
177
-
178
- # Make a list of points if they are retrograde or not.
179
- self.points_retrograde = []
180
- for planet in available_celestial_points:
181
- self.points_retrograde.append(self.user.get(planet).retrograde)
132
+ self.available_kerykeion_celestial_points: list[KerykeionPointModel] = []
133
+ for body in available_celestial_points_names:
134
+ self.available_kerykeion_celestial_points.append(self.user.get(body))
182
135
 
183
136
  # Makes the sign number list.
184
-
185
- self.houses_sign_graph = []
186
- for h in self.user.houses_list:
187
- self.houses_sign_graph.append(h["sign_num"])
188
-
189
137
  if self.chart_type == "Natal" or self.chart_type == "ExternalNatal":
190
138
  natal_aspects_instance = NatalAspects(self.user, new_settings_file=self.new_settings_file)
191
139
  self.aspects_list = natal_aspects_instance.relevant_aspects
192
140
 
193
- # TODO: If not second should exit
194
141
  if self.chart_type == "Transit" or self.chart_type == "Synastry":
195
142
  if not second_obj:
196
143
  raise KerykeionException("Second object is required for Transit or Synastry charts.")
@@ -198,29 +145,12 @@ class KerykeionChartSVG:
198
145
  # Kerykeion instance
199
146
  self.t_user = second_obj
200
147
 
201
- # Make a list for the absolute degrees of the points of the graphic.
202
- self.t_points_deg_ut = []
203
- for planet in available_celestial_points:
204
- self.t_points_deg_ut.append(self.t_user.get(planet).abs_pos)
205
-
206
- # Make a list of the relative degrees of the points in the graphic.
207
- self.t_points_deg = []
208
- for planet in available_celestial_points:
209
- self.t_points_deg.append(self.t_user.get(planet).position)
148
+ # Aspects
149
+ self.aspects_list = SynastryAspects(self.user, self.t_user, new_settings_file=self.new_settings_file).relevant_aspects
210
150
 
211
- # Make list of the poits sign.
212
- self.t_points_sign = []
213
- for planet in available_celestial_points:
214
- self.t_points_sign.append(self.t_user.get(planet).sign_num)
215
-
216
- # Make a list of poits if they are retrograde or not.
217
- self.t_points_retrograde = []
218
- for planet in available_celestial_points:
219
- self.t_points_retrograde.append(self.t_user.get(planet).retrograde)
220
-
221
- self.t_houses_sign_graph = []
222
- for h in self.t_user.houses_list:
223
- self.t_houses_sign_graph.append(h["sign_num"])
151
+ self.t_available_kerykeion_celestial_points = []
152
+ for body in available_celestial_points_names:
153
+ self.t_available_kerykeion_celestial_points.append(self.t_user.get(body))
224
154
 
225
155
  # screen size
226
156
  self.height = self._DEFAULT_HEIGHT
@@ -234,32 +164,30 @@ class KerykeionChartSVG:
234
164
  self.geolat = self.user.lat
235
165
  self.geolon = self.user.lng
236
166
 
237
- logging.info(f"{self.user.name} birth location: {self.location}, {self.geolat}, {self.geolon}")
238
-
239
167
  if self.chart_type == "Transit":
240
168
  self.t_name = self.language_settings["transit_name"]
241
169
 
242
- # configuration
243
- # ZOOM 1 = 100%
244
- self.zoom = 1
245
-
246
- self.zodiac = (
247
- {"name": "aries", "element": "fire"},
248
- {"name": "taurus", "element": "earth"},
249
- {"name": "gemini", "element": "air"},
250
- {"name": "cancer", "element": "water"},
251
- {"name": "leo", "element": "fire"},
252
- {"name": "virgo", "element": "earth"},
253
- {"name": "libra", "element": "air"},
254
- {"name": "scorpio", "element": "water"},
255
- {"name": "sagittarius", "element": "fire"},
256
- {"name": "capricorn", "element": "earth"},
257
- {"name": "aquarius", "element": "air"},
258
- {"name": "pisces", "element": "water"},
259
- )
260
-
261
170
  self.template = None
262
171
 
172
+
173
+ # Default radius for the chart
174
+ self.main_radius = 240
175
+
176
+ # Set circle radii based on chart type
177
+ if self.chart_type == "ExternalNatal":
178
+ self.first_circle_radius, self.second_circle_radius, self.third_circle_radius = 56, 92, 112
179
+ else:
180
+ self.first_circle_radius, self.second_circle_radius, self.third_circle_radius = 0, 36, 120
181
+
182
+ # Initialize element points
183
+ self.fire = 0.0
184
+ self.earth = 0.0
185
+ self.air = 0.0
186
+ self.water = 0.0
187
+
188
+ # Calculate element points from planets
189
+ self._calculate_elements_points_from_planets()
190
+
263
191
  def set_output_directory(self, dir_path: Path) -> None:
264
192
  """
265
193
  Sets the output direcotry and returns it's path.
@@ -292,17 +220,17 @@ class KerykeionChartSVG:
292
220
  Returns:
293
221
  str: The SVG string representing the zodiac circle.
294
222
  """
295
-
223
+ sings = get_args(Sign)
296
224
  output = ""
297
- for i, zodiac_element in enumerate(self.zodiac):
225
+ for i, sing in enumerate(sings):
298
226
  output += draw_zodiac_slice(
299
- c1=self.c1,
227
+ c1=self.first_circle_radius,
300
228
  chart_type=self.chart_type,
301
229
  seventh_house_degree_ut=self.user.houses_degree_ut[6],
302
230
  num=i,
303
231
  r=r,
304
232
  style=f'fill:{self.chart_colors_settings[f"zodiac_bg_{i}"]}; fill-opacity: 0.5;',
305
- type=zodiac_element["name"],
233
+ type=sing,
306
234
  )
307
235
 
308
236
  return output
@@ -310,19 +238,47 @@ class KerykeionChartSVG:
310
238
  def _calculate_elements_points_from_planets(self):
311
239
  """
312
240
  Calculate chart element points from a planet.
241
+ TODO: Refactor this method.
242
+ Should be completely rewritten. Maybe even part of the AstrologicalSubject class.
243
+ The points should include just the standard way of calculating the elements points.
313
244
  """
245
+
246
+ zodiac = (
247
+ {"name": "Ari", "element": "fire"},
248
+ {"name": "Tau", "element": "earth"},
249
+ {"name": "Gem", "element": "air"},
250
+ {"name": "Can", "element": "water"},
251
+ {"name": "Leo", "element": "fire"},
252
+ {"name": "Vir", "element": "earth"},
253
+ {"name": "Lib", "element": "air"},
254
+ {"name": "Sco", "element": "water"},
255
+ {"name": "Sag", "element": "fire"},
256
+ {"name": "Cap", "element": "earth"},
257
+ {"name": "Aqu", "element": "air"},
258
+ {"name": "Pis", "element": "water"},
259
+ )
314
260
 
261
+ # Available bodies
262
+ available_celestial_points_names = []
263
+ for body in self.available_planets_setting:
264
+ available_celestial_points_names.append(body["name"].lower())
265
+
266
+ # Make list of the points sign
267
+ points_sign = []
268
+ for planet in available_celestial_points_names:
269
+ points_sign.append(self.user.get(planet).sign_num)
270
+
315
271
  for i in range(len(self.available_planets_setting)):
316
272
  # element: get extra points if planet is in own zodiac sign.
317
273
  related_zodiac_signs = self.available_planets_setting[i]["related_zodiac_signs"]
318
- cz = self.points_sign[i]
274
+ cz = points_sign[i]
319
275
  extra_points = 0
320
276
  if related_zodiac_signs != []:
321
277
  for e in range(len(related_zodiac_signs)):
322
278
  if int(related_zodiac_signs[e]) == int(cz):
323
279
  extra_points = self.planet_in_zodiac_extra_points
324
280
 
325
- ele = self.zodiac[self.points_sign[i]]["element"]
281
+ ele = zodiac[points_sign[i]]["element"]
326
282
  if ele == "fire":
327
283
  self.fire = self.fire + self.available_planets_setting[i]["element_points"] + extra_points
328
284
 
@@ -335,344 +291,6 @@ class KerykeionChartSVG:
335
291
  elif ele == "water":
336
292
  self.water = self.water + self.available_planets_setting[i]["element_points"] + extra_points
337
293
 
338
- def _make_planets(self, r):
339
- planets_degut = {}
340
- diff = range(len(self.available_planets_setting))
341
-
342
- for i in range(len(self.available_planets_setting)):
343
- # list of planets sorted by degree
344
- logging.debug(f"planet: {i}, degree: {self.points_deg_ut[i]}")
345
- planets_degut[self.points_deg_ut[i]] = i
346
-
347
- """
348
- FIXME: The planets_degut is a dictionary like:
349
- {planet_degree: planet_index}
350
- It should be replaced bu points_deg_ut
351
- print(self.points_deg_ut)
352
- print(planets_degut)
353
- """
354
-
355
- output = ""
356
- keys = list(planets_degut.keys())
357
- keys.sort()
358
- switch = 0
359
-
360
- planets_degrouped = {}
361
- groups = []
362
- planets_by_pos = list(range(len(planets_degut)))
363
- planet_drange = 3.4
364
- # get groups closely together
365
- group_open = False
366
- for e in range(len(keys)):
367
- i = planets_degut[keys[e]]
368
- # get distances between planets
369
- if e == 0:
370
- prev = self.points_deg_ut[planets_degut[keys[-1]]]
371
- next = self.points_deg_ut[planets_degut[keys[1]]]
372
- elif e == (len(keys) - 1):
373
- prev = self.points_deg_ut[planets_degut[keys[e - 1]]]
374
- next = self.points_deg_ut[planets_degut[keys[0]]]
375
- else:
376
- prev = self.points_deg_ut[planets_degut[keys[e - 1]]]
377
- next = self.points_deg_ut[planets_degut[keys[e + 1]]]
378
- diffa = degreeDiff(prev, self.points_deg_ut[i])
379
- diffb = degreeDiff(next, self.points_deg_ut[i])
380
- planets_by_pos[e] = [i, diffa, diffb]
381
-
382
- logging.debug(f'{self.available_planets_setting[i]["label"]}, {diffa}, {diffb}')
383
-
384
- if diffb < planet_drange:
385
- if group_open:
386
- groups[-1].append([e, diffa, diffb, self.available_planets_setting[planets_degut[keys[e]]]["label"]])
387
- else:
388
- group_open = True
389
- groups.append([])
390
- groups[-1].append([e, diffa, diffb, self.available_planets_setting[planets_degut[keys[e]]]["label"]])
391
- else:
392
- if group_open:
393
- groups[-1].append([e, diffa, diffb, self.available_planets_setting[planets_degut[keys[e]]]["label"]])
394
- group_open = False
395
-
396
- def zero(x):
397
- return 0
398
-
399
- planets_delta = list(map(zero, range(len(self.available_planets_setting))))
400
-
401
- # print groups
402
- # print planets_by_pos
403
- for a in range(len(groups)):
404
- # Two grouped planets
405
- if len(groups[a]) == 2:
406
- next_to_a = groups[a][0][0] - 1
407
- if groups[a][1][0] == (len(planets_by_pos) - 1):
408
- next_to_b = 0
409
- else:
410
- next_to_b = groups[a][1][0] + 1
411
- # if both planets have room
412
- if (groups[a][0][1] > (2 * planet_drange)) & (groups[a][1][2] > (2 * planet_drange)):
413
- planets_delta[groups[a][0][0]] = -(planet_drange - groups[a][0][2]) / 2
414
- planets_delta[groups[a][1][0]] = +(planet_drange - groups[a][0][2]) / 2
415
- # if planet a has room
416
- elif groups[a][0][1] > (2 * planet_drange):
417
- planets_delta[groups[a][0][0]] = -planet_drange
418
- # if planet b has room
419
- elif groups[a][1][2] > (2 * planet_drange):
420
- planets_delta[groups[a][1][0]] = +planet_drange
421
-
422
- # if planets next to a and b have room move them
423
- elif (planets_by_pos[next_to_a][1] > (2.4 * planet_drange)) & (planets_by_pos[next_to_b][2] > (2.4 * planet_drange)):
424
- planets_delta[(next_to_a)] = groups[a][0][1] - planet_drange * 2
425
- planets_delta[groups[a][0][0]] = -planet_drange * 0.5
426
- planets_delta[next_to_b] = -(groups[a][1][2] - planet_drange * 2)
427
- planets_delta[groups[a][1][0]] = +planet_drange * 0.5
428
-
429
- # if planet next to a has room move them
430
- elif planets_by_pos[next_to_a][1] > (2 * planet_drange):
431
- planets_delta[(next_to_a)] = groups[a][0][1] - planet_drange * 2.5
432
- planets_delta[groups[a][0][0]] = -planet_drange * 1.2
433
-
434
- # if planet next to b has room move them
435
- elif planets_by_pos[next_to_b][2] > (2 * planet_drange):
436
- planets_delta[next_to_b] = -(groups[a][1][2] - planet_drange * 2.5)
437
- planets_delta[groups[a][1][0]] = +planet_drange * 1.2
438
-
439
- # Three grouped planets or more
440
- xl = len(groups[a])
441
- if xl >= 3:
442
- available = groups[a][0][1]
443
- for f in range(xl):
444
- available += groups[a][f][2]
445
- need = (3 * planet_drange) + (1.2 * (xl - 1) * planet_drange)
446
- leftover = available - need
447
- xa = groups[a][0][1]
448
- xb = groups[a][(xl - 1)][2]
449
-
450
- # center
451
- if (xa > (need * 0.5)) & (xb > (need * 0.5)):
452
- startA = xa - (need * 0.5)
453
- # position relative to next planets
454
- else:
455
- startA = (leftover / (xa + xb)) * xa
456
- startB = (leftover / (xa + xb)) * xb
457
-
458
- if available > need:
459
- planets_delta[groups[a][0][0]] = startA - groups[a][0][1] + (1.5 * planet_drange)
460
- for f in range(xl - 1):
461
- planets_delta[groups[a][(f + 1)][0]] = 1.2 * planet_drange + planets_delta[groups[a][f][0]] - groups[a][f][2]
462
-
463
- for e in range(len(keys)):
464
- i = planets_degut[keys[e]]
465
-
466
- # coordinates
467
- if self.chart_type == "Transit" or self.chart_type == "Synastry":
468
- if 22 < i < 27:
469
- rplanet = 76
470
- elif switch == 1:
471
- rplanet = 110
472
- switch = 0
473
- else:
474
- rplanet = 130
475
- switch = 1
476
- else:
477
- # if 22 < i < 27 it is asc,mc,dsc,ic (angles of chart)
478
- # put on special line (rplanet is range from outer ring)
479
- amin, bmin, cmin = 0, 0, 0
480
- if self.chart_type == "ExternalNatal":
481
- amin = 74 - 10
482
- bmin = 94 - 10
483
- cmin = 40 - 10
484
-
485
- if 22 < i < 27:
486
- rplanet = 40 - cmin
487
- elif switch == 1:
488
- rplanet = 74 - amin
489
- switch = 0
490
- else:
491
- rplanet = 94 - bmin
492
- switch = 1
493
-
494
- rtext = 45
495
-
496
- offset = (int(self.user.houses_degree_ut[6]) / -1) + int(self.points_deg_ut[i] + planets_delta[e])
497
- trueoffset = (int(self.user.houses_degree_ut[6]) / -1) + int(self.points_deg_ut[i])
498
-
499
- planet_x = sliceToX(0, (r - rplanet), offset) + rplanet
500
- planet_y = sliceToY(0, (r - rplanet), offset) + rplanet
501
- if self.chart_type == "Transit" or self.chart_type == "Synastry":
502
- scale = 0.8
503
-
504
- elif self.chart_type == "ExternalNatal":
505
- scale = 0.8
506
- # line1
507
- x1 = sliceToX(0, (r - self.c3), trueoffset) + self.c3
508
- y1 = sliceToY(0, (r - self.c3), trueoffset) + self.c3
509
- x2 = sliceToX(0, (r - rplanet - 30), trueoffset) + rplanet + 30
510
- y2 = sliceToY(0, (r - rplanet - 30), trueoffset) + rplanet + 30
511
- color = self.available_planets_setting[i]["color"]
512
- output += (
513
- '<line x1="%s" y1="%s" x2="%s" y2="%s" style="stroke-width:1px;stroke:%s;stroke-opacity:.3;"/>\n'
514
- % (x1, y1, x2, y2, color)
515
- )
516
- # line2
517
- x1 = sliceToX(0, (r - rplanet - 30), trueoffset) + rplanet + 30
518
- y1 = sliceToY(0, (r - rplanet - 30), trueoffset) + rplanet + 30
519
- x2 = sliceToX(0, (r - rplanet - 10), offset) + rplanet + 10
520
- y2 = sliceToY(0, (r - rplanet - 10), offset) + rplanet + 10
521
- output += (
522
- '<line x1="%s" y1="%s" x2="%s" y2="%s" style="stroke-width:1px;stroke:%s;stroke-opacity:.5;"/>\n'
523
- % (x1, y1, x2, y2, color)
524
- )
525
-
526
- else:
527
- scale = 1
528
-
529
- planet_details = self.user[self.available_planets_setting[i]["name"].lower()]
530
-
531
- output += f'<g kr:node="ChartPoint" kr:house="{planet_details["house"]}" kr:sign="{planet_details["sign"]}" kr:slug="{planet_details["name"]}" transform="translate(-{12 * scale},-{12 * scale}) scale({scale})">'
532
- output += f'<use x="{planet_x * (1/scale)}" y="{planet_y * (1/scale)}" xlink:href="#{self.available_planets_setting[i]["name"]}" />'
533
- output += f'</g>'
534
-
535
- # make transit degut and display planets
536
- if self.chart_type == "Transit" or self.chart_type == "Synastry":
537
- group_offset = {}
538
- t_planets_degut = {}
539
- list_range = len(self.available_planets_setting)
540
-
541
- for i in range(list_range):
542
- if self.chart_type == "Transit" and self.available_planets_setting[i]['name'] in self.transit_ring_exclude_points_names:
543
- continue
544
-
545
- group_offset[i] = 0
546
- t_planets_degut[self.t_points_deg_ut[i]] = i
547
-
548
- t_keys = list(t_planets_degut.keys())
549
- t_keys.sort()
550
-
551
- # grab closely grouped planets
552
- groups = []
553
- in_group = False
554
- for e in range(len(t_keys)):
555
- i_a = t_planets_degut[t_keys[e]]
556
- if e == (len(t_keys) - 1):
557
- i_b = t_planets_degut[t_keys[0]]
558
- else:
559
- i_b = t_planets_degut[t_keys[e + 1]]
560
-
561
- a = self.t_points_deg_ut[i_a]
562
- b = self.t_points_deg_ut[i_b]
563
- diff = degreeDiff(a, b)
564
- if diff <= 2.5:
565
- if in_group:
566
- groups[-1].append(i_b)
567
- else:
568
- groups.append([i_a])
569
- groups[-1].append(i_b)
570
- in_group = True
571
- else:
572
- in_group = False
573
- # loop groups and set degrees display adjustment
574
- for i in range(len(groups)):
575
- if len(groups[i]) == 2:
576
- group_offset[groups[i][0]] = -1.0
577
- group_offset[groups[i][1]] = 1.0
578
- elif len(groups[i]) == 3:
579
- group_offset[groups[i][0]] = -1.5
580
- group_offset[groups[i][1]] = 0
581
- group_offset[groups[i][2]] = 1.5
582
- elif len(groups[i]) == 4:
583
- group_offset[groups[i][0]] = -2.0
584
- group_offset[groups[i][1]] = -1.0
585
- group_offset[groups[i][2]] = 1.0
586
- group_offset[groups[i][3]] = 2.0
587
-
588
- switch = 0
589
-
590
- # Transit planets loop
591
- for e in range(len(t_keys)):
592
- if self.chart_type == "Transit" and self.available_planets_setting[e]["name"] in self.transit_ring_exclude_points_names:
593
- continue
594
-
595
- i = t_planets_degut[t_keys[e]]
596
-
597
- if 22 < i < 27:
598
- rplanet = 9
599
- elif switch == 1:
600
- rplanet = 18
601
- switch = 0
602
- else:
603
- rplanet = 26
604
- switch = 1
605
-
606
- # Transit planet name
607
- zeropoint = 360 - self.user.houses_degree_ut[6]
608
- t_offset = zeropoint + self.t_points_deg_ut[i]
609
- if t_offset > 360:
610
- t_offset = t_offset - 360
611
- planet_x = sliceToX(0, (r - rplanet), t_offset) + rplanet
612
- planet_y = sliceToY(0, (r - rplanet), t_offset) + rplanet
613
- output += f'<g class="transit-planet-name" transform="translate(-6,-6)"><g transform="scale(0.5)"><use x="{planet_x*2}" y="{planet_y*2}" xlink:href="#{self.available_planets_setting[i]["name"]}" /></g></g>'
614
-
615
- # Transit planet line
616
- x1 = sliceToX(0, r + 3, t_offset) - 3
617
- y1 = sliceToY(0, r + 3, t_offset) - 3
618
- x2 = sliceToX(0, r - 3, t_offset) + 3
619
- y2 = sliceToY(0, r - 3, t_offset) + 3
620
- output += f'<line class="transit-planet-line" x1="{str(x1)}" y1="{str(y1)}" x2="{str(x2)}" y2="{str(y2)}" style="stroke: {self.available_planets_setting[i]["color"]}; stroke-width: 1px; stroke-opacity:.8;"/>'
621
-
622
- # transit planet degree text
623
- rotate = self.user.houses_degree_ut[0] - self.t_points_deg_ut[i]
624
- textanchor = "end"
625
- t_offset += group_offset[i]
626
- rtext = -3.0
627
-
628
- if -90 > rotate > -270:
629
- rotate = rotate + 180.0
630
- textanchor = "start"
631
- if 270 > rotate > 90:
632
- rotate = rotate - 180.0
633
- textanchor = "start"
634
-
635
- if textanchor == "end":
636
- xo = 1
637
- else:
638
- xo = -1
639
- deg_x = sliceToX(0, (r - rtext), t_offset + xo) + rtext
640
- deg_y = sliceToY(0, (r - rtext), t_offset + xo) + rtext
641
- degree = int(t_offset)
642
- output += f'<g transform="translate({deg_x},{deg_y})">'
643
- output += f'<text transform="rotate({rotate})" text-anchor="{textanchor}'
644
- output += f'" style="fill: {self.available_planets_setting[i]["color"]}; font-size: 10px;">{convert_decimal_to_degree_string(self.t_points_deg[i], type="1")}'
645
- output += "</text></g>"
646
-
647
- # check transit
648
- if self.chart_type == "Transit" or self.chart_type == "Synastry":
649
- dropin = 36
650
- else:
651
- dropin = 0
652
-
653
- # planet line
654
- x1 = sliceToX(0, r - (dropin + 3), offset) + (dropin + 3)
655
- y1 = sliceToY(0, r - (dropin + 3), offset) + (dropin + 3)
656
- x2 = sliceToX(0, (r - (dropin - 3)), offset) + (dropin - 3)
657
- y2 = sliceToY(0, (r - (dropin - 3)), offset) + (dropin - 3)
658
-
659
- output += f'<line x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}" style="stroke: {self.available_planets_setting[i]["color"]}; stroke-width: 2px; stroke-opacity:.6;"/>'
660
-
661
- # check transit
662
- if self.chart_type == "Transit" or self.chart_type == "Synastry":
663
- dropin = 160
664
- else:
665
- dropin = 120
666
-
667
- x1 = sliceToX(0, r - dropin, offset) + dropin
668
- y1 = sliceToY(0, r - dropin, offset) + dropin
669
- x2 = sliceToX(0, (r - (dropin - 3)), offset) + (dropin - 3)
670
- y2 = sliceToY(0, (r - (dropin - 3)), offset) + (dropin - 3)
671
- output += f'<line x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}" style="stroke: {self.available_planets_setting[i]["color"]}; stroke-width: 2px; stroke-opacity:.6;"/>'
672
-
673
- return output
674
-
675
- # Aspect and aspect grid functions for natal type charts.
676
294
  def _draw_all_aspects_lines(self, r, ar):
677
295
  out = ""
678
296
  for aspect in self.aspects_list:
@@ -686,12 +304,8 @@ class KerykeionChartSVG:
686
304
 
687
305
  return out
688
306
 
689
- # Aspect and aspect grid functions for transit type charts
690
307
  def _draw_all_transit_aspects_lines(self, r, ar):
691
308
  out = ""
692
-
693
- self.aspects_list = SynastryAspects(self.user, self.t_user, new_settings_file=self.new_settings_file).relevant_aspects
694
-
695
309
  for aspect in self.aspects_list:
696
310
  out += draw_aspect_line(
697
311
  r=r,
@@ -700,335 +314,186 @@ class KerykeionChartSVG:
700
314
  color=self.aspects_settings[aspect["aid"]]["color"],
701
315
  seventh_house_degree_ut=self.user.seventh_house.abs_pos
702
316
  )
703
-
704
317
  return out
705
318
 
706
- def _makePlanetGrid(self):
707
- li = 10
708
- offset = 0
709
-
710
- out = '<g transform="translate(510,-20)">'
711
- out += '<g transform="translate(140, -15)">'
712
- out += f'<text text-anchor="end" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 14px;">{self.language_settings["planets_and_house"]} {self.user.name}:</text>'
713
- out += "</g>"
714
-
715
- end_of_line = None
716
- for i in range(len(self.available_planets_setting)):
717
- offset_between_lines = 14
718
- end_of_line = "</g>"
719
-
720
- # Guarda qui !!
721
- if i == 27:
722
- li = 10
723
- offset = -120
724
-
725
- # start of line
726
- out += f'<g transform="translate({offset},{li})">'
727
-
728
- # planet text
729
- out += f'<text text-anchor="end" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;">{self.language_settings["celestial_points"][self.available_planets_setting[i]["label"]]}</text>'
730
-
731
- # planet symbol
732
- out += f'<g transform="translate(5,-8)"><use transform="scale(0.4)" xlink:href="#{self.available_planets_setting[i]["name"]}" /></g>'
733
-
734
- # planet degree
735
- out += f'<text text-anchor="start" x="19" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;">{convert_decimal_to_degree_string(self.points_deg[i])}</text>'
736
-
737
- # zodiac
738
- out += f'<g transform="translate(60,-8)"><use transform="scale(0.3)" xlink:href="#{self.zodiac[self.points_sign[i]]["name"]}" /></g>'
739
-
740
- # planet retrograde
741
- if self.points_retrograde[i]:
742
- out += '<g transform="translate(74,-6)"><use transform="scale(.5)" xlink:href="#retrograde" /></g>'
743
-
744
- # end of line
745
- out += end_of_line
746
-
747
- li = li + offset_between_lines
748
-
749
- if self.chart_type == "Transit" or self.chart_type == "Synastry":
750
- if self.chart_type == "Transit":
751
- out += '<g transform="translate(320, -15)">'
752
- out += f'<text text-anchor="end" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 14px;">{self.t_name}:</text>'
753
- else:
754
- out += '<g transform="translate(380, -15)">'
755
- out += f'<text text-anchor="end" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 14px;">{self.language_settings["planets_and_house"]} {self.t_user.name}:</text>'
756
-
757
- out += end_of_line
758
-
759
- t_li = 10
760
- t_offset = 250
761
-
762
- for i in range(len(self.available_planets_setting)):
763
- if i == 27:
764
- t_li = 10
765
- t_offset = -120
766
-
767
- # start of line
768
- out += f'<g transform="translate({t_offset},{t_li})">'
769
-
770
- # planet text
771
- out += f'<text text-anchor="end" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;">{self.language_settings["celestial_points"][self.available_planets_setting[i]["label"]]}</text>'
772
- # planet symbol
773
- out += f'<g transform="translate(5,-8)"><use transform="scale(0.4)" xlink:href="#{self.available_planets_setting[i]["name"]}" /></g>'
774
- # planet degree
775
- out += f'<text text-anchor="start" x="19" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;">{convert_decimal_to_degree_string(self.t_points_deg[i])}</text>'
776
- # zodiac
777
- out += f'<g transform="translate(60,-8)"><use transform="scale(0.3)" xlink:href="#{self.zodiac[self.t_points_sign[i]]["name"]}" /></g>'
778
-
779
- # planet retrograde
780
- if self.t_points_retrograde[i]:
781
- out += '<g transform="translate(74,-6)"><use transform="scale(.5)" xlink:href="#retrograde" /></g>'
782
-
783
- # end of line
784
- out += end_of_line
785
-
786
- t_li = t_li + offset_between_lines
787
-
788
- if end_of_line is None:
789
- raise KerykeionException("End of line not found")
790
-
791
- out += end_of_line
792
- return out
793
-
794
- def _makeHouseGrid(self):
319
+ def _create_template_dictionary(self) -> ChartTemplateDictionary:
795
320
  """
796
- Generate SVG code for a grid of astrological houses.
321
+ Create a dictionary containing the template data for generating an astrological chart.
797
322
 
798
323
  Returns:
799
- str: The SVG code for the grid of houses.
324
+ ChartTemplateDictionary: A dictionary with template data for the chart.
800
325
  """
801
- out = '<g transform="translate(610,-20)">'
326
+ # Initialize template dictionary
327
+ template_dict: ChartTemplateDictionary = dict() # type: ignore
802
328
 
803
- li = 10
804
- for i in range(12):
805
- if i < 9:
806
- cusp = "&#160;&#160;" + str(i + 1)
807
- else:
808
- cusp = str(i + 1)
809
- out += f'<g transform="translate(0,{li})">'
810
- out += f'<text text-anchor="end" x="40" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;">{self.language_settings["cusp"]} {cusp}:</text>'
811
- out += f'<g transform="translate(40,-8)"><use transform="scale(0.3)" xlink:href="#{self.zodiac[self.houses_sign_graph[i]]["name"]}" /></g>'
812
- out += f'<text x="53" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;"> {convert_decimal_to_degree_string(self.user.houses_list[i]["position"])}</text>'
813
- out += "</g>"
814
- li = li + 14
329
+ # Set chart dimensions
330
+ template_dict["chart_height"] = self.height
331
+ template_dict["chart_width"] = self.width
815
332
 
816
- out += "</g>"
333
+ # Set chart name
334
+ template_dict["stringName"] = f"{self.user.name}:" if self.chart_type in ["Synastry", "Transit"] else f'{self.language_settings["info"]}:'
817
335
 
818
- if self.chart_type == "Synastry":
819
- out += '<!-- Synastry Houses -->'
820
- out += '<g transform="translate(850, -20)">'
821
- li = 10
822
-
823
- for i in range(12):
824
- if i < 9:
825
- cusp = "&#160;&#160;" + str(i + 1)
826
- else:
827
- cusp = str(i + 1)
828
- out += '<g transform="translate(0,' + str(li) + ')">'
829
- out += f'<text text-anchor="end" x="40" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;">{self.language_settings["cusp"]} {cusp}:</text>'
830
- out += f'<g transform="translate(40,-8)"><use transform="scale(0.3)" xlink:href="#{self.zodiac[self.t_houses_sign_graph[i]]["name"]}" /></g>'
831
- out += f'<text x="53" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;"> {convert_decimal_to_degree_string(self.t_user.houses_list[i]["position"])}</text>'
832
- out += "</g>"
833
- li = li + 14
834
- out += "</g>"
336
+ # Set viewbox based on chart type
337
+ template_dict['viewbox'] = self.chart_settings["basic_chart_viewBox"] if self.chart_type in ["Natal", "ExternalNatal"] else self.chart_settings["wide_chart_viewBox"]
835
338
 
836
- return out
339
+ # Generate rings and circles based on chart type
340
+ if self.chart_type in ["Transit", "Synastry"]:
341
+ template_dict["transitRing"] = draw_transit_ring(self.main_radius, self.chart_colors_settings["paper_1"], self.chart_colors_settings["zodiac_transit_ring_3"])
342
+ template_dict["degreeRing"] = draw_transit_ring_degree_steps(self.main_radius, self.user.seventh_house.abs_pos)
343
+ template_dict["first_circle"] = draw_first_circle(self.main_radius, self.chart_colors_settings["zodiac_transit_ring_2"], self.chart_type)
344
+ 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)
345
+ 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)
346
+ template_dict["makeAspectGrid"] = draw_aspect_transit_grid(self.language_settings["aspects"], self.aspects_list, self.planets_settings, self.aspects_settings)
837
347
 
838
- def _createTemplateDictionary(self) -> ChartTemplateDictionary:
839
- # self.chart_type = "Transit"
840
- # empty element points
841
- self.fire = 0.0
842
- self.earth = 0.0
843
- self.air = 0.0
844
- self.water = 0.0
845
-
846
- # Calculate the elements points
847
- self._calculate_elements_points_from_planets()
848
-
849
- rotate = "0"
850
-
851
- # template dictionary
852
- td: ChartTemplateDictionary = dict() # type: ignore
853
- r = 240
854
-
855
- # To increase the size of the chart, change the viewbox
856
- if self.chart_type == "Natal" or self.chart_type == "ExternalNatal":
857
- td['viewbox'] = self.chart_settings["basic_chart_viewBox"]
348
+ template_dict["makeAspects"] = self._draw_all_transit_aspects_lines(self.main_radius, self.main_radius - 160)
858
349
  else:
859
- td['viewbox'] = self.chart_settings["wide_chart_viewBox"]
350
+ template_dict["transitRing"] = ""
351
+ 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"])
352
+ 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)
353
+ 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)
354
+ 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)
355
+ template_dict["makeAspectGrid"] = draw_aspect_grid(self.chart_colors_settings['paper_0'], self.available_planets_setting, self.aspects_list)
860
356
 
861
- if self.chart_type == "ExternalNatal":
862
- self.c1 = 56
863
- self.c2 = 92
864
- self.c3 = 112
865
- else:
866
- self.c1 = 0
867
- self.c2 = 36
868
- self.c3 = 120
869
-
870
- # transit
871
- if self.chart_type == "Transit" or self.chart_type == "Synastry":
872
- td["transitRing"] = draw_transit_ring(r, self.chart_colors_settings["paper_1"], self.chart_colors_settings["zodiac_transit_ring_3"])
873
- td["degreeRing"] = draw_transit_ring_degree_steps(r, self.user.seventh_house.abs_pos)
357
+ template_dict["makeAspects"] = self._draw_all_aspects_lines(self.main_radius, self.main_radius - self.third_circle_radius)
874
358
 
875
- # circles
876
- td["first_circle"] = draw_first_circle(r, self.chart_colors_settings["zodiac_transit_ring_2"], self.chart_type)
877
- td["second_circle"] = draw_second_circle(r, self.chart_colors_settings['zodiac_transit_ring_1'], self.chart_colors_settings['paper_1'], self.chart_type)
878
- td['third_circle'] = draw_third_circle(r, self.chart_colors_settings['zodiac_transit_ring_0'], self.chart_colors_settings['paper_1'], self.chart_type)
879
-
880
- td["makeAspects"] = self._draw_all_transit_aspects_lines(r, (r - 160))
881
-
882
- td["makeAspectGrid"] = draw_aspect_transit_grid(
883
- self.language_settings["aspects"],
884
- self.aspects_list,
885
- self.planets_settings,
886
- self.aspects_settings
887
- )
888
-
889
- # Natal, External Natal
890
- else:
891
- td["transitRing"] = ""
892
- td["degreeRing"] = draw_degree_ring(r, self.c1, self.user.seventh_house.abs_pos, self.chart_colors_settings["paper_0"])
893
-
894
- td['first_circle'] = draw_first_circle(r, self.chart_colors_settings["zodiac_radix_ring_2"], self.chart_type, self.c1)
895
- td["second_circle"] = draw_second_circle(r, self.chart_colors_settings["zodiac_radix_ring_1"], self.chart_colors_settings["paper_1"], self.chart_type, self.c2)
896
- td['third_circle'] = draw_third_circle(r, self.chart_colors_settings["zodiac_radix_ring_0"], self.chart_colors_settings["paper_1"], self.chart_type, self.c3)
897
-
898
- td["makeAspects"] = self._draw_all_aspects_lines(r, (r - self.c3))
899
- td["makeAspectGrid"] = draw_aspect_grid(self.chart_colors_settings['paper_0'], self.available_planets_setting, self.aspects_list)
900
-
901
- td["chart_height"] = self.height
902
- td["chart_width"] = self.width
903
-
904
- # Chart Title
359
+ # Set chart title
905
360
  if self.chart_type == "Synastry":
906
- td["stringTitle"] = f"{self.user.name} {self.language_settings['and_word']} {self.t_user.name}"
907
-
361
+ template_dict["stringTitle"] = f"{self.user.name} {self.language_settings['and_word']} {self.t_user.name}"
908
362
  elif self.chart_type == "Transit":
909
- td["stringTitle"] = f"{self.language_settings['transits']} {self.t_user.day}/{self.t_user.month}/{self.t_user.year}"
910
-
363
+ template_dict["stringTitle"] = f"{self.language_settings['transits']} {self.t_user.day}/{self.t_user.month}/{self.t_user.year}"
911
364
  else:
912
- td["stringTitle"] = self.user.name
913
-
914
- # Chart Name
915
- if self.chart_type == "Synastry" or self.chart_type == "Transit":
916
- td["stringName"] = f"{self.user.name}:"
365
+ template_dict["stringTitle"] = self.user.name
366
+
367
+ # Set bottom left corner information
368
+ template_dict["bottomLeft0"] = f"{self.user.zodiac_type if self.user.zodiac_type == 'Tropic' else str(self.user.zodiac_type) + ' ' + str(self.user.sidereal_mode)}"
369
+ template_dict["bottomLeft1"] = f"{self.user.houses_system_name}"
370
+ if self.chart_type in ["Natal", "ExternalNatal", "Synastry"]:
371
+ template_dict["bottomLeft2"] = f'{self.language_settings.get("lunar_phase", "Lunar Phase")}: {self.language_settings.get("day", "Day")} {self.user.lunar_phase.get("moon_phase", "")}'
372
+ template_dict["bottomLeft3"] = f'{self.language_settings.get("lunar_phase", "Lunar Phase")}: {self.user.lunar_phase.moon_phase_name}'
373
+ template_dict["bottomLeft4"] = f'{self.user.perspective_type}'
917
374
  else:
918
- td["stringName"] = f'{self.language_settings["info"]}:'
375
+ template_dict["bottomLeft2"] = f'{self.language_settings.get("lunar_phase", "Lunar Phase")}: {self.language_settings.get("day", "Day")} {self.t_user.lunar_phase.get("moon_phase", "")}'
376
+ template_dict["bottomLeft3"] = f'{self.language_settings.get("lunar_phase", "Lunar Phase")}: {self.t_user.lunar_phase.moon_phase_name}'
377
+ template_dict["bottomLeft4"] = f'{self.t_user.perspective_type}'
919
378
 
920
- # Bottom Left Corner
921
- if self.chart_type == "Natal" or self.chart_type == "ExternalNatal" or self.chart_type == "Synastry":
922
- td["bottomLeft0"] = f"{self.user.zodiac_type if self.user.zodiac_type == 'Tropic' else self.user.zodiac_type + ' ' + self.user.sidereal_mode}"
923
- td["bottomLeft1"] = f"{self.user.houses_system_name}"
924
- td["bottomLeft2"] = f'{self.language_settings.get("lunar_phase", "Lunar Phase")}: {self.language_settings.get("day", "Day")} {self.user.lunar_phase.get("moon_phase", "")}'
925
- td["bottomLeft3"] = f'{self.language_settings.get("lunar_phase", "Lunar Phase")}: {self.user.lunar_phase.moon_phase_name}'
926
- td["bottomLeft4"] = f'{self.user.perspective_type}'
379
+ # Draw moon phase
380
+ template_dict['moon_phase'] = draw_moon_phase(self.user.lunar_phase["degrees_between_s_m"], self.geolat)
927
381
 
928
- else:
929
- td["bottomLeft0"] = f"{self.user.zodiac_type if self.user.zodiac_type == 'Tropic' else self.user.zodiac_type + ' ' + self.user.sidereal_mode}"
930
- td["bottomLeft1"] = f"{self.user.houses_system_name}"
931
- td["bottomLeft2"] = f'{self.language_settings.get("lunar_phase", "Lunar Phase")}: {self.language_settings.get("day", "Day")} {self.t_user.lunar_phase.get("moon_phase", "")}'
932
- td["bottomLeft3"] = f'{self.language_settings.get("lunar_phase", "Lunar Phase")}: {self.t_user.lunar_phase.moon_phase_name}'
933
- td["bottomLeft4"] = f'{self.t_user.perspective_type}'
934
-
935
- td['moon_phase'] = draw_moon_phase(
936
- self.user.lunar_phase["degrees_between_s_m"],
937
- self.geolat
938
- )
939
-
940
- # stringlocation
382
+ # Set location string
941
383
  if len(self.location) > 35:
942
- split = self.location.split(",")
943
- if len(split) > 1:
944
- td["stringLocation"] = split[0] + ", " + split[-1]
945
- if len(td["stringLocation"]) > 35:
946
- td["stringLocation"] = td["stringLocation"][:35] + "..."
384
+ split_location = self.location.split(",")
385
+ if len(split_location) > 1:
386
+ template_dict["stringLocation"] = split_location[0] + ", " + split_location[-1]
387
+ if len(template_dict["stringLocation"]) > 35:
388
+ template_dict["stringLocation"] = template_dict["stringLocation"][:35] + "..."
947
389
  else:
948
- td["stringLocation"] = self.location[:35] + "..."
390
+ template_dict["stringLocation"] = self.location[:35] + "..."
949
391
  else:
950
- td["stringLocation"] = self.location
392
+ template_dict["stringLocation"] = self.location
951
393
 
394
+ # Set additional information for Synastry chart type
952
395
  if self.chart_type == "Synastry":
953
- td["stringLat"] = f"{self.t_user.name}: "
954
- td["stringLon"] = self.t_user.city
955
- td["stringPosition"] = f"{self.t_user.year}-{self.t_user.month}-{self.t_user.day} {self.t_user.hour:02d}:{self.t_user.minute:02d}"
956
-
396
+ template_dict["stringLat"] = f"{self.t_user.name}: "
397
+ template_dict["stringLon"] = self.t_user.city
398
+ template_dict["stringPosition"] = f"{self.t_user.year}-{self.t_user.month}-{self.t_user.day} {self.t_user.hour:02d}:{self.t_user.minute:02d}"
957
399
  else:
958
- latitude_string = convert_latitude_coordinate_to_string(
959
- self.geolat,
960
- self.language_settings['north'],
961
- self.language_settings['south']
962
- )
963
- longitude_string = convert_longitude_coordinate_to_string(
964
- self.geolon,
965
- self.language_settings['east'],
966
- self.language_settings['west']
967
- )
968
-
969
- td["stringLat"] = f"{self.language_settings['latitude']}: {latitude_string}"
970
- td["stringLon"] = f"{self.language_settings['longitude']}: {longitude_string}"
971
- td["stringPosition"] = f"{self.language_settings['type']}: {self.chart_type}"
972
-
973
- # paper_color_X
974
- td["paper_color_0"] = self.chart_colors_settings["paper_0"]
975
- td["paper_color_1"] = self.chart_colors_settings["paper_1"]
976
-
977
- # planets_color_X
978
- for i in range(len(self.planets_settings)):
979
- planet_id = self.planets_settings[i]["id"]
980
- td[f"planets_color_{planet_id}"] = self.planets_settings[i]["color"]
981
-
982
- # zodiac_color_X
400
+ latitude_string = convert_latitude_coordinate_to_string(self.geolat, self.language_settings['north'], self.language_settings['south'])
401
+ longitude_string = convert_longitude_coordinate_to_string(self.geolon, self.language_settings['east'], self.language_settings['west'])
402
+ template_dict["stringLat"] = f"{self.language_settings['latitude']}: {latitude_string}"
403
+ template_dict["stringLon"] = f"{self.language_settings['longitude']}: {longitude_string}"
404
+ template_dict["stringPosition"] = f"{self.language_settings['type']}: {self.chart_type}"
405
+
406
+ # Set paper colors
407
+ template_dict["paper_color_0"] = self.chart_colors_settings["paper_0"]
408
+ template_dict["paper_color_1"] = self.chart_colors_settings["paper_1"]
409
+
410
+ # Set planet colors
411
+ for planet in self.planets_settings:
412
+ planet_id = planet["id"]
413
+ template_dict[f"planets_color_{planet_id}"] = planet["color"]
414
+
415
+ # Set zodiac colors
983
416
  for i in range(12):
984
- td[f"zodiac_color_{i}"] = self.chart_colors_settings[f"zodiac_icon_{i}"]
417
+ template_dict[f"zodiac_color_{i}"] = self.chart_colors_settings[f"zodiac_icon_{i}"]
985
418
 
986
- # orb_color_X
987
- for i in range(len(self.aspects_settings)):
988
- td[f"orb_color_{self.aspects_settings[i]['degree']}"] = self.aspects_settings[i]['color']
419
+ # Set orb colors
420
+ for aspect in self.aspects_settings:
421
+ template_dict[f"orb_color_{aspect['degree']}"] = aspect['color']
989
422
 
990
- # config
991
- td["cfgRotate"] = rotate
423
+ # Drawing functions
424
+ template_dict["makeZodiac"] = self._draw_zodiac_circle_slices(self.main_radius)
992
425
 
993
- # ---
994
- # Drawing Functions
995
- #---
426
+ # Draw houses grid and cusps
427
+ if self.chart_type in ["Transit", "Synastry"]:
428
+ template_dict["makeHousesGrid"] = draw_house_grid(
429
+ main_subject_houses_list=self.user.houses_list,
430
+ secondary_subject_houses_list=self.t_user.houses_list,
431
+ chart_type=self.chart_type,
432
+ text_color=self.chart_colors_settings["paper_0"],
433
+ house_cusp_generale_name_label=self.language_settings["cusp"]
434
+ )
996
435
 
997
- td["makeZodiac"] = self._draw_zodiac_circle_slices(r)
998
- td["makeHousesGrid"] = self._makeHouseGrid()
999
-
1000
- # Houses Cusps and Number
1001
- if self.chart_type == "Transit" or self.chart_type == "Synastry":
1002
- td["makeHouses"] = draw_houses_cusps_and_text_number(
1003
- r=r,
436
+ template_dict["makeHouses"] = draw_houses_cusps_and_text_number(
437
+ r=self.main_radius,
1004
438
  first_subject_houses_list_ut=self.user.houses_degree_ut,
1005
439
  standard_house_cusp_color=self.chart_colors_settings["houses_radix_line"],
1006
440
  first_house_color=self.planets_settings[12]["color"],
1007
441
  tenth_house_color=self.planets_settings[13]["color"],
1008
442
  seventh_house_color=self.planets_settings[14]["color"],
1009
443
  fourth_house_color=self.planets_settings[15]["color"],
1010
- c1=self.c1,
1011
- c3=self.c3,
444
+ c1=self.first_circle_radius,
445
+ c3=self.third_circle_radius,
1012
446
  chart_type=self.chart_type,
1013
447
  second_subject_houses_list_ut=self.t_user.houses_degree_ut,
1014
448
  transit_house_cusp_color=self.chart_colors_settings["houses_transit_line"],
1015
449
  )
450
+
1016
451
  else:
1017
- td["makeHouses"] = draw_houses_cusps_and_text_number(
1018
- r=r,
452
+ template_dict["makeHousesGrid"] = draw_house_grid(
453
+ main_subject_houses_list=self.user.houses_list,
454
+ chart_type=self.chart_type,
455
+ text_color=self.chart_colors_settings["paper_0"],
456
+ house_cusp_generale_name_label=self.language_settings["cusp"]
457
+ )
458
+
459
+ template_dict["makeHouses"] = draw_houses_cusps_and_text_number(
460
+ r=self.main_radius,
1019
461
  first_subject_houses_list_ut=self.user.houses_degree_ut,
1020
462
  standard_house_cusp_color=self.chart_colors_settings["houses_radix_line"],
1021
463
  first_house_color=self.planets_settings[12]["color"],
1022
464
  tenth_house_color=self.planets_settings[13]["color"],
1023
465
  seventh_house_color=self.planets_settings[14]["color"],
1024
466
  fourth_house_color=self.planets_settings[15]["color"],
1025
- c1=self.c1,
1026
- c3=self.c3,
467
+ c1=self.first_circle_radius,
468
+ c3=self.third_circle_radius,
469
+ chart_type=self.chart_type,
470
+ )
471
+
472
+ # Draw planets
473
+ if self.chart_type in ["Transit", "Synastry"]:
474
+ template_dict["makePlanets"] = draw_planets(
475
+ available_kerykeion_celestial_points=self.available_kerykeion_celestial_points,
476
+ available_planets_setting=self.available_planets_setting,
477
+ second_subject_available_kerykeion_celestial_points=self.t_available_kerykeion_celestial_points,
478
+ radius=self.main_radius,
479
+ main_subject_first_house_degree_ut=self.user.houses_degree_ut[0],
480
+ main_subject_seventh_house_degree_ut=self.user.houses_degree_ut[6],
481
+ chart_type=self.chart_type,
482
+ third_circle_radius=self.third_circle_radius,
483
+ )
484
+ else:
485
+ template_dict["makePlanets"] = draw_planets(
486
+ available_planets_setting=self.available_planets_setting,
1027
487
  chart_type=self.chart_type,
488
+ radius=self.main_radius,
489
+ available_kerykeion_celestial_points=self.available_kerykeion_celestial_points,
490
+ third_circle_radius=self.third_circle_radius,
491
+ main_subject_first_house_degree_ut=self.user.houses_degree_ut[0],
492
+ main_subject_seventh_house_degree_ut=self.user.houses_degree_ut[6],
1028
493
  )
1029
494
 
1030
- td["makePlanets"] = self._make_planets(r)
1031
- td["elements_percentages"] = draw_elements_percentages(
495
+ # Draw elements percentages
496
+ template_dict["elements_percentages"] = draw_elements_percentages(
1032
497
  self.language_settings['fire'],
1033
498
  self.fire,
1034
499
  self.language_settings['earth'],
@@ -1039,29 +504,56 @@ class KerykeionChartSVG:
1039
504
  self.water,
1040
505
  )
1041
506
 
1042
- td["makePlanetGrid"] = self._makePlanetGrid()
507
+ # Draw planet grid
508
+ if self.chart_type in ["Transit", "Synastry"]:
509
+ if self.chart_type == "Transit":
510
+ second_subject_table_name = self.language_settings["transit_name"]
511
+ else:
512
+ second_subject_table_name = self.t_user.name
513
+ template_dict["makePlanetGrid"] = draw_planet_grid(
514
+ planets_and_houses_grid_title=self.language_settings["planets_and_house"],
515
+ subject_name=self.user.name,
516
+ available_kerykeion_celestial_points=self.available_kerykeion_celestial_points,
517
+ chart_type=self.chart_type,
518
+ text_color=self.chart_colors_settings["paper_0"],
519
+ celestial_point_language=self.language_settings["celestial_points"],
520
+ second_subject_name=second_subject_table_name,
521
+ second_subject_available_kerykeion_celestial_points=self.t_available_kerykeion_celestial_points,
522
+ )
523
+ else:
524
+ template_dict["makePlanetGrid"] = draw_planet_grid(
525
+ planets_and_houses_grid_title=self.language_settings["planets_and_house"],
526
+ subject_name=self.user.name,
527
+ available_kerykeion_celestial_points=self.available_kerykeion_celestial_points,
528
+ chart_type=self.chart_type,
529
+ text_color=self.chart_colors_settings["paper_0"],
530
+ celestial_point_language=self.language_settings["celestial_points"],
531
+ )
1043
532
 
1044
- # Date time String
533
+ # Set date time string
1045
534
  dt = datetime.fromisoformat(self.user.iso_formatted_local_datetime)
1046
535
  custom_format = dt.strftime('%Y-%-m-%-d %H:%M [%z]') # Note the use of '-' to remove leading zeros
1047
536
  custom_format = custom_format[:-3] + ':' + custom_format[-3:]
1048
- td["stringDateTime"] = f"{custom_format}"
537
+ template_dict["stringDateTime"] = f"{custom_format}"
1049
538
 
1050
- return td
539
+ return template_dict
1051
540
 
1052
541
  def makeTemplate(self, minify: bool = False) -> str:
1053
542
  """Creates the template for the SVG file"""
1054
- td = self._createTemplateDictionary()
543
+ td = self._create_template_dictionary()
1055
544
 
545
+ DATA_DIR = Path(__file__).parent
546
+ xml_svg = DATA_DIR / "templates/chart.xml"
547
+
1056
548
  # read template
1057
- with open(self.xml_svg, "r", encoding="utf-8", errors="ignore") as f:
549
+ with open(xml_svg, "r", encoding="utf-8", errors="ignore") as f:
1058
550
  template = Template(f.read()).substitute(td)
1059
551
 
1060
552
  # return filename
1061
553
 
1062
554
  logging.debug(f"Template dictionary keys: {td.keys()}")
1063
555
 
1064
- self._createTemplateDictionary()
556
+ self._create_template_dictionary()
1065
557
 
1066
558
  if minify:
1067
559
  template = scourString(template).replace('"', "'").replace("\n", "").replace("\t","").replace(" ", "").replace(" ", "")
@@ -1155,3 +647,5 @@ if __name__ == "__main__":
1155
647
  topocentric_subject = AstrologicalSubject("John Lennon - Topocentric", 1940, 10, 9, 18, 30, "Liverpool", "GB", perspective_type="Topocentric")
1156
648
  topocentric_chart = KerykeionChartSVG(topocentric_subject)
1157
649
  topocentric_chart.makeSVG()
650
+
651
+