Guten Abend
In der Hoffnung, dass hier jemand sich etwas mit JavaScript und Ajax
auskennt,
traue ich mich mal, hier meinen ersten Versuch mit diesen Sprachen zu
posten:
1
</head>
2
<script>
3
functiongetdata(){
4
$.getJSON("data1.php?n=1500",function(data){
5
6
newMorris.Line({
7
element:"graph",
8
data:data,
9
xkey:"date",
10
ykeys:['wama_1','wama_2'],
11
labels:['Wama_1','Wama_2'],
12
lineColors:['#1111ff','#ff1111'],
13
pointSize:['0'],
14
hideHover:['always'],
15
smooth:['false']
16
});//Morris.Line
17
18
setTimeout("getdata()",5000);
19
});// getJSON
20
21
}//function getdata
22
23
getdata()
24
25
</script>
26
27
<body>
28
<divid="graph"style="height: 300px"></div>
29
</body>
"Mein" Code besteht eigentlich nur aus dem Line-Graph Beispiel der
Morris.js Graph Bibliothek.
Prinzipiell funktioniert der Code auch, er werden die Daten aus der
data1.php Datei gelesen und dargestellt.
Nur wird alle 5 Sekunden ein neuer Graph unter dem bisherigen Graph
dargestellt / hinzugefügt.
Das soll so natürlich nicht sein.
Wie kann ich erreichen, dass die Daten neu eingelesen werden und der
Graph damit aktualisiert wird?
Muss der alte Graph erst gelöscht werden?
Ist dann kurzzeitig eine weiße Fläche zu sehen?
Dann wäre das Prinzip ja irgendwie blöd und ich hätte auch alles mit
einem Iframe und Meta-Refresh lösen können.
Im Anhang ein Bild wie es gerade aussieht.
Das Ganze soll ein Monitoring für unsere beiden Waschmaschinen werden.
Danke und Gruß
Kolja
Hi Frank
Ja, die Zeile ruft die Funktion getdata() alle 5 Sekunden auf,
meine Idee war ja, dass sich der Graph damit alle 5 Sekunden
aktualisiert.
Wenn ich die Zeile rausnehme, dann ist die Seite ja "statisch".
Daher die Frage: Wie kann ich den div aktualisieren?
Gruß Kolja
Kolja L. schrieb:> Wie kann ich erreichen, dass die Daten neu eingelesen werden und der> Graph damit aktualisiert wird?
Morris Doku:
Note 2: if you need to update the plot, use the setData method on the
object that Morris.Line returns. There's a setData example in the GitHub
repo.
Du musst also mit den ersten Daten das Morris.Line Objekt anlegen und in
einer Variable außerhalb des Scopes von getData anlegen. Bei den
weiteren Daten rufst du dann auf der Variable setData mit den neuen
Daten auf.
Du meinst wahrscheinlich dieses Beispiel:
https://github.com/morrisjs/morris.js/blob/master/examples/updating.html
Das bekomme ich aber nicht mal ohne es zu verändern zum Laufen.
Geschweige, dass ich wüsst, wo ich dort die url zu der php Datei
einfügen muss.
Ich verstehe dieses Javascript einfch zu wenig.
Vielleicht belasse ich es bei einem meta-refresh im iframe.
Kolja L. schrieb:> Du meinst wahrscheinlich dieses Beispiel:
Ich habe mir das Beispiel nicht angeschaut, aber mit meiner Erklärung
kannst du es ja in deinem Code einfach einbauen. Wenn du nicht
weiterkommst, dann poste deinen Code mit dem Versuch.
Das Problem ist jetzt nichts JS spezifisches, sondern
Objektorientierung. Du legst ein Graphobjekt an und dann setzt du immer
wieder neue Daten.
Schreibe Dir eine Initialisierungsfunktion wo Du diese Variable
erzeugst. In dieser Funktion kannst Du auch gleich SetTimeout mit unter
bringen.
In Deiner geposteten Funktion greifst Du einfach auf diese Ojectvariable
zu und modifizierst die Daten
Zeno schrieb:> Allerdings ist es ausreichend setTimeout einmal aufzurufen.
setTimeout muss immer wieder neu aufgerufen werden. Du meinst vermutlich
setInterval.
ich nehme stark an data liegt als Array vor..
oder ist das ein JSOn Objekt?
Naja, jdf sollte es so funktionieren ohne es getestet zu haben
1
</head>
2
<script>
3
var nReloads = 0;
4
var graph = new Morris.Line({
5
element: "graph",
6
data: [],
7
xkey: "date",
8
ykeys: ['wama_1', 'wama_2'],
9
labels: ['Wama_1', 'Wama_2'],
10
lineColors: ['#1111ff',' #ff1111'],
11
pointSize: ['0'],
12
hideHover: ['always'],
13
smooth: ['false']
14
}); //Morris.Line
15
16
function getdata(){
17
$.getJSON("data1.php?n=1500", function(data)
18
{
19
nReloads++;
20
graph.setData(data);
21
$('#reloadStatus').text(nReloads + ' reloads');
22
setTimeout("getdata()",5000);
23
}); // getJSON
24
25
} //function getdata
26
27
getdata()
28
29
</script>
30
31
<body>
32
<div id="graph" style="height: 300px"></div>
33
<div id="reloadStatus"> initial data</div>
34
</body>
Ich hab mal ein reloadStatus div hinzugefügt gemäss dem Beispielcode,
das sollte die Anzahl der Schleifen zählen, damit Du siehst ob es sich
aktualisiert auch bei statischen Daten;
kannst es ja nachher entfernen.
Ich halte das setTimeout übrigens für die elegantere Lösung als
SetInterval,
da es terminiert im Fehlerfall und eben nicht bis in alle Ewigkeit alle
fünf Sekunden auf dem Server rumhämmert solange die Seite geöffnet ist.
TotoMitHarry schrieb:> Oder einfach ein:> document.getElementById('graph').innerHTML = "";> als erste Zeile in/hinter getdata(){ einfügen.
Hallo,
genau so muss es sein. Das Problem hierbei ist, dass die Funktion die
durch getData mit new Morris() immer ein neues Objekt erzeugt und an das
div hängt.
Wenn Du vor getData die Kinder des div löschst und anschließend wie
gehabt getData aufrufst, sollte es funktionieren.
D.h. Dein Ursprungscode war vollkommen korrekt. Lediglich die Zeile von
TotoMitHarry ergänzen.
Gruß
Frank
TotoMitHarry schrieb:> document.getElementById('graph').innerHTML = "";> als erste Zeile in/hinter getdata(){ einfügen.
Oder da jquery im Spiel ist
$('#graph').empty();
AAABER mal ehrlich das Div zu leeren
und neu zu erstellen statt die daten zu aktualisieren
Frank L. schrieb:> Hallo,>> genau so muss es sein. Das Problem hierbei ist, dass die Funktion die> durch getData mit new Morris() immer ein neues Objekt erzeugt und an das> div hängt.>
ist exakt genau FALSCH!
also klar, es funktioniert, ist nur ziemlich das uneleganteste was man
machen kann...
Das ist wie den Briefkopf für jeden Brief einzeln zu erstellen, statt
das fertige Template von gestern zu benutzen ;)
Also einmal Briefkopf
(globalen Morris graphen in "graph" abgelegt)
und bei jedem durchlauf nur den Inhalt (Daten) erneuern,
der Webbrowser braucht dann auch weniger CPU ;)
me culpa, Du hast natürlich recht. Besser ist es den graph zu
aktualisieren. Aber der TO hat geschrieben keine Ahnung von AJAX und JS.
So ist es am einfachsten.
Der korrekt Syntax für eine Aktualisierung wäre hier zu finden:
https://github.com/morrisjs/morris.js/blob/master/examples/updating.html
Gruß
Frank
M.K. B. schrieb:> Zeno schrieb:>> Allerdings ist es ausreichend setTimeout einmal aufzurufen.>> setTimeout muss immer wieder neu aufgerufen werden. Du meinst vermutlich> setInterval.
Ja stimmt. Ich verwende auf meine Seite setInterval - habe ich
verwechselt
Frank L. schrieb:> me culpa, Du hast natürlich recht. Besser ist es den graph zu> aktualisieren.
kein Ding
Frank L. schrieb:> Aber der TO hat geschrieben keine Ahnung von AJAX und JS.
genau deswegen war ich kleinlich ;)
Ich find beides tut sich nix was die Komplexität angeht;
und die 'vom Entwickler so vorgesehene' Variante ist in der Regel die
bessere Wahl ;)
Moin
Erstmal vielen Dank, dass ihr euch so um mich bemüht.
Ich habe verucht euren Erklärungen zu folgen, aber dafür fehlt mir
tatsächlich das Wissen um Javascript.
Nun habe ich mir besagtes Beispiel nochmal angeschaut bzw. ausprobiert.
Wenn ich mir das ganze git runterlade und das updating Beispiel starte
funktioniert es.
Sobald es sich auf meinem Webspace befindet nicht mehr.
Dabei habe ich die vier lokal eingebundenen Skripte einfach mit in das
Stammverzeichnis gelegt und die Pfade angepasst.
Sind auch alle erreichbar.
Als Ausgabe bekomme ich, neben der Überschrift, einen KAsten mit
Scrollbalken und dem Inhalt des JS-Skriptes als Text angezeigt.
Kannsich das jemand erklären?
Hi sid
Geil, vielen Dank für die Kommentare.
Jetzt verstehe ich zumindest, warum data:[] richtig sein muss.
Wir erstellen quasi ein Objekt mit Loch und rufen es später auf und
füllen das Loch mit den Daten :-)
Leider passiert das anscheinend noch nicht bei mir.
Die Seite bleibt weiß, bis auf den Text " initial data".
Die Dateh aus der PHP Datei sehen so aus:
Naja solange da "initial data"
da steht wurde getdata() nicht aufgerufen..
ich nehme an das Ding läuft in deinem Localhost (xampp oder so?)
Also schau mal bitte in deinem Browser im javascript error log..
vielleicht hab ich n Tippfehler drin.
der ursprüngliche getdata() Aufruf ist so wie er ist nicht sonderlich
schön,
könnte ja sein, dass noch nicht alles geladen ist, dann läuft er ins
Leere,
deswegen ist es schöner ihn in ein "onready" zu packen,
oder manchmal schlicht in den footer der html zu setzen.
In dem Fall sollte es mMn gehen,
öffne einfach mal die Konsole im Browser
und gib dort nochmal getdata(); ein (entertaste nicht vergessen)
wenn dann immernoch initial data da steht hab ich bestimmt n TippFehler
drin ;)
oder falls Du's online hast, gib mir mal den Link dann schau ich selbst
wo's klemmt.
Es kann auch sein, dass "setData" die JSON Objekte nicht parsed;
ich hab nichteinmal in den Quelltext von Morris geguckt um ehrlich zu
sein.
Ich hätte behauptet er tut
Falls nicht, muss man sich halt nen Parser bauen,
das ist aber auch relativ banal
1
function getdata()
2
{
3
$.getJSON("data1.php?n=1500", function(data)
4
{
5
// ein neues leeres Array
6
var parseddata=[];
7
for(i=0; i< data.length; i++)
8
{
9
// das Array mit JSON geparsten Objekten füllen
10
parseddata.push(JSON.parse(data[i]));
11
}
12
Mgraph.setData(parseddata); // und dieses nun volle Array dann dem graphen zuschustern
13
nReloads++;
14
$('#reloadStatus').text(nReloads + ' reloads');
15
setTimeout(getdata,5000);
16
});
17
}
Achte darauf dass ich das MorrisGraph Objekt einmal "Mgraph"
und zuletzt nur "graph" genannt hatte (letzteres ist allerdings mit dem
html div leicht verwirrend, deswegen macht ein aussagekräftigere Name
Sinn)
Aaalso
ich hab das Morris Dingen jetzt mal geladen und in meinen localhost
geschoben
wenn ich Deine data1.php richtig verstanden habe
rufst Du 1500 datenpunkte ab,
das läuft in meinem Browser nicht, der morrisgraph braucht länger zum
errechnen der Grafik als 5Sekunden, damit bleibt das Dingen weiss
500 stellt kein Problem dar, ab 1000 wird's schwierig bei meiner alten
xp Kiste hier.
Also mein Test mit nur 150 Datenpunkten.
ich hab ne php gebastelt die zufällige Nummern erzeugt
und die Sekunden mit Übertragen im Datum damit Morris nicht alle Punkte
auf eine Position der Zeitachse malt ;)
Ich denke Du kannst dem Beispiel folgen
(einfach beides in den example-Unterordner kopieren)
sid schrieb:> Naja solange da "initial data"> da steht wurde getdata() nicht aufgerufen..> ich nehme an das Ding läuft in deinem Localhost (xampp oder so?)> Also schau mal bitte in deinem Browser im javascript error log..> vielleicht hab ich n Tippfehler drin.
Nabend
Ne, das ganze läuft schon im Internet, aber ioch würde die URL ungerne
öffentlich machen.
Die Konsole gibt mir aber folgende Fehlermeldung aus:
TypeError: Morris.Line is not a constructor
Und das auch mit deinem neuene Beispiel.
Warum läuft das denn bei dir und bei mir nicht?
Habe W10 und n aktuellen Firefox, daran sollte es nicht scheitern.
Danke für die ganze Unterstützung :-)
aktuell heisst nicht immer besser, aber das ist ein gaaanz anderes Thema
;)
Also, kein Konstruktor heisst, morris.js ist nicht korrekt eingebunden;
möglicherweise fehlt jquery.
oder liegt in falscher version vor (das reicht manchmal)
ich kann ohne nachzusehen leider keine "korrekte" Antwort geben,
und wenn Du die url nicht teilen möchtest müssen wir eben anders an die
Sache ran.
Also mach bitte mal folgendes:
lade diese zip:
https://github.com/morrisjs/morris.js/archive/0.5.1.zip
Entpacke das in einen Order in deinem webarchiv...
sagen wir "var/www/morristest/"
Nun kopiere den Inhalt meines zip Archivs von oben
nach "/var/www/morristest/examples"
[nichts in den Dateien ändern bitte, schau nach, tut nichts böses ;)]
Und zu guter letzt rufe
<deineurl>/morristest/data1.html im Browser auf
Öffne die Browser Konsole (STRG+UMSCHALT+J)
und mach mir von der Seite und der Konsole nen Screenshot bitte
( deine url kannste nachträglich im grafikprogramm schwärzen wenn Du
magst,
mich interessiert der exakte Wortlaut und was wirklich zu sehen ist)
Moin
Licht am Ende des Tunnels :-)
sid schrieb:> <deineurl>/morristest/data1.html im Browser auf
Das funktioniert!
Und wenn ich dann einfach meine echen Daten einbinde funktioniert es
auch noch :-)
Aber wenn ich das Ganze in mein Stammverzeichnis lege, ging es (trotz
angepasster Pfade) zuerst nicht.
Der Unterschied und vielleicht die Erklärung für das mMn etwas
mysteriöse Verhalten:
SSL
Mit https gehts nicht, mit http gehts(! :-).
Die Domain erzwingt kein SSL, meine Stammverzeichnis ist mit https im
Browser gespeichert, den Pfad zu deinem Beispiel habe ich händisch
getippt.
Ich suche mal nach einer Lösung.
Eins noch:
Wenn die Seite aufgerufen wird, erscheint der JS Code solange, bis die
1500 Datensätze geladen worden sind (habe das Timeout einfach auf 10s
gestellt ;-).
Bekommt man das noch relativ einfach weg?
Vielleicht sogar durch so ein sich drehendes Rad?
Lieben Gruß und besten Dank
Kolja