Wprowadzenie do serwisu www - METEO (wersja 0.95 [2020.07.16])
W ramach laboratorium zostaną przedstawione proste skrypty umożliwiające odczyt danych
z centralnej bazy danych w której gromadzone są dane pomiarowe z lokalnych stacji meterologicznych. Dane
udostępniane są w formacie CSV (ang. Comma Separated Values - wartości rozdzielone przecinkiem)
lub w formacie JSON (ang. JavaScript Object Notation). W ramach zajęć przedstawione zostaną obydwa formaty danych i
metody pobierania ich z serwisu. W kolejnych ćwiczeniach zostaną zaprezentowane odpowiednie skrypty opracowane
w języku HTML i JavaScript przetwarzające dane do odpowiednich wykresów i tabel.
Plan laboratorium
Ćwiczenie 1. Dane w formacie CSV i JSON
Dane w formacie CSV
Dane w formacie CSV (ang. Comma Separated Values - wartości rozdzielone przecinkiem) [1] wykorzystywane są do przechowywania danych
w plikach tekstowych lub przenoszenia danych pomiędzy aplikacjami z wykorzystaniem typu MIME [2] - text/csv.
Specyfiakacja struktury danych została zamieszczona w dokumencie RFC 4180 [3]. W ramach tego formatu
moźemy wyróżnić rekordy, w których wartości są oddzielone od siebie seperatorem (przecinek, średnik lub znak tabulacji). Kolejne rekordy oddzielone
są znakami końca linii CRLF.
Dla serwisu METEO opracowano polecenia zwracające pary wartości ( czas pomiaru, wielkość mierzona) np. czas i temperatura. Przykładowy
rekord dla czasu i temperatury przedstawiono poniżej.
2014-06-24 10:00:01, 14.6
Przykładowy plik w formacie CSV data_csv.txt
Dane w formacie JSON
JSON jest formatem wymiany danych pomiędzy systemami komputerowymi opracowanymi w różnych językach programistycznych
[4,5].
Odpowiednie biblioteki przetwarzające dane dostępne są w większości z nich. Jest formatem tekstowym, będącym podzbiorem języka JavaScript.
Struktura tego formatu danych została opisana w dokumencie RFC 4627 [6].
Obecną implementację w języku ECMA Script można znaleźć w dokumencie ECMA-404 [7].
Podczas przesyłania danych w formacie JSON wykorzystujemy typ MIME - application/json. Standardowym system kodowania jest format UTF-8
[8,9]
Struktura jednego rekordu danych generowanego przez serwis METEO dla wszystkich typów danych pomiarowych zawartych w bazie przedstawiona
została poniżej.
{"time":"2014-06-01 00:00:05", "station":"s0",
"data":{"pa":"988.40","ha":"81.00","ws":"1.30","t0":"10.00","p0":"1013.00","ta":"13.20","ra":"1.77","wd":"225.00"}}
Kolejne klucze przedstawiają następujące wielkości meteorologiczne:
- time - czas pomiaru
- station - identyfikator stacji
- p0 - ciśnienie na poziomie morza
- ta - temperatura
- t0 - temperatura punktu rosy
- ha - wilgotność
- r1 - opad w ostaniej godzinie
- ra - opad
- wd - kierunek wiatru
- ws - prędkość wiatru
- wg - chwilowa prędkość wiatru
- h0 - wysokość nad poziom morza
Przykładowy plik w formacie JSON : data_json.txt
Ćwiczenie 2. Odczyt danych z serwisu METEO w formacie CSV i JSON
Dane w formacie CSV
Odczyt danych z serwisu WWW w formacie CSV następuje poprzez polecenie:
http://mech.fis.agh.edu.pl/meteo/rest/csv/{par}/{station}/{start-data}/{end-data}
gdzie:
- {par}
- identyfikator mierzonej wielkości meteorologicznej:
pres0 - ciśnienie na poziomie morza,
temp - temperatura,
temp0 - temperatura punktu rosy,
humi - wilgotność,
rain1 - opad w ciągu ostatniej godziny,
rain - opad dobowy,
windd - kierunek wiatru,
winds - prędkość wiatru
i windg - chwilowa prędkość wiatru.
- {station}
- identyfikator stacji
- {start-date}
- początkowa data pomiarów
- {end-date}
- końcowa data pomiarów
Przykładowe polecenie pobierające dane ze stacji "s000" dotyczące temperatury z okresu od 2020-07-10 do 2020-07-15.
http://mech.fis.agh.edu.pl/meteo/rest/csv/temp/s000/2020-07-10/2020-07-15
Dane w formacie JSON
Odczyt danych z serwisu WWW w formacie JSON następuje poprzez polecenie:
http://mech.fis.agh.edu.pl/meteo/rest/json/{par}/{station}/{start-data}/{end-data}
gdzie:
- {par}
- identyfikator mierzonej wielkości meteorologicznej:
all - wszystkie parametry,
pres0 - ciśnienie na poziomie morza,
temp - temperatura,
temp0 - temperatura punktu rosy,
humi - wilgotność,
rain1 - opad w ciągu ostatniej godziny,
rain - opad dobowy,
windd - kierunek wiatru,
winds - prędkość wiatru
i windg - chwilowa prędkość wiatru.
- {station}
- identyfikator stacji
- {start-date}
- początkowa data pomiarów
- {end-date}
- końcowa data pomiarów
Przykładowe polecenie pobierające dane z okresu od 2020-07-10 do 2020-07-15.
http://mech.fis.agh.edu.pl/meteo/rest/json/all/s000/2020-07-10/2020-07-15
Ćwiczenie 3. Odczyt danych z serwisu METEO i prezentacja w tabeli HTML
Dane w formacie CSV
Do prezentacji danych w postaci tabeli wykorzystamy odpowiedni skrypt opracowany w języku HTML5 [1]. Krótkie
wprowadzenie do języka HTML5 można znaleźć na stronach serwisów: W3Schools [2] lub "Kurs HTML" [3]. W ramach
skryptu wykorzystany został element <input> typu "button", w którym obsługując zdarzenie "onclick()" w JavaScript wywołujemy funkcję sendRequest() pobierającą
dane z serwera z wykorzystaniem technologii AJAX. Element <div> z identyfikatorem "result" jest węzłem dokumentu HTML w którym umieścimy dane pobrane z serwera.
Plik lab_ex01.html ( [listing skryptu] link do skryptu )
#1: <!DOCTYPE html>
#2: <html>
#3: <head>
#4: <meta charset="utf-8">
#5: <title>Ajax: Odczyt danych z serwera</title>
#6: <link type="text/css" href="lab.css" rel="stylesheet" />
#7: <script src="lab_ex01.js" type="text/javascript"></script>
#8: </head>
#9: <body>
#10: <div style="text-align:center" >
#11: <table border="1" bgcolor="gray">
#12: <tr><th><big>Ajax: Odczyt danych z serwera</big></th></tr>
#13: </table>
#14: <br />
#15: <form action="#">
#16: <input type="button" value="Pobierz dane z serwera" onclick="sendRequest()"/>
#17: </form>
#18: </div>
#19: <div id="result"></div>
#20: </body>
#21: </html>
Przedstawiony poniżej skrypt składa się z trzech funkcji, które obsługują technologię AJAX. Technologia AJAX (ang. Asynchronous JavaScript and XML, asynchroniczny JavaScript i XML)
umożliwiają opracowanie aplikacji internetowych, w których interakcja przeglądarki z serwerem WWW odbywa się bez przeładowania całego dokumentu
wyświetlanego w przeglądarce [4, 5, 6, 7]. W standardowym modelu serwisu WWW, każda interakcja z serwerem WWW wymaga przeładowania całego dokumentu HTML wyświetlanego
w przeglądarce. W ramach technologii AJAX wykorzystujęmy następujące standardy: język HTML, język JavaScript, język XML [8] oraz standard DOM [9]. Do komunikacji pomiędzy przeglądarką a serwerem WWW wykorzystywany jest obiekt XMLHttpRequest (XHR) obsługiwany
przez język JavaScript.
Utworzenie instancji obiektu XHR jest realizowane w pierwszej funkcji getRequestObject() w poniższym skrypcie. Standardowo w języku
JavaScript obiekt ten tworzymy poleceniem "new XMLHttpRequest()" (linia kodu 7). Jednakże w starszych przeglądarkach IE (wersja 5 i 6) obiekt ten zostanie utworzony
poprzez polecenie "new ActiveXObject('Microsoft.XMLHTTP')" (linia kodu 5).
W kolejnej funkcji "sendRequest()" przygotowujemy obiekt XHR do wysłania na serwer WWW. Własność "onreadystatechange"
obsługuje funkcję, która zostanie wykonana po poprawnym odebraniu informacji z serwisu WWW poprzez przeglądarkę W naszym przykładzie jest to nazwa trzeciej funkcji "handleResponse"
umieszczonej w naszym skrypcie. Kolejne dwie linie kodu w funkcji są odpowiedzialne za wysłanie żądania na serwer. Metoda open() ustala adres serwera i metodę
protokołu HTTP wybraną do komunikacji z serwerem, w naszym przypadku jest to metoda GET. Metoda send() wysyła żądanie na serwer.
Ostatnia funkcja "handleResponse()"
odpowiedzialna jest za obsługę zwrotnej informacji z serwera. Po sprawdzeniu czy kod odpowiedzi jest 4 (obsługa żądania zakończona), w własności "responseTEXT" obiektu XHR
znajdujemy zwróconą przez serwer informację. Teraz należy ją odpowiednio przetworzyć i wyświetlić na stronie. W odpowiedzi z serwera otrzymujemy dane w formacie CSV. Na początek
wykorzystując metodę "split()" umieszczamy kolejne rekordy dokumentu CSV w kolejnych rekordach tablicy txtLines[] (linia kodu 28). Następnie tworzymy tabelkę HTML
w zmiennej znakowej txt. W pętli for (linie kodu 33-36) przetwarzamy tablice txtLines umieszczając poszczególne wartości danych w kolejnych komórkach tablicy (linie 34 i 35).
Na koniec pozostaje umieszczenie tablicy na stronie. Realizowane jest poprzez metodę innerHTML [10] w standardzie DOM, która modyfikuje określony węzeł naszego dokumentu HTML.
Wybór węzła dokunujemy wykorzystując metodę "getElementById()" [11] obiektu "document".
Plik lab_ex01.js ( [listing skryptu] link do skryptu )
#1: var xhr;
#2: function getRequestObject() {
#3: // Utworzenie obiektu XMLHttpRequest
#4: if ( window.ActiveXObject) {
#5: return ( new ActiveXObject("Microsoft.XMLHTTP")) ;
#6: } else if (window.XMLHttpRequest) {
#7: return (new XMLHttpRequest()) ;
#8: } else {
#9: return (null) ;
#10: }
#11: }
#12: function sendRequest() {
#13: // Inicjalizacja obiektu xhr typu XMLHttpRequest
#14: xhr = getRequestObject() ;
#15: // Przydzielenie obserwatora do zdarzenia readystatechange
#16: // Utworzenie wlasnej implementacji obslugujacej zdarzenie
#17: xhr.onreadystatechange = handleResponse ;
#18: // Ustalenie adresu i protokolu HTTP
#19: xhr.open("GET", "http://mech.fis.agh.edu.pl/meteo/rest/csv/temp/s000/2020-07-10/2020-07-15", true);
#20: // Wyslanie zadania na serwer
#21: xhr.send(null);
#22: }
#23: function handleResponse() {
#24: if (xhr.readyState == 4) {
#25: //alert(xhr.responseText);
#26: var txtData = xhr.responseText ;
#27: var txtLines = [];
#28: txtLines = txtData.split(/\r\n|\n/);
#29: txtLines.pop();
#30: var Lines = [];
#31: var txt = "<p>Licza przetworzonych wierszy: " + txtLines.length.toString() + "</p>";
#32: txt += "<table class='data'><tr><th>Czas</th><th>Temperatura (C)</th></tr>" ;
#33: for (var i=0, max=txtLines.length; i<max; i++) {
#34: Lines = txtLines[i].split(',');
#35: txt += "<tr><td>" + Lines[0] + "</td><td>" + Lines[1] + "</td></tr>" ;
#36: }
#37: txt += "</table>" ;
#38: document.getElementById('result').innerHTML = txt;
#39: }
#40: }
Do sformatowania tesktu dokumentu HTML wykorzystane zostały polecenia języka arkuszy styli CSS (ang. Cascading Style Sheets) [12].
Plik CSS formatujący stronę - lab.css ( [listing skryptu] link do pliku )
#1: table.data { border-collapse:collapse; width:60%; font-size:12px; }
#2: table.data, table.data td, table.data th { border:1px solid blue; }
#3: table.data th { background-color: aqua; }
#4: table.data td { text-align:right ; padding-right:10px; }
#5: table.data tr:nth-child(old) { background-color: #f0f8ff; }
#6: table.data tr:nth-child(even) { background-color: #e8e8e8 }
Poniżej prezentacja uruchomionego przykładu (link do uruchomienia w nowym oknie lab_ex01.html).
Dane w formacie JSON
Do prezentacji danych w postaci tabeli wykorzystamy odpowiednie skrypty opracowane w języku HTML5, JavaScript i CSS. Funkcjonalność skryptów w języku HTML i CSS
jest analogicza do przedstawionych powyżej skryptów "lab_ex01.html" i "lab.css".
Plik lab_ex02.html ( [listing skryptu] link do skryptu )
#1: <!DOCTYPE html>
#2: <html>
#3: <head>
#4: <meta charset="utf-8">
#5: <title>Ajax: Odczyt danych z serwera</title>
#6: <link type="text/css" href="lab.css" rel="stylesheet" />
#7: <script src="lab_ex02.js" type="text/javascript"></script>
#8: </head>
#9: <body>
#10: <div style="text-align:center" >
#11: <table border="1" bgcolor="gray">
#12: <tr><th><big>Ajax: Odczyt danych z serwera</big></th></tr>
#13: </table>
#14: <br />
#15: <form action="#">
#16: <input type="button" value="Pobierz dane z serwera" onclick="sendRequest()"/>
#17: </form>
#18: </div>
#19: <div id="result"></div>
#20: </body>
#21: </html>
Podobnie jak dla formatu CSV został przygotowany odpowiedni skrypt w JavaScript pobierający dane z wykorzystaniem technologii AJAX. Dwie pierwsze funkcje "getRequestObject()"
i "sendRequest()" są identyczne do odpowiednich funkcji w skrypcie "lab_ex01.js". W trzeciej funcji "handleResponse()" różnica jest w przetworzeniu zwróconego wyniku.
Po przeczytaniu danych z własnoności "responseText" obiektu XHR wykorzystujemy funkcję "evel()" [13] w JavaScript do utworzenia tablicy obiektów (linia kodu 20).
Pojedynczy obiekt w tablicy zawiera dane przedstawione w ćwiczeniu 1 dla formatu danych JSON. Dostęp do określonego parametru pomiaru następuje przez wskazanie na numer obiektu
w tablicy i wskazanie określonego parametru. Przykładowo wpis "jsonObj[2].time" pobiera czas pomiaru dla trzeciego punktu pomiarowego w danych zwróconych przez serwer, a wpis
"jsonObj[2].data.temp" pobiera wartość temperatury dla tego punktu.
Plik lab_ex02.js ( [listing skryptu] link do skryptu )
#1: var request;
#2: function getRequestObject() {
#3: if ( window.ActiveXObject) {
#4: return ( new ActiveXObject("Microsoft.XMLHTTP")) ;
#5: } else if (window.XMLHttpRequest) {
#6: return (new XMLHttpRequest()) ;
#7: } else {
#8: return (null) ;
#9: }
#10: }
#11: function sendRequest() {
#12: request = getRequestObject() ;
#13: request.onreadystatechange = handleResponse ;
#14: request.open("GET", "http://mech.fis.agh.edu.pl/meteo/rest/json/all/s000/2020-07-10/2020-07-15", true);
#15: request.send(null);
#16: }
#17: function handleResponse() {
#18: if (request.readyState == 4) {
#19: //alert(request.responseText);
#20: var jsonObj=eval( "(" + request.responseText + ")" );
#21: //alert(jsonObj[0].data.p0);
#22: var txt = "<p>Licza przetworzonych wierszy: " + jsonObj.length.toString() + "</p>";
#23: txt += "<table class='data'><tr><th>Czas</th><th>Ciśnienie (hPa)</th></tr>"
#24: for (var i=0, max=jsonObj.length; i<max; i++) {
#25: txt += "<tr><td>" + jsonObj[i].time + "</td><td>" + jsonObj[i].data.p0 + "</td></tr>" ;
#26: }
#27: txt += "</table>" ;
#28: document.getElementById('result').innerHTML = txt;
#29: }
#30: }
Poniżej prezentacja uruchomionego przykładu (link do uruchomienia w nowym oknie lab_ex02.html).
Ćwiczenie 4. Tworzymy wykres określonej wielkości meteorologicznej
W ramach tego ćwiczenia zostanie przedstawiony skrypt umożliwiający tworzenie wykresów mierzonych wielkości fizycznych. Do realizacji
projektu wykorzystamy bibliotekę graficzną opracowaną w języku JavaScript dygraphs. Biblioteka dostępna jest pod adres URL
http://dygraphs.com/. Biblioteka wymaga danych w formacie CSV. Dane pobierane są w skrypcie opracowanym w języku
JavaScript. Skrypt lab_ex03.js jest modyfikacją skryptu lab_ex01.js, w którym zamiast tworzyć tabelkę wywołujemy funkcję graph() rysującą wykres.
Parametry wykorzystane do tworzenia wykresu - podpis wykresu "title", podpis osi y "ylabel", rysowanie punktów "drawPoints:true" i brak linii
łączącej poszczególne punkty pomiarowe "strokeWidth:0". W ramach ćwiczenia został przedstawiony wykres dla ciśnienia atmosferycznego, zmieniając
polecenie pobierające dane z serwera (skrypt lab_ex03.ja) zgodnie z informacją w ćwiczeniu drugim można otrzymać wykresy dla każdej mierzonej
wielkości meteorologicznej (dodatkowo należy również zmienić opis rysunku i osi y w funkcji graph()).
Plik lab_ex03.html ( [listing skryptu] link do skryptu )
#1: <!DOCTYPE html>
#2: <html>
#3: <head>
#4: <meta charset="utf-8">
#5: <script type="text/javascript" src="dygraphs.js" ></script>
#6: <script type="text/javascript" src="lab_ex03.js" ></script>
#7: <script type="text/javascript" >
#8: function graph(csv_data) {
#9: var g3 = new Dygraph(
#10: document.getElementById("graphdiv3"),
#11: csv_data,
#12: {
#13: title: 'Temperatura',
#14: ylabel: 'Temperatura (C)',
#15: strokeWidth: 0,
#16: drawPoints: true
#17: //drawGapEdgePoints: true
#18: } );
#19: }
#20: </script>
#21: </head>
#22: <body onload="sendRequest()">
#23: <div id="myDiv"></div>
#24: <div id="graphdiv3" style="width:500px; height:300px;"></div>
#25: </body>
#26: </html>
Plik lab_ex03.js ( [listing skryptu] link do skryptu )
#1: var request;
#2: function getRequestObject() {
#3: if ( window.ActiveXObject) {
#4: return ( new ActiveXObject("Microsoft.XMLHTTP")) ;
#5: } else if (window.XMLHttpRequest) {
#6: return (new XMLHttpRequest()) ;
#7: } else {
#8: return (null) ;
#9: }
#10: }
#11: function sendRequest() {
#12: request = getRequestObject() ;
#13: request.onreadystatechange = handleResponse ;
#14: request.open("GET", "http://mech.fis.agh.edu.pl/meteo/rest/csv/temp/s000/2020-07-10/2020-07-15/", true);
#15: request.send(null);
#16: }
#17: function handleResponse() {
#18: myDiv = document.getElementById("myDiv");
#19: if (request.readyState == 1) {
#20: myDiv.innerHTML += "Status zadania:" ;
#21: }
#22: else if (request.readyState == 2) {
#23: myDiv.innerHTML += "." ;
#24: }
#25: else if (request.readyState == 3) {
#26: myDiv.innerHTML += "." ;
#27: }
#28: else if (request.readyState == 4) {
#29: //alert(request.responseText);
#30: var data = request.responseText;
#31: graph(data);
#32: }
#33: }
Poniżej prezentacja uruchomionego przykładu (link do uruchomienia w nowym oknie lab_ex03.html).
Ćwiczenie 5. Wyznaczamy dobową wartość średnią, minimalna i maksymalną
W ramach tego ćwiczenia zostaną wyznaczone wartości śrenie, minimalne i maksymalne dla pomiarów dobowych. W ramach ćwiczenia wykorzystamy trzy skrypty: lab_ex04.html, lab_ex04.js i lab.css.
Skrypt lab_ex04.js jest analogiczny do skryptu lab_ex02.js. Wykorzystując technologię AJAX czytamy z serwisu WWW dane w formacie JSON. W ramach skryptu
lab_ex04.html został zawarty kod HTML i skrypt w języku JavaScript przeliczający dane pomiarowe w funkcji values(). Schemat blokowy funkcji values() przedstawiono na rysunku poniżej.
Na schemacie blokowym nie umieszczono wszystkich zmiennych reprezentujących poszczególne wielkości pomiarowe.
Funkcja values() jest wywoływana w funkcji handleResponse() w skrypcie lab_ex04.js po poprawnym pobraniu danych w formacie JSON przez technologię AJAX. Początkowo w liniach kodu od 13 do 46
initializujemy zmienne wykorzystywane w programie poprzez przypisanie wartości 0 lub wartości pierwszego analizowanego pomiaru (np. data w linii kodu 14 czy wartości
minimalne i maksymalne w liniach kodu 26 - 43). Zmienna n reprezentuje liczbę pomiarów w ciagu doby, natomiast zmienna id kolejną analizowaną dobę, W ramach
pętli, która zaczyna się w linii 47 a kńczy w linii 115, analizowane są kolejne wartości pomiarowe. Pętla kończy się po przeanalizowaniu wszystkich danych. Po odczytaniu daty pomiaru w kolejnym pomiarze
sprawdzamy czy należy on do analizowanej doby czy nie. Jeżeli należy to dodajemy kolejne wartości pomiarów do tablicy avgValue (linie 55-62) oraz sprawdzamy wartości
minimalne (63-70) i maksymalne (71-78). Jeżeli jest to inna data to wyliczamy wartości średnie (linie 81-88) dzieląc zsumowane wartości pomiarów przez ich liczbę
w czasie analizowanej doby, zwiększamy wartość zmiennej id o jeden i tworzymy odpowiednie elementy w tablicach avgValue, minValue i maxValue
dla następnej doby. Zmienną n zerujemy.
Plik lab_ex04.html ( [listing skryptu] link do skryptu )
#1: <!DOCTYPE html>
#2: <html>
#3: <head>
#4: <meta charset="utf-8">
#5: <link type="text/css" href="lab.css" rel="stylesheet" />
#6: <script type="text/javascript" src="lab_ex04.js" ></script>
#7: <script type="text/javascript">
#8: function datesEqual(d1,d2,m1,m2,y1,y2) {
#9: ret = d1 === d2 && m1 === m2 && y1 === y2;
#10: return ret;
#11: }
#12: function values(jsonObj) {
#13: var avgValue = [];
#14: var s = jsonObj[0].time;
#15: var bits = s.split(/\D/);
#16: date1 = new Date(bits[0], --bits[1], bits[2], bits[3], bits[4]);
#17: y1 = date1.getFullYear();
#18: m1 = date1.getMonth();
#19: d1 = date1.getDate();
#20:
#21: var dateValue = [];
#22: var minValue = [];
#23: var maxValue = [];
#24:
#25: dateValue[0] = new Date(y1, m1, d1);
#26: minValue[0] = [];
#27: minValue[0][0] = parseFloat(jsonObj[0].data.p0);
#28: /*
#29: minValue[0][1] = parseFloat(jsonObj[0].data.ha);
#30: minValue[0][2] = parseFloat(jsonObj[0].data.ws);
#31: minValue[0][3] = parseFloat(jsonObj[0].data.t0);
#32: minValue[0][4] = parseFloat(jsonObj[0].data.);
#33: minValue[0][5] = parseFloat(jsonObj[0].data.ta);
#34: minValue[0][6] = parseFloat(jsonObj[0].data.ra);
#35: minValue[0][7] = parseFloat(jsonObj[0].data.wd);
#36: */
#37: maxValue[0] = [];
#38: maxValue[0][0] = parseFloat(jsonObj[0].data.p0);
#39: /*
#40: maxValue[0][1] = parseFloat(jsonObj[0].data.ha);
#41: maxValue[0][2] = parseFloat(jsonObj[0].data.ws);
#42: maxValue[0][3] = parseFloat(jsonObj[0].data.t0);
#43: maxValue[0][4] = parseFloat(jsonObj[0].data.p0);
#44: maxValue[0][5] = parseFloat(jsonObj[0].data.ta);
#45: maxValue[0][6] = parseFloat(jsonObj[0].data.ra);
#46: maxValue[0][7] = parseFloat(jsonObj[0].data.wd);
#47: */
#48: avgValue[0] = [0,0,0,0,0,0,0,0];
#49: var n =0;
#50: var id = 0;
#51: for (var i=0, max=jsonObj.length; i<max; i++) {
#52: s = jsonObj[i].time;
#53: bits = s.split(/\D/);
#54: date2 = new Date(bits[0], --bits[1], bits[2], bits[3], bits[4]);
#55: d2 = date2.getDate();
#56: m2 = date2.getMonth();
#57: y2 = date2.getFullYear();
#58: if ( datesEqual(d1,d2,m1,m2,y1,y2) ) {
#59: avgValue[id][0] += parseFloat(jsonObj[i].data.p0);
#60: /*
#61: avgValue[id][1] += parseFloat(jsonObj[i].data.ha);
#62: avgValue[id][2] += parseFloat(jsonObj[i].data.ws);
#63: avgValue[id][3] += parseFloat(jsonObj[i].data.t0);
#64: avgValue[id][4] += parseFloat(jsonObj[i].data.p0);
#65: avgValue[id][5] += parseFloat(jsonObj[i].data.ta);
#66: avgValue[id][6] += parseFloat(jsonObj[i].data.ra);
#67: avgValue[id][7] += parseFloat(jsonObj[i].data.wd);
#68: */
#69: if ( minValue[id][0] > parseFloat(jsonObj[i].data.p0) ) minValue[id][0] = parseFloat(jsonObj[i].data.p0);
#70: /*
#71: if ( minValue[id][1] > parseFloat(jsonObj[i].data.ha) ) minValue[id][1] = parseFloat(jsonObj[i].data.ha);
#72: if ( minValue[id][2] > parseFloat(jsonObj[i].data.ws) ) minValue[id][2] = parseFloat(jsonObj[i].data.ws);
#73: if ( minValue[id][3] > parseFloat(jsonObj[i].data.t0) ) minValue[id][3] = parseFloat(jsonObj[i].data.t0);
#74: if ( minValue[id][4] > parseFloat(jsonObj[i].data.p0) ) minValue[id][4] = parseFloat(jsonObj[i].data.p0);
#75: if ( minValue[id][5] > parseFloat(jsonObj[i].data.ta) ) minValue[id][5] = parseFloat(jsonObj[i].data.ta);
#76: if ( minValue[id][6] > parseFloat(jsonObj[i].data.ra) ) minValue[id][6] = parseFloat(jsonObj[i].data.ra);
#77: if ( minValue[id][7] > parseFloat(jsonObj[i].data.wd) ) minValue[id][7] = parseFloat(jsonObj[i].data.wd);
#78: */
#79: if ( maxValue[id][0] < parseFloat(jsonObj[i].data.p0) ) maxValue[id][0] = parseFloat(jsonObj[i].data.p0);
#80: /*
#81: if ( maxValue[id][1] < parseFloat(jsonObj[i].data.ha) ) maxValue[id][1] = parseFloat(jsonObj[i].data.ha);
#82: if ( maxValue[id][2] < parseFloat(jsonObj[i].data.ws) ) maxValue[id][2] = parseFloat(jsonObj[i].data.ws);
#83: if ( maxValue[id][3] < parseFloat(jsonObj[i].data.t0) ) maxValue[id][3] = parseFloat(jsonObj[i].data.t0);
#84: if ( maxValue[id][4] < parseFloat(jsonObj[i].data.p0) ) maxValue[id][4] = parseFloat(jsonObj[i].data.p0);
#85: if ( maxValue[id][5] < parseFloat(jsonObj[i].data.ta) ) maxValue[id][5] = parseFloat(jsonObj[i].data.ta);
#86: if ( maxValue[id][6] < parseFloat(jsonObj[i].data.ra) ) maxValue[id][6] = parseFloat(jsonObj[i].data.ra);
#87: if ( maxValue[id][7] < parseFloat(jsonObj[i].data.wd) ) maxValue[id][7] = parseFloat(jsonObj[i].data.wd);
#88: */
#89: n++;
#90: } else {
#91: avgValue[id][0] /= n;
#92: /*
#93: avgValue[id][1] /= n;
#94: avgValue[id][2] /= n;
#95: avgValue[id][3] /= n;
#96: avgValue[id][4] /= n;
#97: avgValue[id][5] /= n;
#98: avgValue[id][6] /= n;
#99: avgValue[id][7] /= n;
#100: */
#101: id++;
#102: y1=y2;
#103: m1=m2;
#104: d1=d2;
#105: dateValue[id] = new Date(y1, m1, d1);
#106: avgValue[id] = [0,0,0,0,0,0,0,0];
#107: minValue[id] = [];
#108: minValue[id][0] = parseFloat(jsonObj[i].data.p0);
#109: /*
#110: minValue[id][1] = parseFloat(jsonObj[i].data.ha);
#111: minValue[id][2] = parseFloat(jsonObj[i].data.ws);
#112: minValue[id][3] = parseFloat(jsonObj[i].data.t0);
#113: minValue[id][4] = parseFloat(jsonObj[i].data.p0);
#114: minValue[id][5] = parseFloat(jsonObj[i].data.ta);
#115: minValue[id][6] = parseFloat(jsonObj[i].data.ra);
#116: minValue[id][7] = parseFloat(jsonObj[i].data.wd);
#117: */
#118: maxValue[id] = [];
#119: maxValue[id][0] = parseFloat(jsonObj[i].data.p0);
#120: /*
#121: maxValue[id][1] = parseFloat(jsonObj[i].data.ha);
#122: maxValue[id][2] = parseFloat(jsonObj[i].data.ws);
#123: maxValue[id][3] = parseFloat(jsonObj[i].data.t0);
#124: maxValue[id][4] = parseFloat(jsonObj[i].data.p0);
#125: maxValue[id][5] = parseFloat(jsonObj[i].data.ta);
#126: maxValue[id][6] = parseFloat(jsonObj[i].data.ra);
#127: maxValue[id][7] = parseFloat(jsonObj[i].data.wd);
#128: */
#129: n=0;
#130: }
#131: }
#132: avgValue[id][0] /= n;
#133: /*
#134: avgValue[id][1] /= n;
#135: avgValue[id][2] /= n;
#136: avgValue[id][3] /= n;
#137: avgValue[id][4] /= n;
#138: avgValue[id][5] /= n;
#139: avgValue[id][6] /= n;
#140: avgValue[id][7] /= n;
#141: */
#142: var txt = "<table class='data'><tr><th>Czas pomiaru</th><th>Ciśnienie min</th><th>Ciśnienie max</th><th>Ciśnienie avg</th></tr>"
#143: for (var i=0; i<id; i++) {
#144: txt += "<tr><td class='val'>" + dateValue[i].toDateString() + "</td>";
#145: txt += "<td class='val'>" + minValue[i][0] + "</td>";
#146: txt += "<td class='val'>" + maxValue[i][0] + "</td>";
#147: txt += "<td class='val'>" + avgValue[i][0].toFixed(2) + "</td></tr>" ;
#148: }
#149: txt += "</table>" ;
#150: document.getElementById('result').innerHTML = txt;
#151: }
#152: </script>
#153: </head>
#154: <body onload=sendRequest()>
#155: <div id="result" ></div>
#156: </body>
Plik lab_ex04.js ( [listing skryptu] link do skryptu )
#1: var request;
#2: function getRequestObject() {
#3: if ( window.ActiveXObject) {
#4: return ( new ActiveXObject("Microsoft.XMLHTTP")) ;
#5: } else if (window.XMLHttpRequest) {
#6: return (new XMLHttpRequest()) ;
#7: } else {
#8: return (null) ;
#9: }
#10: }
#11: function sendRequest() {
#12: request = getRequestObject() ;
#13: request.onreadystatechange = handleResponse ;
#14: request.open("GET", "http://mech.fis.agh.edu.pl/meteo/rest/json/all/s000/2020-06-01/2020-06-15", true);
#15: request.send(null);
#16: }
#17: function handleResponse() {
#18: if (request.readyState == 4) {
#19: //alert(request.responseText);
#20: var jsonObj=eval( "(" + request.responseText + ")" );
#21: //alert(jsonObj[0].time);
#22: values(jsonObj);
#23: }
#24: }
Poniżej prezentacja uruchomionego przykładu (link do uruchomienia w nowym oknie lab_ex04.html).
Ćwiczenie 6. Skrypt z możliwością wyboru wielkości prezentowanej na wykresie
W kolejnym ćwiczeniu wykorzystamy rozwiązania przedstawione w poprzednich ćwiczeniach. Przedstawiona poniżej strona WWW umożliwia
wybór okresu dla którego będziemy analizować dane pomiarowe. Po wyborze dat, dane zostają pobrane z serwisu z wykorzystaniem
technilogii AJAX w formacie JSON dla wszystkich danych pomiarowych z wybranego okresu. Stronę obsługują trzy skrypty: lab_ex05.html, lab_ex05a.js
i lab_ex05b.js.
W ramach skryptu lab_ex05.html wybieramy poczatkową i końcową datę dla analizowanych danych pomiarowych (elementy <input>) a następnie wybieramy typ danych, które będą
prezentowane w ramach elementu <select>. W skrypcie zawarte są również dwie funkcje opracowane w JavaScript - "checkData()" sprawdzająca poprawność
wprowadzonych dat i "graph() rysująca wykres".
Skrypt lab_ex05a.js jest modyfikacją skryptu lab_ex02.js i odpowiada za transfer danych z serwera w formacie JSON.
Skrypt lab_ex05b.js zawiera funkcję values() przedstawioną w ćwiczeniu 4. Funkcja została zmodyfikowana, dane dla kolejnych wartości dobowych
umiwszczane są w tablicy obiektów (np. avgValue[]{} ) a nie jak w ćwiczeniu 4 w dwuwymiarowej tablicy (np. avgValue[][]). Takie rozwiązanie ułatwia
wybór danych do prezenacji na wykresie i w tablicy.
Plik lab_ex05.html ( [listing skryptu] link do skryptu )
#1: <!DOCTYPE html>
#2: <html>
#3: <head>
#4: <meta charset="utf-8">
#5: <script type="text/javascript" src="dygraphs.js" ></script>
#6: <script type="text/javascript" src="lab_ex05a.js" ></script>
#7: <script type="text/javascript" src="lab_ex05b.js" ></script>
#8: <link type="text/css" href="lab.css" rel="stylesheet" />
#9: <link rel="stylesheet" type="text/css" href="http://cdn.gday.net.au/A.form_formatting.css.pagespeed.cf.MNok_y6LAw.css">
#10: <script type="text/javascript" >
#11: var jsonObj = {};
#12: var parTitllv= {};
#13: var minValue = [];
#14: var maxValue = [];
#15: var avgValue = [];
#16: var dateValue = [];
#17: parTitle = { "pa":"Ciśnienie" , "p0":"Ciśnienie zredukowane", "ha":"Wilgotność",
#18: "ta":"Temperatura", "t0":"Punkt rosy", "ra":"Opad",
#19: "wd":"Kierunek wiatru", "ws":"Szybkość wiatru" };
#20: function checkData() {
#21: // regular expression to match required date format
#22: re = /^20[12][0-9]\-[01][0-9]\-[0-3][0-9]$/;
#23: var d1 = document.getElementById("startdate");
#24: //alert(" 1. Invalid date format: " + d1.value);
#25: if(d1.value == '' || (d1.value != '' && !d1.value.match(re)) ) {
#26: alert("Nieporawny data początkowa: " + d1.value);
#27: //form.startdate.focus();
#28: return false;
#29: }
#30: var d2 = document.getElementById("enddate");
#31: if( !d2.value.match(re) ) {
#32: alert("Niepoprawna data końcowa: " + d2.value);
#33: //form.startdate.focus();
#34: return false;
#35: }
#36: sendRequest(d1,d2);
#37: }
#38: function graph() {
#39: values();
#40: var par = document.getElementById('par');
#41: if ( par.selectedIndex > 0 ) {
#42: var val = par.options[par.selectedIndex].value;
#43: var csv_data = "";
#44: for (var i=0; i<jsonObj.length; i++) {
#45: csv_data += jsonObj[i].time + "," + jsonObj[i].data[val] + "\n" ;
#46: }
#47: var g3 = new Dygraph(
#48: document.getElementById("graphdiv3"),
#49: csv_data,
#50: {
#51: title: parTitle[val],
#52: ylabel: parTitle[val],
#53: strokeWidth: 0,
#54: drawPoints: true
#55: //drawGapEdgePoints: true
#56: } );
#57: var txt = "<table class='data'><tr><th>Data pomiaru</th><th>Wart. min</th><th>Wart. max</th><th>Wart. avg</th></tr>"
#58: for (var i=0; i<dateValue.length; i++) {
#59: txt += "<tr><td class='val'>" + dateValue[i].toDateString() + "</td>";
#60: txt += "<td class='val'>" + minValue[i][val] + "</td>";
#61: txt += "<td class='val'>" + maxValue[i][val] + "</td>";
#62: txt += "<td class='val'>" + avgValue[i][val].toFixed(2) + "</td></tr>" ;
#63: }
#64: txt += "</table>" ;
#65: document.getElementById('valdiv').innerHTML = txt;
#66: }
#67: }
#68: </script >
#69: </head>
#70: <body >
#71: <div id="inp">
#72: <fieldset><legend>Wybór okresu pomiarowego</legend>
#73: <label>Data początkowa</label><span><input id="startdate" type="text" size="12" placeholder="yyyy-mm-dd" name="startdate" value="2020-06-01"> <small>(yyyy-mm-dd)</small></span>
#74: <label>Data końcowa</label><span><input id="enddate" type="text" size="12" placeholder="yyyy-mm-dd" name="enddate" value="2020-06-14"> <small>(yyyy-mm-dd)</small></span>
#75: <span><input type="submit" onclick="checkData()"></input></span>
#76: </fieldset>
#77: </div>
#78: <div id="myDiv"></div>
#79: <div id="sel" style="display:none">
#80: <select id="par" name="par" onchange=graph() >
#81: <option value="0">Proszę wybrać wielkość mierzona</option>
#82: <!--option value="pa">Ciśnienie</option-->
#83: <option value="p0">Ciśnienie na poziomie morza</option>
#84: <option value="ha">Wilgotność</option>
#85: <option value="ws">Prędkość wiatru</option>
#86: <option value="wd">Kierunek wiatru</option>
#87: <option value="ta">Temperatura</option>
#88: <option value="t0">Punkt rosy</option>
#89: <option value="ra">Opad deszczu</option>
#90: </select>
#91: </div>
#92: </div>
#93: <div id="graphdiv3" style="width:500px; height:300px;"></div>
#94: <div id="valdiv" style="width:800px; height:300px""><div>
#95: </body>
#96: </html>
Plik lab_ex05a.js ( [listing skryptu] link do skryptu )
#1: var request;
#2: function getRequestObject() {
#3: if ( window.ActiveXObject) {
#4: return ( new ActiveXObject("Microsoft.XMLHTTP")) ;
#5: } else if (window.XMLHttpRequest) {
#6: return (new XMLHttpRequest()) ;
#7: } else {
#8: return (null) ;
#9: }
#10: }
#11: function sendRequest(d1,d2) {
#12: request = getRequestObject() ;
#13: request.onreadystatechange = handleResponse ;
#14: //alert ("/"+d1.value+"/"+d2.value);
#15: request.open("GET", "http://mech.fis.agh.edu.pl/meteo/rest/json/all/s000/"+d1.value+"/"+d2.value, true);
#16: request.send(null);
#17: }
#18: function handleResponse() {
#19: myDiv = document.getElementById("myDiv");
#20: if (request.readyState == 1) {
#21: myDiv.innerHTML += "Pobieranie danych:" ;
#22: }
#23: else if (request.readyState == 2) {
#24: myDiv.innerHTML += "." ;
#25: }
#26: else if (request.readyState == 3) {
#27: myDiv.innerHTML += "." ;
#28: }
#29: if (request.readyState == 4) {
#30: //alert(request.responseText);
#31: jsonObj=eval( "(" + request.responseText + ")" );
#32: //alert(jsonObj[0].data.pa);
#33: document.getElementById('sel').style.display = "block";
#34: }
#35: }
Plik lab_ex05b.js ( [listing skryptu] link do skryptu )
#1: function datesEqual(d1,d2,m1,m2,y1,y2) {
#2: ret = d1 === d2 && m1 === m2 && y1 === y2;
#3: return ret;
#4: }
#5: function values() {
#6: //var avgValue = [];
#7: var s = jsonObj[0].time;
#8: var bits = s.split(/\D/);
#9: date1 = new Date(bits[0], --bits[1], bits[2], bits[3], bits[4]);
#10: y1 = date1.getFullYear();
#11: m1 = date1.getMonth();
#12: d1 = date1.getDate();
#13:
#14: //var dateValue = [];
#15: //var minValue = [];
#16: //var maxValue = [];
#17:
#18: dateValue[0] = new Date(y1, m1, d1);
#19: minValue[0] = {};
#20: minValue[0].pa = parseFloat(jsonObj[0].data.pa);
#21: minValue[0].ha = parseFloat(jsonObj[0].data.ha);
#22: minValue[0].ws = parseFloat(jsonObj[0].data.ws);
#23: minValue[0].t0 = parseFloat(jsonObj[0].data.t0);
#24: minValue[0].p0 = parseFloat(jsonObj[0].data.p0);
#25: minValue[0].ta = parseFloat(jsonObj[0].data.ta);
#26: minValue[0].ra = parseFloat(jsonObj[0].data.ra);
#27: minValue[0].wd = parseFloat(jsonObj[0].data.wd);
#28: maxValue[0] = {};
#29: maxValue[0].pa = parseFloat(jsonObj[0].data.pa);
#30: maxValue[0].ha = parseFloat(jsonObj[0].data.ha);
#31: maxValue[0].ws = parseFloat(jsonObj[0].data.ws);
#32: maxValue[0].t0 = parseFloat(jsonObj[0].data.t0);
#33: maxValue[0].p0 = parseFloat(jsonObj[0].data.p0);
#34: maxValue[0].ta = parseFloat(jsonObj[0].data.ta);
#35: maxValue[0].ra = parseFloat(jsonObj[0].data.ra);
#36: maxValue[0].wd = parseFloat(jsonObj[0].data.wd);
#37: avgValue[0] = {pa:0,ha:0,ws:0,t0:0,p0:0,ta:0,ra:0,wd:0};
#38: var n =0;
#39: var id = 0;
#40: for (var i=0, max=jsonObj.length; i<max; i++) {
#41: s = jsonObj[i].time;
#42: bits = s.split(/\D/);
#43: date2 = new Date(bits[0], --bits[1], bits[2], bits[3], bits[4]);
#44: d2 = date2.getDate();
#45: m2 = date2.getMonth();
#46: y2 = date2.getFullYear();
#47: if ( datesEqual(d1,d2,m1,m2,y1,y2) ) {
#48: avgValue[id].pa += parseFloat(jsonObj[i].data.pa);
#49: avgValue[id].ha += parseFloat(jsonObj[i].data.ha);
#50: avgValue[id].ws += parseFloat(jsonObj[i].data.ws);
#51: avgValue[id].t0 += parseFloat(jsonObj[i].data.t0);
#52: avgValue[id].p0 += parseFloat(jsonObj[i].data.p0);
#53: avgValue[id].ta += parseFloat(jsonObj[i].data.ta);
#54: avgValue[id].ra += parseFloat(jsonObj[i].data.ra);
#55: avgValue[id].wd += parseFloat(jsonObj[i].data.wd);
#56: if ( minValue[id].pa > parseFloat(jsonObj[i].data.pa) ) minValue[id].pa =parseFloat(jsonObj[i].data.pa);
#57: if ( minValue[id].ha > parseFloat(jsonObj[i].data.ha) ) minValue[id].ha =parseFloat(jsonObj[i].data.ha);
#58: if ( minValue[id].ws > parseFloat(jsonObj[i].data.ws) ) minValue[id].ws =parseFloat(jsonObj[i].data.ws);
#59: if ( minValue[id].t0 > parseFloat(jsonObj[i].data.t0) ) minValue[id].t0 =parseFloat(jsonObj[i].data.t0);
#60: if ( minValue[id].p0 > parseFloat(jsonObj[i].data.p0) ) minValue[id].p0 =parseFloat(jsonObj[i].data.p0);
#61: if ( minValue[id].ta > parseFloat(jsonObj[i].data.ta) ) minValue[id].ta =parseFloat(jsonObj[i].data.ta);
#62: if ( minValue[id].ra > parseFloat(jsonObj[i].data.ra) ) minValue[id].ra =parseFloat(jsonObj[i].data.ra);
#63: if ( minValue[id].wd > parseFloat(jsonObj[i].data.wd) ) minValue[id].wd =parseFloat(jsonObj[i].data.wd);
#64: if ( maxValue[id].pa < parseFloat(jsonObj[i].data.pa) ) maxValue[id].pa =parseFloat(jsonObj[i].data.pa);
#65: if ( maxValue[id].ha < parseFloat(jsonObj[i].data.ha) ) maxValue[id].ha =parseFloat(jsonObj[i].data.ha);
#66: if ( maxValue[id].ws < parseFloat(jsonObj[i].data.ws) ) maxValue[id].ws =parseFloat(jsonObj[i].data.ws);
#67: if ( maxValue[id].t0 < parseFloat(jsonObj[i].data.t0) ) maxValue[id].t0 =parseFloat(jsonObj[i].data.t0);
#68: if ( maxValue[id].p0 < parseFloat(jsonObj[i].data.p0) ) maxValue[id].p0 =parseFloat(jsonObj[i].data.p0);
#69: if ( maxValue[id].ta < parseFloat(jsonObj[i].data.ta) ) maxValue[id].ta =parseFloat(jsonObj[i].data.ta);
#70: if ( maxValue[id].ra < parseFloat(jsonObj[i].data.ra) ) maxValue[id].ra =parseFloat(jsonObj[i].data.ra);
#71: if ( maxValue[id].wd < parseFloat(jsonObj[i].data.wd) ) maxValue[id].wd =parseFloat(jsonObj[i].data.wd);
#72: n++;
#73: } else {
#74: //alert ( "-----"+n+"------" ) ;
#75: avgValue[id].pa /= n;
#76: avgValue[id].ha /= n;
#77: avgValue[id].ws /= n;
#78: avgValue[id].t0 /= n;
#79: avgValue[id].p0 /= n;
#80: avgValue[id].ta /= n;
#81: avgValue[id].ra /= n;
#82: avgValue[id].wd /= n;
#83: id++;
#84: y1=y2;
#85: m1=m2;
#86: d1=d2;
#87: dateValue[id] = new Date(y1, m1, d1);
#88: avgValue[id] = {pa:0,ha:0,ws:0,t0:0,p0:0,ta:0,ra:0,wd:0};
#89: minValue[id] = {};
#90: minValue[id].pa = parseFloat(jsonObj[i].data.pa);
#91: minValue[id].ha = parseFloat(jsonObj[i].data.ha);
#92: minValue[id].ws = parseFloat(jsonObj[i].data.ws);
#93: minValue[id].t0 = parseFloat(jsonObj[i].data.t0);
#94: minValue[id].p0 = parseFloat(jsonObj[i].data.p0);
#95: minValue[id].ta = parseFloat(jsonObj[i].data.ta);
#96: minValue[id].ra = parseFloat(jsonObj[i].data.ra);
#97: minValue[id].wd = parseFloat(jsonObj[i].data.wd);
#98: maxValue[id] = {};
#99: maxValue[id].pa = parseFloat(jsonObj[i].data.pa);
#100: maxValue[id].ha = parseFloat(jsonObj[i].data.ha);
#101: maxValue[id].ws = parseFloat(jsonObj[i].data.ws);
#102: maxValue[id].t0 = parseFloat(jsonObj[i].data.t0);
#103: maxValue[id].p0 = parseFloat(jsonObj[i].data.p0);
#104: maxValue[id].ta = parseFloat(jsonObj[i].data.ta);
#105: maxValue[id].ra = parseFloat(jsonObj[i].data.ra);
#106: maxValue[id].wd = parseFloat(jsonObj[i].data.wd);
#107: n=0;
#108: }
#109: }
#110: avgValue[id].pa /= n;
#111: avgValue[id].ha /= n;
#112: avgValue[id].ws /= n;
#113: avgValue[id].t0 /= n;
#114: avgValue[id].p0 /= n;
#115: avgValue[id].ta /= n;
#116: avgValue[id].ra /= n;
#117: avgValue[id].wd /= n;
#118: }
Poniżej prezentacja uruchomionego przykładu (link do uruchomienia w nowym oknie lab_ex05.html).
Ćwiczenie 7. Dane statystyczne - liczba pomiarów w miesiącu w każdym dniu
W przedstawionym ćwiczeniu wykorzystamy polecenie REST zwracające liczbę pomiarów w ramach wybranego miesiąca w kolejnych jego dniach. W przyszłości
zostanie udostępniona metoda zwracająca informację czy w danym miesiącu były zbierane dane. Stronę obsługują dwa skrypty: lab_ex06.html, lab_ex06.js.
Odczyt danych z serwisu WWW w formacie JSON następuje poprzez polecenie:
http://mech.fis.agh.edu.pl/meteo/rest/json/stat/{station}/{rrrr-mm}
gdzie:
- {station}
- identyfikator stacji
- {rrrr-mm}
- wybrany miesiąc pomiarów
Przykładowe polecenie pobierające dane z miesiąca - czerwiec 2020.
http://mech.fis.agh.edu.pl/meteo/rest/json/stat/s000/2020-06
Do prezentacji danych w postaci tabeli wykorzystamy odpowiednie skrypty opracowane w języku HTML5, JavaScript i CSS. Funkcjonalność skryptów w języku HTML i CSS
jest analogicza do przedstawionych powyżej skryptów "lab_ex02.html" i "lab.css".
Plik lab_ex06.html ( [listing skryptu] link do skryptu )
#1: <!DOCTYPE html>
#2: <html>
#3: <head>
#4: <meta charset="utf-8">
#5: <title>Ajax: Odczyt danych z serwera</title>
#6: <link type="text/css" href="lab.css" rel="stylesheet" />
#7: <script src="lab_ex06.js" type="text/javascript"></script>
#8: </head>
#9: <body>
#10: <div style="text-align:center" >
#11: <table border="1" bgcolor="gray">
#12: <tr><th><big>Ajax: Odczyt danych z serwera</big></th></tr>
#13: </table>
#14: <br />
#15: <form action="#">
#16: <input type="button" value="Pobierz dane z serwera" onclick="sendRequest()"/>
#17: </form>
#18: </div>
#19: <div id="result"></div>
#20: </body>
#21: </html>
Podobnie jak w ćwiczeniu drugim został przygotowany odpowiedni skrypt w JavaScript pobierający dane z wykorzystaniem technologii AJAX. Dwie pierwsze funkcje "getRequestObject()"
i "sendRequest()" są identyczne do odpowiednich funkcji w skrypcie "lab_ex02.js". W trzeciej funcji "handleResponse()" różnica jest w przetworzeniu zwróconego wyniku.
Po przeczytaniu danych z własnoności "responseText" obiektu XHR wykorzystujemy funkcję "evel()" w JavaScript do utworzenia tablicy obiektów (linia kodu 20).
Dostęp do określonej wartości parametru następuje przez wskazanie na numer obiektu w tablicy i wskazanie określonego parametru. Przykładowo wpis "jsonObj[2].data.day"
pobiera numer dnia w miesiącu dla którego zostały zebrane wszystkie wyniki pomiarowe dostępne w bazie. Wpis "jsonObj[2].count" pobiera liczbę zarejestrowanych pomiarów.
Plik lab_ex06.js ( [listing skryptu] link do skryptu )
#1: var request;
#2: function getRequestObject() {
#3: if ( window.ActiveXObject) {
#4: return ( new ActiveXObject("Microsoft.XMLHTTP")) ;
#5: } else if (window.XMLHttpRequest) {
#6: return (new XMLHttpRequest()) ;
#7: } else {
#8: return (null) ;
#9: }
#10: }
#11: function sendRequest() {
#12: request = getRequestObject() ;
#13: request.onreadystatechange = handleResponse ;
#14: request.open("GET", "http://mech.fis.agh.edu.pl/meteo/rest/json/stat/s000/2020-06", true);
#15: request.send(null);
#16: }
#17: function handleResponse() {
#18: if (request.readyState == 4) {
#19: //alert(request.responseText);
#20: var jsonObj=eval( "(" + request.responseText + ")" );
#21: //alert(jsonObj[0].data.pa);
#22: var txt = "<p>Licza przetworzonych wierszy: " + jsonObj.length.toString() + "</p>";
#23: txt += "<table class='data'><tr><th>Dzień pomiaru</th><th>Liczba pomiarów</th></tr>"
#24: for (var i=0, max=jsonObj.length; i<max; i++) {
#25: txt_day = jsonObj[i].data.day + "/" + jsonObj[i].data.month + "/" + jsonObj[i].data.year ;
#26: txt += "<tr><td>" + txt_day + "</td><td>" + jsonObj[i].count + "</td></tr>" ;
#27: }
#28: txt += "</table>" ;
#29: document.getElementById('result').innerHTML = txt;
#30: }
#31: }
Poniżej prezentacja uruchomionego przykładu (link do uruchomienia w nowym oknie lab_ex06.html).
Ćwiczenie 8. Informacje o szkołach uczestniczących w projekcie
W przedstawionym ćwiczeniu wykorzystamy polecenie REST zwracające informacje o szkołach w projekcie. Ćwiczenie obsługują dwa skrypty: lab_ex07.html, lab_ex07.js.
Odczyt danych z serwisu WWW w formacie JSON następuje poprzez polecenie:
http://mech.fis.agh.edu.pl/meteo/rest/json/info/
Do prezentacji danych w postaci tabeli wykorzystamy odpowiednie skrypty opracowane w języku HTML5, JavaScript i CSS. Funkcjonalność skryptów w języku HTML i CSS
jest analogicza do przedstawionych powyżej skryptów "lab_ex02.html" i "lab.css".
Plik lab_ex07.html ( [listing skryptu] link do skryptu )
#1: <!DOCTYPE html>
#2: <html>
#3: <head>
#4: <meta charset="utf-8">
#5: <title>Ajax: Odczyt danych z serwera</title>
#6: <link type="text/css" href="lab.css" rel="stylesheet" />
#7: <script src="lab_ex07.js" type="text/javascript"></script>
#8: </head>
#9: <body>
#10: <div style="text-align:center" >
#11: <table border="1" bgcolor="gray">
#12: <tr><th><big>Ajax: Odczyt danych z serwera</big></th></tr>
#13: </table>
#14: <br />
#15: <form action="#">
#16: <input type="button" value="Pobierz dane z serwera" onclick="sendRequest()"/>
#17: </form>
#18: </div>
#19: <div id="result"></div>
#20: </body>
#21: </html>
Podobnie jak w ćwiczeniu drugim został przygotowany odpowiedni skrypt w JavaScript pobierający dane z wykorzystaniem technologii AJAX. Dwie pierwsze funkcje "getRequestObject()"
i "sendRequest()" są identyczne do odpowiednich funkcji w skrypcie "lab_ex02.js". W trzeciej funcji "handleResponse()" różnica jest w przetworzeniu zwróconego wyniku.
Po przeczytaniu danych z własnoności "responseText" obiektu XHR wykorzystujemy funkcję "evel()" w JavaScript do utworzenia tablicy obiektów (linia kodu 20).
Dostęp do określonej wartości parametru następuje przez wskazanie na numer obiektu w tablicy i wskazanie określonego parametru. Przykładowo wpis "jsonObj[2].station"
pobiera identyfikator szkoły.
Plik lab_ex07.js ( [listing skryptu] link do skryptu )
#1: var request;
#2: function getRequestObject() {
#3: if ( window.ActiveXObject) {
#4: return ( new ActiveXObject("Microsoft.XMLHTTP")) ;
#5: } else if (window.XMLHttpRequest) {
#6: return (new XMLHttpRequest()) ;
#7: } else {
#8: return (null) ;
#9: }
#10: }
#11: function sendRequest() {
#12: request = getRequestObject() ;
#13: request.onreadystatechange = handleResponse ;
#14: request.open("GET", "http://mech.fis.agh.edu.pl/meteo/rest/json/info/", true);
#15: request.send(null);
#16: }
#17: function handleResponse() {
#18: if (request.readyState == 4) {
#19: //alert(request.responseText);
#20: var jsonObj=eval( "(" + request.responseText + ")" );
#21: //alert(jsonObj[0].data.pa);
#22: // var txt = "<p>Licza przetworzonych wierszy: " + jsonObj.length.toString() + "</p>";
#23: txt = "<table class='data'><tr><th>Identyfikator</th><th>Nazwa</th><th>Długość</th><th>Szerokość</th><th>Wysokość</th></tr>";
#24: txt += "<tr><th>szkoły</th><th>szkoły</th><th>geograficzna</th><th>geograficzna</th><th></th></tr>";
#25: for (var i=0, max=jsonObj.length; i<max; i++) {
#26: txt += "<tr><td>" + jsonObj[i].station + "</td><td>" + jsonObj[i].name + "</td><td>" + jsonObj[i].long ;
#27: txt += "</td><td>" + jsonObj[i].lati + "</td><td>" + jsonObj[i].alti + "</td></tr>" ;
#28: }
#29: txt += "</table>" ;
#30: document.getElementById('result').innerHTML = txt;
#31: }
#32: }
Poniżej prezentacja uruchomionego przykładu (link do uruchomienia w nowym oknie lab_ex07.html).