kerykeion.charts.charts_utils
1import math 2import datetime 3from kerykeion.kr_types import KerykeionException, ChartType 4from typing import Union 5 6 7def decHourJoin(inH: int, inM: int, inS: int) -> float: 8 """Join hour, minutes, seconds, timezone integer to hour float. 9 10 Args: 11 - inH (int): hour 12 - inM (int): minutes 13 - inS (int): seconds 14 Returns: 15 float: hour in float format 16 """ 17 18 dh = float(inH) 19 dm = float(inM) / 60 20 ds = float(inS) / 3600 21 output = dh + dm + ds 22 return output 23 24 25def degreeDiff(a: Union[int, float], b: Union[int, float]) -> float: 26 """Calculate the difference between two degrees. 27 28 Args: 29 - a (int | float): first degree 30 - b (int | float): second degree 31 32 Returns: 33 float: difference between a and b 34 """ 35 36 out = float() 37 if a > b: 38 out = a - b 39 if a < b: 40 out = b - a 41 if out > 180.0: 42 out = 360.0 - out 43 return out 44 45 46def offsetToTz(datetime_offset: Union[datetime.timedelta, None]) -> float: 47 """Convert datetime offset to float in hours. 48 49 Args: 50 - datetime_offset (datetime.timedelta): datetime offset 51 52 Returns: 53 - float: offset in hours 54 """ 55 56 if datetime_offset is None: 57 raise KerykeionException("datetime_offset is None") 58 59 # days to hours 60 dh = float(datetime_offset.days * 24) 61 # seconds to hours 62 sh = float(datetime_offset.seconds / 3600.0) 63 # total hours 64 output = dh + sh 65 return output 66 67 68def sliceToX(slice: Union[int, float], radius: Union[int, float], offset: Union[int, float]) -> float: 69 """Calculates the x-coordinate of a point on a circle based on the slice, radius, and offset. 70 71 Args: 72 - slice (int | float): Represents the 73 slice of the circle to calculate the x-coordinate for. 74 It must be between 0 and 11 (inclusive). 75 - radius (int | float): Represents the radius of the circle. 76 - offset (int | float): Represents the offset in degrees. 77 It must be between 0 and 360 (inclusive). 78 79 Returns: 80 float: The x-coordinate of the point on the circle. 81 82 Example: 83 >>> import math 84 >>> sliceToX(3, 5, 45) 85 2.5000000000000018 86 """ 87 88 plus = (math.pi * offset) / 180 89 radial = ((math.pi / 6) * slice) + plus 90 return radius * (math.cos(radial) + 1) 91 92 93def sliceToY(slice: Union[int, float], r: Union[int, float], offset: Union[int, float]) -> float: 94 """Calculates the y-coordinate of a point on a circle based on the slice, radius, and offset. 95 96 Args: 97 - slice (int | float): Represents the slice of the circle to calculate 98 the y-coordinate for. It must be between 0 and 11 (inclusive). 99 - r (int | float): Represents the radius of the circle. 100 - offset (int | float): Represents the offset in degrees. 101 It must be between 0 and 360 (inclusive). 102 103 Returns: 104 float: The y-coordinate of the point on the circle. 105 106 Example: 107 >>> import math 108 >>> __sliceToY(3, 5, 45) 109 -4.330127018922194 110 """ 111 plus = (math.pi * offset) / 180 112 radial = ((math.pi / 6) * slice) + plus 113 return r * ((math.sin(radial) / -1) + 1) 114 115 116def draw_zodiac_slice( 117 c1: Union[int, float], 118 chart_type: ChartType, 119 seventh_house_degree_ut: Union[int, float], 120 num: int, 121 r: Union[int, float], 122 style: str, 123 type: str, 124) -> str: 125 """Draws a zodiac slice based on the given parameters. 126 127 Args: 128 - c1 (Union[int, float]): The value of c1. 129 - chart_type (ChartType): The type of chart. 130 - seventh_house_degree_ut (Union[int, float]): The degree of the seventh house. 131 - num (int): The number of the sign. Note: In OpenAstro it did refer to self.zodiac, 132 which is a list of the signs in order, starting with Aries. Eg: 133 {"name": "aries", "element": "fire"} 134 - r (Union[int, float]): The value of r. 135 - style (str): The CSS inline style. 136 - type (str): The type ?. In OpenAstro, it was the symbol of the sign. Eg: "aries". 137 self.zodiac[i]["name"] 138 139 Returns: 140 - str: The zodiac slice and symbol as an SVG path. 141 """ 142 143 # pie slices 144 offset = 360 - seventh_house_degree_ut 145 # check transit 146 if chart_type == "Transit" or chart_type == "Synastry": 147 dropin = 0 148 else: 149 dropin = c1 150 slice = f'<path d="M{str(r)},{str(r)} L{str(dropin + sliceToX(num, r - dropin, offset))},{str(dropin + sliceToY(num, r - dropin, offset))} A{str(r - dropin)},{str(r - dropin)} 0 0,0 {str(dropin + sliceToX(num + 1, r - dropin, offset))},{str(dropin + sliceToY(num + 1, r - dropin, offset))} z" style="{style}"/>' 151 152 # symbols 153 offset = offset + 15 154 # check transit 155 if chart_type == "Transit" or chart_type == "Synastry": 156 dropin = 54 157 else: 158 dropin = 18 + c1 159 sign = f'<g transform="translate(-16,-16)"><use x="{str(dropin + sliceToX(num, r - dropin, offset))}" y="{str(dropin + sliceToY(num, r - dropin, offset))}" xlink:href="#{type}" /></g>' 160 161 return slice + "" + sign 162 163 164def convert_latitude_coordinate_to_string(coord: Union[int, float], north_label: str, south_label: str) -> str: 165 """Converts a floating point latitude to string with 166 degree, minutes and seconds and the appropriate sign 167 (north or south). Eg. 52.1234567 -> 52°7'25" N 168 169 Args: 170 - coord (float | int): latitude in floating or integer format 171 - north_label (str): String label for north 172 - south_label (str): String label for south 173 Returns: 174 - str: latitude in string format with degree, minutes, 175 seconds and sign (N/S) 176 """ 177 178 sign = north_label 179 if coord < 0.0: 180 sign = south_label 181 coord = abs(coord) 182 deg = int(coord) 183 min = int((float(coord) - deg) * 60) 184 sec = int(round(float(((float(coord) - deg) * 60) - min) * 60.0)) 185 return f"{deg}°{min}'{sec}\" {sign}" 186 187 188def convert_longitude_coordinate_to_string(coord: Union[int, float], east_label: str, west_label: str) -> str: 189 """Converts a floating point longitude to string with 190 degree, minutes and seconds and the appropriate sign 191 (east or west). Eg. 52.1234567 -> 52°7'25" E 192 193 Args: 194 - coord (float|int): longitude in floating point format 195 - east_label (str): String label for east 196 - west_label (str): String label for west 197 Returns: 198 str: longitude in string format with degree, minutes, 199 seconds and sign (E/W) 200 """ 201 202 sign = east_label 203 if coord < 0.0: 204 sign = west_label 205 coord = abs(coord) 206 deg = int(coord) 207 min = int((float(coord) - deg) * 60) 208 sec = int(round(float(((float(coord) - deg) * 60) - min) * 60.0)) 209 return f"{deg}°{min}'{sec}\" {sign}" 210 211 212def draw_aspect_line( 213 r: Union[int, float], 214 ar: Union[int, float], 215 degA: Union[int, float], 216 degB: Union[int, float], 217 color: str, 218 seventh_house_degree_ut: Union[int, float], 219) -> str: 220 """Draws svg aspects: ring, aspect ring, degreeA degreeB 221 222 Args: 223 - r (Union[int, float]): The value of r. 224 - ar (Union[int, float]): The value of ar. 225 - degA (Union[int, float]): The degree of A. 226 - degB (Union[int, float]): The degree of B. 227 - color (str): The color of the aspect. 228 - seventh_house_degree_ut (Union[int, float]): The degree of the seventh house. 229 230 Returns: 231 str: The SVG line element as a string. 232 """ 233 234 first_offset = (int(seventh_house_degree_ut) / -1) + int(degA) 235 x1 = sliceToX(0, ar, first_offset) + (r - ar) 236 y1 = sliceToY(0, ar, first_offset) + (r - ar) 237 238 second_offset = (int(seventh_house_degree_ut) / -1) + int(degB) 239 x2 = sliceToX(0, ar, second_offset) + (r - ar) 240 y2 = sliceToY(0, ar, second_offset) + (r - ar) 241 242 out = f'<line class="aspect" x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}" style="stroke: {color}; stroke-width: 1; stroke-opacity: .9;"/>' 243 244 return out 245 246 247def draw_elements_percentages( 248 fire_label: str, 249 fire_points: float, 250 earth_label: str, 251 earth_points: float, 252 air_label: str, 253 air_points: float, 254 water_label: str, 255 water_points: float, 256) -> str: 257 """Draw the elements grid. 258 259 Args: 260 - fire_label (str): Label for fire 261 - fire_points (float): Points for fire 262 - earth_label (str): Label for earth 263 - earth_points (float): Points for earth 264 - air_label (str): Label for air 265 - air_points (float): Points for air 266 - water_label (str): Label for water 267 - water_points (float): Points for water 268 269 Returns: 270 str: The SVG elements grid as a string. 271 """ 272 total = fire_points + earth_points + air_points + water_points 273 274 fire_percentage = int(round(100 * fire_points / total)) 275 earth_percentage = int(round(100 * earth_points / total)) 276 air_percentage = int(round(100 * air_points / total)) 277 water_percentage = int(round(100 * water_points / total)) 278 279 out = '<g transform="translate(-30,79)">' 280 out += f'<text y="0" style="fill:#ff6600; font-size: 10px;">{fire_label} {str(fire_percentage)}%</text>' 281 out += f'<text y="12" style="fill:#6a2d04; font-size: 10px;">{earth_label} {str(earth_percentage)}%</text>' 282 out += f'<text y="24" style="fill:#6f76d1; font-size: 10px;">{air_label} {str(air_percentage)}%</text>' 283 out += f'<text y="36" style="fill:#630e73; font-size: 10px;">{water_label} {str(water_percentage)}%</text>' 284 out += "</g>" 285 286 return out 287 288 289def convert_decimal_to_degree_string(dec: float, type="3") -> str: 290 """ 291 Coverts decimal float to degrees in format a°b'c". 292 293 Args: 294 - dec (float): decimal float 295 - type (str): type of format: 296 - 1: a° 297 - 2: a°b' 298 - 3: a°b'c" 299 300 Returns: 301 str: degrees in format a°b'c" 302 """ 303 304 dec = float(dec) 305 a = int(dec) 306 a_new = (dec - float(a)) * 60.0 307 b_rounded = int(round(a_new)) 308 b = int(a_new) 309 c = int(round((a_new - float(b)) * 60.0)) 310 311 if type == "3": 312 out = f"{a:02d}°{b:02d}'{c:02d}"" 313 elif type == "2": 314 out = f"{a:02d}°{b_rounded:02d}'" 315 elif type == "1": 316 out = f"{a:02d}°" 317 else: 318 raise KerykeionException(f"Wrong type: {type}, it must be 1, 2 or 3.") 319 320 return str(out) 321 322 323def draw_transit_ring_degree_steps(r: Union[int, float], seventh_house_degree_ut: Union[int, float]) -> str: 324 """Draws the transit ring degree steps. 325 326 Args: 327 - r (Union[int, float]): The value of r. 328 - seventh_house_degree_ut (Union[int, float]): The degree of the seventh house. 329 330 Returns: 331 str: The SVG path of the transit ring degree steps. 332 """ 333 334 out = '<g id="transitRingDegreeSteps">' 335 for i in range(72): 336 offset = float(i * 5) - seventh_house_degree_ut 337 if offset < 0: 338 offset = offset + 360.0 339 elif offset > 360: 340 offset = offset - 360.0 341 x1 = sliceToX(0, r, offset) 342 y1 = sliceToY(0, r, offset) 343 x2 = sliceToX(0, r + 2, offset) - 2 344 y2 = sliceToY(0, r + 2, offset) - 2 345 out += f'<line x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}" style="stroke: #F00; stroke-width: 1px; stroke-opacity:.9;"/>' 346 out += "</g>" 347 348 return out 349 350 351def draw_degree_ring(r: Union[int, float], c1: Union[int, float], seventh_house_degree_ut: Union[int, float], stroke_color: str) -> str: 352 """Draws the degree ring. 353 354 Args: 355 - r (Union[int, float]): The value of r. 356 - c1 (Union[int, float]): The value of c1. 357 - seventh_house_degree_ut (Union[int, float]): The degree of the seventh house. 358 - stroke_color (str): The color of the stroke. 359 360 Returns: 361 str: The SVG path of the degree ring. 362 """ 363 out = '<g id="degreeRing">' 364 for i in range(72): 365 offset = float(i * 5) - seventh_house_degree_ut 366 if offset < 0: 367 offset = offset + 360.0 368 elif offset > 360: 369 offset = offset - 360.0 370 x1 = sliceToX(0, r - c1, offset) + c1 371 y1 = sliceToY(0, r - c1, offset) + c1 372 x2 = sliceToX(0, r + 2 - c1, offset) - 2 + c1 373 y2 = sliceToY(0, r + 2 - c1, offset) - 2 + c1 374 375 out += f'<line x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}" style="stroke: {stroke_color}; stroke-width: 1px; stroke-opacity:.9;"/>' 376 out += "</g>" 377 378 return out 379 380def draw_transit_ring(r: Union[int, float], paper_1_color: str, zodiac_transit_ring_3_color: str) -> str: 381 """ 382 Draws the transit ring. 383 384 Args: 385 - r (Union[int, float]): The value of r. 386 - paper_1_color (str): The color of paper 1. 387 - zodiac_transit_ring_3_color (str): The color of the zodiac transit ring 388 389 Returns: 390 str: The SVG path of the transit ring. 391 """ 392 radius_offset = 18 393 394 out = f'<circle cx="{r}" cy="{r}" r="{r - radius_offset}" style="fill: none; stroke: {paper_1_color}; stroke-width: 36px; stroke-opacity: .4;"/>' 395 out += f'<circle cx="{r}" cy="{r}" r="{r}" style="fill: none; stroke: {zodiac_transit_ring_3_color}; stroke-width: 1px; stroke-opacity: .6;"/>' 396 397 return out 398 399 400def draw_first_circle(r: Union[int, float], stroke_color: str, chart_type: ChartType, c1: Union[int, float, None] = None) -> str: 401 """ 402 Draws the first circle. 403 404 Args: 405 - r (Union[int, float]): The value of r. 406 - color (str): The color of the circle. 407 - chart_type (ChartType): The type of chart. 408 - c1 (Union[int, float]): The value of c1. 409 410 Returns: 411 str: The SVG path of the first circle. 412 """ 413 if chart_type == "Synastry" or chart_type == "Transit": 414 return f'<circle cx="{r}" cy="{r}" r="{r - 36}" style="fill: none; stroke: {stroke_color}; stroke-width: 1px; stroke-opacity:.4;" />' 415 else: 416 if c1 is None: 417 raise KerykeionException("c1 is None") 418 419 return f'<circle cx="{r}" cy="{r}" r="{r - c1}" style="fill: none; stroke: {stroke_color}; stroke-width: 1px; " />' 420 421 422def draw_second_circle(r: Union[int, float], stroke_color: str, fill_color: str, chart_type: ChartType, c2: Union[int, float, None] = None) -> str: 423 """ 424 Draws the second circle. 425 426 Args: 427 - r (Union[int, float]): The value of r. 428 - stroke_color (str): The color of the stroke. 429 - fill_color (str): The color of the fill. 430 - chart_type (ChartType): The type of chart. 431 - c2 (Union[int, float]): The value of c2. 432 433 Returns: 434 str: The SVG path of the second circle. 435 """ 436 437 if chart_type == "Synastry" or chart_type == "Transit": 438 return f'<circle cx="{r}" cy="{r}" r="{r - 72}" style="fill: {fill_color}; fill-opacity:.4; stroke: {stroke_color}; stroke-opacity:.4; stroke-width: 1px" />' 439 440 else: 441 if c2 is None: 442 raise KerykeionException("c2 is None") 443 444 return f'<circle cx="{r}" cy="{r}" r="{r - c2}" style="fill: {fill_color}; fill-opacity:.2; stroke: {stroke_color}; stroke-opacity:.4; stroke-width: 1px" />'
8def decHourJoin(inH: int, inM: int, inS: int) -> float: 9 """Join hour, minutes, seconds, timezone integer to hour float. 10 11 Args: 12 - inH (int): hour 13 - inM (int): minutes 14 - inS (int): seconds 15 Returns: 16 float: hour in float format 17 """ 18 19 dh = float(inH) 20 dm = float(inM) / 60 21 ds = float(inS) / 3600 22 output = dh + dm + ds 23 return output
Join hour, minutes, seconds, timezone integer to hour float.
Args: - inH (int): hour - inM (int): minutes - inS (int): seconds Returns: float: hour in float format
26def degreeDiff(a: Union[int, float], b: Union[int, float]) -> float: 27 """Calculate the difference between two degrees. 28 29 Args: 30 - a (int | float): first degree 31 - b (int | float): second degree 32 33 Returns: 34 float: difference between a and b 35 """ 36 37 out = float() 38 if a > b: 39 out = a - b 40 if a < b: 41 out = b - a 42 if out > 180.0: 43 out = 360.0 - out 44 return out
Calculate the difference between two degrees.
Args: - a (int | float): first degree - b (int | float): second degree
Returns: float: difference between a and b
47def offsetToTz(datetime_offset: Union[datetime.timedelta, None]) -> float: 48 """Convert datetime offset to float in hours. 49 50 Args: 51 - datetime_offset (datetime.timedelta): datetime offset 52 53 Returns: 54 - float: offset in hours 55 """ 56 57 if datetime_offset is None: 58 raise KerykeionException("datetime_offset is None") 59 60 # days to hours 61 dh = float(datetime_offset.days * 24) 62 # seconds to hours 63 sh = float(datetime_offset.seconds / 3600.0) 64 # total hours 65 output = dh + sh 66 return output
Convert datetime offset to float in hours.
Args: - datetime_offset (datetime.timedelta): datetime offset
Returns: - float: offset in hours
69def sliceToX(slice: Union[int, float], radius: Union[int, float], offset: Union[int, float]) -> float: 70 """Calculates the x-coordinate of a point on a circle based on the slice, radius, and offset. 71 72 Args: 73 - slice (int | float): Represents the 74 slice of the circle to calculate the x-coordinate for. 75 It must be between 0 and 11 (inclusive). 76 - radius (int | float): Represents the radius of the circle. 77 - offset (int | float): Represents the offset in degrees. 78 It must be between 0 and 360 (inclusive). 79 80 Returns: 81 float: The x-coordinate of the point on the circle. 82 83 Example: 84 >>> import math 85 >>> sliceToX(3, 5, 45) 86 2.5000000000000018 87 """ 88 89 plus = (math.pi * offset) / 180 90 radial = ((math.pi / 6) * slice) + plus 91 return radius * (math.cos(radial) + 1)
Calculates the x-coordinate of a point on a circle based on the slice, radius, and offset.
Args: - slice (int | float): Represents the slice of the circle to calculate the x-coordinate for. It must be between 0 and 11 (inclusive). - radius (int | float): Represents the radius of the circle. - offset (int | float): Represents the offset in degrees. It must be between 0 and 360 (inclusive).
Returns: float: The x-coordinate of the point on the circle.
Example:
import math sliceToX(3, 5, 45) 2.5000000000000018
94def sliceToY(slice: Union[int, float], r: Union[int, float], offset: Union[int, float]) -> float: 95 """Calculates the y-coordinate of a point on a circle based on the slice, radius, and offset. 96 97 Args: 98 - slice (int | float): Represents the slice of the circle to calculate 99 the y-coordinate for. It must be between 0 and 11 (inclusive). 100 - r (int | float): Represents the radius of the circle. 101 - offset (int | float): Represents the offset in degrees. 102 It must be between 0 and 360 (inclusive). 103 104 Returns: 105 float: The y-coordinate of the point on the circle. 106 107 Example: 108 >>> import math 109 >>> __sliceToY(3, 5, 45) 110 -4.330127018922194 111 """ 112 plus = (math.pi * offset) / 180 113 radial = ((math.pi / 6) * slice) + plus 114 return r * ((math.sin(radial) / -1) + 1)
Calculates the y-coordinate of a point on a circle based on the slice, radius, and offset.
Args: - slice (int | float): Represents the slice of the circle to calculate the y-coordinate for. It must be between 0 and 11 (inclusive). - r (int | float): Represents the radius of the circle. - offset (int | float): Represents the offset in degrees. It must be between 0 and 360 (inclusive).
Returns: float: The y-coordinate of the point on the circle.
Example:
import math __sliceToY(3, 5, 45) -4.330127018922194
117def draw_zodiac_slice( 118 c1: Union[int, float], 119 chart_type: ChartType, 120 seventh_house_degree_ut: Union[int, float], 121 num: int, 122 r: Union[int, float], 123 style: str, 124 type: str, 125) -> str: 126 """Draws a zodiac slice based on the given parameters. 127 128 Args: 129 - c1 (Union[int, float]): The value of c1. 130 - chart_type (ChartType): The type of chart. 131 - seventh_house_degree_ut (Union[int, float]): The degree of the seventh house. 132 - num (int): The number of the sign. Note: In OpenAstro it did refer to self.zodiac, 133 which is a list of the signs in order, starting with Aries. Eg: 134 {"name": "aries", "element": "fire"} 135 - r (Union[int, float]): The value of r. 136 - style (str): The CSS inline style. 137 - type (str): The type ?. In OpenAstro, it was the symbol of the sign. Eg: "aries". 138 self.zodiac[i]["name"] 139 140 Returns: 141 - str: The zodiac slice and symbol as an SVG path. 142 """ 143 144 # pie slices 145 offset = 360 - seventh_house_degree_ut 146 # check transit 147 if chart_type == "Transit" or chart_type == "Synastry": 148 dropin = 0 149 else: 150 dropin = c1 151 slice = f'<path d="M{str(r)},{str(r)} L{str(dropin + sliceToX(num, r - dropin, offset))},{str(dropin + sliceToY(num, r - dropin, offset))} A{str(r - dropin)},{str(r - dropin)} 0 0,0 {str(dropin + sliceToX(num + 1, r - dropin, offset))},{str(dropin + sliceToY(num + 1, r - dropin, offset))} z" style="{style}"/>' 152 153 # symbols 154 offset = offset + 15 155 # check transit 156 if chart_type == "Transit" or chart_type == "Synastry": 157 dropin = 54 158 else: 159 dropin = 18 + c1 160 sign = f'<g transform="translate(-16,-16)"><use x="{str(dropin + sliceToX(num, r - dropin, offset))}" y="{str(dropin + sliceToY(num, r - dropin, offset))}" xlink:href="#{type}" /></g>' 161 162 return slice + "" + sign
Draws a zodiac slice based on the given parameters.
Args: - c1 (Union[int, float]): The value of c1. - chart_type (ChartType): The type of chart. - seventh_house_degree_ut (Union[int, float]): The degree of the seventh house. - num (int): The number of the sign. Note: In OpenAstro it did refer to self.zodiac, which is a list of the signs in order, starting with Aries. Eg: {"name": "aries", "element": "fire"} - r (Union[int, float]): The value of r. - style (str): The CSS inline style. - type (str): The type ?. In OpenAstro, it was the symbol of the sign. Eg: "aries". self.zodiac[i]["name"]
Returns: - str: The zodiac slice and symbol as an SVG path.
165def convert_latitude_coordinate_to_string(coord: Union[int, float], north_label: str, south_label: str) -> str: 166 """Converts a floating point latitude to string with 167 degree, minutes and seconds and the appropriate sign 168 (north or south). Eg. 52.1234567 -> 52°7'25" N 169 170 Args: 171 - coord (float | int): latitude in floating or integer format 172 - north_label (str): String label for north 173 - south_label (str): String label for south 174 Returns: 175 - str: latitude in string format with degree, minutes, 176 seconds and sign (N/S) 177 """ 178 179 sign = north_label 180 if coord < 0.0: 181 sign = south_label 182 coord = abs(coord) 183 deg = int(coord) 184 min = int((float(coord) - deg) * 60) 185 sec = int(round(float(((float(coord) - deg) * 60) - min) * 60.0)) 186 return f"{deg}°{min}'{sec}\" {sign}"
Converts a floating point latitude to string with degree, minutes and seconds and the appropriate sign (north or south). Eg. 52.1234567 -> 52°7'25" N
Args: - coord (float | int): latitude in floating or integer format - north_label (str): String label for north - south_label (str): String label for south Returns: - str: latitude in string format with degree, minutes, seconds and sign (N/S)
189def convert_longitude_coordinate_to_string(coord: Union[int, float], east_label: str, west_label: str) -> str: 190 """Converts a floating point longitude to string with 191 degree, minutes and seconds and the appropriate sign 192 (east or west). Eg. 52.1234567 -> 52°7'25" E 193 194 Args: 195 - coord (float|int): longitude in floating point format 196 - east_label (str): String label for east 197 - west_label (str): String label for west 198 Returns: 199 str: longitude in string format with degree, minutes, 200 seconds and sign (E/W) 201 """ 202 203 sign = east_label 204 if coord < 0.0: 205 sign = west_label 206 coord = abs(coord) 207 deg = int(coord) 208 min = int((float(coord) - deg) * 60) 209 sec = int(round(float(((float(coord) - deg) * 60) - min) * 60.0)) 210 return f"{deg}°{min}'{sec}\" {sign}"
Converts a floating point longitude to string with degree, minutes and seconds and the appropriate sign (east or west). Eg. 52.1234567 -> 52°7'25" E
Args: - coord (float|int): longitude in floating point format - east_label (str): String label for east - west_label (str): String label for west Returns: str: longitude in string format with degree, minutes, seconds and sign (E/W)
213def draw_aspect_line( 214 r: Union[int, float], 215 ar: Union[int, float], 216 degA: Union[int, float], 217 degB: Union[int, float], 218 color: str, 219 seventh_house_degree_ut: Union[int, float], 220) -> str: 221 """Draws svg aspects: ring, aspect ring, degreeA degreeB 222 223 Args: 224 - r (Union[int, float]): The value of r. 225 - ar (Union[int, float]): The value of ar. 226 - degA (Union[int, float]): The degree of A. 227 - degB (Union[int, float]): The degree of B. 228 - color (str): The color of the aspect. 229 - seventh_house_degree_ut (Union[int, float]): The degree of the seventh house. 230 231 Returns: 232 str: The SVG line element as a string. 233 """ 234 235 first_offset = (int(seventh_house_degree_ut) / -1) + int(degA) 236 x1 = sliceToX(0, ar, first_offset) + (r - ar) 237 y1 = sliceToY(0, ar, first_offset) + (r - ar) 238 239 second_offset = (int(seventh_house_degree_ut) / -1) + int(degB) 240 x2 = sliceToX(0, ar, second_offset) + (r - ar) 241 y2 = sliceToY(0, ar, second_offset) + (r - ar) 242 243 out = f'<line class="aspect" x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}" style="stroke: {color}; stroke-width: 1; stroke-opacity: .9;"/>' 244 245 return out
Draws svg aspects: ring, aspect ring, degreeA degreeB
Args: - r (Union[int, float]): The value of r. - ar (Union[int, float]): The value of ar. - degA (Union[int, float]): The degree of A. - degB (Union[int, float]): The degree of B. - color (str): The color of the aspect. - seventh_house_degree_ut (Union[int, float]): The degree of the seventh house.
Returns: str: The SVG line element as a string.
248def draw_elements_percentages( 249 fire_label: str, 250 fire_points: float, 251 earth_label: str, 252 earth_points: float, 253 air_label: str, 254 air_points: float, 255 water_label: str, 256 water_points: float, 257) -> str: 258 """Draw the elements grid. 259 260 Args: 261 - fire_label (str): Label for fire 262 - fire_points (float): Points for fire 263 - earth_label (str): Label for earth 264 - earth_points (float): Points for earth 265 - air_label (str): Label for air 266 - air_points (float): Points for air 267 - water_label (str): Label for water 268 - water_points (float): Points for water 269 270 Returns: 271 str: The SVG elements grid as a string. 272 """ 273 total = fire_points + earth_points + air_points + water_points 274 275 fire_percentage = int(round(100 * fire_points / total)) 276 earth_percentage = int(round(100 * earth_points / total)) 277 air_percentage = int(round(100 * air_points / total)) 278 water_percentage = int(round(100 * water_points / total)) 279 280 out = '<g transform="translate(-30,79)">' 281 out += f'<text y="0" style="fill:#ff6600; font-size: 10px;">{fire_label} {str(fire_percentage)}%</text>' 282 out += f'<text y="12" style="fill:#6a2d04; font-size: 10px;">{earth_label} {str(earth_percentage)}%</text>' 283 out += f'<text y="24" style="fill:#6f76d1; font-size: 10px;">{air_label} {str(air_percentage)}%</text>' 284 out += f'<text y="36" style="fill:#630e73; font-size: 10px;">{water_label} {str(water_percentage)}%</text>' 285 out += "</g>" 286 287 return out
Draw the elements grid.
Args: - fire_label (str): Label for fire - fire_points (float): Points for fire - earth_label (str): Label for earth - earth_points (float): Points for earth - air_label (str): Label for air - air_points (float): Points for air - water_label (str): Label for water - water_points (float): Points for water
Returns: str: The SVG elements grid as a string.
290def convert_decimal_to_degree_string(dec: float, type="3") -> str: 291 """ 292 Coverts decimal float to degrees in format a°b'c". 293 294 Args: 295 - dec (float): decimal float 296 - type (str): type of format: 297 - 1: a° 298 - 2: a°b' 299 - 3: a°b'c" 300 301 Returns: 302 str: degrees in format a°b'c" 303 """ 304 305 dec = float(dec) 306 a = int(dec) 307 a_new = (dec - float(a)) * 60.0 308 b_rounded = int(round(a_new)) 309 b = int(a_new) 310 c = int(round((a_new - float(b)) * 60.0)) 311 312 if type == "3": 313 out = f"{a:02d}°{b:02d}'{c:02d}"" 314 elif type == "2": 315 out = f"{a:02d}°{b_rounded:02d}'" 316 elif type == "1": 317 out = f"{a:02d}°" 318 else: 319 raise KerykeionException(f"Wrong type: {type}, it must be 1, 2 or 3.") 320 321 return str(out)
Coverts decimal float to degrees in format a°b'c".
Args: - dec (float): decimal float - type (str): type of format: - 1: a° - 2: a°b' - 3: a°b'c"
Returns: str: degrees in format a°b'c"
324def draw_transit_ring_degree_steps(r: Union[int, float], seventh_house_degree_ut: Union[int, float]) -> str: 325 """Draws the transit ring degree steps. 326 327 Args: 328 - r (Union[int, float]): The value of r. 329 - seventh_house_degree_ut (Union[int, float]): The degree of the seventh house. 330 331 Returns: 332 str: The SVG path of the transit ring degree steps. 333 """ 334 335 out = '<g id="transitRingDegreeSteps">' 336 for i in range(72): 337 offset = float(i * 5) - seventh_house_degree_ut 338 if offset < 0: 339 offset = offset + 360.0 340 elif offset > 360: 341 offset = offset - 360.0 342 x1 = sliceToX(0, r, offset) 343 y1 = sliceToY(0, r, offset) 344 x2 = sliceToX(0, r + 2, offset) - 2 345 y2 = sliceToY(0, r + 2, offset) - 2 346 out += f'<line x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}" style="stroke: #F00; stroke-width: 1px; stroke-opacity:.9;"/>' 347 out += "</g>" 348 349 return out
Draws the transit ring degree steps.
Args: - r (Union[int, float]): The value of r. - seventh_house_degree_ut (Union[int, float]): The degree of the seventh house.
Returns: str: The SVG path of the transit ring degree steps.
352def draw_degree_ring(r: Union[int, float], c1: Union[int, float], seventh_house_degree_ut: Union[int, float], stroke_color: str) -> str: 353 """Draws the degree ring. 354 355 Args: 356 - r (Union[int, float]): The value of r. 357 - c1 (Union[int, float]): The value of c1. 358 - seventh_house_degree_ut (Union[int, float]): The degree of the seventh house. 359 - stroke_color (str): The color of the stroke. 360 361 Returns: 362 str: The SVG path of the degree ring. 363 """ 364 out = '<g id="degreeRing">' 365 for i in range(72): 366 offset = float(i * 5) - seventh_house_degree_ut 367 if offset < 0: 368 offset = offset + 360.0 369 elif offset > 360: 370 offset = offset - 360.0 371 x1 = sliceToX(0, r - c1, offset) + c1 372 y1 = sliceToY(0, r - c1, offset) + c1 373 x2 = sliceToX(0, r + 2 - c1, offset) - 2 + c1 374 y2 = sliceToY(0, r + 2 - c1, offset) - 2 + c1 375 376 out += f'<line x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}" style="stroke: {stroke_color}; stroke-width: 1px; stroke-opacity:.9;"/>' 377 out += "</g>" 378 379 return out
Draws the degree ring.
Args: - r (Union[int, float]): The value of r. - c1 (Union[int, float]): The value of c1. - seventh_house_degree_ut (Union[int, float]): The degree of the seventh house. - stroke_color (str): The color of the stroke.
Returns: str: The SVG path of the degree ring.
381def draw_transit_ring(r: Union[int, float], paper_1_color: str, zodiac_transit_ring_3_color: str) -> str: 382 """ 383 Draws the transit ring. 384 385 Args: 386 - r (Union[int, float]): The value of r. 387 - paper_1_color (str): The color of paper 1. 388 - zodiac_transit_ring_3_color (str): The color of the zodiac transit ring 389 390 Returns: 391 str: The SVG path of the transit ring. 392 """ 393 radius_offset = 18 394 395 out = f'<circle cx="{r}" cy="{r}" r="{r - radius_offset}" style="fill: none; stroke: {paper_1_color}; stroke-width: 36px; stroke-opacity: .4;"/>' 396 out += f'<circle cx="{r}" cy="{r}" r="{r}" style="fill: none; stroke: {zodiac_transit_ring_3_color}; stroke-width: 1px; stroke-opacity: .6;"/>' 397 398 return out
Draws the transit ring.
Args: - r (Union[int, float]): The value of r. - paper_1_color (str): The color of paper 1. - zodiac_transit_ring_3_color (str): The color of the zodiac transit ring
Returns: str: The SVG path of the transit ring.
401def draw_first_circle(r: Union[int, float], stroke_color: str, chart_type: ChartType, c1: Union[int, float, None] = None) -> str: 402 """ 403 Draws the first circle. 404 405 Args: 406 - r (Union[int, float]): The value of r. 407 - color (str): The color of the circle. 408 - chart_type (ChartType): The type of chart. 409 - c1 (Union[int, float]): The value of c1. 410 411 Returns: 412 str: The SVG path of the first circle. 413 """ 414 if chart_type == "Synastry" or chart_type == "Transit": 415 return f'<circle cx="{r}" cy="{r}" r="{r - 36}" style="fill: none; stroke: {stroke_color}; stroke-width: 1px; stroke-opacity:.4;" />' 416 else: 417 if c1 is None: 418 raise KerykeionException("c1 is None") 419 420 return f'<circle cx="{r}" cy="{r}" r="{r - c1}" style="fill: none; stroke: {stroke_color}; stroke-width: 1px; " />'
Draws the first circle.
Args: - r (Union[int, float]): The value of r. - color (str): The color of the circle. - chart_type (ChartType): The type of chart. - c1 (Union[int, float]): The value of c1.
Returns: str: The SVG path of the first circle.
423def draw_second_circle(r: Union[int, float], stroke_color: str, fill_color: str, chart_type: ChartType, c2: Union[int, float, None] = None) -> str: 424 """ 425 Draws the second circle. 426 427 Args: 428 - r (Union[int, float]): The value of r. 429 - stroke_color (str): The color of the stroke. 430 - fill_color (str): The color of the fill. 431 - chart_type (ChartType): The type of chart. 432 - c2 (Union[int, float]): The value of c2. 433 434 Returns: 435 str: The SVG path of the second circle. 436 """ 437 438 if chart_type == "Synastry" or chart_type == "Transit": 439 return f'<circle cx="{r}" cy="{r}" r="{r - 72}" style="fill: {fill_color}; fill-opacity:.4; stroke: {stroke_color}; stroke-opacity:.4; stroke-width: 1px" />' 440 441 else: 442 if c2 is None: 443 raise KerykeionException("c2 is None") 444 445 return f'<circle cx="{r}" cy="{r}" r="{r - c2}" style="fill: {fill_color}; fill-opacity:.2; stroke: {stroke_color}; stroke-opacity:.4; stroke-width: 1px" />'
Draws the second circle.
Args: - r (Union[int, float]): The value of r. - stroke_color (str): The color of the stroke. - fill_color (str): The color of the fill. - chart_type (ChartType): The type of chart. - c2 (Union[int, float]): The value of c2.
Returns: str: The SVG path of the second circle.