Q&A Highcharts - Multigraph V1.0

Hallo zusammen,

benutze Highcharts jetzt schon ziemlich lange. Besteht eigentlich die Möglichkeit, Live Data umzusetzen? Also ohne zyklisches Ausführen des Highcharts Skriptes und komplette Neudarstellung des Trends?

Mir fehlt irgendwie ein Live Trend, der einfach immer weiter geht, ohne was zu machen.

Liebe Grüße Sebastian

Einfach Update-Skripte bei Value Change ausführen.

Das ändert dennoch nichts am Verhalten, dass sich alles komplett neu aufbaut und unschön aussieht. Schau dir mal die Live Update Geschichte an auf der Highcharts Seite, da sieht man es ganz gut was ich meine.

Ich scheitere gerade bei der Array-Erstellung an meinen PHP-Fähigkeiten… :frowning:

Ich möchte externe Daten darstellen und dazu das hier nutzen:

$serie[data] = $data

Wenn ich $data „manuell“ als Array erstelle, dann klappt es. Wenn ich das Array aber aus einem String erstellen lasse, dann bleibt der HC-Container (ohne Fehlermeldung) leer:

 // Array $werte_arr3 wird angezeigt
$werte_arr3 = [[1528495200000,43.83],[1527285600000,43.76]]; 

// Array $werte_arr2 wird nicht angezeigt
$test = "1528495200000!43.83!!1527285600000!43.76";
$werte_arr = explode("!!", $test);
foreach($werte_arr as $key1 => $value1)
	{
	$werte_arr1 = explode("!",$value1);
	$werte_arr2[] = $werte_arr1;
	}

Beide Arrays sehen bei der Ausgabe (print_r) absolut identisch aus:

Array ( [0] => Array ( [0] => 1528495200000 [1] => 43,83 ) [1] => Array ( [0] => 1527285600000 [1] => 43,76 ) )
Array ( [0] => Array ( [0] => 1528495200000 [1] => 43,83 ) [1] => Array ( [0] => 1527285600000 [1] => 43,76 ) ) 

Muss ich noch irgendwo ein „(int)“ oder sowas anwenden? Wo liegt der Fehler?

Dank und Grüße
galleto

Nimm mal var_dump statt print_r. Vielleicht gibt es doch einen Unterschied.

Danke, das zeigt tatsächlich Unterschiede an:

// funktioniert nicht
array(2) { [0]=> array(2) { [0]=> string(13) "1528495200000" [1]=> string(5) "43.83" } [1]=> array(2) { [0]=> string(13) "1527285600000" [1]=> string(5) "43.76" } }
// funktioniert
array(2) { [0]=> array(2) { [0]=> int(1528495200000) [1]=> float(43,83) } [1]=> array(2) { [0]=> int(1527285600000) [1]=> float(43,76) } } 

Offenbar lag ich mit meiner Vermutung gar nicht so falsch, das Format ist unterschiedlich. Kann jemand das Problem erklären (Link reicht) und mich in Richtung Lösung schubbsen? :slight_smile:

Dank und Grüße
galleto

Probiere es mal mit

$werte_arr2[] = [(int) $werte_arr1[0], (float ) $werte_arr1[1]];

Mit explode zerlegst du nur den String in Strings.

HC braucht aber den Timestamp als int und den Wert als float.

Herzlichen Dank, läuft! :smiley:

Grüße
galleto

Woran liegt es, wenn der Subtitel „verfälscht“ wird?

Folgender Code…

$CfgDaten['title']['text'] = "Octavia";
$CfgDaten['subtitle']['text'] = "Octavia";
//$CfgDaten['subtitle']['Ips']['DateTimeFormat'] = "(D) d.m.Y H:i";

…führt zu folgender Ausgabe:
Oktavia.jpg

Aus dem C ist im Subtitel überraschend ein K geworden. :confused:

Ergänzung: „Octavia1“ wird „Oktavia1“, aber „Occtavia“ bleibt „Occtavia“.

Grüße
galleto

Fake ? :smiley:

Das ist mein voller ernst! :eek:

Grüße
galleto

Ich tippe auf eine Spracheinstellung oder sowas: Es wird nur „Oct…“ zu „Okt…“ geändert, „Act…“ und „Ocd“ bleiben unverändert. Sieht aus wie die automatische Übersetzung des Monats Oktober. :confused:

Edit sagt: Aus „December“ wird auch „Dezember“ und aus „Decimal“ wird „Dezimal“…

Grüße
galleto

