Ankündigung

Einklappen
Keine Ankündigung bisher.

Universeller XY-Plot

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    Universeller XY-Plot

    @wolfram: Mal so 'out of the blue' - wäre das nicht der Punkt, wo man mal über einen zeitunabhängigen, universellen Plot-Typ nachdenken sollte? Also einen Linien-/Balken-/Areaplot, in den ich zwar auch die Zeit als X-Achse reingeben kann, aber auch jede beliebige andere Einheit (Beispiele: Heatingcurve (°C zu °C), Comfortchart (°C zu rH))? Ich könnte mir gut vorstellen, dass es hier viele Anwendungsmöglichkeiten gibt ...
    /tom


    EDIT wvhn: Thread geteilt von https://knx-user-forum.de/forum/supp...42#post1716942
    Zuletzt geändert von wvhn; 09.01.2022, 20:40. Grund: Status gelöst gesetzt

    #2
    Tom Bombadil , Du meinst, wenn wir eh schon dabei sind?

    Also gut: ich hab aus dem plot.period ein zusätzliches plot.xyplot gemacht und dabei die meisten Optionen einfach mal drin gelassen. Das ganze ist nur sehr rudimentär mit einem einzigen XY-Plot getestet. Wenn Du Lust zum Spielen und Testen hast, bin ich auf Rückmeldungen gespannt.

    Die Dateien sind hier im Gist zu finden und sind zum aktuellen Stand des Develop kompatibel.

    Datenformat im List-item: Wertepaare [xWert, yWert].

    Gruß
    Wolfram
    Zuletzt geändert von wvhn; 12.12.2021, 08:21. Grund: Datenformat ergänzt.

    Kommentar


      #3
      (Vorweg: Hat etwas gedauert - mein Testsystem war noch auf 2.8, und da ich es seit fast einem Jahr nicht mehr verwendet habe, musste ich erstmal Xubuntu samt php & co auf den aktuellen Stand bringen, bevor ich an's SV-Update gehen konnte).

      Der XY-Plot scheint erstmal grundsätzlich zu funktionieren:

      Schritt 1: Plot auf meiner Seite "bastelecke.html' definiert:
      Code:
          {{ plot.xyplot('','zz_testitems.list1', 0, 2.5) }}
      Anmerkung: Hier bin ich das erste Mal auf die Nase gefallen - min/max der X-Achse sind Pflichtangaben. Etwas ungewöhnlich, aber vermutlich könnte man die sogar programmatisch aus der Liste ermitteln und optional machen.

      Schritt 2: zz_testitems.list1 mit der Kennlinie eines Solarmoduls im Admin-Interface befüllt:
      Code:
          [[0,0],[0.25,0.004],[1,0.02],[1.9,0.036],[2.3,0.026],[2.5,0.002]]
      Schritt 3: Ergebnis bestaunt (links unten):
      xyplot.png

      Soweit erstmal die allererste Rückmeldung, mehr konnte ich noch nicht testen. Danke nochmal!

      /tom

      Kommentar


        #4
        Die Autoskalierung habe ich noch nicht umgesetzt, aber es war noch ein Fehler im item update, der die Darstellung mehrerer Kurven verhindert hat.
        Das ist jetzt im oben verlinkten gist gefixt.

        Hier ein Beispiel mit exposure = ['spline','areaspline']

        Screenshot 2021-12-13.png

        Gruß
        Wolfram

        Kommentar


          #5
          So, Testszenario ist vorbereitet. Hab mich für die Heizkennlinien entschieden, da kann man schön vergleichen:

          Items:
          Code:
          zz_testitems:
          
              list01:
                  type: list
                  desc: 0.2
                  value: '[[-20,27.8],[-19,27.6],[-18,27.5],[-17,27.3],[-16,27.1],[-15,27],[-14,26.8],[-13,26.6],[-12,26.5],[-11,26.3],[-10,26.1],[-9,26],[-8,25.8],[-7,25.6],[-6,25.4],[-5,25.3],[-4,25.1],[-3,24.9],[-2,24.7],[-1,24.6],[0,24.4],[1,24.2],[2,24],[3,23.8],[4,23.6],[5,23.5],[6,23.3],[7,23.1],[8,22.9],[9,22.7],[10,22.5],[11,22.3],[12,22.1],[13,21.8],[14,21.6],[15,21.4],[16,21.2],[17,20.9],[18,20.7],[19,20.4],[20,20]]'
                  visu_acl: rw
          
              list02:
                  type: list
                  desc: 0.4
                  value: '[[-20,35.6],[-19,35.2],[-18,34.9],[-17,34.6],[-16,34.3],[-15,33.9],[-14,33.6],[-13,33.3],[-12,32.9],[-11,32.6],[-10,32.3],[-9,31.9],[-8,31.6],[-7,31.2],[-6,30.9],[-5,30.5],[-4,30.2],[-3,29.8],[-2,29.5],[-1,29.1],[0,28.8],[1,28.4],[2,28],[3,27.7],[4,27.3],[5,26.9],[6,26.5],[7,26.1],[8,25.7],[9,25.3],[10,24.9],[11,24.5],[12,24.1],[13,23.7],[14,23.2],[15,22.8],[16,22.3],[17,21.8],[18,21.3],[19,20.7],[20,20]]'
                  visu_acl: rw
                  
              list03:
                  type: list
                  desc: 0.6
                  value: '[[-20,43.3],[-19,42.8],[-18,42.4],[-17,41.9],[-16,41.4],[-15,40.9],[-14,40.4],[-13,39.9],[-12,39.4],[-11,38.9],[-10,38.4],[-9,37.9],[-8,37.4],[-7,36.8],[-6,36.3],[-5,35.8],[-4,35.3],[-3,34.8],[-2,34.2],[-1,33.7],[0,33.1],[1,32.6],[2,32],[3,31.5],[4,30.9],[5,30.4],[6,29.8],[7,29.2],[8,28.6],[9,28],[10,27.4],[11,26.8],[12,26.2],[13,25.5],[14,24.8],[15,24.2],[16,23.5],[17,22.7],[18,22],[19,21.1],[20,20]]'
                  visu_acl: rw
                  
              list04:
                  type: list
                  desc: 0.8
                  value: '[[-20,51.1],[-19,50.5],[-18,49.8],[-17,49.2],[-16,48.5],[-15,47.8],[-14,47.2],[-13,46.5],[-12,45.9],[-11,45.2],[-10,44.5],[-9,43.8],[-8,43.1],[-7,42.5],[-6,41.8],[-5,41.1],[-4,40.4],[-3,39.7],[-2,39],[-1,38.2],[0,37.5],[1,36.8],[2,36.1],[3,35.3],[4,34.6],[5,33.8],[6,33],[7,32.3],[8,31.5],[9,30.7],[10,29.9],[11,29],[12,28.2],[13,27.3],[14,26.5],[15,25.6],[16,24.6],[17,23.6],[18,22.6],[19,21.5],[20,20]]'
                  visu_acl: rw
                  
              list05:
                  type: list
                  desc: 1.0
                  value: '[[-20,58.9],[-19,58.1],[-18,57.3],[-17,56.4],[-16,55.6],[-15,54.8],[-14,54],[-13,53.2],[-12,52.3],[-11,51.5],[-10,50.6],[-9,49.8],[-8,48.9],[-7,48.1],[-6,47.2],[-5,46.3],[-4,45.5],[-3,44.6],[-2,43.7],[-1,42.8],[0,41.9],[1,41],[2,40.1],[3,39.1],[4,38.2],[5,37.3],[6,36.3],[7,35.3],[8,34.3],[9,33.3],[10,32.3],[11,31.3],[12,30.3],[13,29.2],[14,28.1],[15,26.9],[16,25.8],[17,24.6],[18,23.3],[19,21.8],[20,20]]'
                  visu_acl: rw
                  
              list06:
                  type: list
                  desc: 1.2
                  value: '[[-20,66.7],[-19,65.7],[-18,64.7],[-17,63.7],[-16,62.8],[-15,61.8],[-14,60.8],[-13,59.8],[-12,58.8],[-11,57.8],[-10,56.8],[-9,55.7],[-8,54.7],[-7,53.7],[-6,52.7],[-5,51.6],[-4,50.6],[-3,49.5],[-2,48.4],[-1,47.4],[0,46.3],[1,45.2],[2,44.1],[3,43],[4,41.8],[5,40.7],[6,39.6],[7,38.4],[8,37.2],[9,36],[10,34.8],[11,33.6],[12,32.3],[13,31],[14,29.7],[15,28.3],[16,26.9],[17,25.5],[18,23.9],[19,22.2],[20,20]]'
                  visu_acl: rw
                  
              list07:
                  type: list
                  desc: 1.4
                  value: '[[-20,74.4],[-19,73.3],[-18,72.2],[-17,71],[-16,69.9],[-15,68.7],[-14,67.6],[-13,66.4],[-12,65.2],[-11,64.1],[-10,62.9],[-9,61.7],[-8,60.5],[-7,59.3],[-6,58.1],[-5,56.9],[-4,55.7],[-3,54.4],[-2,53.2],[-1,51.9],[0,50.7],[1,49.4],[2,48.1],[3,46.8],[4,45.5],[5,44.2],[6,42.8],[7,41.5],[8,40.1],[9,38.7],[10,37.3],[11,35.8],[12,34.4],[13,32.9],[14,31.3],[15,29.7],[16,28.1],[17,26.4],[18,24.6],[19,22.6],[20,20]]'
                  visu_acl: rw
                  
              list08:
                  type: list
                  desc: 1.6
                  value: '[[-20,75],[-19,75],[-18,75],[-17,75],[-16,75],[-15,75],[-14,74.4],[-13,73],[-12,71.7],[-11,70.4],[-10,69],[-9,67.7],[-8,66.3],[-7,64.9],[-6,63.5],[-5,62.1],[-4,60.7],[-3,59.3],[-2,57.9],[-1,56.5],[0,55],[1,53.6],[2,52.1],[3,50.6],[4,49.1],[5,47.6],[6,46.1],[7,44.5],[8,42.9],[9,41.4],[10,39.7],[11,38.1],[12,36.4],[13,34.7],[14,32.9],[15,31.1],[16,29.2],[17,27.3],[18,25.2],[19,22.9],[20,20]]'
                  visu_acl: rw
                  
              list09:
                  type: list
                  desc: 1.8
                  value: '[[-20,75],[-19,75],[-18,75],[-17,75],[-16,75],[-15,75],[-14,75],[-13,75],[-12,75],[-11,75],[-10,75],[-9,73.6],[-8,72.1],[-7,70.5],[-6,69],[-5,67.4],[-4,65.8],[-3,64.3],[-2,62.7],[-1,61],[0,59.4],[1,57.8],[2,56.1],[3,54.5],[4,52.8],[5,51.1],[6,49.3],[7,47.6],[8,45.8],[9,44],[10,42.2],[11,40.3],[12,38.5],[13,36.5],[14,34.5],[15,32.5],[16,30.4],[17,28.2],[18,25.9],[19,23.3],[20,20]]'
                  visu_acl: rw
                  
              list10:
                  type: list
                  desc: 2.0
                  value: '[[-20,75],[-19,75],[-18,75],[-17,75],[-16,75],[-15,75],[-14,75],[-13,75],[-12,75],[-11,75],[-10,75],[-9,75],[-8,75],[-7,75],[-6,74.4],[-5,72.7],[-4,70.9],[-3,69.2],[-2,67.4],[-1,65.6],[0,63.8],[1,62],[2,60.1],[3,58.3],[4,56.4],[5,54.5],[6,52.6],[7,50.7],[8,48.7],[9,46.7],[10,44.7],[11,42.6],[12,40.5],[13,38.4],[14,36.2],[15,33.9],[16,31.5],[17,29.1],[18,26.5],[19,23.7],[20,20]]'
                  visu_acl: rw
          bastelecke.html:
          Code:
          {% set items = [] %}
          {% for nr in 1..9 %}
             {% set items = items|merge(['zz_testitems.list0'~nr]) %}
          {% endfor %}
          {% set items = items|merge(['zz_testitems.list10']) %}
          
          {{ plot.xyplot('', items, -20, 20) }}
          
          <!--
          * @param {id=} unique id for this widget (optional)
          * @param {item[?](bool,num,list)} series of item(s); multiple items in array form: [ item1 , item2 ]
          * @param {text} the minimum x-axis value (required).
          * @param {text} the maximum x-axis value (required)
          * @param {text[?]=} the minimum for each y-axis; multiples in array form: [ min_y-axis1, min_y-axis2, ...] (optional)
          If the axis type is boolean the passed value will be the label of the low state (e.g. 'Off')
          * @param {text[?]=} the maximum for each y-axis; multiples in array form: [ max_y-axis1, max_y-axis2, ...] (optional)
          If the axis type is boolean the passed value will be the label of the high state (e.g. 'On')
          * @param {text[?]=} label for each series; multiples in array form (optional)
          * @param {color[?]=} color for each series; multiples in array form (optional, default: suitable for design)
          * @param {text[?](line,linestack,stair,spline,area,areastair,areaspline,areastack,column,columnstack)=line} type of each serie: 'line', 'linestack', 'stair', 'spline', 'area', 'areastair', 'areaspline', 'areastacked','column', 'columnstacked'; multiples in array form (optional, default 'line')
          * @param {text[?]=} title for the x-axis and y-axes in array form: [title_x-axis, title_y-axis1, title_y-axis2, ...] (optional)
          * @param {duration(advanced,day)=} minimal time range while zooming or 'advanced' or 'day' (optional, duration-format)
          By passing 'advanced' a seaparate range selector is shown and data grouping for large amount of data is enabled
          By passing 'day', the plot is shown from 0:00 until 24:00 on the current day (it makes sense to set tmin to '24h' and tmax to 'now').
          * @param {value[]=} assignment of the series to the y-axes; multiples in array form (optional)
          * @param {value[]=} y-axes setup for left '0' and right '1' hand in array form (optional)
          * @param {color[?]=} y-axes color; multiples in array form (optional)
          * @param {text[?](linear,logarithmic,boolean)=linear} y-axes type, one of 'linear', 'logarithmic' or 'boolean'; multiples in array form (optional, default 'linear')
          * @param {format[?]=} either a unit of the language file, an individual format string (PHP sprintf like) or a simple string as suffix. (optional)
          * @param {text[?]=} object with additional options for Highcharts, see https://api.highcharts.com/ (optional)
          * @param {text[?](normal,percent)=normal} stacking of series for each stack (array for multiple stacks in ascending order): 'normal', 'percent' (optional, default=normal).
          * @param {text[]=} assign stacked series to different stacks: '0', '1, '2'... or ''. Sequence must be same as item sequence (optional, default='')
          * @param {value=0} control for the export of plot data: 0 = none, 1 = images, 2 = images and data (e.g.csv) (optional)
          -->
          Erstes Ergebnis:

          hk1.png

          Jetzt kann ich damit beginnen, das Ding 'aufzuhübschen' und die vielen Optionen auszuprobieren.

          Einen Fehler habe ich seit gestern, dessen Ursache ich noch nicht lokalisieren konnte. Das shNG Log ist jetzt voll von:
          Code:
          2021-12-13 17:47:19 WARNING plugins.database Database: Unknown time frame 'Arra'
          /tom
          Zuletzt geändert von Tom Bombadil; 13.12.2021, 18:54. Grund: Dieser sch..... Code-Editor hier kostet mich schon wieder jede Menge nerven ....

          Kommentar


            #6
            Benennung der Serien macht lustige Dinge mit dem Hintergrund (soll vermutlich die Legende sein):

            hk2.png

            Code:
            	{% set items = [] %}
            	{% for nr in 1..9 %}
            	  {% set items = items|merge(['zz_testitems.list0'~nr]) %}
            	{% endfor %}
            	{% set items = items|merge(['zz_testitems.list10']) %}
            
            	{{ plot.xyplot(
            		'',
            		items,
            		-20, 20,
            		20, 80,
            		['0.2','0.4','0.6','0.8','1.0','1.2','1.4','1.6','1.8','2.0'],
            		'',
            		'spline',
            		['AT','Vorlauf']
            	)}}
            /tom

            Kommentar


              #7
              Da war noch ein Bug im Code. Sollte aktuell im gist schon gefixt sein. Zeile 1639:
              Code:
              var seriesCount = this.items.length;

              Kommentar


                #8
                Ja, das war es. Muss jetzt erstmal Schluss machen - aktueller Stand der Dinge:

                Code:
                <div>
                
                    {% set items = [] %}
                    {% for nr in 1..9 %}
                        {% set items = items|merge(['zz_testitems.list0'~nr]) %}
                    {% endfor %}
                    {% set items = items|merge(['zz_testitems.list10']) %}
                
                    {% set min_x = -20 %} {% set max_x = 20 %}
                    {% set min_y =  20 %} {% set max_y = 80 %}
                    {% set series_labels = ['0.2','0.4','0.6','0.8','1.0','1.2','1.4','1.6','1.8','2.0'] %}
                    {% set series_colors = ['lightblue','darkblue','lightgreen','darkgreen','lightgrey','darkgrey','red','yellow','brown','lime'] %}
                    {% set series_types = 'spline' %}
                    {% set axis_titles = ['AT','Vorlauf'] %}
                    {% set duration = '' %}                                     /** Fehler, bei 'advanced', Rest nicht getestet **/
                    {% set series_to_y_axis = '' %}    
                    {% set y_axis_setup = '' %}
                    {% set y_axis_colors = '' %}
                    {% set y_axis_lin_log_bool = '' %}
                    {% set units = '°C' %}                                      /** wird nicht angezeigt **/
                    {% set stacking = '' %} {% set stackassignments = '' %}
                    {% set exporting = 2 %}
                    {% set ich_kann_mit_highcharts_reden =
                        {
                            chart:{zoomType: 'xy'},
                            xAxis:{reversed: true },
                            title:{text: 'Heizkurven mit unterscheidlicher Steigung', align: 'left'},
                            legend:{align: 'right', floating:true, y:-3}
                       }
                     %}
                
                    {{ plot.xyplot(
                        '',
                        items,
                        min_x, max_x,
                        min_y, max_y,
                        series_labels, series_colors, series_types,
                        axis_titles,
                        duration,
                        series_to_y_axis, y_axis_setup, y_axis_colors, y_axis_lin_log_bool,
                        units,
                        ich_kann_mit_highcharts_reden,
                        stacking, stackassignments,
                        exporting
                    )}}
                
                </div>
                hk3.png

                Danke!

                /tom

                Kommentar


                  #9
                  Cool.
                  Habe gerade das gist nochmal aktualisiert. Jetzt sind die Angaben von xmin und xmax optional. Wenn die Parameter leer bleiben, kümmert sich Highcharts um die Skalierung.
                  Auch die Zoom-Modi funktionieren jetzt.

                  Gruß
                  Wolfram

                  Kommentar


                    #10
                    Tom Bombadil & others,

                    gibt es zu diesem Widget noch Feedback / Wünsche? Ich werde das sonst so in den develop branch nehmen und demnächst in v3.2 releasen.

                    Gruß
                    Wolfram

                    Kommentar


                      #11
                      Habe ehrlich gesagt nicht viel weiter testen können - aber inklusive der Änderungen von #9 habe ich alles zum Laufen bekommen, daher von meiner Seite aus 'Feuer frei'.

                      Ich wollte noch ein Spannungs-Leistungs-Diagramm darstellen (oder auch Licht zu Spannung für PV-Module), habe aber leider selbst keine Daten dafür und auch im Internet keine brauchbare Excel-Tabelle gefunden. Vielleicht kann da ein PV-Besitzer nochmal testen.

                      Habe auch noch mehrfach über die Einsatzszenarien dieses Plots nachgedacht - vermutlich wird mehrheitlich eine bekannte SOLL-Kennlinie gegen den aktuellen Betriebszustand dargestellt (z.B. Photovoltaik: Leistungskurven, Spannung zu Restenergie im Akku, Stromentnahme zu Restzeit usw). Dafür wäre es sinnvoll, noch einen optionalen x/y Punkt mit dem aktuellen Betriebszustand (ggf. auch mehrere als Array) samt Text für diesen Punkt mit übergeben zu können. Das würde dann sogar plot.heatingcurve obsolet machen, der genau das macht (auch die Heizkurve ist eigentlich nichts anderes als eine Kennlinie) ...

                      /tom
                      Zuletzt geändert von Tom Bombadil; 29.12.2021, 14:46.

                      Kommentar


                        #12
                        Zitat von Tom Bombadil Beitrag anzeigen
                        Dafür wäre es sinnvoll, noch einen optionalen x/y Punkt mit dem aktuellen Betriebszustand (ggf. auch mehrere als Array) samt Text für diesen Punkt mit übergeben zu können.
                        Im Prinzip geht das heute schon, wenn man den aktuellen Arbeitspunkt als List-item mit je einem x- und y-Wert übergibt. Über die Chartoptions kann man dem eine besondere Gestalt (großer Punkt, Diamantform ...) geben. Der Arbeitspunkt muss dazu als Hilfsitem im Backend aus den beiden interessierenden items zusammengesetzt werden.

                        Getrennte items für x und y sollten auch machbar sein, aber dem ersten Anschein nach wird das aufwendig. Das stelle ich für eine spätere Version ins Backlog. Ich reserviere aber schon mal Platz für die Parameter x-item und y-item direkt hinter den anderen items. D.h. der Aufruf des Widgets ändert sich jetzt nochmal. Aber besser jetzt, als bei späteren Versionswechseln.

                        Gruß
                        Wolfram

                        Kommentar


                          #13
                          Heißt das, man kann jetzt auch für die letzten sieben Tage vernünftige Balken einer Grafik generieren (und nicht diesen Wechsel zwischen dünnen und dicken Balken), wenn man keine Zeiteinheit in der x-Achse definiert, sondern nur Angaben zum Tag in dem x-Wert verpackt und im y-Wert dann den Tageshöchstwert aus der Datenbank übernimmt?
                          Das wäre ja mal praktisch…

                          Kommentar


                            #14
                            Das Thema ist zuletzt mehrfach diskutiert worden. Siehe hier und in dem darin verlinkten Post.

                            EDiT: und hier
                            Zuletzt geändert von wvhn; 29.12.2021, 18:10.

                            Kommentar


                              #15
                              Ja, nur mein Problem ist eines: ich kann Dir Gebäude und Maschinen Elektrotechnisch ausstatten und auch alles passend dazu berechnen und montieren.

                              Wenn es aber um solche Dinge wie die SmartVisu geht; da bin ich raus und verstehe nur Bahnhof.
                              Ich schaffe es noch, mittels SmarthomeNG einmal täglich via Logik die aktuellen Zählerstände zu kopieren, damit ich einmal am Tag zur festen Zeit einen definierten Zählerstand habe.
                              Alles andere - inklusive der Seiten in der SmartVisu - packe ich (vermutlich auch wie viele andere) mangels Grundkenntnissen nicht an.
                              Die verlinkten Beiträge sind für mich als reiner Anwender nicht zu verstehen. Alles was über die Doku hinausgeht und dort ordentlich erklärt ist, kann ich irgendwie nie nachvollziehen.

                              Daher wäre eine einfache Plot-Funktion: nimm die x-Achse, nummerier die einfach je nach eingestelltem Parameter von 1-7 (oder länger) durch und hole die Werte mit der parametrierten Menge aus der Datenbank.
                              Eigentlich das, was plot.period auch macht, nur ohne Zeitwerte der Datenbank in der x-Achse. Dann gäbe es auch nicht diese „ungeliebten“ Balken am Ende eines Plots außerhalb der turnusmäßigen Zeitangabe.

                              Das mag sich zwar alles aus der Verlinkungen ergeben, aber ich verstehe das einfach nicht. Ich habe halt noch nie irgendwelche Websites mit css oder sonstigen Dingen erstellt.

                              Kommentar

                              Lädt...
                              X