Ankündigung

Einklappen
Keine Ankündigung bisher.

Gauges

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

    Gauges

    Hallo,

    es wird ja gerade an Steelseries-Canvas geschraubt - aber hat schon mal jemand "einfache" Gauges in die sV implementiert?

    Ich schaue mir gerade justGage und gauge.js an (Demos hier und hier, Github hier und hier) - die sollten meiner blauäugigen Meinung nach wohl recht einfach zu integrieren sein, bei gauge.js gibt's sogar ein jQuery-Script 'frei Haus'.

    Oder hat da schon jemand erprobte Alternativen? Sind irgendwelche Stolpersteine zu befürchten?

    /tom

    #2
    Was spricht dagegen, Gauges des bereits für die Plots integrierten highcharts zu verwenden?

    Kommentar


      #3
      Wusste nicht, dass Highcharts auch Gauges hat - muss ich mich mal einlesen ...
      /tom

      Kommentar


        #4
        Tom
        Hier mein Code:

        Es müssen zusätlich
        'vendor/plot.highcharts/highcharts-more.js',
        'vendor/plot.highcharts/modules/solid-gauge.js'

        eingebunden werden.
        Die musste ich nach widget.js einbinden, da es sonst Probleme mit uzsu bei eingeschaltetem Pagecache gab.


        Code für das widget (gauge.html):

        Code:
        /**
        * A solid gauge
        *
        * @param unique id for this widget
        * @param a item for the gauge
        * @param min value
        * @param max value
        * @param unit for the gauge
        * @param text for label
        * @param set mode 'half', 'cshape', 'circle' (optional, default: 'half')
        * @param stop/s for the series e. g. '#f00' for red. More stops/s in array form: [0.1,0.4]
        * @param color/s for the series e. g. '#f00' for red. More stops/s in array form: ['#f00','#fff']
        * @param
        */
        {% macro solid(id, item, min, max, unit, label, mode, stop, color) %}
        
            <div id="{{ uid(page, id) }}" data-widget="plot.gauge-solid" data-item="{{ item }}"
                data-label="{{ label|default('') }}" data-stop="{{ implode(stop)|default([0.5]) }}" data-color="{{ implode(color)|default(['#DF5353']) }}" data-min="{{ min|default(0) }}" data-max="{{ max|default(255) }}" data-unit="{{ unit|default('') }}" data-mode="{{ mode|default('half') }}"  data-axis="{{ lang('plot.gauge', unit) }}"
                class="plot"></div>
        
        {% endmacro %}
        
        
        /**
        * A speedometer gauge
        *
        * @param unique id for this widget
        * @param a item for the gauge
        * @param min value
        * @param max value
        * @param unit for the gauge
        * @param text for label
        * @param
        */
        {% macro speedometer(id, item, min, max, unit, label) %}
        
            <div id="{{ uid(page, id) }}" data-widget="plot.gauge-speedometer" data-item="{{ item }}"
                data-label="{{ label|default('') }}" data-min="{{ min|default(0) }}" data-max="{{ max|default(255) }}" data-unit="{{ unit|default('') }}" data-axis="{{ lang('plot.gauge', unit) }}"
                class="plot"></div>
        
        {% endmacro %}
        
        
        /**
        * A VU meter gauge
        *
        * @param unique id for this widget
        * @param series of two item/s. The two item/s in array form: [ item1 , item2 ]
        * @param min value (optional, default: 0)
        * @param max value (optional, default: 255)
        * @param text for label
        * @param
        */
        {% macro vumeter(id, item, min, max, label) %}
        
            <div id="{{ uid(page, id) }}" data-widget="plot.gauge-vumeter" data-item="{{ implode(item) }}"
                data-label="{{ label|default('') }}" data-min="{{ min|default(0) }}" data-max="{{ max|default(255) }}"
                class="plot"></div>
        
        {% endmacro %}
        Javascript-Code (gauge.js):

        Code:
        $(document).on('pagecreate', function (bevent, bdata) {
        
            // ----- plot.gauge-solid ----------------------------------------------------------
            $(bevent.target).find('div[data-widget="plot.gauge-solid"]').on( {
                'update': function (event, response) {
                    event.stopPropagation();
        
                    //debug: console.log("[plot.gauge-solid] '" + this.id + "' update: " + response);    
        
                    var stop = [];
                    if ($(this).attr('data-stop') && $(this).attr('data-color')) {
                        var datastop = $(this).attr('data-stop').explode();    
                        var datacolor = $(this).attr('data-color').explode();
        
                        if (datastop.length == datacolor.length)
                        {
                            for (var i = 0; i < datastop.length; i++) {
                                stop[i] = [ +datastop[i], datacolor[i]]
                            }
                        }            
                    }
                    var startAngle = -90;
                    var endAngle = 90;
                    var shape = 'arc';
                    var step = 1;
                    var distance = -15;
                    var yHeadline = 20;
                    var yLabel = 16;
                    var yDataLabel = 23;
                    var center = ['50%', '85%'];
                    var margin = $(this).attr('data-label') == '' ? [-80, -20, 80, 20] : [-40, -20, 40, 20];
                    var isLabel = true;
                    if ($(this).attr('data-mode') == 'cshape')
                    {
                        startAngle = -130;
                        endAngle = 130;
                        distance = -25;
                        yLabel = 20;
                        yDataLabel = -25;
                        center = ['50%', '60%'];
                        margin = $(this).attr('data-label') == '' ? [-40, -20, 40, 20] : [0, -20, 0, 20];
                    }
                    else if ($(this).attr('data-mode') == 'circle')
                    {
                        startAngle = 0;
                        endAngle = 360;
                        yHeadline = 5;
                        yLabel = -20;
                        yDataLabel = -25;
                        center = ['50%', '50%'];
                        margin = $(this).attr('data-label') == '' ? [0, -20, 0, 20] : [15, -20, -15, 20];
                        shape = 'circle';
                        step = 2;
                    }
                    var headline = $(this).attr('data-label') == '' ? null : $(this).attr('data-label');
                    var axis = $(this).attr('data-axis').explode();
        
                    var diff = ($(this).attr('data-max') - ($(this).attr('data-max') - $(this).attr('data-min')));
                    var range = $(this).attr('data-max') - $(this).attr('data-min');
                    var percent = (((response - diff) * 100) / range);
        
        
                    $(this).highcharts({
                        chart: {
                            type: 'solidgauge',
                            margin: margin
                        },
        
                        title: {
                            text: headline,
                            x: 15,
                            y: yHeadline            
                        },
        
                        pane: {
                            center: center,
                            size: '80%',
                            startAngle: startAngle,
                            endAngle: endAngle,
                            background: {
                                innerRadius: '60%',
                                outerRadius: '100%',
                                shape: shape
                            }
                        },
        
                        tooltip: {
                            enabled: false
                        },
        
                        // the value axis
                        yAxis: {
                            min: 0,
                            max: 100,
                            title: {
                                text: headline
                            },
                            stops: stop,
                            lineWidth: 0,
                            gridLineColor: 'rgba(255, 255, 255, 0)',
                            minorTickInterval: null,
                            tickAmount: 2,
                            title: {
                                y: -70
                            },
                            labels: {
                                distance: distance,
                                step: step,
                                //x: 20,
                                y: yLabel,
                                enabled: isLabel,
                                formatter: function () {return (((this.value * range) / 100) + diff)}
                            }
                        },
        
                        plotOptions: {
                            solidgauge: {
                                dataLabels: {
                                    y: yDataLabel,
                                    borderWidth: 0,
                                    useHTML: true
                                }
                            }
                        },
        
                        series: [{
                            name: headline,
                            data: [percent],
                            dataLabels: {
                                formatter: function () {return '<div class="gauge"><span class="value">' + (((this.y * range) / 100) + diff).transUnit('dec') + '</span><br/><span class="unit">' + axis + '</span></div>'}
                            },
                            tooltip: {
                                valueSuffix: ' ' + axis
                            }
                        }]
                    });                
                },
        
                'point': function (event, response) {
                    event.stopPropagation();
        
                    //debug: console.log("[plot.gauge-solid] '" + this.id + "' point: " + response);
        
                    var diff = ($(this).attr('data-max') - ($(this).attr('data-max') - $(this).attr('data-min')));
                    var range = $(this).attr('data-max') - $(this).attr('data-min');
                    var percent = (((response - diff) * 100) / range);            
        
                    if (response)
                    {
                        var chart = $(this).highcharts();
                        chart.series[0].points[0].update(percent);
                        chart.redraw();    
                    }
                }
            });
        
            // ----- plot.gauge-speedometer ----------------------------------------------------------
            $(bevent.target).find('div[data-widget="plot.gauge-speedometer"]').on( {
                'update': function (event, response) {
                    event.stopPropagation();
        
                    //debug: console.log("[plot.gauge-speedometer] '" + this.id + "' update: " + response);    
        
                    var headline = $(this).attr('data-label') == '' ? null : $(this).attr('data-label');
                    var unit = $(this).attr('data-unit');
                    var axis = $(this).attr('data-axis').explode();
        
                    var diff = ($(this).attr('data-max') - ($(this).attr('data-max') - $(this).attr('data-min')));
                    var range = $(this).attr('data-max') - $(this).attr('data-min');
                    var percent = (((response - diff) * 100) / range);
                    var size = $(this).attr('data-label') == '' ? '100%' : '110%';
        
        
                    $(this).highcharts({
                        chart: {
                            type: 'gauge',
                            plotBackgroundColor: null,
                            plotBackgroundImage: null,
                            plotBorderWidth: 0,
                            plotShadow: false
                        },
        
                        title: {
                            text: headline            
                        },
        
                        pane: {
                            startAngle: -150,
                            endAngle: 150,
                            size: size,
                            background: [{
                                backgroundColor: {
                                    linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
                                    stops: [
                                        [0, '#FFF'],
                                        [1, '#333']
                                    ]
                                },
                                borderWidth: 0,
                                outerRadius: '109%'
                            }, {
                                backgroundColor: {
                                    linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
                                    stops: [
                                        [0, '#333'],
                                        [1, '#FFF']
                                    ]
                                },
                                borderWidth: 1,
                                outerRadius: '107%'
                            }, {
                                // default background
                            }, {
                                backgroundColor: '#DDD',
                                borderWidth: 0,
                                outerRadius: '105%',
                                innerRadius: '103%'
                            }]
                        },
        
                        tooltip: {
                            formatter: function() {return '<b>' + (((this.y * range) / 100) + diff).transUnit(unit) +  '</b>'}
                        },
        
                        // the value axis
                        yAxis: {
                            min: 0,
                            max: 100,
        
                            minorTickInterval: 'auto',
                            minorTickWidth: 1,
                            minorTickLength: 10,
                            minorTickPosition: 'inside',
                            minorTickColor: '#666',
        
                            tickPixelInterval: 30,
                            tickWidth: 2,
                            tickPosition: 'inside',
                            tickLength: 10,
                            tickColor: '#666',
                            labels: {
                                step: 2,
                                rotation: 'auto',
                                formatter: function () {return (((this.value * range) / 100) + diff)}
                            },
                            title: {
                                text: axis
                            },
                            plotBands: [{
                                from: 0,
                                to: 60,
                                color: '#55BF3B' // green
                            }, {
                                from: 60,
                                to: 80,
                                color: '#DDDF0D' // yellow
                            }, {
                                from: 80,
                                to: 100,
                                color: '#DF5353' // red
                            }]
                        },
        
                        series: [{
                            name: headline,
                            data: [percent],
                            dataLabels: {
                                color: 'grey',
                                formatter: function () {return (((this.y * range) / 100) + diff).transUnit('dec')}
                            },
                            tooltip: {
                                valueSuffix: ' ' + axis
                            }
                        }]
                    });                
                },
        
                'point': function (event, response) {
                    event.stopPropagation();
        
                    //debug: console.log("[plot.gauge-speedometer] '" + this.id + "' point: " + response);
        
                    var diff = ($(this).attr('data-max') - ($(this).attr('data-max') - $(this).attr('data-min')));
                    var range = $(this).attr('data-max') - $(this).attr('data-min');
                    var percent = (((response - diff) * 100) / range);            
        
                    if (response)
                    {
                        var chart = $(this).highcharts();
                        chart.series[0].points[0].update(percent);
                        chart.redraw();    
                    }
                }
            });
        
            // ----- plot.gauge-vumeter ----------------------------------------------------------
            $(bevent.target).find('div[data-widget="plot.gauge-vumeter"]').on( {
                'update': function (event, response) {
                    event.stopPropagation();
        
                    //debug: console.log("[plot.gauge-vumeter] '" + this.id + "' update: " + response);    
        
                    var headline = $(this).attr('data-label') == '' ? null : $(this).attr('data-label');
                    var chartHeight = $(this).attr('data-label') == '' ? 150 : 200;
        
                    var diff = ($(this).attr('data-max') - ($(this).attr('data-max') - $(this).attr('data-min')));
                    var range = $(this).attr('data-max') - $(this).attr('data-min');
        
                    var percent = [];            
                    for (i = 0; i < response.length; i++) {                    
                        percent[i] = (((response[i] - diff) * 100) / range);
                        console.log("[plot.gauge-vumeter] '" + this.id + "' update: " + (((response[i] - diff) * 100) / range));                    
                    }
        
                    $(this).highcharts({
                        chart: {
                            type: 'gauge',
                            plotBorderWidth: 1,
                             plotBackgroundColor: {
                                linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
                                stops: [
                                    [0, '#FFF4C6'],
                                    [0.3, '#FFFFFF'],
                                    [1, '#FFF4C6']
                                ]
                            },
                            plotBackgroundImage: null,
                            height: chartHeight
                        },
        
                        title: {
                            text: headline,                    
                        },
        
                        pane: [{
                            startAngle: -45,
                            endAngle: 45,
                            background: null,
                            center: ['25%', '145%'],
                            size: 280
                        }, {
                            startAngle: -45,
                            endAngle: 45,
                            background: null,
                            center: ['75%', '145%'],
                            size: 280
                        }],
        
                        tooltip: {
                            enabled: false,
                        },
        
                        // the value axis
                        yAxis: [{
                            min: 0,
                            max: 100,
        
                            minorTickPosition: 'outside',
                            tickPosition: 'outside',
                            labels: {
                                rotation: 'auto',
                                distance: 20,
                                formatter: function () {return (((this.value * range) / 100) + diff)}
                            },
                            plotBands: [{
                                from: 0,
                                to: 6,
                                color: '#C02316',
                                innerRadius: '100%',
                                outerRadius: '105%'
                            }],
                            pane: 0,
                            title: {
                                text: 'VU<br/><span style="font-size:8px">Channel A</span>',
                                y: -40
                            }
                        }, {
                            min: 0,
                            max: 100,
                            minorTickPosition: 'outside',
                            tickPosition: 'outside',
                            labels: {
                                rotation: 'auto',
                                distance: 20,
                                formatter: function () {return (((this.value * range) / 100) + diff)}
                            },
                            plotBands: [{
                                from: 0,
                                to: 6,
                                color: '#C02316',
                                innerRadius: '100%',
                                outerRadius: '105%'
                            }],
                            pane: 1,
                            title: {
                                text: 'VU<br/><span style="font-size:8px">Channel B</span>',
                                y: -40
                            }
                        }],
        
                        plotOptions: {
                            gauge: {
                                dataLabels: {
                                    enabled: false
                                },
                                dial: {
                                    radius: '100%'
                                }
                            }
                        },
        
                        series: [{
                            name: 'Channel A',
                            data: [percent[0]],
                            yAxis: 0
                        }, {
                            name: 'Channel B',
                            data: [percent[1]],
                            yAxis: 1
                        }]
                    });                
                },
        
                'point': function (event, response) {
                    event.stopPropagation();
        
                    //debug: console.log("[plot.gauge-vumeter] '" + this.id + "' point: " + response);
        
                    var diff = ($(this).attr('data-max') - ($(this).attr('data-max') - $(this).attr('data-min')));
                    var range = $(this).attr('data-max') - $(this).attr('data-min');
        
                    var data = [];
                    var items = $(this).attr('data-item').explode();        
                    for (i = 0; i < items.length; i++) {
                        if (response[i]) {
                            data[i] = (((+response[i] - diff) * 100) / range);
                        }
                        else
                        {
                            data[i] = (((+widget.get(items[i]) - diff) * 100) / range);
                        }
                    }
        
                    var chart = $(this).highcharts();
                    for (i = 0; i < data.length; i++) {
                        chart.series[i].points[0].update(data[i]);                
                    }
                    chart.redraw();    
                }
            });
        
        });
        css-Code für die Schrift der Solid gauges (z.B in eigene visu.css kopieren):

        Code:
        /* highcharts */
        div.gauge {
          text-align: center;
        }
        div.gauge span.value {
          color: #CCCCCC;
          font-size: 25px;
        }
        div.gauge span.unit {
          color: #CCCCCC;
          font-size: 12px;
        }
        Zusätzlich habe ich lang_##.txt noch ergänzt, um die Einheiten einzeln abrufen zu können (hier beispielsweise für lang_de.txt):

        $lang['plot.gauge']['temp'] = '°C';
        $lang['plot.gauge']['°'] = '°C';
        $lang['plot.gauge']['%'] = '%';
        $lang['plot.gauge']['€'] = '€';
        $lang['plot.gauge']['speed'] = 'km/h';
        $lang['plot.gauge']['km/h'] = 'km/h';
        $lang['plot.gauge']['v'] = 'V';
        $lang['plot.gauge']['a'] = 'A';
        $lang['plot.gauge']['w'] = 'W';
        $lang['plot.gauge']['kwh'] = 'kWh';

        Und für format habe ich noch folgendes hinzugefügt, damit ich den Wert ohne Einheit zurückbekomme:

        $lang['format']['dec'] = '%01,1f';
        Zuletzt geändert von ramann; 29.01.2017, 16:27.

        Kommentar


          #5
          Perfekt, danke.

          /tom

          Kommentar


            #6
            Es können noch Fehler drin sein, einfach mal testen.

            Noch ein paar Beispieldefinitionen:

            Wenn man zwei Solid-Gauges nebeneinander plazieren will:
            Code:
            {% import "gauge.html" as gauge %}
            <div style="float: left;">{{ gauge.solid('Test_4', 'Test_Solid_1', 10, 30, '°', 'Temperatur', '', [0.4,0.6,0.7], ['#55BF3B','#DDDF0D','#DF5353']) }}</div>
            <div style="float: left;">{{ gauge.solid('Test_5', 'Test_Solid_2', 0, 100, '%', 'Luftfeuchtigkeit', '', [0.4,0.6,0.7], ['#55BF3B','#DDDF0D','#DF5353']) }}</div>
            Speedometer:
            Code:
            {{ gauge.speedometer('Test_6', 'Test_Speed_1', 10, 30, '°', '') }}
            VU-Meter
            Code:
            {{ gauge.vumeter('Test_plot7', ['Test_VU_1','Test_VU_2'], 0, 300) }}
            Zuletzt geändert von ramann; 29.01.2017, 16:25.

            Kommentar


              #7
              Aye, wird gemacht!

              /tom

              Kommentar


                #8
                Zitat von ramann Beitrag anzeigen
                Tom

                Es müssen zusätlich
                'vendor/plot.highcharts/highcharts-more.js',
                'vendor/plot.highcharts/modules/solid-gauge.js'

                eingebunden werden.
                Die musste ich nach widget.js einbinden, da es sonst Probleme mit uzsu bei eingeschaltetem Pagecache gab.
                Was ist damit genau gemeint?
                Insbesondere mit
                Die musste ich nach widget.js einbinden, da es sonst Probleme mit uzsu bei eingeschaltetem Pagecache gab.

                Kommentar


                  #9
                  @ramann: Rückmeldung könnte aber ein 1-2 Tage dauern, da ich erst noch alle notwendigen Optionen kennenlernen muss, um die Tabelle unten als Skala anzuzeigen, sowie die den aktuellen Luftdurchsatz entsprechend Skala darzustellen und einzufärben.

                  Im Moment stellt sich die automatische Größenanpassung des Gauges zickig an (hier noch mit dem Original von Highcharts in meinem HTML), wenn ich die geknackt hab, sind Skala + Farbstufen dran:

                  gauge.png

                  /tom

                  Kommentar


                    #10
                    Sisamiwe
                    Die gauges haben noch weitere Abhängigkeiten, deswegen müssen highcharts-more.js und solid-gauge.js im html-Code eingebunten werden.
                    Am besten du kopierst aus dem Ordner pages/base die root.html in deinen Projektordner und passt diese Datei entsprechend an.

                    Wenn ich die Dateien in SV2.9 vor widget.js einbinde, dann funktioniert bei mir das Popup von uzsu nicht mehr.

                    Tom
                    Den Abstand zwischen den unteren Werten kannst du mit distance: für die labels der yAchse beeinflussen, die Position des aktuellen Werts mit y:

                    Das "Einfärben" lasse ich ja "dynamisch" für die Solid-Gauges erstellen, je nachdem welche Werte bei der Definition übergeben werden. Ein Array mit Werten, z.B. [0.4,0.6,0.7], die den Prozentwerten entsprechen, wie weit der entsprechende Bereich gehen soll und ein Array mit den Farben ['#55BF3B','#DDDF0D','#DF5353'] für die Bereiche.

                    Kommentar


                      #11
                      highcharts-more.js ist in der aktuellsten develop schon in root.html drin.
                      Weshalb es nicht vor widget.js sein darf, versuche ich bei Gelegenheit noch rauszufinden, v.A. auch, was das mit UZSU zu tun hat.

                      Kommentar


                        #12
                        Überarbeitetes gauge widget (Post #4) ist jetzt hier zu finden:

                        a.A.
                        Zuletzt geändert von ramann; 22.02.2017, 11:40.

                        Kommentar


                          #13
                          Zur Info:
                          Die Highchart-Gauges habe ich in develop integriert.
                          Damit die Anzahl Widgets nicht schon wieder ausartet, habe ich sie alle in plot.gauge zusammengefasst.
                          Und auch plot.pie ist neu drin.

                          Danke ramann!

                          Kommentar


                            #14
                            Coole Sache, probier ich am Wochenende gleich aus! Dankeschön!

                            Ich finde die Highcharts-Gauges zwar etwas 'beschnitten' (bzw. eigentlich anders herum - es fehlen mir einige Möglichkeiten anderer Gauges, wie z.B. eine nicht-lineare Beschriftung an beliebigen Datenpunkten / Schwellwerten). Aber für schnelle, einfache Gauges reicht es allemal.

                            Frage am Rande (hatten wir in einem anderen Thread diskutiert): Kann auch hsla/rgba mittlerweile als Farbwert übergeben werden, oder gibt es eine andere Möglichkeit, transparente Flächen einzubinden?

                            /tom

                            Kommentar


                              #15
                              Zitat von Tom Bombadil Beitrag anzeigen
                              Ich finde die Highcharts-Gauges zwar etwas 'beschnitten' (bzw. eigentlich anders herum - es fehlen mir einige Möglichkeiten anderer Gauges, wie z.B. eine nicht-lineare Beschriftung an beliebigen Datenpunkten / Schwellwerten). Aber für schnelle, einfache Gauges reicht es allemal.
                              Meinst du damit das Widget oder Highcharts selbst? Ohne es geprüft zu habeb, könnte ich mir durchaus vorstellen, dass Highcharts sowas kann. Einfärben kann man jedenfalls nicht-linear, sogar im Widget.
                              Zitat von Tom Bombadil Beitrag anzeigen
                              Frage am Rande (hatten wir in einem anderen Thread diskutiert): Kann auch hsla/rgba mittlerweile als Farbwert übergeben werden, oder gibt es eine andere Möglichkeit, transparente Flächen einzubinden?
                              Leider nein. Eine andere Möglichkeit ist mir auch nicht bekannt.
                              Voraussichtkich werde ich das ändern, aber wie erwähnt habe ich keine Ahnung, wo dadurch überall Fehler auftauchen werde.

                              Kommentar

                              Lädt...
                              X