Add constellation offset trend statistics
This commit is contained in:
@@ -897,6 +897,10 @@ footer a:hover { color: var(--gold); }
|
||||
width: 7rem;
|
||||
}
|
||||
|
||||
.sun-constellations-form select {
|
||||
min-width: 12rem;
|
||||
}
|
||||
|
||||
.sun-constellations-table-wrap {
|
||||
overflow-x: auto;
|
||||
}
|
||||
@@ -910,6 +914,89 @@ footer a:hover { color: var(--gold); }
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.sun-constellations-stats-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
|
||||
gap: 0.75rem;
|
||||
margin: 1.25rem 0;
|
||||
}
|
||||
|
||||
.sun-constellations-stats-grid div {
|
||||
background: rgba(79, 195, 216, 0.06);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius);
|
||||
padding: 0.9rem 1rem;
|
||||
}
|
||||
|
||||
.sun-constellations-stats-grid span {
|
||||
display: block;
|
||||
color: var(--text-dim);
|
||||
font-size: 0.75rem;
|
||||
letter-spacing: 0.06em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.sun-constellations-stats-grid strong {
|
||||
display: block;
|
||||
color: var(--gold-pale);
|
||||
margin-top: 0.3rem;
|
||||
}
|
||||
|
||||
.sun-constellations-year-details summary {
|
||||
color: var(--cyan);
|
||||
cursor: pointer;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.sun-constellations-chart-wrap {
|
||||
background: rgba(3, 8, 18, 0.45);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius);
|
||||
margin: 1.25rem 0;
|
||||
padding: 0.8rem;
|
||||
}
|
||||
|
||||
.sun-constellations-chart {
|
||||
display: block;
|
||||
height: auto;
|
||||
overflow: visible;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.sun-chart-grid {
|
||||
stroke: rgba(180, 210, 235, 0.16);
|
||||
stroke-width: 1;
|
||||
}
|
||||
|
||||
.sun-chart-line {
|
||||
fill: none;
|
||||
stroke: var(--cyan);
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
stroke-width: 2.5;
|
||||
}
|
||||
|
||||
.sun-chart-moving-average {
|
||||
fill: none;
|
||||
stroke: var(--gold);
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
stroke-width: 3;
|
||||
}
|
||||
|
||||
.sun-chart-marker {
|
||||
fill: var(--gold-pale);
|
||||
stroke: #07101d;
|
||||
stroke-width: 1.5;
|
||||
}
|
||||
|
||||
.sun-chart-axis-label {
|
||||
fill: var(--text-dim);
|
||||
font-family: 'Space Mono', monospace;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: 560px) {
|
||||
.sun-constellations-form {
|
||||
align-items: stretch;
|
||||
|
||||
+94
-2
@@ -2306,6 +2306,93 @@ def action_sun_constellation_changes_for_year(args: list[str]) -> dict:
|
||||
}
|
||||
|
||||
|
||||
def action_sun_constellation_offset_statistics(args: list[str]) -> dict:
|
||||
if len(args) != 3:
|
||||
fail(
|
||||
"Aktion sun_constellation_offset_statistics erwartet 3 Argumente: start_year constellation_symbol timezone",
|
||||
extra={"argv": args},
|
||||
)
|
||||
|
||||
try:
|
||||
start_year = int(args[0])
|
||||
except ValueError as exc:
|
||||
fail("Startjahr ist ungueltig.", extra={"details": str(exc), "argv": args})
|
||||
|
||||
end_year = start_year + 99
|
||||
if start_year < 1600 or end_year > 2200:
|
||||
fail("Der Zeitraum von 100 Jahren muss zwischen 1600 und 2200 liegen.", extra={"start_year": start_year})
|
||||
|
||||
constellation_symbol = args[1]
|
||||
astrological_starts = {
|
||||
"Cap": ("Steinbock", -1, 12, 22),
|
||||
"Aqr": ("Wassermann", 0, 1, 20),
|
||||
"Psc": ("Fische", 0, 2, 19),
|
||||
"Ari": ("Widder", 0, 3, 21),
|
||||
"Tau": ("Stier", 0, 4, 20),
|
||||
"Gem": ("Zwillinge", 0, 5, 21),
|
||||
"Cnc": ("Krebs", 0, 6, 21),
|
||||
"Leo": ("Löwe", 0, 7, 23),
|
||||
"Vir": ("Jungfrau", 0, 8, 23),
|
||||
"Lib": ("Waage", 0, 9, 23),
|
||||
"Sco": ("Skorpion", 0, 10, 23),
|
||||
"Sgr": ("Schütze", 0, 11, 22),
|
||||
}
|
||||
if constellation_symbol not in astrological_starts:
|
||||
fail("Sternbild ist fuer den astrologischen Vergleich nicht verfuegbar.", extra={"constellation_symbol": constellation_symbol})
|
||||
|
||||
timezone_name = args[2]
|
||||
try:
|
||||
tz = ZoneInfo(timezone_name)
|
||||
except Exception as exc:
|
||||
fail("Zeitzone ist ungueltig oder auf dem Server nicht verfuegbar.", extra={"details": str(exc)})
|
||||
|
||||
constellation_name, year_offset, month, day = astrological_starts[constellation_symbol]
|
||||
yearly_values: list[dict] = []
|
||||
differences: list[float] = []
|
||||
|
||||
for year in range(start_year, end_year + 1):
|
||||
yearly_data = action_sun_constellation_changes_for_year([str(year), timezone_name])
|
||||
event = next(
|
||||
(item for item in yearly_data["events"] if item["to_constellation_symbol"] == constellation_symbol),
|
||||
None,
|
||||
)
|
||||
if event is None:
|
||||
fail("Kein Sternbildwechsel im Berechnungszeitraum gefunden.", extra={"year": year, "constellation_symbol": constellation_symbol})
|
||||
|
||||
astronomical_change = datetime.fromisoformat(event["local_iso"]).astimezone(tz)
|
||||
astrological_start = datetime(year + year_offset, month, day, 0, 0, 0, tzinfo=tz)
|
||||
difference_days = (astronomical_change - astrological_start).total_seconds() / 86400.0
|
||||
differences.append(difference_days)
|
||||
yearly_values.append({
|
||||
"year": year,
|
||||
"astronomical_date": astronomical_change.strftime("%d.%m.%Y"),
|
||||
"astrological_date": astrological_start.strftime("%d.%m.%Y"),
|
||||
"difference_days": round(difference_days, 2),
|
||||
})
|
||||
|
||||
mean_days = sum(differences) / len(differences)
|
||||
variance = sum((value - mean_days) ** 2 for value in differences) / len(differences)
|
||||
|
||||
return {
|
||||
"ok": True,
|
||||
"action": "sun_constellation_offset_statistics",
|
||||
"selected": {
|
||||
"constellation_symbol": constellation_symbol,
|
||||
"constellation_name": constellation_name,
|
||||
"start_year": start_year,
|
||||
"end_year": end_year,
|
||||
"timezone": timezone_name,
|
||||
},
|
||||
"statistics": {
|
||||
"min_days": round(min(differences), 2),
|
||||
"max_days": round(max(differences), 2),
|
||||
"standard_deviation_days": round(math.sqrt(variance), 2),
|
||||
"change_over_period_days": round(differences[-1] - differences[0], 2),
|
||||
},
|
||||
"years": yearly_values,
|
||||
}
|
||||
|
||||
|
||||
def action_month_sky_context(args: list[str]) -> dict:
|
||||
if len(args) != 8:
|
||||
fail(
|
||||
@@ -6057,7 +6144,7 @@ def action_barycenter(args: list[str]) -> dict:
|
||||
|
||||
def main() -> None:
|
||||
if len(sys.argv) < 2:
|
||||
fail("Es wurde keine Aktion uebergeben.", extra={"available_actions": ["sun_moon_rise_set", "solar_longitude_to_datetime", "current_solar_longitude", "astronomical_conversions", "comet_brightnesses", "favorite_comet_events_for_month", "moon_star_occultations", "moon_phase_details", "satellite_passes", "planet_rise_set", "planet_ephemeris", "month_sky_context", "moon_phases_for_month", "golden_handle_for_month", "season_changes_for_month", "time_changes_for_month", "moon_planet_approaches", "moon_deep_sky_approaches_for_month", "planet_bright_star_approaches_for_month", "golden_gate_of_ecliptic_for_month", "planet_conjunctions_for_month", "eclipses_for_month", "moon_apsides_for_month", "sun_apsides_for_month", "inner_planet_elongations_for_month", "venus_peak_magnitude_for_month", "outer_planet_events_for_month", "outer_planet_stations_for_month", "jupiter_moons_one_side_for_month", "mercury_good_visibility_for_month", "planet_parades_for_month", "planet_constellation_changes_for_month", "sun_constellation_changes_for_year", "moon_star_occultations_for_month"]})
|
||||
fail("Es wurde keine Aktion uebergeben.", extra={"available_actions": ["sun_moon_rise_set", "solar_longitude_to_datetime", "current_solar_longitude", "astronomical_conversions", "comet_brightnesses", "favorite_comet_events_for_month", "moon_star_occultations", "moon_phase_details", "satellite_passes", "planet_rise_set", "planet_ephemeris", "month_sky_context", "moon_phases_for_month", "golden_handle_for_month", "season_changes_for_month", "time_changes_for_month", "moon_planet_approaches", "moon_deep_sky_approaches_for_month", "planet_bright_star_approaches_for_month", "golden_gate_of_ecliptic_for_month", "planet_conjunctions_for_month", "eclipses_for_month", "moon_apsides_for_month", "sun_apsides_for_month", "inner_planet_elongations_for_month", "venus_peak_magnitude_for_month", "outer_planet_events_for_month", "outer_planet_stations_for_month", "jupiter_moons_one_side_for_month", "mercury_good_visibility_for_month", "planet_parades_for_month", "planet_constellation_changes_for_month", "sun_constellation_changes_for_year", "sun_constellation_offset_statistics", "moon_star_occultations_for_month"]})
|
||||
|
||||
action = sys.argv[1]
|
||||
args = sys.argv[2:]
|
||||
@@ -6237,6 +6324,11 @@ def main() -> None:
|
||||
print(json.dumps(result, ensure_ascii=True))
|
||||
return
|
||||
|
||||
if action == "sun_constellation_offset_statistics":
|
||||
result = action_sun_constellation_offset_statistics(args)
|
||||
print(json.dumps(result, ensure_ascii=True))
|
||||
return
|
||||
|
||||
if action == "moon_star_occultations_for_month":
|
||||
result = action_moon_star_occultations_for_month(args)
|
||||
print(json.dumps(result, ensure_ascii=True))
|
||||
@@ -6252,7 +6344,7 @@ def main() -> None:
|
||||
print(json.dumps(result, ensure_ascii=True))
|
||||
return
|
||||
|
||||
fail("Unbekannte Aktion.", extra={"action": action, "available_actions": ["sun_moon_rise_set", "solar_longitude_to_datetime", "current_solar_longitude", "astronomical_conversions", "twilight_chart", "comet_brightnesses", "favorite_comet_events_for_month", "moon_star_occultations", "moon_phase_details", "satellite_passes", "planet_rise_set", "planet_ephemeris", "planet_visibility_chart", "month_sky_context", "moon_phases_for_month", "golden_handle_for_month", "season_changes_for_month", "time_changes_for_month", "moon_planet_approaches", "moon_deep_sky_approaches_for_month", "planet_bright_star_approaches_for_month", "golden_gate_of_ecliptic_for_month", "planet_conjunctions_for_month", "eclipses_for_month", "moon_apsides_for_month", "sun_apsides_for_month", "inner_planet_elongations_for_month", "venus_peak_magnitude_for_month", "outer_planet_events_for_month", "outer_planet_stations_for_month", "jupiter_moons_one_side_for_month", "mercury_good_visibility_for_month", "planet_parades_for_month", "planet_constellation_changes_for_month", "sun_constellation_changes_for_year", "moon_star_occultations_for_month"]})
|
||||
fail("Unbekannte Aktion.", extra={"action": action, "available_actions": ["sun_moon_rise_set", "solar_longitude_to_datetime", "current_solar_longitude", "astronomical_conversions", "twilight_chart", "comet_brightnesses", "favorite_comet_events_for_month", "moon_star_occultations", "moon_phase_details", "satellite_passes", "planet_rise_set", "planet_ephemeris", "planet_visibility_chart", "month_sky_context", "moon_phases_for_month", "golden_handle_for_month", "season_changes_for_month", "time_changes_for_month", "moon_planet_approaches", "moon_deep_sky_approaches_for_month", "planet_bright_star_approaches_for_month", "golden_gate_of_ecliptic_for_month", "planet_conjunctions_for_month", "eclipses_for_month", "moon_apsides_for_month", "sun_apsides_for_month", "inner_planet_elongations_for_month", "venus_peak_magnitude_for_month", "outer_planet_events_for_month", "outer_planet_stations_for_month", "jupiter_moons_one_side_for_month", "mercury_good_visibility_for_month", "planet_parades_for_month", "planet_constellation_changes_for_month", "sun_constellation_changes_for_year", "sun_constellation_offset_statistics", "moon_star_occultations_for_month"]})
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -12,6 +12,11 @@ function h(string $value): string
|
||||
return htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
|
||||
}
|
||||
|
||||
function formatSignedDays(float $value): string
|
||||
{
|
||||
return ($value >= 0 ? '+' : '-') . number_format(abs($value), 2, ',', '.') . ' Tage';
|
||||
}
|
||||
|
||||
$timezoneName = 'Europe/Berlin';
|
||||
$currentYear = (int) (new DateTimeImmutable('now', new DateTimeZone($timezoneName)))->format('Y');
|
||||
$selectedYear = filter_input(INPUT_GET, 'year', FILTER_VALIDATE_INT);
|
||||
@@ -49,6 +54,44 @@ $astrologicalStarts = [
|
||||
'Skorpion' => [$selectedYear, 10, 23],
|
||||
'Schütze' => [$selectedYear, 11, 22],
|
||||
];
|
||||
$astrologicalStartsBySymbol = [
|
||||
'Cap' => [$selectedYear - 1, 12, 22],
|
||||
'Aqr' => [$selectedYear, 1, 20],
|
||||
'Psc' => [$selectedYear, 2, 19],
|
||||
'Ari' => [$selectedYear, 3, 21],
|
||||
'Tau' => [$selectedYear, 4, 20],
|
||||
'Gem' => [$selectedYear, 5, 21],
|
||||
'Cnc' => [$selectedYear, 6, 21],
|
||||
'Leo' => [$selectedYear, 7, 23],
|
||||
'Vir' => [$selectedYear, 8, 23],
|
||||
'Lib' => [$selectedYear, 9, 23],
|
||||
'Sco' => [$selectedYear, 10, 23],
|
||||
'Sgr' => [$selectedYear, 11, 22],
|
||||
];
|
||||
$statConstellations = [
|
||||
'Cap' => 'Steinbock',
|
||||
'Aqr' => 'Wassermann',
|
||||
'Psc' => 'Fische',
|
||||
'Ari' => 'Widder',
|
||||
'Tau' => 'Stier',
|
||||
'Gem' => 'Zwillinge',
|
||||
'Cnc' => 'Krebs',
|
||||
'Leo' => 'Löwe',
|
||||
'Vir' => 'Jungfrau',
|
||||
'Lib' => 'Waage',
|
||||
'Sco' => 'Skorpion',
|
||||
'Sgr' => 'Schütze',
|
||||
];
|
||||
$selectedStatConstellation = trim((string) ($_GET['stat_constellation'] ?? 'Cap'));
|
||||
if (!isset($statConstellations[$selectedStatConstellation])) {
|
||||
$selectedStatConstellation = 'Cap';
|
||||
}
|
||||
$statisticsResult = runPythonApi('sun_constellation_offset_statistics', [
|
||||
(string) $selectedYear,
|
||||
$selectedStatConstellation,
|
||||
$timezoneName,
|
||||
]);
|
||||
$statisticsData = $statisticsResult['ok'] ? $statisticsResult['data'] : null;
|
||||
?>
|
||||
|
||||
<main class="sun-constellations-tool">
|
||||
@@ -92,8 +135,9 @@ $astrologicalStarts = [
|
||||
$constellationName = (string) ($event['to_constellation_name'] ?? '');
|
||||
$interval = $intervalsByStart[(string) ($event['local_iso'] ?? '')] ?? [];
|
||||
$astrologicalStart = null;
|
||||
if (isset($astrologicalStarts[$constellationName])) {
|
||||
[$astrologicalYear, $astrologicalMonth, $astrologicalDay] = $astrologicalStarts[$constellationName];
|
||||
$constellationSymbol = (string) ($event['to_constellation_symbol'] ?? '');
|
||||
if (isset($astrologicalStartsBySymbol[$constellationSymbol])) {
|
||||
[$astrologicalYear, $astrologicalMonth, $astrologicalDay] = $astrologicalStartsBySymbol[$constellationSymbol];
|
||||
$astrologicalStart = new DateTimeImmutable(
|
||||
sprintf('%04d-%02d-%02d 00:00:00', $astrologicalYear, $astrologicalMonth, $astrologicalDay),
|
||||
$displayTimezone
|
||||
@@ -120,6 +164,133 @@ $astrologicalStarts = [
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="card sun-constellations-card sun-constellations-statistics">
|
||||
<h2>Versatz über 100 Jahre</h2>
|
||||
<form class="sun-constellations-form" method="get">
|
||||
<input type="hidden" name="year" value="<?= h((string) $selectedYear) ?>">
|
||||
<label for="stat_constellation">Sternbild</label>
|
||||
<select id="stat_constellation" name="stat_constellation">
|
||||
<?php foreach ($statConstellations as $symbol => $label): ?>
|
||||
<option value="<?= h($symbol) ?>"<?= $symbol === $selectedStatConstellation ? ' selected' : '' ?>><?= h($label) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<button class="btn btn-primary" type="submit">100 Jahre auswerten</button>
|
||||
</form>
|
||||
<p class="hint">
|
||||
Zeitraum: <?= h((string) $selectedYear) ?> bis <?= h((string) ($selectedYear + 99)) ?>. Der Versatz ist der astronomische Wechselzeitpunkt minus dem üblichen astrologischen Beginn.
|
||||
</p>
|
||||
|
||||
<?php if ($statisticsData === null): ?>
|
||||
<p class="msg-error"><?= h((string) ($statisticsResult['error'] ?? 'Statistik konnte nicht berechnet werden.')) ?></p>
|
||||
<?php else: ?>
|
||||
<?php $statistics = is_array($statisticsData['statistics'] ?? null) ? $statisticsData['statistics'] : []; ?>
|
||||
<?php $yearValues = is_array($statisticsData['years'] ?? null) ? $statisticsData['years'] : []; ?>
|
||||
<?php
|
||||
$chartWidth = 900.0;
|
||||
$chartHeight = 270.0;
|
||||
$chartLeft = 58.0;
|
||||
$chartRight = 20.0;
|
||||
$chartTop = 20.0;
|
||||
$chartBottom = 42.0;
|
||||
$chartValues = array_map(
|
||||
static fn(array $yearValue): float => (float) ($yearValue['difference_days'] ?? 0),
|
||||
$yearValues
|
||||
);
|
||||
$chartMin = min($chartValues);
|
||||
$chartMax = max($chartValues);
|
||||
$chartPadding = max(0.25, ($chartMax - $chartMin) * 0.12);
|
||||
$chartLow = $chartMin - $chartPadding;
|
||||
$chartHigh = $chartMax + $chartPadding;
|
||||
$chartRange = $chartHigh - $chartLow;
|
||||
$chartPlotWidth = $chartWidth - $chartLeft - $chartRight;
|
||||
$chartPlotHeight = $chartHeight - $chartTop - $chartBottom;
|
||||
$chartPoints = [];
|
||||
$chartMarkers = [];
|
||||
foreach ($yearValues as $index => $yearValue) {
|
||||
$value = (float) ($yearValue['difference_days'] ?? 0);
|
||||
$x = $chartLeft + ($index / max(1, count($yearValues) - 1)) * $chartPlotWidth;
|
||||
$y = $chartTop + (($chartHigh - $value) / $chartRange) * $chartPlotHeight;
|
||||
$chartPoints[] = number_format($x, 2, '.', '') . ',' . number_format($y, 2, '.', '');
|
||||
if ($index % 10 === 0 || $index === count($yearValues) - 1) {
|
||||
$chartMarkers[] = [
|
||||
'x' => $x,
|
||||
'y' => $y,
|
||||
'year' => (string) ($yearValue['year'] ?? ''),
|
||||
'value' => $value,
|
||||
];
|
||||
}
|
||||
}
|
||||
$movingAverageWindow = 10;
|
||||
$movingAverageValues = [];
|
||||
$movingAveragePoints = [];
|
||||
foreach ($chartValues as $index => $value) {
|
||||
if ($index < $movingAverageWindow - 1) {
|
||||
continue;
|
||||
}
|
||||
$movingAverage = array_sum(array_slice($chartValues, $index - $movingAverageWindow + 1, $movingAverageWindow)) / $movingAverageWindow;
|
||||
$x = $chartLeft + ($index / max(1, count($yearValues) - 1)) * $chartPlotWidth;
|
||||
$y = $chartTop + (($chartHigh - $movingAverage) / $chartRange) * $chartPlotHeight;
|
||||
$movingAverageValues[] = $movingAverage;
|
||||
$movingAveragePoints[] = number_format($x, 2, '.', '') . ',' . number_format($y, 2, '.', '');
|
||||
}
|
||||
?>
|
||||
<div class="sun-constellations-stats-grid">
|
||||
<div><span>10-Jahres-Trend</span><strong><?= h(formatSignedDays((float) ($movingAverageValues[count($movingAverageValues) - 1] ?? 0))) ?></strong></div>
|
||||
<div><span>Kleinster Versatz</span><strong><?= h(formatSignedDays((float) ($statistics['min_days'] ?? 0))) ?></strong></div>
|
||||
<div><span>Größter Versatz</span><strong><?= h(formatSignedDays((float) ($statistics['max_days'] ?? 0))) ?></strong></div>
|
||||
<div><span>Streuung</span><strong><?= h(number_format((float) ($statistics['standard_deviation_days'] ?? 0), 2, ',', '.') . ' Tage') ?></strong></div>
|
||||
<div><span>Änderung im Zeitraum</span><strong><?= h(formatSignedDays((float) ($statistics['change_over_period_days'] ?? 0))) ?></strong></div>
|
||||
</div>
|
||||
|
||||
<div class="sun-constellations-chart-wrap">
|
||||
<svg class="sun-constellations-chart" viewBox="0 0 900 270" role="img" aria-label="Zeitlicher Versatz über 100 Jahre in Tagen">
|
||||
<?php for ($line = 0; $line <= 4; $line++): ?>
|
||||
<?php $value = $chartLow + (($chartHigh - $chartLow) * $line / 4); ?>
|
||||
<?php $y = $chartTop + $chartPlotHeight - ($chartPlotHeight * $line / 4); ?>
|
||||
<line class="sun-chart-grid" x1="<?= h(number_format($chartLeft, 2, '.', '')) ?>" y1="<?= h(number_format($y, 2, '.', '')) ?>" x2="<?= h(number_format($chartWidth - $chartRight, 2, '.', '')) ?>" y2="<?= h(number_format($y, 2, '.', '')) ?>"></line>
|
||||
<text class="sun-chart-axis-label" x="<?= h(number_format($chartLeft - 9, 2, '.', '')) ?>" y="<?= h(number_format($y + 4, 2, '.', '')) ?>" text-anchor="end"><?= h(number_format($value, 1, ',', '.')) ?></text>
|
||||
<?php endfor; ?>
|
||||
<polyline class="sun-chart-line" points="<?= h(implode(' ', $chartPoints)) ?>"></polyline>
|
||||
<polyline class="sun-chart-moving-average" points="<?= h(implode(' ', $movingAveragePoints)) ?>"></polyline>
|
||||
<?php foreach ($chartMarkers as $marker): ?>
|
||||
<circle class="sun-chart-marker" cx="<?= h(number_format($marker['x'], 2, '.', '')) ?>" cy="<?= h(number_format($marker['y'], 2, '.', '')) ?>" r="3">
|
||||
<title><?= h($marker['year'] . ': ' . formatSignedDays($marker['value'])) ?></title>
|
||||
</circle>
|
||||
<?php endforeach; ?>
|
||||
<text class="sun-chart-axis-label" x="<?= h(number_format($chartLeft, 2, '.', '')) ?>" y="<?= h(number_format($chartHeight - 12, 2, '.', '')) ?>" text-anchor="start"><?= h((string) ($yearValues[0]['year'] ?? '')) ?></text>
|
||||
<text class="sun-chart-axis-label" x="<?= h(number_format($chartWidth - $chartRight, 2, '.', '')) ?>" y="<?= h(number_format($chartHeight - 12, 2, '.', '')) ?>" text-anchor="end"><?= h((string) ($yearValues[count($yearValues) - 1]['year'] ?? '')) ?></text>
|
||||
</svg>
|
||||
<p class="hint">Cyan: jährlicher Versatz. Gold: gleitender 10-Jahres-Durchschnitt.</p>
|
||||
</div>
|
||||
|
||||
<details class="sun-constellations-year-details">
|
||||
<summary>Jahreswerte anzeigen (<?= h((string) count($yearValues)) ?> Jahre)</summary>
|
||||
<div class="sun-constellations-table-wrap">
|
||||
<table class="data-table sun-constellations-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Jahr</th>
|
||||
<th>Astronomisch</th>
|
||||
<th>Astrologisch</th>
|
||||
<th>Versatz</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($yearValues as $yearValue): ?>
|
||||
<tr>
|
||||
<td><?= h((string) ($yearValue['year'] ?? '')) ?></td>
|
||||
<td><?= h((string) ($yearValue['astronomical_date'] ?? '')) ?></td>
|
||||
<td><?= h((string) ($yearValue['astrological_date'] ?? '')) ?></td>
|
||||
<td><?= h(formatSignedDays((float) ($yearValue['difference_days'] ?? 0))) ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</details>
|
||||
<?php endif; ?>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
</main>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user