Hallo
Hier wird das uebersetzt in Highcharts.inc.php

	// ------------------------------------------------------------------------
	// ReplaceToGermanDate
	//    Falls nicht konfiguriert, wird dies als Default String genommen
	//    IN: String mit englischen Wochentagen, bzw. Monaten
	//    OUT: der String übersetzt ins Deutsche
	// ------------------------------------------------------------------------
	function ReplaceToGermanDate($value)
	{
			$trans = array(
			    'Monday'    => 'Montag',
			    'Tuesday'   => 'Dienstag',
			    'Wednesday' => 'Mittwoch',
			    'Thursday'  => 'Donnerstag',
			    'Friday'    => 'Freitag',
			    'Saturday'  => 'Samstag',
			    'Sunday'    => 'Sonntag',
			    'Mon'       => 'Mo',
			    'Tue'       => 'Di',
			    'Wed'       => 'Mi',
			    'Thu'       => 'Do',
			    'Fri'       => 'Fr',
			    'Sat'       => 'Sa',
			    'Sun'       => 'So',
			    'January'   => 'Januar',
			    'February'  => 'Februar',
			    'March'     => 'März',
			    'May'       => 'Mai',
			    'June'      => 'Juni',
			    'July'      => 'Juli',
			    'October'   => 'Oktober',
			    'December'  => 'Dezember',
			    'Mar'     	 => 'Mär',
			    'May'       => 'Mai',
			    'Oct'   	 => 'Okt',
			    'Dec'  		 => 'Dez',
		);
		return  strtr($value, $trans);
	}

Wenn du ReplaceToGermanDate im Script deaktiviert sollte das nicht mehr passieren.
Ist glaube ich nur an 3 Stellen im Script.

Danke! :slight_smile:

Die Funktion wird im Skript gar nicht aufgerufen, wahrscheinlich passiert das beim Subtitel automatisch. Aber jetzt kann ich es ja direkt in der Highcharts.inc.php abschalten.

Grüße
galleto

Bei mir die Funktion aufgerufen.

function CreateArrayForSubTitle($cfg)
	{
		if (!isset($cfg['subtitle']))
			$cfg['subtitle'] = array();

		//Default
		IfNotIssetSetValue($cfg['subtitle']['text'], "Zeitraum: %STARTTIME% - %ENDTIME%");
		IfNotIssetSetValue($cfg['subtitle']['Ips']['DateTimeFormat'], "(D) d.m.Y H:i");

		$s = $cfg['subtitle']['text'];
		$s = str_ireplace("%STARTTIME%", date($cfg['subtitle']['Ips']['DateTimeFormat'], $cfg['Ips']['ChartStartTime']), $s);
		$s = str_ireplace("%ENDTIME%", date($cfg['subtitle']['Ips']['DateTimeFormat'], $cfg['Ips']['ChartEndTime']), $s);
--->		$cfg['subtitle']['text'] = ReplaceToGermanDate($s);

		unset($cfg['subtitle']['Ips']);

		return $cfg['subtitle'];
	}

So ein Aufruf ist in diesem Skriptnicht enthalten.

Grüße
galleto

Mir macht die Umsetzung von folgendem OriginalcodeSchwierigkeiten:

    pane: {
        startAngle: -150,
        endAngle: 150,
        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%'
        }]
    },

So sieht meine Umsetzung aus, ich habe schlicht aus jeder Klammer ein Array gemacht:

$pane = array
		(
		'startAngle' => -150,
		'endAngle' => 150,
		'background' => array
			(
			array
				(
				'backgroundColor' => array
					(
					'linearGradient' => array
						(
						'x1' => 0,
						'y1' => 0,
						'x2' => 0,
						'y2' => 1
						),
					'stops' => array
						(
						array
							(
							'0' => '#FFF',
							'1' => '#333'
							)
						)		
					),
				'borderWidth' => 0,
				'outerRadius' => '109%'
				),
			array
				(
				'backgroundColor' => array
					(
					'linearGradient' => array
						(
						'x1' => 0,
						'y1' => 0,
						'x2' => 0,
						'y2' => 1
						),
					'stops' => array
						(
						array
							(
							'0' => '#333',
							'1' => '#FFF'
							)
						)		
					),
				'borderWidth' => 1,
				'outerRadius' => '107%'
				),
			array
				(
				),
			array
				(
				'backgroundColor' => '#DDD',
				'borderWidth' => 0,
      			'outerRadius' => '105%',
      			'innerRadius' => '103%'
				)
			)
		);
$CfgDaten['pane'][] = $pane;

Im Prinzip funktioiert es, nur die Optik am 3D-Rand (simulierter „Chromring“) wird nicht richtig dargestellt, wahrscheinlich fehlt der Farbverlauf. Irgendwas bei linearGradient ist bei meiner Umsetzung wohl nicht korrekt. Oder?

Hier hat es schon mal jemand in IPS umgesetzt, leider ist kein Code angegeben.

Grüße
galleto

Hat irgendwer ein Code-Schnippsel mit linearGradient?

Grüße
galleto

Hallo,

ich nutze die scriptversion 3.01. Es funktioniert auch alles.
Ich bin jetzt dabei mir eine Übersichtsseite im IPSView zu erstellen wo mehrere Highcharts auf einer Seite im fest definierten Zeitrahmen dargestellt werde sollen. Hier möchte ich gern Titel , Subtitel und die Legend ausschalten.
Titel und Subtitel habe ich hinbekommen. Ich finde aber noch keinen Ansatz die Legende auszuschalten.
Wer kann mir einen Tip geben wo und wie man die Legende ausbleden kann.

Thomas :confused:

Hallo,

