FHEM Forum

FHEM => Frontends => TabletUI => Thema gestartet von: Thorsten Pferdekaemper am 20 März 2019, 22:02:16

Titel: Chart Widget: Endlosschleife wenn Max-Wert nicht in data-yticks
Beitrag von: Thorsten Pferdekaemper am 20 März 2019, 22:02:16
Hi,
Das Chart Widget produziert (nicht immer) eine Endlosschleife, wenn man data-yticks verwendet, aber der maximale Wert in den yticks kleiner ist als der Maximalwert der zugehörigen Achse (bzw. data-maxvalue).
Ein Beispiel dazu gibt es in folgendem Thread: https://forum.fhem.de/index.php?topic=98778. Im HTML sieht das dann so aus:

<div data-type="chart"
data-device='["ESPEasy_ESP_Easy_CO2SensorMHZ19","ESPEasy_ESP_Easy_CO2SensorMHZ19","ESPEasy_ESP_Easy_CO2SensorMHZ19"]'
data-logdevice='["esjaylog","esjaylog","esjaylog"]'
data-columnspec='["4:ESPEasy_ESP_Easy_CO2SensorMHZ19.PPM\\x3a::$fld[3]>1000?1000:$fld[3]","4:ESPEasy_ESP_Easy_CO2SensorMHZ19.PPM\\x3a::$fld[3]>1500?1500:$fld[3]","4:ESPEasy_ESP_Easy_CO2SensorMHZ19.PPM\\x3a::$fld[3]>2000?2000:$fld[3]"]'
data-timeranges='[["Letzte Stunde","1h","0h"],["3 Stunden","3h","0h"],["6 Stunden","6h","0h"],["12 Stunden","12h","0h"],["24 Stunden","24h","0h"],["Heute","0D","-1D"],["Gestern","1D","0D"],["Aktuelle Woche","0W","-1W"],["Vorherige Woche","1W","0W"],["Aktueller Monat","0M","-1M"],["Vorheriger Monat","1M","0M"],["Aktuelles Jahr","0Y","-1Y"],["Vorheriges Jahr","1Y","0Y"]]'
data-daysago_start="0D"
data-daysago_end="-1D"
data-nofulldays="false"
data-yticks='[[750,"good"],[1250,"ok"],[1750,"bad"]]'
data-style='["SVGplot fuipchart l1fill lwidth1","SVGplot fuipchart l4fill lwidth1","SVGplot fuipchart l0fill lwidth1"]'
data-ptype='["lines","lines","lines"]'
data-uaxis='["primary","primary","primary"]'
data-legend='["Luft gut","Luft ok","Luft schlecht"]'
data-minvalue="450"
data-maxvalue="2000"
data-minvalue_sec="450"
data-maxvalue_sec="2000"
data-title="<L1>"
data-title_class="fuipchart title fuip-color-foreground"
data-ytext="CO2 Wert"
data-ytext_sec=""
data-legendpos='["left","top"]'
data-width="100%" data-height="100%"
style="width:100%;height:calc(100% - 4px);">
</div>

Man kann das Problem umgehen, indem man immer auch den Maximalwert bei data-yticks angibt, aber unter Umständen kennt man den Maximalwert beim Anlegen des Charts noch gar nicht.

Ich habe das ganze mal etwas weiter analysiert und bin auf folgendes gestoßen (Zeile 3955 in widget_chart.js):

