ShineBridge v1.9.5 — Finanzen-Chart: Container-Breite gemessen, Periodenanzahl passt sich an statt Balken aufzublasen
Statt die SVG per viewBox unbegrenzt mitwachsen zu lassen (wurde am Desktop riesig) oder sie bei einer festen max-width zu kappen (ließ rechts Leerraum), wird jetzt die tatsächliche Container-Breite gemessen und in echten Pixeln gerendert — Höhe bleibt dabei komplett unabhängig fix. Zusätzlich: auf breiten Screens werden mehr Wochen gezeigt statt derselben 14 Balken künstlich zu verbreitern (Zielbreite ~24px/Periode, min. 10, max. 28 Perioden) — nutzt den zusätzlichen Platz sinnvoll für mehr Historie statt für aufgeblähte Einzelbalken. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
name: ShineBridge
|
||||
version: "1.9.4"
|
||||
version: "1.9.5"
|
||||
slug: shinebridge
|
||||
description: Energiemanagement für Growatt/Goodwe-Wechselrichter — PV-Überschussladen, Wallbox-EMS, Tarifvergleich, Zigbee2MQTT-Überschussgeräte
|
||||
url: https://gitea.bitfire.work/retr0/shinebridge
|
||||
|
||||
@@ -798,8 +798,7 @@ async function loadFinance() {
|
||||
|
||||
// ── SVG-Balkendiagramm ────────────────────────────────────────
|
||||
// Bei langen Abrechnungsjahren nicht jeden einzelnen Tag zeigen — statt 112
|
||||
// Tagesbalken lieber Wochenbalken, und davon nur die letzten 14 (reicht für
|
||||
// einen Trend, bleibt aber lesbar statt endlos zu scrollen).
|
||||
// Tagesbalken lieber Wochenbalken.
|
||||
const rawN = days.length;
|
||||
const bucket = rawN > 180 ? 14 : rawN > 21 ? 7 : 1;
|
||||
const allPeriods = bucket === 1 ? days.map(d => ({
|
||||
@@ -815,18 +814,25 @@ async function loadFinance() {
|
||||
}
|
||||
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 W = 380, H = 220, PL = 40, PR = 8, PT = 14, PB = 46;
|
||||
// Container-Breite messen und die SVG in echten Pixeln in genau dieser Breite
|
||||
// zeichnen (keine viewBox-Skalierung mehr) — Höhe bleibt dabei fix, unabhängig
|
||||
// von der Breite. Statt auf breiten Screens dieselben 14 Balken künstlich
|
||||
// aufzublasen, wird stattdessen die Anzahl gezeigter Perioden an die Breite
|
||||
// angepasst — mehr Platz zeigt mehr Wochen, bei einer angenehmen Zielbreite
|
||||
// pro Balkenpaar (~46px), nicht überbreite Einzelbalken.
|
||||
const H = 240, PL = 40, PR = 8, PT = 14, PB = 46;
|
||||
const measuredW = el.clientWidth || 380;
|
||||
const W = Math.max(300, measuredW);
|
||||
const cW = W - PL - PR;
|
||||
const IDEAL_SLOT = 24; // px/Periode, entspricht dem Slot, der auf Handy-Breite gut aussah
|
||||
const maxPeriods = Math.min(28, Math.max(10, Math.round(cW / IDEAL_SLOT)));
|
||||
const periods = allPeriods.slice(-maxPeriods);
|
||||
|
||||
const n = periods.length;
|
||||
const cH = H - PT - PB;
|
||||
const slot = cW / n;
|
||||
const barW = Math.max(3, slot * 0.36);
|
||||
const barW = Math.max(3, Math.min(26, slot * 0.36));
|
||||
const barGap = Math.max(1.5, slot * 0.08);
|
||||
const rBar = Math.min(2.5, barW / 2);
|
||||
|
||||
@@ -869,7 +875,7 @@ async function loadFinance() {
|
||||
</defs>`;
|
||||
|
||||
const bucketLabel = bucket === 1 ? 'Tag' : bucket === 7 ? 'Woche' : '2 Wochen';
|
||||
const rangeNote = allPeriods.length > MAX_PERIODS ? ` · letzte ${n}` : '';
|
||||
const rangeNote = allPeriods.length > n ? ` · letzte ${n}` : '';
|
||||
const legend = `<div style="display:flex;gap:18px;margin-top:10px;font-size:11px;color:var(--text-dim)">
|
||||
<span style="display:inline-flex;align-items:center;gap:6px"><span style="width:10px;height:10px;border-radius:3px;background:${C.fixed};display:inline-block"></span>Festpreis</span>
|
||||
<span style="display:inline-flex;align-items:center;gap:6px"><span style="width:10px;height:10px;border-radius:3px;background:${C.spot};display:inline-block"></span>Spot (hypothetisch)</span>
|
||||
@@ -878,7 +884,7 @@ async function loadFinance() {
|
||||
const chartSection = `
|
||||
<div style="border-top:1px solid var(--border);padding-top:24px;margin-top:4px">
|
||||
<div style="font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.08em;color:var(--text-dim);margin-bottom:14px">Kosten je ${bucketLabel}${rangeNote}</div>
|
||||
<svg viewBox="0 0 ${W} ${H}" style="width:100%;max-width:640px;height:auto;display:block">
|
||||
<svg width="${W}" height="${H}" style="display:block">
|
||||
${defs}${gridLines}${yLabels}${bars}${xLabels}
|
||||
</svg>
|
||||
${legend}
|
||||
|
||||
Reference in New Issue
Block a user