TCrB Diagramm verbessert

This commit is contained in:
2026-04-06 10:16:48 +02:00
parent 078c7ac8d0
commit f3e613e98e
5 changed files with 436 additions and 101 deletions
+82 -8
View File
@@ -23,6 +23,7 @@ $stateFile = __DIR__ . DIRECTORY_SEPARATOR . 'telegram_cron_state.json';
$dbConfig = require $rootDir . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'database.php';
$telegramConfig = require $rootDir . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'telegram.php';
require_once $rootDir . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'telegram_message_footer.php';
$filterColorConfigPath = $rootDir . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'filter_colors.json';
$dsn = sprintf(
'mysql:host=%s;port=%d;dbname=%s;charset=%s',
@@ -547,6 +548,12 @@ function formatGermanDateTime(?string $value): string
function buildTcrbVChartSvg(array $observations, array $latestObservation): string
{
$filterColors = loadFilterColors();
$vColor = (string) ($filterColors['V'] ?? '#92FF00');
$vStrokeColor = darkenHexColor($vColor, 0.35);
$vHighlightColor = lightenHexColor($vColor, 0.35);
$vHighlightStrokeColor = lightenHexColor($vColor, 0.6);
$width = 1200;
$height = 700;
$paddingLeft = 90;
@@ -639,14 +646,15 @@ function buildTcrbVChartSvg(array $observations, array $latestObservation): stri
$yTop = $scaleY($magnitude - $error);
$yBottom = $scaleY($magnitude + $error);
$errorBars[] = sprintf(
'<line x1="%1$.2f" y1="%2$.2f" x2="%1$.2f" y2="%3$.2f" stroke="#8fd694" stroke-width="2" opacity="0.9" />' .
'<line x1="%4$.2f" y1="%2$.2f" x2="%5$.2f" y2="%2$.2f" stroke="#8fd694" stroke-width="2" opacity="0.9" />' .
'<line x1="%4$.2f" y1="%3$.2f" x2="%5$.2f" y2="%3$.2f" stroke="#8fd694" stroke-width="2" opacity="0.9" />',
'<line x1="%1$.2f" y1="%2$.2f" x2="%1$.2f" y2="%3$.2f" stroke="%6$s" stroke-width="2" opacity="0.9" />' .
'<line x1="%4$.2f" y1="%2$.2f" x2="%5$.2f" y2="%2$.2f" stroke="%6$s" stroke-width="2" opacity="0.9" />' .
'<line x1="%4$.2f" y1="%3$.2f" x2="%5$.2f" y2="%3$.2f" stroke="%6$s" stroke-width="2" opacity="0.9" />',
$x,
$yTop,
$yBottom,
$x - 7,
$x + 7
$x + 7,
htmlspecialchars($vHighlightColor, ENT_QUOTES, 'UTF-8')
);
}
@@ -658,8 +666,8 @@ function buildTcrbVChartSvg(array $observations, array $latestObservation): stri
$x,
$y,
$isLatest ? 7.0 : 4.2,
$isLatest ? '#f4d35e' : '#7bd389',
$isLatest ? '#fff3bf' : '#d9f99d',
$isLatest ? $vHighlightColor : $vColor,
$isLatest ? $vHighlightStrokeColor : $vHighlightColor,
$isLatest ? 2.6 : 1.4
);
}
@@ -691,13 +699,13 @@ function buildTcrbVChartSvg(array $observations, array $latestObservation): stri
<text x="%d" y="70" fill="#cbd5e1" font-size="19">letzte 2 Monate</text>
<text x="%d" y="%d" fill="#cbd5e1" font-size="18">%s</text>
<text x="%d" y="%d" fill="#cbd5e1" font-size="18" text-anchor="end">%s</text>
<text x="%d" y="48" fill="#f4d35e" font-size="22" text-anchor="end">Aktuell: %s%s</text>
<text x="%d" y="48" fill="%s" font-size="22" text-anchor="end">Aktuell: %s%s</text>
<text x="%d" y="74" fill="#cbd5e1" font-size="18" text-anchor="end">%s UTC</text>
%s
<line x1="%d" y1="%d" x2="%d" y2="%d" stroke="#88a4bf" stroke-width="1.6"/>
<line x1="%d" y1="%d" x2="%d" y2="%d" stroke="#88a4bf" stroke-width="1.6"/>
%s
<path d="%s" fill="none" stroke="#7bd389" stroke-width="3" stroke-linejoin="round" stroke-linecap="round"/>
<path d="%s" fill="none" stroke="%s" stroke-width="3" stroke-linejoin="round" stroke-linecap="round"/>
%s
</svg>
SVG,
@@ -720,6 +728,7 @@ SVG,
$height - 28,
htmlspecialchars($lastLabel, ENT_QUOTES, 'UTF-8'),
$width - $paddingRight,
htmlspecialchars($vHighlightColor, ENT_QUOTES, 'UTF-8'),
htmlspecialchars($latestMagnitude, ENT_QUOTES, 'UTF-8'),
htmlspecialchars($latestError, ENT_QUOTES, 'UTF-8'),
$width - $paddingRight,
@@ -735,10 +744,75 @@ SVG,
$plotBottomY,
$errorBarsSvg,
$pathSvg,
htmlspecialchars($vStrokeColor, ENT_QUOTES, 'UTF-8'),
$pointsSvgMarkup
);
}
function loadFilterColors(): array
{
static $colors = null;
global $filterColorConfigPath;
if (is_array($colors)) {
return $colors;
}
$colors = [];
if (!is_string($filterColorConfigPath) || !is_file($filterColorConfigPath)) {
return $colors;
}
$raw = file_get_contents($filterColorConfigPath);
$decoded = is_string($raw) ? json_decode($raw, true) : null;
if (!is_array($decoded)) {
return $colors;
}
foreach ($decoded as $filterCode => $config) {
if (is_array($config) && !empty($config['color'])) {
$colors[(string) $filterCode] = (string) $config['color'];
}
}
return $colors;
}
function darkenHexColor(string $hexColor, float $amount): string
{
return adjustHexColor($hexColor, -abs($amount));
}
function lightenHexColor(string $hexColor, float $amount): string
{
return adjustHexColor($hexColor, abs($amount));
}
function adjustHexColor(string $hexColor, float $amount): string
{
$hex = ltrim(trim($hexColor), '#');
if (!preg_match('/^[0-9a-fA-F]{6}$/', $hex)) {
return '#92FF00';
}
$channels = [
hexdec(substr($hex, 0, 2)),
hexdec(substr($hex, 2, 2)),
hexdec(substr($hex, 4, 2)),
];
foreach ($channels as $index => $value) {
if ($amount >= 0) {
$channels[$index] = (int) round($value + ((255 - $value) * $amount));
} else {
$channels[$index] = (int) round($value * (1 + $amount));
}
$channels[$index] = max(0, min(255, $channels[$index]));
}
return sprintf('#%02X%02X%02X', $channels[0], $channels[1], $channels[2]);
}
function buildTcrbObservationSignature(array $observation): string
{
return implode('|', [