Grafici di stato dei sensori connessi all'Internet of Things IoT
Uno dei vantaggi di connettere una rete di sensori all’Internet of Things è la possibilità di analizzare i dati ottenuti. Rappresentando graficamente queste informazioni, una persona (e non un programma) può comprendere in modo più intuitivo il significato delle grandezze monitorate, ad esempio confrontandole tra loro o seguendone l'evoluzione nel tempo.
Questo articolo inizia una serie, composta da quattro parti, che spiega una semplice proposta di rappresentazione grafica dei dati ottenuti dai sensori collegati all'IoT. Con la stessa filosofia degli altri articoli, il metodo suggerito è perfettamente funzionale nonostante l'obiettivo principale sia didattico. Come il profilo tecnico del pubblico a cui si rivolge il blog polaridad.es, e questo testo riguarda l'elettronica e non lo sviluppo web, ciascuna delle sezioni funge da introduzione ai linguaggi o alla tecnologia utilizzata: HTML, CSS, SVG y JavaScript.
Gli articoli della serie precedente su come archiviare i dati ottenuti dai dispositivi connessi all'Internet of Things (IoT) Hanno concluso spiegando come accedere alle informazioni archiviate nei database. Negli esempi della serie, per facilitare il processo, è stato utilizzato un server web come intermediario che si occupava di ricevere i dati tramite richieste POST del protocollo HTTP, memorizzarli in un database e visualizzarli su una pagina web.
Sebbene lo svantaggio principale di questo sistema siano le prestazioni (che potrebbero essere alleviate con alternative come Node.js e MongoDB, che verranno spiegate nei prossimi articoli), in cambio offre due grandi vantaggi: la sua implementazione è molto semplice (inclusa la disponibilità di servizi pubblici) e può visualizzare i dati in un browser, cioè non necessita di applicazioni specifiche (come un'app per un dispositivo mobile) per presentare le informazioni memorizzate che rappresenterebbero lo stato storico dei dispositivi connessi a Internet di Cose.
Sfruttando il vantaggio di poter presentare facilmente su una pagina web le informazioni memorizzate con questo sistema sullo stato dei dispositivi connessi all'IoT, questo articolo spiega come visualizzare graficamente queste informazioni utilizzando il formato SVG da JavaScript per generare dinamicamente una pagina web in HTML.
Ci sono molte librerie JavaScript con cui risolvere la presentazione grafica dei dati. Questi articoli non intendono svilupparne un altro; Lo scopo di questo testo è comprendere il processo ed essere in grado di sviluppare le proprie implementazioni; un obiettivo didattico oltre che produttivo. Se sei interessato a utilizzare un prodotto anziché svilupparlo da solo, ti consiglio di dare un'occhiata ad alcune delle eccellenti librerie per generare grafica con JavaScript con licenze gratuite come Charts.js, Highcharts, Strumenti grafici di Google, Epoch, Raphael, Grafico (basato su Raphael), dc.js, Chartist.js, D3.js (la mia raccomandazione), C3.js (basato su D3.js), NVD3 (grafica riutilizzabile per D3.js) ...
Struttura del documento HTML con grafica SVG
Nella proposta di questo articolo di presentare graficamente i dati dei sensori, la pagina web su cui vengono visualizzati è composta da:
- è scritto il documento che funge da contenitore HTML,
- l'aspetto della pagina è definito con il codice CSS,
- il disegno del grafico viene eseguito utilizzando il linguaggio SVG y
- La lettura dei dati dal server e la visualizzazione dei grafici è programmata in JavaScript
Tutti gli elementi, in particolare il codice HTML della pagina, possono essere generati sul server con PHP come spiegato nell'articolo sul Linguaggio di programmazione PHP dalla serie su archiviazione dei dati da dispositivi connessi all’Internet of Things.
Il codice CSS y JavaScript può essere caricato (importato) nel codice HTML invece di essere scritto direttamente come parte del documento HTML. Questo ha il vantaggio di poter riutilizzare gli stessi documenti su più pagine e poterli modificare più comodamente; ma forse l'inconveniente di impiegare un po' più tempo di caricamento a seconda che si possa utilizzare il codice contenuto nella cache (caricato nell'utilizzo precedente) o anche un CDN. In fase di produzione è banale integrare tutto il codice proveniente da PHP, generando un unico documento in HTML con tutte le informazioni se scegli questa alternativa. In tutta questa serie di articoli, per chiarezza, si considera che stiamo lavorando con documenti separati.
Per gli scopi che ci interessano, per usarlo come contenitore grafico, e molto approssimativamente, il contenuto del primo livello della struttura di un documento HTML voluto:
1
2
3
4
5
6
7
|
<!DOCTYPE html>
<html lang=“es”> <!– El código del documento HTML está escrito en español –>
<head>
</head>
<body onload=“funcion();”>
</body>
</html>
|
La prima riga serve ad indicare al browser web che il documento che sta leggendo è scritto HTML, in particolare nella versione 5 (nota come HTML5). Versioni precedenti di HTML, basato su SGML (Standard Generalized Markup Language), includeva una definizione del tipo di documento (DTD) in cui veniva dichiarato il tipo di regole utilizzate nella lingua per descrivere il documento.
La seconda e l'ultima riga contengono il codice HTML tra le direttive <html>
y </html>
che funzionano rispettivamente come apertura e chiusura. Le direttive HTML Racchiudono il nome e gli attributi tra i segni “minore di” e “maggiore di” formando una sorta di segni di “parentesi acuta”. Gli elementi HTML che racchiudono il contenuto hanno una direttiva di chiusura che include la barra davanti al nome come in </html>
.
Le proprietà o gli attributi degli elementi sono separati da spazi dal nome e tra loro e sono espressi come testo semplice o, più frequentemente, come testo (il nome della proprietà) seguito da un segno di uguale e da un valore racchiuso tra virgolette. Nel caso della direttiva sull'apertura del codice HTML la proprietà è stata utilizzata lang
con il valore es
, lang="es"
per indicare che il testo del documento HTML usa la lingua spagnola.
È stato incluso un commento dopo la direttiva di apertura del codice HTML. I commenti dentro HTML Possono occupare più righe e utilizzare il codice come segno di apertura <!--
e come chiusura -->
Il codice HTML È composto da due blocchi: l'intestazione <head>
e il corpo <body>
. Il primo ha lo scopo di informare sul documento stesso, comprese le informazioni su di esso (meta-informazione) e il secondo è di supportare il contenuto del documento.
Nella direttiva <body>
è stato incluso un evento onload
con cui eseguire automaticamente una funzione JavaScript una volta caricato il contenuto. Questa risorsa consente di avviare l'esecuzione del codice che definirà gli oggetti grafici e di aggiornarli man mano che le informazioni vengono caricate dal server sullo stato dei sensori che rappresentano questi grafici.
Di tutte le metainformazioni che possono essere incluse nell'intestazione del documento HTML, ci interessa soprattutto conoscere quella descritta dalle seguenti direttive:
-
<title>
che serve a dare un titolo al documento. Normalmente apparirà nella finestra del browser o nella scheda corrispondente e ci aiuterà a identificare la grafica che contiene. -
<charset>
dichiara il set di caratteri utilizzato per codificare il documento. È particolarmente importante per i segni "speciali" come eñes o accenti. -
<link>
consente di stabilire una relazione tra il documento HTML attuali e altri esterni. Ci aiuterà a caricare il foglio di stile in formato CSS con l'aspetto del documento. -
<script>
contiene uno script con codice eseguibile. Usando questa direttiva caricheremo le funzioni JavaScript con cui generare o modificare la grafica SVG.
1
2
3
4
5
6
7
8
9
10
11
|
<!DOCTYPE html>
<html lang=“es”> <!– El código del documento HTML está escrito en español… –>
<head>
<meta charset=“utf-8”> <!– …y codificado en el juego de caracteres UTF-8 –>
<title>Gáfico SVG de sensores conectados a la IoT</title>
<link href=“https://polaridad.es/grafica-sensor-internet-de-las-cosas-iot/aspecto.css” type=“text/css” rel=“stylesheet” media=“all”>
<script src=“graficos.js” type=“text/javascript”></script>
</head>
<body onload=“funcion();”>
</body>
</html>
|
Come si può vedere nell'esempio di HTML sopra, il nome (e il percorso, se applicabile) del documento con lo stile CSS è indicato con l'attributo href
, mentre nel caso del codice JavaScript è usato src
. Entrambi condividono la proprietà type
con il valore text/css
y text/javascript
rispettivamente.
Rispetto al contenuto del documento, la parte che corrisponde all'elemento <body>
, HTML5 Permette di creare strutture specifiche per i componenti più frequenti di una pagina web come un footer, una sezione laterale o una barra di navigazione, ma quello che ci interessa è utilizzare il documento come contenitore grafico. SVG sono gli elementi <div>
che funzionano come blocchi indipendenti che consentono di definire una struttura gerarchica annidandone alcuni <div>
all'interno degli altri.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<!DOCTYPE html>
<html lang=“es”> <!– El código del documento HTML está escrito en español… –>
<head>
<meta charset=“utf-8”> <!– …y codificado en el juego de caracteres UTF-8 –>
<title>Gáfico SVG de sensores conectados a la IoT</title>
<link href=“https://polaridad.es/grafica-sensor-internet-de-las-cosas-iot/aspecto.css” type=“text/css” rel=“stylesheet” media=“all”>
<script src=“graficos.js” type=“text/javascript”></script>
</head>
<body onload=“funcion();”>
<div id=“padre” class=“aspecto_de_padre”>
<div id=“primer_hijo” class=“aspecto_de_hijo”>
</div>
<div id=“segundo_hijo” class=“aspecto_de_hijo”>
</div>
</div>
</body>
</html>
|
Nell'esempio precedente viene utilizzato un elemento <div>
che ne contiene altri due. Questo esempio introduce due proprietà molto importanti per l'uso che vogliamo fare del codice. HTML: id
che viene utilizzato per assegnare un identificatore univoco a un elemento HTML (One <div>
, in questo caso) e class
con la quale viene assegnata una categoria che utilizzeremo per stabilirne l'aspetto. La categoria, la classe, non deve essere unica, infatti gran parte della sua efficacia risiede nel fatto che più elementi condividono lo stesso aspetto.
L'elemento (o tag) <p>
serve a definire un paragrafo che normalmente conterrà testo (anche se in HTML non vi è alcuna limitazione al riguardo). Per creare raggruppamenti all'interno di un paragrafo (o a <div>
, non ci sono inoltre limitazioni) viene utilizzato il tag <span>
. Con questo elemento è possibile, ad esempio, includere del testo all'interno di un paragrafo per conferirgli un aspetto diverso come sottolineato o grassetto.
La definizione delle caratteristiche grafiche e in generale il comportamento che viene associato ad un elemento HTML L'attribuzione di una classe viene eseguita nel codice CSS; nel caso dell'esempio precedente nel documento aspecto.css
.
Per ottimizzare l'assegnazione delle caratteristiche CSS è possibile che lo stesso elemento HTML appartiene a diverse classi e quindi ha l'aspetto o il comportamento da esse definito. Per effettuare questa assegnazione, scrivi i nomi delle diverse classi, separandole con virgole a destra della proprietà. class
9
10
11
12
13
14
15
16
|
<body onload=“funcion();”>
<div id=“padre” class=“aspecto_de_padre”>
<div id=“primer_hijo” class=“aspecto_de_hijo aspecto_raro tipografia_grande”>
</div>
<div id=“segundo_hijo” class=“aspecto_de_hijo”>
</div>
</div>
</body>
|
Nell'esempio precedente, l'elemento <div>
che è stato identificato come primer_hijo
Sono state assegnate tre classi: aspecto_de_hijo
, aspecto_raro
y tipografia_grande
, che dovrebbero definire insieme l'aspetto e il comportamento dell'elemento. Come spiegato nel seguente articolo su Definizione dell'aspetto Web della grafica del sensore IoT con CSS, quando si utilizzano più classi, se una qualsiasi delle proprietà che definiscono l'aspetto è definita in entrambe, prevale l'ultima a cui si fa riferimento.
Come si è visto, gli elementi <div>
Possono contenere altri elementi, inclusi altri <div>
. Un caso più semplice sarebbe <div>
che conteneva testo. Il look che definisce lo stile CSS influenzerebbe anche il testo contenuto nell'elemento.
Per ottimizzare l'assegnazione delle caratteristiche CSS è possibile che lo stesso elemento HTML appartiene a diverse classi e quindi ha l'aspetto o il comportamento da esse definito. Per effettuare questa assegnazione, scrivi i nomi delle diverse classi, separandole con virgole a destra della proprietà. class
9
10
11
12
13
14
15
16
17
|
<body onload=“funcion();”>
<div id=“padre” class=“aspecto_de_padre”>
<div id=“primer_hijo” class=“aspecto_de_hijo aspecto_raro tipografia_grande”>
Este hijo de aspecto raro tiene la tipografía grande
</div>
<div id=“segundo_hijo” class=“aspecto_de_hijo”>
</div>
</div>
</body>
|
Nell'esempio precedente, le tre classi associate a <div>
primer_hijo
Definirebbero l'aspetto dell'elemento e del testo che lo contiene, ad esempio, rendendo grande il carattere con cui è scritto (se è vero lo scopo indicato dal suo nome nell'ultima classe)
Dalla versione 5 (HTML5) è possibile includere il codice grafico nel formato SVG all'interno del codice stesso HTML come un elemento in più. Dal punto di vista del codice HTML, il contenuto SVG è un elemento <svg>
che contiene i diversi elementi grafici (linee, cerchi, rettangoli...
9
10
11
12
13
14
15
16
17
18
19
20
|
<body onload=“funcion();”>
<div id=“padre” class=“aspecto_de_padre”>
<div id=“primer_hijo” class=“aspecto_de_hijo aspecto_raro tipografia_grande”>
Este hijo de aspecto raro tiene la tipografía grande
</div>
<div id=“segundo_hijo” class=“aspecto_de_hijo”>
<svg id=“dibujo” class=“grafico” width=“100%” height=“100%” viewBox=“0 0 100 100” preserveAspectRatio=“none”>
<circle cx=“100” cy=“200” r=“50”>
</svg>
</div>
</div>
</body>
|
Anche se è stato detto che le caratteristiche grafiche degli elementi HTML sono definiti in uno stile CSS e ad esso associati tramite una classe, è inoltre possibile assegnarne alcuni direttamente agli elementi in due modi. Da un lato è possibile utilizzare la proprietà style
e assegnare come valore le diverse caratteristiche grafiche dell'oggetto. Logicamente è preferibile utilizzare la tecnica sopra citata di assegnare l'aspetto ad una classe, ma con questa possibilità è possibile aggiungere una piccola correzione ad un elemento (un'eccezione molto particolare) senza dover creare una nuova classe.
D'altra parte, alcuni elementi HTML Permettono di utilizzare proprietà specifiche che ne definiscono l'aspetto. In generale, anche se queste proprietà esistono, è preferibile utilizzare le classi ma, purtroppo, non tutti gli elementi offrono questa alternativa, alcuni pretendono che un certo valore venga indicato direttamente con quelle specifiche proprietà invece che fare riferimento alla classe associata. Uno degli elementi che hanno questo tipo di comportamento è proprio il codice SVG, a cui dobbiamo assegnare nelle proprietà il valore percentuale della larghezza e dell'altezza width
y height
, rispettivamente, invece della classe.
Come si vedrà più in dettaglio nel articolo che parla del codice SVG, per utilizzare il semplice metodo proposto, è consigliabile considerare le dimensioni del grafico in percentuale. Nel caso della dimensione totale dell'oggetto, indicando 100% nei valori di larghezza e altezza, sarà il contenitore a fissare le dimensioni finali (la <div>
con id="dibujo"
, nell'esempio precedente)
Nel caso delle diverse componenti del grafico SVG (linee, cerchi, rettangoli...), sono compresi in un'area che misura 100×100 (qualsiasi unità) e si espandono in forma rettangolare senza conservare la proporzione. Le proprietà viewBox
y preserveAspectRatio
dell'elemento SVG Sono loro a dover stabilire questi valori. nel primo caso con una vista rettangolare che va dal punto delle coordinate (0,0) al punto delle coordinate (100,100) ed è espressa come "0 0 100 100"
e nel secondo con il valore none
.
14
15
16
17
18
|
<div id=“segundo_hijo” class=“aspecto_de_hijo”>
<svg viewBox=“0 0 100 100” preserveAspectRatio=“none” width=“100%” height=“100%” id=“dibujo” class=“grafico”>
<circle cx=“100” cy=“200” r=“50”>
</svg>
</div>
|
Con tutto quanto sopra, ora puoi definire un codice completo che fungerebbe da contenitore grafico. SVG generato o modificato da JavaScript. L'esempio seguente contiene quattro blocchi grafici che utilizzano il formato HTML della proposta di rappresentazione che utilizzeremo.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
<!DOCTYPE html>
<html lang=“es”> <!– Inicio del documento HTML con el idioma –>
<head> <!– Cabecera del documento HTML –>
<meta charset=“utf-8”> <!– Se utiliza el juego de caracteres UTF8 –>
<title>Temperaturas Nave E1</title> <!– Título del documento y seguramente de la ventana del navegador –>
<link rel=“stylesheet” href=“https://polaridad.es/grafica-sensor-internet-de-las-cosas-iot/estilo.css” type=“text/css” media=“all”> <!– Cargar el estilo “https://polaridad.es/grafica-sensor-internet-de-las-cosas-iot/estilo.css” guardado en la misma carpeta que este documento HTML –>
<script type=“text/javascript” src=“graficos.js”></script> <!– Cargar el código JavaScript del documento “graficos.js” guardado en la misma carpeta que este documento HTML –>
</head> <!– Final de la cabecera del documento HTML –>
<body onload=“iniciar_graficos();”> <!– Cuerpo del documento HTML. Al cargar el contenido llama a la función JavaScript iniciar_graficos() –>
<div id=“temperatura_frigorifico_a” class=“bloque_sensor”> <!– Bloque de datos del primer sensor –>
<div id=“titulo_temperatura_frigorifico_a” class=“bloque_titulo”>Temperatura frigorífico 01A</div> <!– Título del bloque de datos del sensor –>
<div id=“descripcion_temperatura_frigorifico_a” class=“bloque_descripcion”>Media de las sondas de temperatura del frigorífico 01A</div> <!– Descripción del bloque de datos del sensor –>
<div id=“fecha_temperatura_frigorifico_a” class=“bloque_fecha”>Cargando emperaturas</div> <!– Fecha de la última lectura de datos del sensor. Por ahora vacío, luego se rellenará con la aplicación JavaScript –>
<div id=“bloque_temperatura_frigorifico_a” class=“bloque_grafico”> <!– Bloque con el gráfico –>
<svg id=“grafico_temperatura_frigorifico_a” class=“grafico” width=“100%” height=“100%” viewBox=“0 0 100 100” preserveAspectRatio=“none”>
<path id=“linea_temperatura_frigorifico_a” d=“” style=“fill:none;stroke:#205587;stroke-width:4;stroke-opacity:1;” vector-effect=“non-scaling-stroke” />
</svg> <!– Gráfico de los datos –>
</div> <!– Final del bloque que contiene el gráfico –>
</div> <!– Final del bloque de datos del primer sensor –>
<div id=“temperatura_frigorifico_b” class=“bloque_sensor”>
<div id=“titulo_temperatura_frigorifico_b” class=“bloque_titulo”>Temperatura frigorífico 01B</div>
<div id=“descripcion_temperatura_frigorifico_b” class=“bloque_descripcion”>Media de las sondas de temperatura del frigorífico 01B</div>
<div id=“fecha_temperatura_frigorifico_b” class=“bloque_fecha”>Cargando emperaturas</div>
<div id=“bloque_grafico_temperatura_frigorifico_b” class=“bloque_grafico”>
<svg id=“grafico_temperatura_frigorifico_b” class=“grafico” width=“100%” height=“100%” viewBox=“0 0 100 100” preserveAspectRatio=“none”>
<path id=“linea_temperatura_frigorifico_b” d=“” style=“fill:none;stroke:#205587;stroke-width:4;stroke-opacity:1;” vector-effect=“non-scaling-stroke” />
</svg>
</div>
</div>
<div id=“temperatura_frigorifico_c” class=“bloque_sensor”>
<div id=“titulo_temperatura_frigorifico_c” class=“bloque_titulo”>Temperatura frigorífico 01C</div>
<div id=“descripcion_temperatura_frigorifico_c” class=“bloque_descripcion”>Media de las sondas de temperatura del frigorífico 01C</div>
<div id=“fecha_temperatura_frigorifico_c” class=“bloque_fecha”>Cargando emperaturas</div>
<div id=“bloque_grafico_frigorifico_c” class=“bloque_grafico”>
<svg id=“grafico_temperatura_frigorifico_c” class=“grafico” width=“100%” height=“100%” viewBox=“0 0 100 100” preserveAspectRatio=“none”>
<path id=“linea_temperatura_frigorifico_c” d=“” style=“fill:none;stroke:#205587;stroke-width:4;stroke-opacity:1;” vector-effect=“non-scaling-stroke” />
</svg>
</div>
</div>
<div id=“temperatura_frigorifico_d” class=“bloque_sensor”>
<div id=“titulo_temperatura_frigorifico_d” class=“bloque_titulo”>Temperatura frigorífico 01D</div>
<div id=“descripcion_temperatura_frigorifico_d” class=“bloque_descripcion”>Media de las sondas de temperatura del frigorífico 01D</div>
<div id=“fecha_temperatura_frigorifico_d” class=“bloque_fecha”>Cargando emperaturas</div>
<div id=“bloque_grafico_frigorifico_d” class=“bloque_grafico”>
<svg id=“grafico_temperatura_frigorifico_d” class=“grafico” width=“100%” height=“100%” viewBox=“0 0 100 100” preserveAspectRatio=“none”>
<path id=“linea_temperatura_frigorifico_d” d=“” style=“fill:none;stroke:#205587;stroke-width:4;stroke-opacity:1;” vector-effect=“non-scaling-stroke” />
</svg>
</div>
</div>
</body> <!– Final del cuerpo del documento HTML –>
</html> <!– Final del documento HTML –>
|
Di seguito puoi vedere come apparirebbe il codice precedente, formattato con lo stile CSS corrispondente, generando con JavaScript la grafica SVG con letture da parte del server dei dati memorizzati dai sensori collegati all'IoT. Tranne che i dati non vengono caricati dal server ma vengono generati in modo casuale nel client (il browser), il resto del codice è quello che verrà utilizzato nella proposta definita in questa serie di articoli.
Il prossimo articolo di questa serie spiega come definire gli stili CSS per dare aspetto al codice HTML che funge da contenitore per la grafica SVG con cui rappresentare lo stato dei sensori connessi all'Internet of Things (IoT).
1 commento