if ($.isArray(ytary)) {
yticks = (ytary.length && ytary.length > iyticks+1)?(($.isArray(ytary[iyticks])?ytary[iyticks+1][0]-ytary[iyticks][0]:ytary[iyticks+1]-ytary[iyticks])):yticks;
yticks = yticks * ((data.isPrimary(uaxis))?data.yLimits[AI].primary.scaleY:data.yLimits[AI].secondary.scaleY);

Mit yticks wird dann in Zeile 3911 eine for-Schleife hochgezählt. Blöderweise kann es vorkommen, dass yticks 0 wird. Das passiert meistens, wenn data.yLimits[AI].primary/secondary.scaleY (viel) kleiner als 1 ist und ytary (also data-yticks) keinen Eintrag größer oder gleich dem Maximalwert enthält. Dann bleibt nämlich yticks wegen der ersten "yticks-Zeile" gleich und wird dann in der zweiten Zeile verkleinert. Je nachdem, wie weit weg der letzte ytary-Eintrag vom Maximalwert ist und wie klein scaleY ist, kommt es dann zu einer Endlosschleife.
Außerdem erzeugt das ganze "seltsame" Zahlen am oberen Rand des Charts.

Ich habe bei mir das ganze folgendermaßen geändert (ab Zeile 3955 sieht es jetzt so aus):

if ($.isArray(ytary)) {
if (ytary[iyticks] && $.isArray(ytary[iyticks])) {
text.HTML2SVG(ytary[iyticks][1]);
} else {
text.HTML2SVG( widget_chart.formatTicksText(ysc,fix,data.getAxisSetting('yunit',uaxis),data.getAxisSetting('yticks_format',uaxis)));
}
// exit for loop if yticks array is "finished" now
if(iyticks+1 >= ytary.length)
break;
yticks = $.isArray(ytary[iyticks])?ytary[iyticks+1][0]-ytary[iyticks][0]:ytary[iyticks+1]-ytary[iyticks];
yticks = yticks * ((data.isPrimary(uaxis))?data.yLimits[AI].primary.scaleY:data.yLimits[AI].secondary.scaleY);
} else {

D.h. das ganze bricht ab, wenn es eine data-yticks (bzw. ytary) gibt, aber keine Einträge mehr zu verarbeiten sind. 

Vielleicht will das ja mal jemand im widget_chart.js ändern.

Gruß,
   Thorsten
Titel: Antw:Chart Widget: Endlosschleife wenn Max-Wert nicht in data-yticks
Beitrag von: eki am 21 März 2019, 08:01:56
Mit "jemand" meinst Du wahrscheinlich mich. Ich habe den Fehler eigentlich bei mir auch schon entdeckt und (anders) behoben, allerdings bin ich gerade dabei, einiges am Chart zu ändern (besseres Clipping, Zoomen und Schieben per Touch Gesten, ...), und da dauert es noch etwas bis ich wieder eine stabile Version habe. Ich schau mir Deine Lösung mal an (vor allem in Bezug auf Seiteneffekte) und werde dann entscheiden, ob ich sie nehme oder meine Variante lasse. Danke auf jeden Fall schon mal fürs Analysieren.
Titel: Antw:Chart Widget: Endlosschleife wenn Max-Wert nicht in data-yticks
Beitrag von: Thorsten Pferdekaemper am 21 März 2019, 09:52:36
Zitat von: eki am 21 März 2019, 08:01:56
Mit "jemand" meinst Du wahrscheinlich mich.
Ich wollte nur keine Annahme treffen, wer zurzeit der Maintainer für FTUI Chart ist. Aber ja, wahrscheinlich Du.

Zitat
Ich habe den Fehler eigentlich bei mir auch schon entdeckt und (anders) behoben, allerdings bin ich gerade dabei, einiges am Chart zu ändern (besseres Clipping, Zoomen und Schieben per Touch Gesten, ...), und da dauert es noch etwas bis ich wieder eine stabile Version habe. Ich schau mir Deine Lösung mal an (vor allem in Bezug auf Seiteneffekte) und werde dann entscheiden, ob ich sie nehme oder meine Variante lasse. Danke auf jeden Fall schon mal fürs Analysieren.
Kein Problem. Ich denke, dass die von mir vorgeschlagene Umgehungslösung in den meisten Fällen funktionieren dürfte.  In vielen Fällen könnte ich das sogar ggf. in FUIP automatisch machen, aber wir müssen uns ja die Arbeit nicht doppelt machen.
Wenn Du da sowieso einen größeren Wurf machst, könntest Du dann auch an der ein oder anderen Stelle das Coding ein bisschen besser modularisieren? Das Teil ist echt grausam zu debuggen, speziell drawChart hat mehr als 1500 Zeilen. Das ist schon heftigst unübersichtlich.
Übrigens ist die Variable "max" anscheinend ein Array und wird des Öfteren als Zahl verwendet (z.B. "y <= max"). Anscheinend funktioniert das irgendwie (JavaScript scheint da einfach max[0] zu verwenden), ich bin mir aber nicht sicher, ob das so gewollt ist.
Gruß,
   Thorsten
Titel: Antw:Chart Widget: Endlosschleife wenn Max-Wert nicht in data-yticks
Beitrag von: eki am 21 März 2019, 10:13:15
Danke für die Hinweise. Als ich damit angefangen habe, hatte ich Null JS und HTML/SVG Ahnung, daher schleppe ich ziemlich viel Müll und auch Dinge mit, die ich jetzt anders machen würde (wie üblich wenn man nicht von Anfang an weiß wohin es läuft, und die Software "wächst"). Ich blicke da immer noch ganz gut durch, aber für jemand Fremden ist das nicht so einfach, Respekt, dass Du Dich da überhaupt ran traust.

Ich schau mal was ich machen kann.
Titel: Antw:Chart Widget: Endlosschleife wenn Max-Wert nicht in data-yticks
Beitrag von: Thorsten Pferdekaemper am 22 März 2019, 08:54:06
Zitat von: eki am 21 März 2019, 10:13:15
Danke für die Hinweise. Als ich damit angefangen habe, hatte ich Null JS und HTML/SVG Ahnung,
Was JS (und HTML5) betrifft ging mir das ähnlich, als ich mit FUIP angefangen habe. ...aber davon darf man sich nicht abschrecken lassen. Alle Sprachen sind irgendwie gleich.

ZitatIch blicke da immer noch ganz gut durch, aber für jemand Fremden ist das nicht so einfach, Respekt, dass Du Dich da überhaupt ran traust.
Naja, so richtig mutig muss man dafür nicht sein, wenn man dann die tatsächliche Korrektur jemand anderem überlässt ;-)

Gruß,
   Thorsten
Titel: Antw:Chart Widget: Endlosschleife wenn Max-Wert nicht in data-yticks
Beitrag von: Thorsten Pferdekaemper am 03 Mai 2019, 15:55:59
Hi eki,
hat sich da inzwischen was ergeben mit der Endlosschleife?
...dann könnte ich nämlich ein Issue bei mir zumachen.
Danke&Gruß,
   Thorsten
Titel: Antw:Chart Widget: Endlosschleife wenn Max-Wert nicht in data-yticks
Beitrag von: eki am 09 Mai 2019, 14:13:37
Ich haben Deinen Vorschlag getestet und bei mir jetzt übernommen. Ich bin inhaltlich im Moment so weit, dass ich in den nächsten Tagen eine Neue Version zum Testen herausgeben kann (leider habe ich es noch nicht geschafft, das Thema "entschlacken" anzugehen, aber ich würde gern jetzt erst mal das inhaltlich Neue auf den Weg geben).
Aus meiner Sicht kannst Du das auf Deiner Seite mit der nächsten Chart Version schließen.