98_SVG.pm: Autoskalierung für Abszisse

Begonnen von Dr. Boris Neubert, 05 Februar 2017, 15:53:33

Vorheriges Thema - Nächstes Thema

Dr. Boris Neubert

Hallo,

wenn man in einem SVG-Plot auf der Abszisse nicht die Uhrzeit stehen haben möchte sondern eine andere Größe, muss man in der .gplot-Datei eine xrange-Direktive einfügen. Das ist z.B. der Fall bei xy-Plots mit Hilfe vom logProxy.

xrange lässt aber keine automatische Skalierung/Auswahl des Viewport zu. Wenn man xrange [:] angibt, knallt es in Zeile 1474 (r13329). Meiner Auffassung nach würde es genügen, hinter Zeilen 1421ff

  my ($xmin, $xmax, $xtics);
  if($conf{xrange} && $conf{xrange} =~ /\[(.*):(.*)\]/) {
    $xmin = $1 if($1 ne "");
    $xmax = $2 if($2 ne "");
  }


noch den minimalen und/oder maximalen Wert aus der Datenmenge herauszusuchen, falls $xmin bzw. $xmax leer sind.

Ich stelle gerne einen getesteten Patch zur Verfügung. Brauche aber bitte eine kurze Info, wo ich die x-Werte finde, und ob es beachtenswerte Punkte gibt.

Viele Grüße
Boris
Globaler Moderator, Developer, aktives Mitglied des FHEM e.V. (Marketing, Verwaltung)
Bitte keine unaufgeforderten privaten Nachrichten!

rudolfkoenig

Das Wort Abszisse habe ich zuletzt in der Schule gehoert, das weckt Erinnerungen :)
Wo man die X-Werte findet, kann (ohne Code-Studium) vmtl. nur andre beantworten.

justme1968

#2
hallo boris,

der knackpunkt ist das SVG eigentlich nichts von den x-werten kennt. anders als der normale plot der tatsächlich direkt auf dem daten array arbeitet ist der 2d mode und auch der polar mode nur als 'krücke' auf den normalen mode aufgepropft und erzeugt mehr oder weniger direkt svg plot anweisungen. dazu ist zwingend nötig das die skalierung vorher schon bekannt ist. alles andere hätte einen kompletten SVG umbau bedeutet.


ich habe mal in logProxy eingebaut das hier beim erstellen des plots die extrema in x richtung mit bestimmt und in $data{xminN} und $data{xmaxN} abgelegt werden.

diese kannst du dann in der perl code version von xrange etwa so verwenden:set xrange {"[".($data{xmin2}-1).":".($data{xmax2}+1)."]"}

wenn das funktioniert kannst du das bitte noch an der von dir vorgeschlagenen stelle in SVG einbauen und schauen ob auch das geht?

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

Dr. Boris Neubert

Danke Andre, das werde ich am Wochenende ausprobieren.

Was bitte ist die Perl-Code-Version von xrange?

Warum habe ich an der von mir bezeichneten Stellle im SVG-Modul die x-Werte nicht? Ich plotte die doch, oder liefert der logproxy schon Pixelkoordinaten?

Globaler Moderator, Developer, aktives Mitglied des FHEM e.V. (Marketing, Verwaltung)
Bitte keine unaufgeforderten privaten Nachrichten!

justme1968

xrange darf auch ein perl ausdruck sein der einen string im erwarteten format zurück gibt. das ganze ist im laufe dieses threads: https://forum.fhem.de/index.php/topic,25618.msg457512.html#msg457512 entstanden um in plots oben und unten dynamische abstände lassen zu können.

die schnittstelle zwischen logProxy und SVG sind in diesem fall nicht die (x/y) koordinaten der punkte sondern 'spezielle' zeilen die dann direkt in svg befehle umgesetzt werden. die x-werte sind zwar theoretisch noch da, aber aus der plot anweisung ist nicht mehr ersichtlich das es mal eine xy koordinate war. d.h. die operation rückwärts ist nicht eindeutig da die plot anweisung auch andere ursachen haben kann.

wie gesagt: SVG hat einige sehr tief eingebaute annahmen (wie z.b. auch es einen zeitraum gibt durch den man vorwärts und rückwärts sollen kann, das man zoomen kann,...) die für 2d & co nicht passen. alles komplett umzubauen wäre aber ein riesen aufwand.

deshalb setzen fast alle logProxy features eine ebene tiefer direkt auf svg plot kommandos wie line ziehen, marker und text setzen, pfad schliessen,... mit eigener koordinaten berechnung auf. ein bisschen wie ganz altmodische plotter ansteuerung von hand.





hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

Dr. Boris Neubert

Hallo,

ich verstehe es noch nicht.

Ich habe in der .gplot-Datei jetzt

set xrange {"[".$data{xmin2}.":".$data{xmax2}."]"}

stehen. Warum die 2 hinter xmin? Ich habe drei Kurven, die ich in einem Graph plotten will, und ich brauche den minimalen bzw. maximalen x-Wert aller drei Kurven. Rund um Zeile 1422 in 98_SVG.pm gibt es auch nur  $xmin und $xmax.

