From e9168ee72b7077a0499ddc1f6abbabeeba874744 Mon Sep 17 00:00:00 2001 From: retr0 <42kdesigners@gmail.com> Date: Tue, 25 Aug 2026 13:52:25 +0200 Subject: [PATCH] =?UTF-8?q?ShineBridge=20v1.9.1=20=E2=80=94=20Fix:=20Finan?= =?UTF-8?q?zen-Chart=20bei=20langen=20Abrechnungsjahren=20unlesbar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 'Kosten je Tag' quetschte alle Tage in eine feste Breite von 600px — bei 112 Tagen wurden die Balken zu ~1px-Haarlinien. Breite skaliert jetzt mit der Tagesanzahl (min. 10px Slot/Tag), Chart scrollt bei vielen Tagen horizontal statt gestaucht zu werden. X-Achsen-Labels richten sich an der tatsächlichen Balkenbreite aus statt an einer festen Label-Anzahl. Co-Authored-By: Claude Sonnet 5 --- haos-addon/config.yaml | 2 +- haos-addon/src/web/index.html | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/haos-addon/config.yaml b/haos-addon/config.yaml index bb633fe..af26c6c 100644 --- a/haos-addon/config.yaml +++ b/haos-addon/config.yaml @@ -1,5 +1,5 @@ name: ShineBridge -version: "1.9.0" +version: "1.9.1" slug: shinebridge description: Energiemanagement für Growatt/Goodwe-Wechselrichter — PV-Überschussladen, Wallbox-EMS, Tarifvergleich, Zigbee2MQTT-Überschussgeräte url: https://gitea.bitfire.work/retr0/shinebridge diff --git a/haos-addon/src/web/index.html b/haos-addon/src/web/index.html index 32c05db..ceb99b7 100644 --- a/haos-addon/src/web/index.html +++ b/haos-addon/src/web/index.html @@ -797,11 +797,16 @@ async function loadFinance() { `; // ── SVG-Balkendiagramm ──────────────────────────────────────── - const W = 600, H = 180, PL = 44, PR = 12, PT = 10, PB = 28; + // Breite skaliert mit der Anzahl Tage (Mindestplatz pro Tag), statt bei vielen + // Tagen alles in eine feste Breite zu quetschen — sonst werden Balken bei + // langen Abrechnungsjahren (>60 Tage) zu Haarlinien und unlesbar. + const H = 180, PL = 44, PR = 12, PT = 10, PB = 28; + const n = days.length; + const MIN_SLOT = 10; // px pro Tag (Balkenpaar + Abstand), unterhalb dessen nichts mehr lesbar ist + const W = Math.max(600, PL + PR + n * MIN_SLOT); const cW = W - PL - PR; const cH = H - PT - PB; - const n = days.length; - const barW = Math.max(2, Math.floor(cW / n) - 2); + const barW = Math.max(3, Math.floor(cW / n) - 2); const gap = Math.max(1, Math.floor(cW / n) - barW); const allVals = days.flatMap(d => [d.fixed_eur, d.spot_eur].filter(v => v != null)); @@ -816,6 +821,9 @@ async function loadFinance() { yLabels += `${fEur(v)}`; } + // Label-Abstand an der tatsächlichen Balkenbreite ausrichten (~60px pro Label), + // statt pauschal 8 Labels über die ganze — jetzt variable — Breite zu verteilen. + const labelStep = Math.max(1, Math.round(60 / (barW + gap))); let bars = '', xLabels = ''; days.forEach((d, i) => { const x0 = PL + i * (barW + gap); @@ -825,7 +833,7 @@ async function loadFinance() { const hSpot = cH * d.spot_eur / maxVal; bars += ``; } - if (i % Math.max(1, Math.floor(n / 8)) === 0) { + if (i % labelStep === 0) { const label = d.date.slice(5); xLabels += `${label}`; } @@ -838,10 +846,11 @@ async function loadFinance() {
Kosten je Tag
- + ${gridLines}${yLabels}${bars}${xLabels}${legend}
+ ${n > 60 ? `
← Horizontal scrollbar, ${n} Tage
` : ''}
`; el.innerHTML = `
${empfehlung}${cards}${chartSection}
`;