Dashboard: Doppelungen zusammengelegt, Lade- und Renderlast gesenkt
Zusammenlegung
- Die sechs Endpunkte getConsData_/getProdData_{month,year,decade}.php sind
ajax/energyHistory.php?series=&range= gewichen, der gemeinsame Aufbau der
Chart-Daten steht in ajax/chartData.php. Die erzeugte SQL wurde gegen alle
sechs Originale abgeglichen.
- Die 13 Raeume der Home-Ansicht stehen nur noch in restricted/rooms.php.
home.php rendert die SVG-Kacheln daraus, homeMQTT.js bekommt dieselbe
Tabelle als JSON (346 -> 222 bzw. 428 -> 197 Zeilen).
- Gemeinsame JS-Helfer in js/solar/common.js; geteilte Bausteine fuer
Wetterkacheln, Chart-Skripte und das Formular der Ladesteuerung.
- Seitenvorlagen sind jetzt .php und werden eingebunden, statt per
file_get_contents zusammengesetzt zu werden.
Fehlerbehebungen
- ?action=weather fuehrte auf eine leere Seite, es gibt jetzt weather.php.
- homeMQTT.js griff auf ein #meteogram zu, das home.php nie hatte, und brach
damit den readystatechange-Handler ab.
- Die Heizungsseite abonnierte weatherStation/#, zeigte die Werte aber nie an.
Ladelast
- Chart.js, MQTT und Meteogramm werden nur noch auf den Seiten geladen, die
sie brauchen; die Seitentabelle dafuer steht in index.php.
- mqtt.js durch die minifizierte Fassung ersetzt (859 -> 359 KB). MQTT.js
5.14.1, byte-identisch mit dem signierten npm-Tarball.
- Rund 3,1 MB ungenutzte Vendor-Reste und AdminLTE-Demobilder entfernt.
- Solar 1796 -> 1240 KB, Home 1796 -> 873 KB, Historie 1796 -> 843 KB.
Speicher im Browser
- Chart.defaults.devicePixelRatio auf 1.5 gedeckelt. Die Zeichenpuffer der
Diagramme waren mit 20-45 MB der groesste Posten der Seite.
- Das Meteogramm-iframe laedt erst beim Hinscrollen.
Realtime-SVG
- Filterbereiche auf das noetige Mass verkleinert und den wirkungslosen
feOffset-Durchgang entfernt: 60 % weniger gerasterte Filterflaeche bei
pixelgleichem Ergebnis.
- Die Fluss-Animation laeuft ueber transform statt stroke-dashoffset, mit
Punkten statt Strichmuster; sie ruht, wo kein Fluss anliegt.
- Der Wertupdate schreibt nur noch bei echter Aenderung und benutzt
textContent statt innerHTML: 9 statt 86 Elemente pro Update, davon keines
mit Filter. describeArc rundet auf volle Grad.
- waterInfo auf scale(0.90) wie die uebrigen Info-Gruppen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+50
-44
@@ -1,21 +1,30 @@
|
||||
<style>
|
||||
.stream{
|
||||
animation: stream 2s steps(40) infinite;
|
||||
/* Fluss-Animation als transform statt stroke-dashoffset.
|
||||
stroke-dashoffset ist nicht kompositierbar - jede Stufe kostete einen
|
||||
Neuzeichenvorgang auf dem Hauptthread. Ein transform kann der Compositor
|
||||
dagegen selbst verschieben.
|
||||
Die Punkte laufen eine Periode (111 Einheiten) weit, danach steht der
|
||||
naechste an derselben Stelle - der Zyklus schliesst nahtlos.
|
||||
--dx/--dy stehen pro Linie im style-Attribut, --w setzt setFlowWidth().
|
||||
steps(40) = 20 Bewegungen pro Sekunde, wie in der urspruenglichen
|
||||
Fassung. Das deckelt die Neuzeichnungen fuer den Fall, dass der Browser
|
||||
das transform doch nicht kompositiert; auf dem Compositor kostet die
|
||||
Stufung nichts. Fuer volle Fluessigkeit: linear statt steps(40). */
|
||||
.stream, .stream-rev {
|
||||
animation: flow 2s steps(40) infinite;
|
||||
}
|
||||
@keyframes stream {
|
||||
100%{
|
||||
stroke-dashoffset: -110;
|
||||
.stream-rev {
|
||||
animation-direction: reverse;
|
||||
}
|
||||
}
|
||||
.stream-rev{
|
||||
animation: stream-rev 2s steps(40) infinite;
|
||||
@keyframes flow {
|
||||
to { transform: translate(var(--dx), var(--dy)); }
|
||||
}
|
||||
@keyframes stream-rev {
|
||||
100%{
|
||||
stroke-dashoffset: 110;
|
||||
.stream circle, .stream-rev circle {
|
||||
r: calc(var(--w, 0px) / 2);
|
||||
fill: gray;
|
||||
}
|
||||
}
|
||||
.powerTextClass {
|
||||
|
||||
.powerTextClass {
|
||||
font-size: 27px;
|
||||
font-family: sans-serif;
|
||||
text-anchor: middle;
|
||||
@@ -63,6 +72,16 @@
|
||||
<feMergeNode in="SourceGraphic" />
|
||||
</feMerge>
|
||||
</filter>
|
||||
<clipPath id="clip_consOGani"><rect x="-30" y="-30" width="404.4" height="60" transform="translate(770.0,380.0) rotate(-64.1790)"/></clipPath>
|
||||
<clipPath id="clip_consAni"><rect x="-30" y="-30" width="400.0" height="60" transform="translate(430.0,380.0) rotate(0.0000)"/></clipPath>
|
||||
<clipPath id="clip_consEGani"><rect x="-30" y="-30" width="386.5" height="60" transform="translate(770.0,380.0) rotate(62.6501)"/></clipPath>
|
||||
<clipPath id="clip_consUGani"><rect x="-30" y="-30" width="396.2" height="60" transform="translate(770.0,380.0) rotate(120.3791)"/></clipPath>
|
||||
<clipPath id="clip_consHeatAni"><rect x="-30" y="-30" width="410.0" height="60" transform="translate(770.0,380.0) rotate(0.0000)"/></clipPath>
|
||||
<clipPath id="clip_consEVani"><rect x="-30" y="-30" width="360.0" height="60" transform="translate(920.0,670.0) rotate(0.0000)"/></clipPath>
|
||||
<clipPath id="clip_consEVOGani"><rect x="-30" y="-30" width="360.0" height="60" transform="translate(920.0,70.0) rotate(0.0000)"/></clipPath>
|
||||
<clipPath id="clip_consGridani"><rect x="-30" y="-30" width="390.0" height="60" transform="translate(100.0,380.0) rotate(0.0000)"/></clipPath>
|
||||
<clipPath id="clip_pvani"><rect x="-30" y="-30" width="413.6" height="60" transform="translate(180.0,130.0) rotate(45.0000)"/></clipPath>
|
||||
<clipPath id="clip_battani"><rect x="-30" y="-30" width="413.6" height="60" transform="translate(180.0,630.0) rotate(-45.0000)"/></clipPath>
|
||||
</defs>
|
||||
<g opacity="0">
|
||||
<animate begin="lastInitAni.end" attributetype="CSS" attributeName="opacity" from="0.0" to="1.0"
|
||||
@@ -81,44 +100,34 @@
|
||||
+500 -300 (center +90 in x und y)
|
||||
-->
|
||||
<line x1="770" y1="380" x2="920" y2="70" style="stroke:#777;stroke-width:2;stroke-dasharray:1,6;" />
|
||||
<line id="consOGani" class="stream" x1="770" y1="380" x2="920" y2="70" stroke-linecap="round"
|
||||
stroke-width="0" stroke="gray" stroke-dasharray="1,110" />
|
||||
<g clip-path="url(#clip_consOGani)"><g id="consOGani" class="stream" style="--dx:48.347px;--dy:-99.918px"><circle cx="721.7" cy="479.9"/><circle cx="770.0" cy="380.0"/><circle cx="818.3" cy="280.1"/><circle cx="866.7" cy="180.2"/><circle cx="915.0" cy="80.2"/><circle cx="963.4" cy="-19.7"/></g></g>
|
||||
|
||||
<line x1="430" y1="380" x2="770" y2="380" style="stroke:#777;stroke-width:2;stroke-dasharray:1,6;" />
|
||||
<line id="consAni" class="stream" x1="430" y1="380" x2="770" y2="380" stroke-linecap="round"
|
||||
stroke-width="0" stroke="gray" stroke-dasharray="1,110" />
|
||||
<g clip-path="url(#clip_consAni)"><g id="consAni" class="stream" style="--dx:111.000px;--dy:0.000px"><circle cx="319.0" cy="380.0"/><circle cx="430.0" cy="380.0"/><circle cx="541.0" cy="380.0"/><circle cx="652.0" cy="380.0"/><circle cx="763.0" cy="380.0"/><circle cx="874.0" cy="380.0"/></g></g>
|
||||
|
||||
<line x1="770" y1="380" x2="920" y2="670" style="stroke:#777;stroke-width:2;stroke-dasharray:1,6;" />
|
||||
<line id="consEGani" class="stream" x1="770" y1="380" x2="920" y2="670" stroke-linecap="round"
|
||||
stroke-width="0" stroke="gray" stroke-dasharray="1,110" />
|
||||
<g clip-path="url(#clip_consEGani)"><g id="consEGani" class="stream" style="--dx:50.996px;--dy:98.592px"><circle cx="719.0" cy="281.4"/><circle cx="770.0" cy="380.0"/><circle cx="821.0" cy="478.6"/><circle cx="872.0" cy="577.2"/><circle cx="923.0" cy="675.8"/></g></g>
|
||||
|
||||
<line x1="770" y1="380" x2="600" y2="670" style="stroke:#777;stroke-width:2;stroke-dasharray:1,6;" />
|
||||
<line id="consUGani" class="stream" x1="770" y1="380" x2="600" y2="670" stroke-linecap="round"
|
||||
stroke-width="0" stroke="gray" stroke-dasharray="1,110" />
|
||||
<g clip-path="url(#clip_consUGani)"><g id="consUGani" class="stream" style="--dx:-56.135px;--dy:95.759px"><circle cx="826.1" cy="284.2"/><circle cx="770.0" cy="380.0"/><circle cx="713.9" cy="475.8"/><circle cx="657.7" cy="571.5"/><circle cx="601.6" cy="667.3"/><circle cx="545.5" cy="763.0"/></g></g>
|
||||
|
||||
<line x1="770" y1="380" x2="1120" y2="380" style="stroke:#777;stroke-width:2;stroke-dasharray:1,6;" />
|
||||
<line id="consHeatAni" class="stream" x1="770" y1="380" x2="1120" y2="380" stroke-linecap="round"
|
||||
stroke-width="0" stroke="gray" stroke-dasharray="1,110" />
|
||||
<g clip-path="url(#clip_consHeatAni)"><g id="consHeatAni" class="stream" style="--dx:111.000px;--dy:0.000px"><circle cx="659.0" cy="380.0"/><circle cx="770.0" cy="380.0"/><circle cx="881.0" cy="380.0"/><circle cx="992.0" cy="380.0"/><circle cx="1103.0" cy="380.0"/><circle cx="1214.0" cy="380.0"/></g></g>
|
||||
|
||||
<line x1="920" y1="670" x2="1220" y2="670" style="stroke:#777;stroke-width:2;stroke-dasharray:1,6;" />
|
||||
<line id="consEVani" class="stream" x1="920" y1="670" x2="1220" y2="670" stroke-linecap="round"
|
||||
stroke-width="0" stroke="gray" stroke-dasharray="1,110" />
|
||||
<g clip-path="url(#clip_consEVani)"><g id="consEVani" class="stream" style="--dx:111.000px;--dy:0.000px"><circle cx="809.0" cy="670.0"/><circle cx="920.0" cy="670.0"/><circle cx="1031.0" cy="670.0"/><circle cx="1142.0" cy="670.0"/><circle cx="1253.0" cy="670.0"/></g></g>
|
||||
|
||||
<line x1="920" y1="70" x2="1220" y2="70" style="stroke:#777;stroke-width:2;stroke-dasharray:1,6;" />
|
||||
<line id="consEVOGani" class="stream" x1="920" y1="70" x2="1220" y2="70" stroke-linecap="round"
|
||||
stroke-width="0" stroke="gray" stroke-dasharray="1,110" />
|
||||
<g clip-path="url(#clip_consEVOGani)"><g id="consEVOGani" class="stream" style="--dx:111.000px;--dy:0.000px"><circle cx="809.0" cy="70.0"/><circle cx="920.0" cy="70.0"/><circle cx="1031.0" cy="70.0"/><circle cx="1142.0" cy="70.0"/><circle cx="1253.0" cy="70.0"/></g></g>
|
||||
|
||||
<line x1="100" y1="380" x2="430" y2="380" style="stroke:#777;stroke-width:2;stroke-dasharray:1,6;" />
|
||||
<line id="consGridani" class="stream" x1="100" y1="380" x2="430" y2="380" stroke-linecap="round"
|
||||
stroke-width="0" stroke="gray" stroke-dasharray="1,110" />
|
||||
<g clip-path="url(#clip_consGridani)"><g id="consGridani" class="stream" style="--dx:111.000px;--dy:0.000px"><circle cx="-11.0" cy="380.0"/><circle cx="100.0" cy="380.0"/><circle cx="211.0" cy="380.0"/><circle cx="322.0" cy="380.0"/><circle cx="433.0" cy="380.0"/></g></g>
|
||||
|
||||
<line x1="180" y1="130" x2="430" y2="380" style="stroke:#777;stroke-width:2;stroke-dasharray:1,6;" />
|
||||
<line id="pvani" class="stream" x1="180" y1="130" x2="430" y2="380" stroke-linecap="round"
|
||||
stroke-width="0" stroke="gray" stroke-dasharray="1,110" />
|
||||
<g clip-path="url(#clip_pvani)"><g id="pvani" class="stream" style="--dx:78.489px;--dy:78.489px"><circle cx="101.5" cy="51.5"/><circle cx="180.0" cy="130.0"/><circle cx="258.5" cy="208.5"/><circle cx="337.0" cy="287.0"/><circle cx="415.5" cy="365.5"/><circle cx="494.0" cy="444.0"/></g></g>
|
||||
|
||||
<line x1="180" y1="630" x2="430" y2="380" style="stroke:#777;stroke-width:2;stroke-dasharray:1,6;" />
|
||||
<line id="battani" class="stream" x1="180" y1="630" x2="430" y2="380" stroke-linecap="round"
|
||||
stroke-width="0" stroke="gray" stroke-dasharray="1,110" />
|
||||
<g clip-path="url(#clip_battani)"><g id="battani" class="stream" style="--dx:78.489px;--dy:-78.489px"><circle cx="101.5" cy="708.5"/><circle cx="180.0" cy="630.0"/><circle cx="258.5" cy="551.5"/><circle cx="337.0" cy="473.0"/><circle cx="415.5" cy="394.5"/><circle cx="494.0" cy="316.0"/></g></g>
|
||||
|
||||
</g>
|
||||
</svg>
|
||||
@@ -127,21 +136,18 @@
|
||||
style="position:absolute;top:0;"
|
||||
viewBox="-100 -100 1600 950" width="100%" height="100%" id="realtimeSvg">
|
||||
<defs>
|
||||
<filter id="shadow" x="-0.5" y="-0.5" width="200%" height="200%">
|
||||
<feOffset result="offOut" in="SourceAlpha" dx="0" dy="0" />
|
||||
<feMorphology in="offOut" result="offOut" operator="dilate" radius="0.7" />
|
||||
<filter id="shadow" x="-0.3" y="-0.3" width="160%" height="160%">
|
||||
<feMorphology in="SourceAlpha" result="offOut" operator="dilate" radius="0.7" />
|
||||
<feGaussianBlur result="blurOut" in="offOut" stdDeviation="0.5" />
|
||||
<feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
|
||||
</filter>
|
||||
<filter id="shadowMiddle" x="-1.0" y="-1.0" width="300%" height="300%">
|
||||
<feOffset result="offOut" in="SourceAlpha" dx="0" dy="0" />
|
||||
<feMorphology in="offOut" result="offOut" operator="dilate" radius="3" />
|
||||
<filter id="shadowMiddle" x="-0.4" y="-0.4" width="180%" height="180%">
|
||||
<feMorphology in="SourceAlpha" result="offOut" operator="dilate" radius="3" />
|
||||
<feGaussianBlur result="blurOut" in="offOut" stdDeviation="1" />
|
||||
<feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
|
||||
</filter>
|
||||
<filter id="shadowBig" x="-1" y="-1" width="300%" height="300%">
|
||||
<feOffset result="offOut" in="SourceAlpha" dx="0" dy="0" />
|
||||
<feMorphology in="offOut" result="offOut" operator="dilate" radius="3" />
|
||||
<filter id="shadowBig" x="-0.45" y="-0.45" width="190%" height="190%">
|
||||
<feMorphology in="SourceAlpha" result="offOut" operator="dilate" radius="3" />
|
||||
<feGaussianBlur result="offOut" in="offOut" stdDeviation="2" />
|
||||
<feBlend in="SourceGraphic" in2="offOut" mode="normal" />
|
||||
</filter>
|
||||
@@ -581,7 +587,7 @@
|
||||
style='display:none;mix-blend-mode: difference;fill:#70CCBB;' href="#heater" />
|
||||
</g>
|
||||
|
||||
<g transform="translate(330,280), scale(0.70,0.70)" id="waterInfo" class="clickable" onclick="openModal('watering')">
|
||||
<g transform="translate(330,280), scale(0.90,0.90)" id="waterInfo" class="clickable" onclick="openModal('watering')">
|
||||
<animateMotion begin="0.5s" dur=".7s" repeatCount="1" calcMode="spline" keyTimes="0;1"
|
||||
keySplines=".1,0,.27,1" path="M0 0 L340 0" fill="freeze" />
|
||||
<animateMotion begin="1.2s" dur=".7s" repeatCount="1" calcMode="spline" keyTimes="0;1"
|
||||
@@ -591,7 +597,7 @@
|
||||
d="M 99.863863 22.00012 A 78 78 0 1 0 100 22" />
|
||||
<use href="#water" transform="translate(60,55), scale(0.20,0.20)" fill="#3A6292" />
|
||||
<!-- Wasserstand und Temperatur werden von der Bewässerungssteuerung nicht unterstützt.
|
||||
<text id="waterText" filter="url(#shadowMiddle)" class="powerTextClass" text-anchor="middle" x="100" y="55">--.- cm</text>
|
||||
<text id="waterText" filter="url(#shadowMiddle)" class="powerTextClass" text-anchor="middle" x="100" y="55">-.- cm</text>
|
||||
<text id="waterTemp" filter="url(#shadowMiddle)" class="powerTextClass" text-anchor="middle" x="100" y="88">-.- °C</text>
|
||||
-->
|
||||
<use id="wateringFrontIcon" href="#gardenPlantIcon" transform="translate(152,162),rotate(310),scale(1.3)" fill="#6c757d" color="#6c757d">
|
||||
|
||||
Reference in New Issue
Block a user