Wenn ich den xrange-Eintrag wie oben verwende, zertrümmert es mir FHEM mit
2017.02.11 10:49:47 1: PERL WARNING: Argument "".$data{xmax2}."" isn't numeric in subtraction (-) at /users/neubert/Development/Perl/fhem/FHEM/98_SVG.pm line 1474.
2017.02.11 10:49:47 1: stacktrace:
2017.02.11 10:49:47 1:     main::__ANON__                      called by /users/neubert/Development/Perl/fhem/FHEM/98_SVG.pm (1474)
2017.02.11 10:49:47 1:     main::SVG_render                    called by /users/neubert/Development/Perl/fhem/FHEM/98_SVG.pm (1134)
2017.02.11 10:49:47 1:     main::SVG_doShowLog                 called by /users/neubert/Development/Perl/fhem/FHEM/98_SVG.pm (1023)
2017.02.11 10:49:47 1:     main::SVG_showLog                   called by /users/neubert/Development/Perl/fhem/FHEM/01_FHEMWEB.pm (849)
2017.02.11 10:49:47 1:     main::FW_answerCall                 called by /users/neubert/Development/Perl/fhem/FHEM/01_FHEMWEB.pm (521)
2017.02.11 10:49:47 1:     main::FW_Read                       called by /users/neubert/Development/Perl/fhem/fhem.pl (3304)
2017.02.11 10:49:47 1:     main::CallFn                        called by /users/neubert/Development/Perl/fhem/fhem.pl (674)
Illegal division by zero at /users/neubert/Development/Perl/fhem/FHEM/98_SVG.pm line 1474.


Viele Grüße
Boris
Globaler Moderator, Developer, aktives Mitglied des FHEM e.V. (Marketing, Verwaltung)
Bitte keine unaufgeforderten privaten Nachrichten!

justme1968

2 steht hier für die zweite kurve. schau mal in der commandref unter SVG  label. dort sind min, max, mindate, maxdate, avg, cnt, sum, firstval, ... bescrhieben. mit dem patch kommt einfach noch xmin und xmax dazu.

wenn du die extreme über alle drei kurven brauchst kannst du die im ausdruck mit minNum und maxNum bestimmen.

kannst du bitte den plot mal ohne die dynamische xrange zeile erstellen und mit {Dumper \%data} schauen ob die xmin und xmax werte in %data landen? oder durch eine log ausgabe am ende von logProxy_xy2Plot.

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

Dr. Boris Neubert

Hallo Andre,

Zitat von: justme1968 am 11 Februar 2017, 11:08:03
kannst du bitte den plot mal ohne die dynamische xrange zeile erstellen und mit {Dumper \%data} schauen ob die xmin und xmax werte in %data landen? oder durch eine log ausgabe am ende von logProxy_xy2Plot.

xmin1 bis xmax3 stehen im %data-Hash.

Bist Du Dir sicher, dass man in der .gplot-Datei hinter xrange einen Perl-Ausdruck angeben kann?

set xrange { "[0:" . $data{xmax1} . "]" }

gibt nämlich

2017.02.11 17:08:19 1: PERL WARNING: Argument "" . $data{xmax1} . "" isn't numeric in subtraction (-) at /users/neubert/Development/Perl/fhem/FHEM/98_SVG.pm line 1474.

gefolgt vom Tod:

Illegal division by zero at /users/neubert/Development/Perl/fhem/FHEM/98_SVG.pm line 1474.

Habe jedenfalls nicht die Code-Passage gefunden, wo der Perl-Ausdruck bei xrange ausgewertet würde.

Ich glaube ja immer noch, dass ich die xmin/xmax-Werte bei Zeile 1422 in SVG_render() einwerfen muss, aber mir erschließt sich nicht, wie ganzen Funktionen ineinander greifen.

Viele Grüße
Boris
Globaler Moderator, Developer, aktives Mitglied des FHEM e.V. (Marketing, Verwaltung)
Bitte keine unaufgeforderten privaten Nachrichten!

justme1968

hallo boris,

ZitatBist Du Dir sicher, dass man in der .gplot-Datei hinter xrange einen Perl-Ausdruck angeben kann?
du hast recht. das scheint das aktuelle problem zu sein. die möglichkeit für yrangeX einen perl ausdruck zu verwenden hatte ich garnicht nicht für xrange übernommen.

für yrange passiert das in zeile 1657. für xrange muss analog dazu nach zeile 1420 das hier eingefügt werden:$conf{xrange} = AnalyzeCommand(undef, $1) if($conf{xrange} =~ /^({.*})$/);

wenn das dann funktioniert kann man das automatische setzen in einen else zweig des folgenden if stecken und dazu die extrem werte über alle kurven bestimmt.

unabhängig davon wäre es vermutlich gut die beiden if( $conf{xrange}} in zeile 1474 folgende in ein  $xmax-$xmin > 0 zu ändern damit bei einiger falsch eingabe fhem nicht gleich abschmiert.

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

Dr. Boris Neubert

Top! Nun habe ich es hinbekommen.

Anbei der Patch für die aktualisierte Version, die
- für xrange Perl-Ausdrücke zulässt,
- bei set xrange [:] automatisch die Abszisse skaliert,
- bei mir keine WARNINGs ausgibt und
- nicht abstürzt.

Globaler Moderator, Developer, aktives Mitglied des FHEM e.V. (Marketing, Verwaltung)
Bitte keine unaufgeforderten privaten Nachrichten!

rudolfkoenig


Dr. Boris Neubert

Danke.

Off-topic: habe mich in den letzten Wochen aus Anwendersicht mit SVG auseinandergesetzt und mich sehr schwer getan. Die commandref fällt eher knapp aus und die Zerlegung in Modul-Referenz und Gnuplot-Syntax erschwert mein Verständnis zusätzlich. Konkret gelingt es mir bspw. nicht, eine gplot-Datei von Hand von Null aus zu erstellen. Vermutlich wären auch andere Anwender dankbar, wenn sich ein Freiwilliger findet, der SVG und das .gplot-Format gut kennt und die commandref überarbeitet.
Globaler Moderator, Developer, aktives Mitglied des FHEM e.V. (Marketing, Verwaltung)
Bitte keine unaufgeforderten privaten Nachrichten!