diff --git a/haos-addon/config.yaml b/haos-addon/config.yaml
index 3b57775..363a7ca 100644
--- a/haos-addon/config.yaml
+++ b/haos-addon/config.yaml
@@ -1,5 +1,5 @@
name: ShineBridge
-version: "1.9.2"
+version: "1.9.3"
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 1971683..5cf278e 100644
--- a/haos-addon/src/web/index.html
+++ b/haos-addon/src/web/index.html
@@ -798,11 +798,11 @@ async function loadFinance() {
// ── SVG-Balkendiagramm ────────────────────────────────────────
// Bei langen Abrechnungsjahren nicht jeden einzelnen Tag zeigen — statt 112
- // Tagesbalken lieber ~16 Wochenbalken, deutlich lesbarer und trotzdem
- // aussagekräftig für "würde sich Spot lohnen".
+ // Tagesbalken lieber Wochenbalken, und davon nur die letzten 14 (reicht für
+ // einen Trend, bleibt aber lesbar statt endlos zu scrollen).
const rawN = days.length;
const bucket = rawN > 180 ? 14 : rawN > 21 ? 7 : 1;
- const periods = bucket === 1 ? days.map(d => ({
+ const allPeriods = bucket === 1 ? days.map(d => ({
fixed_eur: d.fixed_eur, spot_eur: d.spot_eur, label: d.date.slice(5),
})) : (() => {
const out = [];
@@ -811,21 +811,24 @@ async function loadFinance() {
const fixed = chunk.reduce((s, d) => s + (d.fixed_eur || 0), 0);
const spotVals = chunk.map(d => d.spot_eur).filter(v => v != null);
const spot = spotVals.length ? spotVals.reduce((a, b) => a + b, 0) : null;
- const from = chunk[0].date.slice(5), to = chunk[chunk.length - 1].date.slice(5);
- out.push({ fixed_eur: fixed, spot_eur: spot, label: from === to ? from : `${from}–${to}` });
+ out.push({ fixed_eur: fixed, spot_eur: spot, label: chunk[0].date.slice(5) });
}
return out;
})();
+ const MAX_PERIODS = 14;
+ const periods = allPeriods.slice(-MAX_PERIODS);
+ // Echtes responsives SVG: viewBox in einer "Mobile-first"-Breite, skaliert per
+ // width:100% frei auf den Container (Handy wie PC) — kein Scrollen mehr nötig,
+ // da wir uns auf max. 14 Balken begrenzen.
const n = periods.length;
- const H = 190, PL = 44, PR = 12, PT = 14, PB = 30;
- const MIN_SLOT = 34; // px pro Balkenpaar — bewusst großzügig, jetzt wo wenige Balken übrig sind
- const W = Math.max(600, PL + PR + n * MIN_SLOT);
+ const W = 380, H = 220, PL = 40, PR = 8, PT = 14, PB = 46;
const cW = W - PL - PR;
const cH = H - PT - PB;
const slot = cW / n;
- const barW = Math.min(22, Math.max(4, slot * 0.34));
- const barGap = Math.max(2, slot * 0.06);
+ const barW = Math.max(3, slot * 0.36);
+ const barGap = Math.max(1.5, slot * 0.08);
+ const rBar = Math.min(2.5, barW / 2);
const allVals = periods.flatMap(d => [d.fixed_eur, d.spot_eur].filter(v => v != null));
const maxVal = Math.max(...allVals, 0.01);
@@ -835,12 +838,12 @@ async function loadFinance() {
for (let i = 0; i <= yTicks; i++) {
const v = maxVal * i / yTicks;
const y = PT + cH - (cH * i / yTicks);
- gridLines += `