fix(energy-pie): represent indeterminate shares and preserve prepared styling
Tests / test (push) Successful in 50s

This commit is contained in:
dh
2026-10-06 17:40:42 +00:00
parent c5f924bd19
commit 5b6125d086
10 changed files with 241 additions and 27 deletions
+45 -11
View File
@@ -63,6 +63,7 @@
html,
body {
min-width: 0;
height: 100%;
min-height: 100%;
margin: 0;
color: var(--content-color, inherit);
@@ -70,6 +71,11 @@
}
#energy-app {
--card-color: #121216;
--content-color: #f5f5f7;
position: relative;
isolation: isolate;
color-scheme: dark;
width: 100%;
min-height: 100%;
box-sizing: border-box;
@@ -80,6 +86,20 @@
background-color: var(--card-color, transparent);
}
/* Keep the original Energy Pie colors behind the scrollable controls. */
#energy-app::before {
content: "";
position: absolute;
inset: 0;
z-index: -1;
background:
radial-gradient(520px 420px at 18% 18%, rgba(99, 179, 255, 0.42), transparent 60%),
radial-gradient(560px 460px at 82% 28%, rgba(168, 85, 247, 0.38), transparent 62%),
radial-gradient(620px 520px at 55% 85%, rgba(99, 179, 255, 0.26), transparent 64%);
filter: blur(18px);
pointer-events: none;
}
.toolbar,
.custom-range,
.button-row,
@@ -228,6 +248,11 @@
dominant-baseline: middle;
}
.donut-label.unavailable {
font-size: 14px;
font-weight: 600;
}
.error {
min-height: 18px;
margin-top: 8px;
@@ -366,6 +391,8 @@
}
function donut(target, percent, color) {
const available = percent !== null && percent !== undefined
&& Number.isFinite(Number(percent));
const value = Math.max(0, Math.min(100, asNumber(percent)));
const radius = 58;
const circumference = 2 * Math.PI * radius;
@@ -373,15 +400,17 @@
target.innerHTML = [
'<svg viewBox="0 0 176 176" role="img" aria-label="'
+ value.toFixed(1) + ' Prozent">',
+ (available ? value.toFixed(1) + ' Prozent' : 'Nicht bestimmbar') + '">',
'<circle class="donut-track" cx="88" cy="88" r="' + radius
+ '" fill="none" stroke-width="18"></circle>',
'<circle class="donut-value" cx="88" cy="88" r="' + radius
available ? '<circle class="donut-value" cx="88" cy="88" r="' + radius
+ '" fill="none" stroke="' + color + '" stroke-width="18"'
+ ' stroke-linecap="round" transform="rotate(-90 88 88)"'
+ ' stroke-dasharray="' + filled + ' ' + circumference + '"></circle>',
'<text class="donut-label" x="88" y="91">'
+ value.toFixed(1) + '%</text>',
+ ' stroke-dasharray="' + filled + ' ' + circumference + '"></circle>' : '',
available ? '<text class="donut-label" x="88" y="91">'
+ value.toFixed(1) + '%</text>'
: '<text class="donut-label unavailable" x="88" y="80">'
+ '<tspan x="88">Nicht</tspan><tspan x="88" dy="20">bestimmbar</tspan></text>',
'</svg>'
].join('');
}
@@ -421,19 +450,24 @@
const colors = data.colors || {};
donut(
selfConsumptionChart,
values.Eigenverbrauchsquote,
data.sharesAvailable === false ? null : values.Eigenverbrauchsquote,
colors.selfConsumption || '#2F80ED'
);
donut(
autarkyChart,
values.Autarkiegrad,
data.sharesAvailable === false ? null : values.Autarkiegrad,
colors.autarky || '#22A06B'
);
message.hidden = data.hasData !== false;
message.textContent = data.hasData === false
? (data.noDataHint || 'Keine Archivwerte verfügbar.')
: '';
const hints = [];
if (data.hasData === false) {
hints.push(data.noDataHint || 'Keine Archivwerte verfügbar.');
}
if (data.sharesAvailable === false) {
hints.push(data.attributionHint || 'Eigenverbrauch und Autarkie sind nicht eindeutig bestimmbar.');
}
message.hidden = hints.length === 0;
message.textContent = hints.join(' ');
}
window.handleMessage = function (data) {