ich beschäftige mich damit die Highcharts dynamischer zu gestalten. Nachdem ich im ersten Versuch in einem anderen (vermutlich falschen) Unterforum einen Thread erfolglos aufgemacht habe, habe ich mich weiter eingefuchst und im Thread zur Skript-Vorstellung einen Beitrag von Raketenschnecke mit den richtigen Hinweisen gefunden. In https://www.symcon.de/forum/threads/17625-Highcharts-Multigraph?p=225894#post225894 ist ein Skriptbeispiel zum Gauge-Diagramm mit wechselndem Wert des Zeigers. Der Trick ist dabei

$(\'#container\').highcharts(%%%%, function(chart){
    .. do something        
            } );

Ich habe zum Probieren ein Label erstellt, dass mir Minimal- und Maximaltemperaturen getrennt nach Innen und Außen zeigt. Zusätzlich wird das Label aktualisiert, wenn einzelne Serien aus- oder eingeblendet werden. Dazu habe ich ein redraw-Event hinzugefügt.
Mir gelingt es bisher jedoch leider nicht, das Label direkt nach dem Laden des Charts anzuzeigen. Es erscheint erst nach dem ersten ausgelösten redraw. Ich habe schon probiert ein load- und render-Event in der oben stehenden Zeile hinzuzufügen. Beide Events reagieren - aber leider vor dem Bildaufbau (ich hab einen Alert ausgeben lassen). Hat jemand eine Idee? Kann ich bereits im eigentlichen Config-Sktipt events hinzufügen? Dies ist der (dynamische) Teil meines Config-Skripts:

    
    $CfgDaten['Ips']['HtmlScript'] ='<div style="height: 30px;position: relative;top: -50px;"><button id="nogrid">NoGrid</button><button id="grid">Grid</button><button id="button">Render</button></div>
        <script type="text/javascript" >
        
        const compare = (arr, key, callback) => arr.reduce((prev, curr) => (callback(prev[key], curr[key]) ? prev : curr), {});

        var clickSeries = function (event) {
            set_label();
            }; 
        
        var set_label = function () {
    
            var innen = innenTemperaturen(chart.series);
            min_innen = compare(innen, "minval", (a, b) => a < b);
            max_innen = compare(innen, "maxval", (a, b) => a > b);

            var aussen = aussenTemperaturen(chart.series);
            min_aussen = compare(aussen, "minval", (a, b) => a < b);
            max_aussen = compare(aussen, "maxval", (a, b) => a > b);
            
            if (min_innen.minval && min_aussen.minval) {                                                              
                var textlabel = "Aussen<br/>Max: " + max_aussen.name + "(" + max_aussen.maxval + "°C)<br/>" + 
                                "Min: " + min_aussen.name + "(" + min_aussen.minval + "°C)<br/>" +
                                "Innen<br/>Max: " + max_innen.name + "(" + max_innen.maxval + "°C)<br/>" +
                                "Min: " + min_innen.name + "(" + min_innen.minval + "°C)";
                }
            else if (min_innen.minval == undefined && min_aussen.minval ) {
                var textlabel = "Aussen<br/>Max: " + max_aussen.name + "(" + max_aussen.maxval + "°C)<br/>" + 
                                "Min: " + min_aussen.name + "(" + min_aussen.minval + "°C)";
                }
            else if (min_innen.minval && min_aussen.minval == undefined) {
                var textlabel = "Innen<br/>Max: " + max_innen.name + "(" + max_innen.maxval + "°C)<br/>" +
                                "Min: " + min_innen.name + "(" + min_innen.minval + "°C)";
                }
            else {
                var textlabel = "keine Datenserie aktiv."
                }

            if (!this.chart.lbl) {
                this.chart.lbl = this.chart.renderer.label(textlabel,100,100)
                .attr({
                    fill: \'#FCFFC5\',
                    zIndex: 8
                    })
                .add();

                }
            else {
                this.chart.lbl.destroy();
                this.chart.lbl = this.chart.renderer.label(textlabel,100,100)
                .attr({
                    fill: \'#FCFFC5\',
                    zIndex: 8
                    })
                .add();
                }
        }

        function innenTemperaturen(series_arr){
            return series_arr.filter(serie => serie.name != "Wetterstation" && serie.name != "Garage" && serie.visible != false).map( serie=> ({ name: serie.getName(), maxval: serie.dataMax, minval: serie.dataMin, vis: serie.visible }));
            }
        
         function aussenTemperaturen(series_arr){
            return series_arr.filter(serie => serie.name == "Wetterstation" && serie.visible != false).map( serie=> ({ name: serie.getName(), maxval: serie.dataMax, minval: serie.dataMin, vis: serie.visible }));
            }

         
        $(\'#container\').highcharts(%%%%, function(chart){
            
            } );
        
        
        var chart = $(\'#container\').highcharts();    
        Highcharts.addEvent(chart, "redraw", clickSeries);
        
        
        
        $(\'#nogrid\').click(function () {
            
            chart.update({
                xAxis: {gridLineWidth: 0}
                });
            });

        $(\'#grid\').click(function () {
            chart.update({
                xAxis: {gridLineWidth: 1}
                });
            });

     $(\'#button\').click(function () {
            alert (set_label);
            });

        </script>';