Luo ja muokkaa SVG-grafiikkaa IoT:hen JavaScriptillä yhdistetyistä antureista
Tässä piirtämistä käsittelevän artikkelisarjan viimeisessä osassa grafiikkaa esineiden Internetiin yhdistettyjen antureiden datalla, on aika puhua luomisesta tai muokkaamisesta JavaScript piirustuksia muodossa SVG ja jotkin elementit HTML jotka toimivat konttina tai tarjoavat grafiikkaa täydentäviä tietoja.
Tämän opetusohjelman kohdekäyttäjien on tarkoitus muodostaa elektroniikka- ja tietokoneohjelmointiprofiili. mikro-ohjaimet, he eivät ehkä ole tuttuja HTML, CSS o SVG; Tästä syystä aiemmissa osissa tehtiin lyhyt esittely kieleen tai vastaavaan tekniikkaan. Tässä viimeisessä osassa lähestymistapa on hieman erilainen, koska lukijat osaavat varmasti ohjelmoida, on mahdollista, että käyttämällä kieltä C + + mitä, miten JavaScript, jakaa perussyntaksin kanssa C ja sitä voidaan pitää viitteenä useimpien ohjelmoinnin peruskonseptien ohittamiseen ja siten keskittymiseen eroihin ja erityiseen käyttöön, joka kiinnostaa meitä luomaan anturigrafiikkaa IoT:ssä.
Nimi antaa vihjeen ensimmäisestä erosta: JavaScript Se on ohjelmointikieli käsikirjoitus (yhdysmerkki) ja sellaisenaan se on tulkita, sitä ei tarvitse kääntää; konteksti, jossa käsikirjoitus (esimerkiksi verkkoselain) lukee, kääntää ja suorittaa tilaukset. Tarkemmin sanottuna useimmissa tapauksissa on a ajonaikainen käännös (JIT), mutta koodin kirjoitusprosessiin JavaScript Se ei vaikuta meihin, kirjoitamme vain koodin ja se voi toimia.
Nimi sisältää myös ensimmäisen hämmennyksen: JavaScript ei ole pienintäkään suhdetta Jaava. Aluksi, kun se kehitettiin Netscape selaimessaan sitä kutsuttiin ensin Mochaksi ja sitten vähemmän hämmentäväksi LiveScriptiksi. Sen onnistuneen käyttöönoton jälkeen selaimissa ja niiden ylittämisen jälkeen se standardisoitiin nimellä ECMAScript (jäljempänä ECMA-262, versio 6 kirjoittamishetkellä) muuttua neutraaliksi sen toteuttavien selaimien suhteen. Tällä hetkellä on myös standardi ISO versiosta 5, 2011 (ISO / IEC 16262: 2011 artikkelin kirjoittamisen yhteydessä)
Muuttujat, perustietotyypit ja objektit JavaScriptissä
Toisin kuin mitä tapahtuu esim C + +, en JavaScript tietotyyppiä ei sisällytetä muuttujaa määritettäessä ja myös muuttujaan liittyvä tyyppi ei ole kiinteä, on mahdollista antaa erityyppinen arvo koko ohjelman suorituksen ajan.
1
2
3
4
5
6
7
|
var cosa;
cosa=“texto”;
console.log(typeof cosa); // Debería mostrar string en la consola
cosa=123;
console.log(typeof cosa); // Debería mostrar number en la consola
cosa={temperatura:22,corriente:1.5};
console.log(typeof cosa); // Debería mostrar object en la consola
|
Edellisessä esimerkissä muuttuja "asia" on ilmoitettu (tietotyyppiä ilmoittamatta), sitten määritetään eri tyyppiset tiedot ja sitä tarkastellaan typeof
se tyyppi JavaScript jonka hän on tulkinnut. Voit korjata koodin kirjoittamalla sen verkkoselaimen tarkastuskonsoliin (mikä ei vaikuta verkon esitykseen) console.log()
.
Voit pakottaa tietojen muuntamisen tiettyyn tyyppiin, erityisesti tekstin numeerisiksi, käyttämällä toimintoja, kuten parseInt()
o parseFloat()
jotka muuntuvat kokonaisluvuiksi tai liukulukuiksi. Päinvastainen muunnos voidaan tehdä String()
, vaikka se on epätodennäköistä, koska automaattinen muuntaminen yleensä riittää. Kanssa parseFloat()
Voit esimerkiksi saada verkkosivun ominaisuuden arvon, kuten yksiköitä sisältävän objektin leveyden tai korkeuden. Tällä tavalla ilmaisu parseFloat("50px");
palauttaa tuloksena 50, numeerisen arvon.
En JavaScript kaksois- ja kertalainausmerkkien välillä ei ole eroa; Tietotyyppi molemmissa tapauksissa on string
, ja jokainen niistä voi sisältää toisen ilman pakokoodeja.
1
2
3
4
5
6
7
8
9
10
|
var texto;
console.log(typeof texto); // Debería mostrar string en la undefined
texto=“esto es un texto”;
console.log(typeof texto); // Debería mostrar string en la consola
texto=‘A’;
console.log(typeof texto); // Debería mostrar string en la consola
texto=“esto es un ‘texto'”;
console.log(typeof texto); // Debería mostrar string en la consola
texto=‘”A”‘;
console.log(typeof texto); // Debería mostrar string en la consola
|
Edellisessä esimerkissä voidaan nähdä, että muuttuja, kun se on ilmoitettu (olemassa), mutta sille ei ole annettu arvoa, sisältää määrittelemättömän tietotyypin (undefined
). Määrittämättömällä objektilla on arvo null
; Eli objekti on olemassa, mutta ilman arvoa; muuttujalla, joka viittaa siihen, ei olisi a typeof
undefined
mutta object
. Objekti voi olla myös tyhjä, eli ei tyhjä, mutta sillä ei voi olla ominaisuuksia.
että määrittele objekti JavaScript ovat henkselien sisällä ({
y }
) ominaisuudet tai menetelmät erotettuna kaksoispisteellä (:
) ominaisuuden nimi ominaisuuden arvo ja pilkulla (,
) eri ominaisuuksia. Löydät lisätietoja tästä tavasta ilmaista esinettä artikkelista JSON-muoto.
Vaikka voit käyttää syntaksia, joka saattaa saada sinut ajattelemaan toisin, en JavaScript Ei ole luokkia, vaan prototyyppejäEli jotta objekti perii ominaisuuksia ja menetelmiä, luodaan toinen objekti (prototyyppi), jota muut (lapset) käyttävät viitteenä. Tyyliä lähinnä oleva syntaksi JavaScript prototyypin käyttäminen on Object.create
vaikka se on myös mahdollista (ja joskus hyödyllistä) käyttää new
kuten muissakin oliokielissä.
1
2
3
4
|
var perro=new Mamifero(); // Esto funciona, pero no es exactamente el nuevo estilo JavaScript
console.log(perro instanceof Mamifero);
var gato=Object.create(Mamifero); // Crear un objeto usando un prototipo al estilo JavaScript
console.log(Mamifero.isPrototypeOf(gato));
|
että kysely, jos jokin objekti on toisen esiintymä, jos käytät sitä prototyyppinä, jos perit sen ominaisuudet, lyhyesti sanottuna voit käyttää instanceof
( luotu kanssa new
) Tai isPrototypeOf
( luotu kanssa Object.create
), jonka arvo on tosi, kun objekti käyttää prototyyppiä, ja epätosi, kun se ei käytä sitä.
Kun objekti on luotu käyttämällä toista prototyyppinä, eli kun objekti on luotu, se voidaan lisätä uusia ominaisuuksia tai ohittaa prototyypin ominaisuudet käyttämällä pistesyntaksia kuten kohdassa gato.peso=2.5
.
La taulukot sisään JavaScript Ne ovat erilaisia kuin luultavasti tuntemasi C. Aluksi ne ilmoitetaan ilman tarvetta ilmoittaa niiden pituutta, vain avaus- ja sulkemishakasulkeilla ([
y ]
), komponentit voivat olla heterogeenisia (eri tietotyyppejä samassa taulukossa) ja uusia elementtejä voidaan lisätä ilman rajoituksia. Matriisit JavaScript ovat itse asiassa luetteloita (kokoelmia) elementeistä, joihin viitataan numeroindeksillä tai nimellä. Taulukko voi sisältää samanaikaisesti numeerisia indeksejä ja elementtien nimiä, mutta on yleistä käyttää objekteja (ominaisuuksia) toisen tyypin hyödyntämiseen.
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
|
// Declarar matrices (arrays)
var preparada=[]; // La matriz ha sido declarada pero (todavía) no contiene valores
var cosas=[“silla”,“mesa”,“caja”]; // Matriz declarada con componentes formada por cadenas de texto
var valores=[200,“lleno”,0.5,true,“simple”,false,false,10]; // Matriz declarada con componentes heterogéneos
var ramas=[20,“abc”,[1,2,3],false,[10,20,[“uno”,“dos”]]]; // Matriz que contiene matrices
var demode=new Array(10,20,30,4,3,2,1); // La sintaxis con new no es la preferida de JavaScript aunque funciona…
var peligrosa=new Array(10); // …pero con el riesgo de confundir índices con elementos: la matriz peligrosa tiene 10 elementos, no un elemento de valor 10
// Acceder a los valores de la matriz
preparada.push(33.33); // Añade un nuevo valor al final de la matriz
console.log(“La matriz ‘preparada’ contiene “+preparada.length+” elementos”); // Ahora contine 1 elemento
console.log(cosas[0]); // Muestra en la consola el primer valor de la matriz (las matrices empiezan en el índice cero)
cosas[2]=“tarro”;
preparada[10]=50; // Los índices no tienen que ser consecutivos
console.log(“La matriz ‘preparada’ contiene “+preparada.length+” elementos”); // Ahora contine 11 elementos
console.log(“Elemento sexto: “+preparada[5]); // undefined
// Verificar si una variable es (apunta a) una matriz
console.log(Array.isArray(cosas)); // Nuevas versiones de JavaScript (ECMAScript versión 5 o superior)
console.log(cosas instanceof Array); // Implementaciones de JavaScript (ECMAScript) más viejas
// Para esto es mejor usar objetos
var frutas=[];
frutas[“peras”]=20;
frutas[“manzanas”]=30;
frutas[4]=10;
console.log(frutas.peras);
console.log(frutas[“manzanas”]);
console.log(frutas[4]);
console.log(frutas[3]); // undefined
|
Kuten edellisestä esimerkistä voidaan nähdä, voit tietää, vastaako muuttuja taulukon esiintymää (se on taulukkoobjekti) instanceof
, kuten on jo käytetty yleisten objektien kanssa tai uudemmissa versioissa JavaScript voit turvautua Array.isArray()
Voit käyttää taulukon elementtejä käyttämällä sen hakemistoa (matriz[7]
) tai ominaisuuden nimellä hakasulkeissa olevalla nimellä (matriz["nombre"]
) tai tavallisella kohteiden pistesyntaksilla (matriz.nombre
). Koska nimi on tekstimerkkijono, sen muodostamiseen voidaan käyttää lauseketta, mukaan lukien muuttujat. Ominaisuuksia sisältävän taulukon läpi kiertämiseen voidaan käyttää muotoa sisältävää silmukkaa for(propiedad in matriz)
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
var matriz=[];
matriz[“color”]=“verde”;
matriz[“grosor”]=10;
matriz[“estado”]=“nuevo”;
matriz[0]=25.0;
matriz[1]=“uno”;
for(propiedad in matriz)
{
console.log(propiedad+” valor “+matriz[propiedad]);
}
/* El resultado en la consola será:
0 valor 25
1 valor uno
color valor verde
grosor valor 10
estado valor nuevo
*/
|
Se on tavoitteemme kannalta kiinnostavaa käsitellä objekti Date
, jolla voit esittää ja hallita päivämäärää ja kellonaikaa JavaScript. Objekti voidaan ilmentää ilman tietoja, joten se ottaa nykyisen päivämäärän ja kellonajan, tai se voidaan luoda ilmoittamalla päivämäärä arvona, joko millisekunteina 1. tammikuuta 1970 lähtien (esim. Unix-aika tai POSIX-aika mutta ilmaistaan millisekunteina sekuntien sijaan) tai määrittämällä erilliset arvot vuodelle, kuukaudelle, päivälle, tunnille...
Kohde sisältää täydellisen sarjan menetelmiä päivämäärän ja ajan kyselyyn tai asettamiseen:
-
now()
Palauttaa nykyisen päivämäärän ja kellonajan millisekunteina 1. tammikuuta 1970 lähtien -
getTime()
|setTime()
Hakee tai muuttaa vastaavasti aika-arvon millisekunteina 1. tammikuuta 1970 lähtien.valueOf()
, joka on useimmissa objekteissa esiintyvä menetelmä, saadaan myös vastaavan Date-objektin arvo, kuten esimgetTime()
kanssa Unix-aika tai POSIX-aika ilmaistuna ms. -
getMilliseconds()
|setMilliseconds()
Käytetään kohteen millisekunnin murto-osan kyselyyn tai asettamiseenDate
jolla se toteutetaan. Tarkasteltaessa saatu arvo on välillä 0 - 999, mutta voidaan määrittää suurempia arvoja, jotka kerääntyvät kokonaispäivämäärään ja kellonaikaan, joten kuten muutkin get-menetelmät, se auttaa lisäämään kohteen arvoaDate
(tai pienennä sitä, jos käytetään negatiivisia arvoja). -
getSeconds()
|setSeconds()
Palauttaa tai muuttaa vastaavasti objektin sekuntien arvonDate
. -
getMinutes()
|setMinutes()
Käytetään kohteen tarkistamiseen tai minuuttien asettamiseenDate
. -
getHours()
|setHours()
Voit tarkastella tai muokata kohteen tunteja (0 - 23).Date
. -
getDay()
Palauttaa päivämäärän viikonpäivän arvona 0 - 6 (sunnuntai - lauantai). -
getDate()
|setDate()
Palauttaa tai muuttaa kohteen kuukauden päivääDate
johon sitä sovelletaan. -
getMonth()
|setMonth()
Käytetään kohteen kuukausinumeron tarkistamiseen tai muokkaamiseenDate
. -
getFullYear()
|setFullYear()
Kyselee tai asettaa vuoden arvon objektille, joka sisältää päivämäärän ja kellonajan.
Aiemmat menetelmät Date
sisältää version UTC pystyä työskentelemään suoraan yleisajan kanssa ilman välilaskutoimituksia. Siinä mielessä esim. getHours()
on versio getUTCHours()
o getMilliseconds()
vaihtoehto getUTCMilliseconds()
työskennellä vaihtoehtoisesti virallisen (laillisen) tai yleisen ajan kanssa. Kanssa getTimezoneOffset()
Voit tietää eron yleisajan ja paikallisen virallisen ajan välillä.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
var dia_semana=[“domingo”,“lunes”,“martes”,“miércoles”,“jueves”,“viernes”,“sábado”];
var nombre_mes=[“enero”,“febrero”,“marzo”,“abril”,“mayo”,“junio”,“julio”,“agosto”,“septiembre”,“octubre”,“noviembre”,“diciembre”];
var digitos_hora;
var hoy=new Date();
var texto_hoy=“”;
texto_hoy+=“Hoy es “;
texto_hoy+=dia_semana[hoy.getDay()];
texto_hoy+=“, “;
texto_hoy+=hoy.getDate();
texto_hoy+=” de “;
texto_hoy+=nombre_mes[hoy.getMonth()];
texto_hoy+=” de “;
texto_hoy+=hoy.getFullYear();
texto_hoy+=” y son las “;
digitos_hora=hoy.getHours();
texto_hoy+=digitos_hora>9?digitos_hora:“0”+digitos_hora;
texto_hoy+=“:”;
digitos_hora=hoy.getMinutes();
texto_hoy+=digitos_hora>9?digitos_hora:“0”+digitos_hora;
texto_hoy+=“:”;
digitos_hora=hoy.getSeconds();
texto_hoy+=digitos_hora>9?digitos_hora:“0”+digitos_hora;
|
JavaScript-toiminnot
Jos luet tätä, tiedät varmasti kuinka ohjelmoida. mikro-ohjaimet en C vuonna C + + ja tietää funktion käsitteen. Vaikka perusidea on sama, JavaScript Tapa, jolla ne määritellään ja käytetään, on hieman erilainen. Aluksi on jo sanottu, JavaScript Se ei käytä nimenomaisesti tietotyyppejä, joten sinun ei tarvitse ilmoittaa sitä funktiota määriteltäessä. Seurata, Toiminnalla ei ole pakollista nimeä, ne voivat olla nimettömiä. Ne voidaan liittää muuttujaan niiden kutsumiseksi, mutta se ei välttämättä ole välttämätöntä, koska joskus on hyödyllistä kutsua ne välittömästi, jolloin sulut ja parametrit lisätään funktion määrittelyn jälkeen.
Jos haluat määrittää funktion, käytä etuliitettä function
, jos mahdollista, kirjoita sulkuihin nimi, argumentit (funktiolle välitetyt parametrit) ja aaltosulkeisiin koodi, joka suoritetaan, kun funktiota kutsutaan.
1
2
3
4
5
|
function doble(numero)
{
var resultado=numero*2;
return resultado;
}
|
Varmasti edellisessä esimerkissä "tulos"-muuttujaa ei tarvittu ollenkaan, mutta se on hyvä tekosyy muistaa muuttuva laajuus, joka toimii odotetulla tavalla: "result"-muuttuja on olemassa vain "double"-funktiossa. Sisään JavaScript voidaan myös käyttää let
, sijaan var
, laajentaaksesi muuttujan koodilohkokontekstiin (suljettu aaltosulkeisiin, {
y }
)
Kun edellisessä osiossa puhuttiin objekteista, jotain perustavanlaatuista puuttui: ominaisuudet on määritelty, mutta menetelmiä ei ole määritelty. Odotetusti, objektimenetelmät ovat funktioita, niillä ei ole nimeä ja niitä käytetään (kutsutaan) objektimääritelmän antamasta (ominaisuuden) nimestä.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
var
termostato=
{
temperatura_actual:0.0,
temperatura_frio:18.5,
temperatura_calor:22.0,
consumo:0,
ver_temperatura:
function()
{
console.log(“Temperatura actual: “+this.temperatura_actual+” °C”);
}
}
|
Edellisessä esimerkissä on jo menetelmä, "view_temperature", joka näyttää "current_temperature"-ominaisuuden arvon konsolin kautta. Se ei ole kovin hyödyllinen, mutta se antaa täydellisemmän käsityksen siitä, millainen objektin määritelmä on JavaScript.
Päästäksesi objektin (funktioiden) menetelmiin sen ominaisuuksiin, käytä this
, kuten edellisessä esimerkissä rivillä 11, kun käytetään "current_temperature"-ominaisuutta.
Käytä asiakirjaobjektimallia (DOM) JavaScriptillä
alkaen JavaScript Sinulla on pääsy sen verkkosivun sisältöön, jolla se toimii, sekä joihinkin sivun näyttävän selaimen osiin, mutta et järjestelmäresursseihin. Tietorakenne, joka tukee ominaisuuksia ja menetelmiä, joista pääsee käsiksi JavaScript osa ikkunaobjektia, erityisesti kohteen (asiakirjan HTML) vastaa objektia document
. Vaikka sitä toisinaan käytetään selvyyden vuoksi, ei ole tarpeen edeltää ikkunoita menetelmiin tai ominaisuuksiin viitatakseen niihin, riittää esim. document
, ei tarvitse kirjoittaa juuriobjektin nimeä kuten on window.document
, niin kauan kuin nykyiseen ikkunaan viitataan.
Eniten käytetty muoto löytää kohteen asiakirjasta HTML Se tapahtuu menetelmän kautta getElementById()
, jolle koodia luotaessa ilmoitettu tunnus välitetään argumenttina HTML. Aiemmissa osissa selitetyn perusteella on helppo olettaa, että pääset käsiksi myös kohteen sisällä oleviin komponentteihin document
käyttämällä pistesyntaksia (document.componente
) tai suluissa käyttäen molempia nimeä (document["componente"]
), hyödyllisin, kuten numeerinen indeksi, vaikeakäyttöinen ja epäkäytännöllinen käsin laaditun verkkosivun sisällössä.
kanssa JavaScript voit hanki elementti, joka sisältää toisen elementin (elementti tai pääsolmu) kiinteistösi konsultointi parentNode
tai omaisuutesi parentElement
, ero on siinä, että pääelementti (parentElement
) merkkijonon viimeisestä elementistä DOM Se on nolla (null
) ja pääsolmu (parentNode
) on itse asiakirja (document
).
että muokata elementin sisältöä HTML, esimerkiksi etiketin <div>
, Sitä voidaan käyttää innerHTML
ja muuttaa sen ominaisuuksia voit määrittää sille eri luokan className
tai muuttaa sen ominaisuuksia erikseen style
. Web-sivun elementin näyttämän tyylin tarkasteleminen ei välttämättä ole hyödyllistä style
koska se voi riippua useista tekijöistä tai sitä ei yksinkertaisesti ole erikseen määritelty. Web-sivulla lopulta näytetyn elementin tyylin tarkistamiseksi käytetään getComputedStyle-menetelmää.
Dokumenttielementtiin HTML Sille voidaan määrittää useita luokkia sen ulkonäön ja käyttäytymisen määrittämiseksi hallita objektin luokkien luetteloa JavaScript voit turvautua classList
joka tarjoaa menetelmät add
lisätäksesi uuden luokan luetteloon, remove
poistamaan se, toggle
korvata se tai tarkastella elementin luokkaluettelon sisältöä item
ja contains
, joka palauttaa luokan, joka on tietyssä paikassa luettelossa, ja arvon true
o false
onko jokin luokka luettelossa vai ei.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
var contenedor_temperatura=document.getElementById(“temperatura”); // Encontrar el div con id=”temperatura”
contenedor_temperatura.innerHTML=“”; // Eliminar el contenido provisionalmente para que no se vean los cambios
contenedor.className=“bloque_temperatura”; // Asignar una nueva clase
if(temperatura>20) // Si la temperatura es mayor que 20 °C…
{
contenedor.style.color=“#FF6666”; // …usar el color rojo en lugar del color normal de la clase
}
contenedor_temperatura.innerHTML=“La temperatura es “+temperatura+” °C”; // Cuando el aspecto esté preparado mostrar el valor
if(document[“titulo”].classList.contains(“estilo_titulo”)) // Si el objeto “titulo” tiene la clase “estilo_titulo”…
{
if(document[“titulo”].classList.contains(“general”)) // …y la clase “general”…
{
document[“titulo”].classList.remove(“general”); // …quitar la clase “general”
}
}
else // Si el objeto “titulo” no tiene la clase “estilo_titulo”…
{
document[“titulo”].classList.add(“estilo_titulo”); // …añadir la clase “estilo_titulo” (da igual que tenga o no la clase “general”)
}
|
Edellisessä esimerkissä se sijaitsee kanssa getElementById
objekti, jota haluat käsitellä (elementti <div>
hänen id
), ennen ulkoasun muuttamista sisältö poistetaan määrittämällä innerHTML
tyhjä tekstimerkkijono, sille määritetään uusi luokka className
ja sen tyyliä on muokattu style
sisällön (lämpötilan) arvosta riippuen värin vaihtaminen tarvittaessa kiinteistön kautta color
. Kun kuvasuhde on määritetty, arvo kirjoitetaan uudelleen käyttämällä innerHTML
.
Yllä olevan esimerkin toisessa osassa (rivit 9-19) käytetään koodielementtiä HTML käyttämällä syntaksia document[]
ja omaisuutta id
elementin muuttaa sen luokkaluetteloa menetelmällä classList.remove()
ja menetelmälläclassList.add()
, joka perustuu useiden kyselyiden tulokseen, jotka suoritetaan ehdollisissa suorituksissa ja joita he vertaavat keskenään classList.contains()
.
Milloin se tulee viittaa elementtiin HTML eri kertaa koko koodin ajan JavaScript, se on vähän tehokkaampaa määrittää se muuttujalle tai käytä sen hakemistoa nimen sijaan, koska muuten käyttämäsi menetelmä JavaScript sen hankkiminen joka kerta vaatisi sen nimen etsimistä, mikä vie hieman enemmän aikaa kuin jos muuttujaa käytettäisiin.
että lisää uusia objekteja dokumenttiin HTML, ne voidaan luoda ensin menetelmällä createElement
de document
ja liittää ne myöhemmin muihin elementteihin puun kohdassa, joka on tarpeen appendChild
. Objektin luomiseen XML, kuten esineitä SVG joita käytämme piirtämään IoT-antureiden kaaviota, voit käyttää createElementNS
(NS varten nimiavaruus). Kuten kerrottiin, kun puhutaan muodosta SVG, sitä vastaava nimiavaruus (nykyisessä versiossa) on http://www.w3.org/2000/svg
, joka tulee välittää createElementNS
argumenttina elementtityypin kanssa, svg
, tässä tapauksessa.
Una vaihtoehto innerHTML
lisätäksesi tekstiä dokumenttielementin sisällöksi HTML on menetelmä createTextNode()
esineen document
. Tällä vaihtoehdolla voit luoda uutta tekstiä (johon päästään myöhemmin, jos se on määritetty muuttujalle), joka sisällytetään objektipuuhun menetelmällä appendChild()
. kuten vaihtoehto appendChild()
, joka lisää uuden sisällön sen solmun loppuun, johon se on lisätty, voit käyttää menetelmää insertBefore()
, joka lisää uuden objektin olemassa olevan objektin eteen. pitää päällä insertBefore()
sijaan appendChild()
tarjoaa menetelmän, joka palvelee esim lajitella uusia esineitä olemassa olevien eteen kun elementin on oltava toisen edessä (kuten luettelossa) tai peittävä tai peitetty graafisessa rakenteessa, jossa on elementtejä lähempänä etu- tai taustaa.
Reagoi tapahtumiin JavaScriptillä
Kun tapa käyttää verkkosivua IoT-kytketyn anturikaavioiden säilönä sitä käytettiin onload
Etiketissä <body>
aloittaaksesi kaavion piirtämisen. Tämä koodiobjekteihin liittyvä ominaisuus HTML, viittaa tapahtumia JavaScript. Kuten jo selitettiin, se suorittaa toiminnon, kun sivu on latautunut. Vaikka se on liitetty koodiin HTML pitääksesi sen paremmin mielessä, se olisi voitu kirjoittaa koodiin JavaScript kuten body.onload=dibujar;
ollessa dibujar
sen toiminnon nimi, joka käynnistetään, kun verkkosivu latautuu.
Uusimmissa versioissa JavaScript tapahtumia voidaan liittää funktioihin käyttämällä addEventListener
muodossa objeto.addEventListener(evento,función);
tai käyttämällä syntaksia objeto.evento=función;
joka toimii myös vanhemmissa toteutuksissa. Voit poistaa tapahtumaan liittyvän toiminnon linkityksen removeEventListener
jolla on sama muoto kuin addEventListener
.
JavaScript Se pystyy reagoimaan lukuisiin tapahtumiin, joita verkkosivulla voi tapahtua. Se voi esimerkiksi havaita, kun elementtiä napsautetaan HTML kanssa onmousedown
, tai kun sitä napsautetaan onclick
, kun näppäintä painetaan onkeydown
, käyttämällä vierityspalkkia painikkeella onscroll
. Meidän tarkoitukseen se riittää meille tunnista sivun lataus onload
ja sen koon muuttaminen kanssa onresize
. Yhdistämme nämä tapahtumat esineisiin body
y window
ja DOM vastaavasti. Ensimmäinen voidaan määrittää koodissa HTML, kuten näkyy ja toinen koodissa JavaScript ensimmäisen kutsuman funktion sisällä ja muodossa window.onresize=redimensionar;
ollessa redimensionar
funktio, jota kutsutaan aina, kun ikkunan koko muuttuu.
Suorita tietyn ajan kuluttua
JavaScript on kaksi resurssia lykätty toteutus: setTimeout
, joka suorittaa toiminnon tietyn ajan kuluttua ja setInterval
joka suorittaa toiminnon joka tietty aikaväli. Molemmat menetelmät vaativat parametreina (1) kutsutun funktion ja (2) millisekunteina ilmaistun aikavälin. Pysäyttääksesi niiden toiminnan, voit määrittää näiden funktioiden palauttaman tuloksen muuttujille ja välittää ne argumenttina clearTimeout
tai clearInterval
kun et halua kutsua niitä uudelleen (tai kun et halua, että niitä suoritetaan ensimmäistä kertaa) setTimeout
o setInterval
vastaavasti.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
var cuenta_atras=setTimeout(descansar,1000*60*20); // Recordar que hay que descansar cuando pasen 20 minutos
var repeticion=setInterval(consultar_correo,1000*60*5); // Revisar el correo cada 5 minutos
function descansar()
{
alert(“Puedes descansar un rato”); // Esto solamente aparecerá una vez
}
function consultar_correo()
{
alert(“Revisa el correo electrónico”); // Esto aparecerá cada cinco minutos
}
function detener_cuenta_atras() // No utiliza argumentos sino la variable global
{
clearTimeout(cuenta_atras); // Detener la cuenta atrás para avisar a los 20 minutos
}
function no_avisar_lectura_correo() // No utiliza argumentos sino la variable global
{
clearInterval(repeticion); // Dejar de avisar cada 5 minutos
}
|
Edellisessä esimerkissä menetelmä esitellään alert
joka näyttää varoituskyltin. Vaikka sitä käytettiin laajasti aiemmin, se on tällä hetkellä melkein kielletty koodista JavaScript koska on aggressiivista (tunkeilevaa) peittää web-sivu valintaikkunalla.
Ohjelmassa, joka on kirjoitettu a mikro-ohjain pienestä sarjasta (kuten lautasella oleva Arduino Uno) on yleistä käyttää globaaleja muuttujia, kuten edellisessä esimerkissä JavaScript, koska koodi on lyhyt eikä erityisen hämmentävä, koska toiminnot on usein toteutettu ad hoc ja koska globaalien muuttujien käyttö mahdollistaa muistin käytön ennustamisen hyvin yksinkertaisella ja intuitiivisella tavalla, mikä on kriittistä järjestelmissä, joissa on vähän resursseja. Sen sijaan, en JavaScript On yleistä vähentää globaalien muuttujien käyttö mahdollisimman vähäiseksi. koska sen ei tarvitse kiirehtiä muistin käyttöä, koska se toimii normaalisti a prosessori joiden resurssit ovat paljon paremmat kuin a MCU, koska se todennäköisesti esiintyy rinnakkain paljon kolmannen osapuolen koodia, joiden kanssa sen on toimittava häiritsemättä ja koska se on avoin järjestelmä, tulevaa suorituskontekstia ei voida ennustaa (ohjelman mikro-ohjain Small määrittelee toimintansa täysin lisäämättä koodia sen ollessa käytössä) ja koska sovellusten mitat voivat vaikeuttaa lukemista, jos koodi ei kapseloi toimintaansa, jolloin menetelmät ovat mahdollisimman itsenäisiä.
Matemaattiset operaatiot JavaScript Math -objektin kanssa
Monimutkaisemman matemaattisen laskennan matemaattiset toiminnot on ryhmitelty objektiin Math
. Tätä objektia käytetään suoraan, sitä ei tarvitse ilmentää sen sisältämien menetelmien tai ominaisuuksien (vakioiden) käyttämiseksi.
Math.abs(n)
Parametrin n absoluuttinen arvoMath.acos(n)
Parametrin n arkosiini (tulos radiaaneina)Math.asin(n)
Parametrin n arksini (tulos radiaaneina)Math.atan(n)
Parametrin n arktangentti (tulos radiaaneina)Math.atan2(n,m)
Arktangentti n/m (tulos radiaaneina)Math.ceil(n)
Pyöristä parametri lähimpään kokonaislukuun ylöspäinMath.cos(α)
Parametrin α kosini (α radiaaneina)Math.E
e-numero (≃2.718281828459045)Math.exp(n)
e korotettu parametriin n: enMath.floor(n)
Pyöristä parametri n lähimpään kokonaislukuun alaspäinMath.log(n)
Parametrin n luonnollinen logaritmi (kanta e).Math.LN2
Luonnollinen logaritmi (kanta e) luvusta 2 (≃0.6931471805599453)Math.LN10
Luonnollinen logaritmi (kanta e) luvusta 10 (≃2.302585092994046)Math.LOG2E
e:n peruslogaritmi 2 (≃1.4426950408889634)Math.LOG10E
e:n peruslogaritmi 10 (≃0.4342944819032518)Math.max(a,b,c,…)
Siirrettyjen parametrien luettelon suurin arvoMath.min(a,b,c,…)
Siirrettyjen parametrien luettelon pienin arvoMath.PI
Numero π (≃3.141592653589793)Math.pow(n,m)
Ensimmäinen parametri n nostettuna toiseksi parametriksi m: nmMath.random()
(Melkein) satunnaisluku välillä 0.0 ja 1.0Math.round(n)
Pyöristä parametri n lähimpään kokonaislukuunMath.sin(α)
Parametrin α sini (α radiaaneina)Math.sqrt(n)
Parametrin n neliöjuuriMath.SQRT1_2
1/2:n neliöjuuri (≃0.7071067811865476)Math.SQRT2
2:n neliöjuuri (≃1.4142135623730951)Math.tan(α)
Parametrin α tangentti (α radiaaneina)
Lataa tiedot palvelimelta AJAX:n avulla
IoT:hen tallennettujen tietojen piirtämisessä noudatetaan sitä, että dataa ladataan aika ajoin palvelimelta ja piirretään uudelleen graafi, jolla ne esitetään. Tietojen lukemiseen palvelimelta käytetään tekniikkaa AJAX (asynkroninen JavaScript ja XML) esineen kautta XMLHttpRequest
de JavaScript. Datakaavion piirtäminen tehdään käyttämällä objektia uudelleen SVG joka on jo koodissa HTML ja joka sisältää kaavion, jonka koordinaatit on muutettu vastaamaan uutta ladattua dataa.
Tämän ehdotuksen esimerkissä piirustuksen päivityksen lisäksi verkkosivulle päivitetään myös teksti, joka näyttää kunkin kaavion viimeisen mittaustiedon päivämäärän ja arvon.
Palvelinpuolella on tietokanta, joka sisältää tiedot että IoT:hen kytketyt anturit ovat valvoneet. Objektipyyntö lukee tämän tietokannan XMLHttpRequest
vastaamalla sisään koodatuilla tiedoilla JSON-muoto, vaikka käytetyn menetelmän nimi viittaa suhteeseen muotoon XML.
Ensimmäisessä polaridad.es-opetusohjelmassa IoT-tietojen tallennus Näet esimerkin infrastruktuurista, jolla voidaan hallita esineiden Internetiin yhdistettyjen laitteiden tarjoamia tietoja palvelinpuolelta. Tässä artikkelisarjassa resurssina käytetään palvelinta Apache josta voit käyttää ohjelmointikieltä PHP päästäksesi tietokantaan MySQL o MariaDB. IoT:tä tukevilla palvelimilla on hyvin yleistä löytää tietokantoja MongoDB (NoSQL) ja ohjelmointikieli JavaScript päälle Node.js ohjelmistoinfrastruktuurina.
Seuraava toiminto vastaa uusimpien tietojen pyytämisestä yhdeltä anturilta palvelimelta. Funktiokutsussa objektia käytetään argumenttina JavaScript joka tukee piirrettyä dataa. Jos sama graafi edustaa useita arvoja, esimerkiksi visuaalisesti korrelaation etsimiseksi, palvelimelle voidaan tehdä pyyntö palauttaa useita samanaikaisesti, mikä on palvelimen toimintatavasta johtuen optimaalinen tapa. HTTP-protokolla.
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
|
function consultar_ultimo_valor_sensores(objeto_grafico)
{
var consulta=‘zona=”+objeto_grafico.sufijo_nombre;
var pagina=“ultimo_valor_sensor.php”;
var resultado;
var ajax;
if(window.XMLHttpRequest)
{
ajax=new XMLHttpRequest(); // ajax=Object.create(XMLHttpRequest);
}
else // Versiones antiguas de MS Internet Explorer
{
ajax=new ActiveXObject(“Microsoft.XMLHTTP”);
}
ajax.onreadystatechange=
function()
{
if(ajax.readyState==4&&ajax.status==200&&ajax.responseType==“json”)
{
resultado=JSON.parse(ajax.responseText);
if(resultado.fecha>objeto_grafico.fecha[objeto_grafico.fecha.length–1])
{
// Normalmente se gestionará la respuesta utilizando el objeto
redibujar_grafico(objeto_grafico,resultado);
// Si los datos son sencillos y tienen una estructura clara puede ser más práctico usarla directamente
// redibujar_grafico(objeto_grafico,[resultado.fecha,resultado.temperatura]);
}
}
}
ajax.open(“POST”,pagina);
ajax.setRequestHeader(“Method”,“POST “+pagina+” HTTP/1.1″);
ajax.setRequestHeader(“Content-type”,“application/x-www-form-urlencoded”);
ajax.setRequestHeader(“Content-length”,consulta.length);
ajax.setRequestHeader(“Connection”,“close”);
ajax.send(consulta);
}
|
Edellisen esimerkin kolmannella rivillä valmistetaan palvelimelle tehtävä kysely, jossa välitetään "vyöhyke"-argumentti, jonka arvo on valvotun paikan nimi tai koodi, koska tiedot alue voi olla rinnakkain samassa tietokannassa eri antureita (esimerkiksi lämpömittarit, jotka mittaavat lämpötilaa eri huoneissa). Edelliselle funktiolle, kaaviotiedot sisältävälle objektille, välitetyn parametrin odotetaan sisältävän ominaisuuden huoneen nimellä ("name_suffix").
Edellisen koodin rivien 7 ja 14 välissä on objekti XMLHttpRequest
joka on tallennettu muuttujaan "ajax". Ennen kuin valitset objektin luontitavan, teet haun window
jos XMLHttpRequest
ei ollut saatavilla (jota tapahtui Microsoftin Explorerin vanhoissa versioissa ja vaikka se on kaukana jäljessä, se toimii esimerkkinä vaihtoehdoista objektin luomiseksi käyttämällä (natiivista) syntaksia. Object.create
o new
, samanlainen kuin muissa oliokielissä.
Jotta vastaus voidaan hallita välittömästi, sitä käsittelevä koodi valmistetaan riveillä 15-26 ennen pyynnön tekemistä palvelimelle.
Tapa suorittaa kyselyn HTTP palvelimelle koostuu avaa yhteys kanssa open
tyyppi ja sivu (valinnaisesti käyttäjätunnus ja salasana), valmistele otsikot pöytäkirjan kanssa setRequestHeader
y lähetä pyyntö kanssa send
. Otsikko HTTP Content-length
sinun on tiedettävä kyselyn pituus (merkkien lukumäärä), joka lasketaan käyttämällä length
.
Kun pyyntö AJAX on valmis, tapahtumaan liittyvä toiminto suoritetaan onreadystatechange
. Toiminnon osoittamisen sijaan edellisessä esimerkissä määritellään lennossa anonyymi toiminto, joka hallitsee palvelimelta saapuvien tietojen vastaanottoa. Ensinnäkin rivillä 18 tarkistetaan, että pyynnön tila on "valmis", mikä vastaa arvoa 4
omaisuuden readyState
, että tila on "OK". HTTP-protokolla (koodi 200
), jonka voi saada kiinteistöstä status
ja että saapuneet tiedot ovat JSON-muoto, konsultoi kiinteistöä responseType
.
Kun on varmistettu, että vastauksen tila on odotetusti, edellisen esimerkin rivillä 20 luo objektin tuloksella muuntaen tekstin JSON. Vastauksessa on palautettava päivämäärä, jonka avulla voimme nähdä, onko palvelimen lähettämä tulos ollut jo aiemmin esitetty kaaviossa, mikä varmistetaan rivillä 21. Jos tiedot ovat uusia, rivillä 23 Toiminto, joka on vastuussa kaavion uudelleenpiirtämisestä uudella tiedolla.
Ajatuksena tätä lukumenetelmää ehdotettaessa on, että tiedot päivitetään hyvin usein. Jos esitetyt tiedot vastaavat pitkää aikaväliä (esim. päivän tai viikon lämpötilat), voidaan toteuttaa ensimmäinen pyyntö, joka kerää kaikki saatavilla olevat tiedot ja sitten esimerkin kaltainen, joka päivittää sen kauden kirjeenvaihtaja.
Luo satunnaisia tietoja testausta varten
Kun kaikki palvelin- ja asiakasinfrastruktuuri on valmis, edellisen osan kaltainen toiminto vastaa tietojen lukemisesta ja graafin piirtämisestä niiden avulla, mutta Testausvaiheessa voi olla käytännöllisempää käyttää satunnaislukuja kontrolloidulla alueella tarkistaaksesi, onko kirjoitettava koodi oikea. Seuraava toiminto voi toimia esimerkkinä tietojen saamiseksi lopullista sovellusta rakennettaessa.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
function consultar_ultimo_valor_sensores
(
objeto_grafico,// Objeto dentro del elemento SVG que representa el trazado
valor_maximo, // Valor máximo
valor_minimo, // Valor mínimo
margen_valor // Cantidad extra que se representa sobre/bajo el valor máximo/mínimo
)
{
// La forma más genérica es usar objetos
/*
var nuevo_valor_inventado=
{
fecha:Math.round(Date.now()+Math.random()*1000),
temperatura:Math.random()*Math.abs(valor_maximo-valor_minimo)+valor_minimo
};
*/
// En este caso concreto, como son pocos datos y con una estructura concreta es más práctico usar un vector
var nuevo_valor_inventado=
[
Math.round(Date.now()+Math.random()*1000),
Math.random()*Math.abs(valor_maximo–valor_minimo)+valor_minimo
];
redibujar_grafico(objeto_grafico,nuevo_valor_inventado);
}
|
Sen sijaan, että luettaisiin tiedot tietokannasta, yllä oleva esimerkki luo ne satunnaisesti ja välittää ne funktiolle, joka vastaa kaavion piirtämisestä. Keksitty data on vektori, joka muodostuu arvona millisekunteina ilmaistusta päivämäärästä, anturitiedon tallennushetkestä ja valvotusta tiedosta, joka on maksimiarvon ja minimiarvon välissä.
Tässä esimerkissä päivämäärää luotaessa sitä voidaan viivästyttää jopa yksi sekunti (1000 millisekuntia) suhteessa päivämäärään keksinnön ajankohtana. Kuten Math.random()
luo luvun välillä 0.0 - 1.0, kertomalla sen 1000:lla saadaan luku väliltä 0 - 1000, joka muunnetaan sitten kokonaisluvuksi. Samalla tavalla arvo saadaan kertomalla satunnaisluku vaihteluvälillä (maksimi miinus minimi) ja lisäämällä minimi.
Piirrä IoT-antureiden kaavio SVG-kaaviolla
Koska olemme nähneet, kuinka voimme saada arvot, joita haluamme esittää (esimerkissä lämpötila) ja niiden ajallisen sijainnin, jotka voidaan ilmaista yhdessä koordinaattien muodossa, alla oleva esimerkki näyttää funktion polun piirtämiseen joka yhdistää nämä pisteet ja valinnaisesti värillisen alueen, jonka rajaa tämä viiva yläreunassa. Lopputulos olisi seuraavan kuvan kaltainen.
Kaavion vaaka-akseli (X) edustaa aikaa ja pystyakseli (Y) arvoja, joita IoT:hen kytketyt anturit ovat seuranneet. Vaakaväli on muutama sekunti, koska tässä ehdotuksessa kaaviota päivitetään hyvin usein (esimerkiksi joka sekunti) antamaan lähes reaaliaikaista tietoa anturien tilasta.
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
52
53
54
|
function actualizar_grafico
(
grafico, // Objeto SVG con el que se dibuja la gráfico
coordenada, // Matriz con las coordenadas del trazado formada por pares [tiempo,valor] ordenados primero el más antiguo (tiempo menor) último el más nuevo
tiempo_total_representado, // Tiempo total representado por la gráfico (en milisegundos)
valor_maximo, // Valor máximo aceptable antes de emitir una alarma
valor_minimo, // Valor mínimo aceptable antes de emitir una alarma
margen_valor, // Cantidad extra que se representa sobre/bajo el valor máximo/mínimo
parametro_cerrado, // Valor booleano que indica si el trazado se cierra o no (por defecto false)
parametro_ancho_caja, // Ancho de la caja que contiene la gráfico (por defecto 100.0)
parametro_alto_caja // Alto de la caja que contiene la gráfico (por defecto 100.0)
)
{
var cerrado=parametro_cerrado||false; // Valor booleano que indica si el trazado se cierra o no (por defecto false)
var ancho_caja=parametro_ancho_caja||100.0; // Ancho de la caja que contiene la gráfico (por defecto 100.0)
var alto_caja=parametro_alto_caja||100.0; // Alto de la caja que contiene la gráfico (por defecto 100.0)
var coordenadas_trazado=“M “; // Cadena de texto que representa la propiedad “d” del trazado SVG
var desplazamiento=[]; // Desplazamientos X e Y para posicionar el tiempo y el valor representado dentro del rango del gráfico
var escala=[]; // Coeficientes X e Y para calcular el tamaño al representar el gráfico
var sin_recortar=true; // False si la gráfico se sale de la caja (si se sale, si recorta, se hace false para no seguir dibujando puntos)
var contador_valor=coordenada.length–1; // Variable para recorrer los valores (índice)
var posicion=[]; // Variable intermedia (para hacer más legible el código) con la que calcular la posición horizontal y vertical de un punto del trazado
escala[0]=ancho_caja/tiempo_total_representado; // Coeficiente que multiplica a los valores horizontales (tiempo) para calcular las coordenadas X
escala[1]=alto_caja/(Math.abs(valor_maximo–valor_minimo)+margen_valor*2); // Coeficiente que multiplica a los valores (vertical) para calcular las coordenadas Y
desplazamiento[0]=coordenada[coordenada.length–1][0]–tiempo_total_representado; // Valor desde el que se empieza a contar el tiempo: el valor mayor (último) menos el rango de tiempo representado
desplazamiento[1]=margen_valor–valor_minimo; // Valor menor mostrado (al menor se le añade un margen para visualizar el principio de los valores fuera del rango permitido)
if(cerrado) // Si se dibuja un path (trazado) cerrado…
{
coordenadas_trazado+=ancho_caja+“,”+alto_caja+” L “; // …se empieza por la parte inferior de la caja
}
while(contador_valor>=0&&sin_recortar) // Mientras queden valores por representar y no se haya llegado al borde izquierdo del gráfico…
{
posicion[0]=(coordenada[contador_valor][0]–desplazamiento[0])*escala[0]; // Calcular la X restando al tiempo el desplazamiento y convirtiéndolo a la escala del gráfico con el coeficiente horizontal
posicion[1]=alto_caja–(coordenada[contador_valor][1]+desplazamiento[1])*escala[1]; // Calcular la Y restando del alto de la caja (la Y crece hacia abajo en SVG)
coordenadas_trazado+=posicion[0]+“,”+posicion[1]; // Formar la coordenada con la X y la Y
if(posicion[0]>0) // Si no se ha rebasado el margen izquierdo…
{
coordenadas_trazado+=contador_valor>0?” L “:“”; // …y quedan valores que represntar, añadir una nueva línea (código L) para el próximo
contador_valor—; // Pasar al siguiente valor
}
else // Si se ha rebasado el margen izquierdo…
{
sin_recortar=false; // …abandonar el modo sin recorte (lo que terminará de calcular coordenadas)
}
}
if(cerrado) // Si se dibuja un trazado (path) cerrado…
{
coordenadas_trazado+=” L “+posicion[0]+“,”+alto_caja+” Z”; // …se termina por la parte inferior de la caja y se añade Z para cerrarlo en SVG
}
grafico.setAttribute(“d”,coordenadas_trazado); // Cambiar las coordenadas del trazado (propiedad “d”) por las que se han calculado
}
|
Edellisessä koodissa on kaksi mielenkiintoista näkökohtaa, ensinnäkin mahdollistava laskenta mukauttaa esitettyjen arvojen aluetta ja toiseksi kiinteistöjen rakentaminen d
joka ilmaisee asettelun pisteiden koordinaatit (path
).
Esitettyjen arvojen alueen mukauttamiseksi niitä siirretään minimistä ja skaalataan niin, että näkyvä suuruus vastaa kaavion kokoa. Ajan tapauksessa siirtymä saadaan vähentämällä näytettävän ajanjakson pisimmästä ajasta (päivämäärä ja kellonaika lähimpänä nykyistä) (esimerkissä 20 sekuntia). Lämpötila-arvojen siirtymä on alemman alueen (yksi aste) miinus pienin arvo, joten alla näkyvät tiedot ovat eniten samankaltaisia kuin pienin sallittu arvo, mutta jättävät marginaalin, jonka avulla voimme arvioida, mitä ohitetaan.
Kerroin, joka kertoo aika-arvot graafin vaakakoordinaattien saamiseksi, saadaan jakamalla kaavion kokonaisleveys (esimerkissä 100 yksikköä) esitetyllä aikavälillä (esimerkissä 20 sekuntia). Kertoimen saamiseksi skalaarilämpötila-arvoilla on muistettava, että esitetty alue siirtyy minimiarvon alapuolella olevasta marginaalista maksimin yläpuolelle, yksi aste molemmissa tapauksissa. Tällä tavalla pystyskaalauskerroin saadaan jakamalla kaavion korkeus (esimerkissä 100 yksikköä) maksimiarvolla, josta on vähennetty minimi plus ylä- ja alamarginaali. Koska nämä arvot voivat kehittyä täysin negatiivisissa lämpötiloissa, käytämme Math.abs()
käyttää erotuksen itseisarvoa.
Omaisuus d
esineen path
Se muodostetaan ketjuttamalla tekstin pisteiden koordinaatit. Jokaista koordinaattiparia edeltää koodi SVG L
, joka piirtää viivan nykyisestä sijainnista absoluuttiseen arvoon, jonka koordinaatit osoittavat. X- ja Y-arvot erotetaan pilkuilla ja kukin operaatio SVG erotetaan välilyönnillä seuraavasta.
Käytä koodia aloittaaksesi asettelun M
(siirry absoluuttiseen koordinaattiin). Suljetun ja täytetyn kaavion tapauksessa aloitat oikeasta alakulmasta, avoimen käyrän tapauksessa, joka piirtää tietoprofiilin, aloitat viimeisestä esitetystä arvosta (viimeisin). Suljetun asettelun viimeistelemiseksi käytetään koodia Z
lisäämällä viimeiseksi pisteeksi se, jolla on sama X-koordinaattiarvo kuin suoran viimeisellä pisteellä ja Y-koordinaatiksi pienin esitetty arvo.
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
|
function dibujar_grafico()
{
var tiempo_mostrado=20000; // Se representan 20 segundos (20000 milisegundos)
var valor_maximo=10; // 10 grados sobre cero
var valor_minimo=–5; // Cinco grados bajo cero
var fecha_hora=Date.now(); // Hora actual
var matriz_de_coordenadas_de_prueba=[]; // Preparar el vector de coordenadas
for(var contador=0;contador<20;contador++)
{
fecha_hora+=500+1500*Math.random(); // Añadir medio segundo a la hora anterior y entre 0 y segundo y medio aleatoriamente
matriz_de_coordenadas_de_prueba[contador]=[]; // Preparar el siguiente punto del vector de coordenadas
matriz_de_coordenadas_de_prueba[contador][0]=fecha_hora; // En la coordenada horizontal, situar la hora
matriz_de_coordenadas_de_prueba[contador][1]=Math.random()*Math.abs(valor_maximo–valor_minimo)+valor_minimo; // En la coordenada vertical situar el valor del sensor
}
actualizar_grafico
(
document.getElementById(“relleno_temperatura”), // Trazado para el relleno definido en el código HTML
matriz_de_coordenadas_de_prueba,
tiempo_mostrado,
valor_maximo, // Diez grados de valor máximo
valor_minimo, // Cinco grados bajo cero como valor mínimo
1, // Un grado por encima y por debajo de las temperatura mínimas y máximas respectivamente
true // Cerrar el trazado para representar el área rellena
);
actualizar_grafico
(
document.getElementById(“linea_temperatura”), // Trazado para el relleno definido en el código HTML
matriz_de_coordenadas_de_prueba,
tiempo_mostrado,
valor_maximo, // Diez grados de valor máximo
valor_minimo, // Cinco grados bajo cero como valor mínimo
1, // Un grado por encima y por debajo de las temperatura mínimas y máximas respectivamente
false // No cerrar el trazado para representar la linea que une los puntos que representan las temperaturas
);
}
|
Tässä esimerkissä funktio dibujar_grafico()
, joka on sivun latauksen kutsu, saa alkuarvot testattavaksi (ei viimeistä reaaliaikaista arvoa) ja valmistelee alueen, jolla tiedot renderöidään: 20 sekuntia (20000 15 ms) vaakasuunnassa ja 5 °C pystysuora -10°C - +XNUMX°C yhden asteen ylä- ja alamarginaalilla. Soita kaksi puhelua numeroon actualizar_grafico()
, ensimmäisellä kerralla true
argumenttina, joka osoittaa, että kaavio tulee sulkea edustamaan täytettyä aluetta, ja toisessa kutsussa se menee ohi false
vetää rajan. Kussakin tapauksessa kohde path
modifioitu on se, jolla on vastaava ulkonäkö, jossa ensimmäisessä tapauksessa on täyttö ja ilman reunaa ja toisessa tapauksessa tietty viivan paksuus ja ilman täyttöä.
Toiminto actualizar_grafico()
työskennellä esineen parissa SVG joka käyttää seuraavaa koodia säilönä HTML. Objekti SVG sisältää kaksi polkua, joista toinen piirtää viivan ja toinen täytetyn alueen. Ladattaessa verkkosivua elementistä <body>
edellinen toiminto kutsutaan automaattisesti, dibujar_grafico()
kiitos tapahtumasta JavaScript onload
.
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
|
<!DOCTYPE html>
<html lang=“es”>
<head>
<meta charset=“utf-8”>
<title>Temperatura</title>
<script type=“text/javascript” src=“https://polaridad.es/javascript-grafico-svg-sensor-internet-de-las-cosas-iot/grafico.js”></script>
</head>
<body onload=“dibujar_grafico();” style=“margin:0;”> <!– Cuerpo del documento HTML. Al cargar el contenido llama a la función JavaScript dibujar_grafico() –>
<div id=“temperatura”>
<div id=“bloque_temperatura” style=“width:820px;height:150px”>
<svg
id=“grafico_temperatura”
width=“100%”
height=“100%”
viewBox=“0 0 100 100”
preserveAspectRatio=“none”>
<path
id=“relleno_temperatura”
d=“”
style=“fill:#A8C3EA;stroke:none;”
vector-effect=“non-scaling-stroke”
/>
<path
id=“linea_temperatura”
d=“”
style=“fill:none;stroke:#205587;stroke-width:4;stroke-opacity:1;”
vector-effect=“non-scaling-stroke”
/>
</svg>
</div>
</div>
</body>
</html>
|
Koodin rivillä 10 HTML edellä, leveys (esimerkiksi) 820 px ja korkeus 150 px määritetään tyyliin (jota lopullisessa versiossa on suositeltavaa tehdä luokan ja asiakirjan kanssa CSS). Tuntuu oudolta, että rivit 13 ja 14 määrittelevät kohteen koon SVG kuten 100 % leveys ja korkeus (joka vastaa parhaiten ikkunan mittoja, 100 × 100). Kuten jo mainittiin, tämän tekemisen syynä on aina työskennellä tunnetuilla mitoilla ja säätää esitetyt arvot siihen. Muut vaihtoehdot olisivat laskea kaavion tila joka kerta ja säätää sitten arvot uudelleen tai pakottaa graafin kiinteät mitat, joita asiakirjan on noudatettava.
Kun olet valinnut kaavion, jonka mitat muuttuvat koodin mukaan HTML, on tarpeen sisällyttää omaisuus vector-effect
rohkeudella non-scaling-stroke
estää viivojen paksuuden vääristymisen, kun kaavio ei säilytä valittuja 1:1-suhteita verkkosivulla, jolla se näytetään, kuten edellisessä ehdotuksessa.
Käytä kaaviota "rajataksesi" ja näyttääksesi vain valitsemasi alueen viewBox
. Tässä tapauksessa olemme valinneet nähdä sen kaavion osan, joka alkaa numerosta 0,0 (vasen yläkulma) ja on kooltaan 100x100 alas ja oikealle. Piirustuksen osaa, joka sijaitsee koordinaateissa, joiden arvo on negatiivinen tai suurempi kuin 100, ei näy verkkosivulla, vaikka ne olisivatkin objektissa SVG
Lisää uusia elementtejä SVG-piirustukseen
Edellisessä esimerkissä funktio actualizar_grafico()
käytä asettelua SVG johon omistaja vaihtuu d
, joka ilmaisee koordinaattiketjun. Vaihtoehtona olisi luoda koko objekti aina, kun se piirretään uudelleen. Ensimmäisen vaihtoehdon etuna on, että graafinen ulkonäkö (kuten paksuus tai väri) määritellään koodissa HTML, rajoitus on, että objektit on luotava aiemmin.
Voit luoda SVG-objekteja käyttämällä createElementNS()
, joka mahdollistaa muun muassa nimiavaruus. Alla olevassa esimerkissä luodaan uusi tekstiobjekti (text
) ja se liittyy elementtiin SVG joka on jo koodissa HTML verkkosivustolta. Kun uusi elementti on luotu, sen ominaisuudet määritetään setAttribute()
ja lisätään SVG kanssa appendChild()
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
function
rotular
(
objeto_grafico,
texto,
inicio=[0,0],
altura=10.0,
tipo_letra=“SircuitoRegularMedium”,
color_texto=“#000000”,
color_fondo=“#FFFFFF”
)
{
nuevo_objeto_svg=document.createElementNS(“http://www.w3.org/2000/svg”,“text”);
nuevo_objeto_svg.setAttribute(“x”,inicio[0]);
nuevo_objeto_svg.setAttribute(“y”,inicio[1]);
nuevo_objeto_svg.setAttribute(“font-family”,tipo_letra);
nuevo_objeto_svg.setAttribute(“font-size”,altura);
nuevo_objeto_svg.setAttribute(“fill”,color_texto);
nuevo_objeto_svg.textContent=texto;
objeto_grafico.appendChild(nuevo_objeto_svg);
}
//rotular(document.getElementById(“cosa_svg”),”HOLA”,[10,10]);
|
Muokkaa piirustuselementtien osuutta
Jos olet yrittänyt merkitä edellisen osan esimerkin funktiolla, olet huomannut, että teksti näyttää epämuodostuneelta, kun objektin osuus web-sivulla (width
y height
Koodista HTML) ei ole sama kuin edustettu alue (viewBox
). Osuuden mukauttamiseksi on tarpeen tietää kohteen mitat SVG josta voit tarkistaa kohteen tai säiliön tyylin HTML, jos esine SVG siirtää tämä omaisuus. Omistajuuden määrittäminen transform
esineisiin SVG suhteesta riippuen muodonmuutos voidaan korjata käyttämällä skaalausoperaatiota scale()
jossa X:n kerroin on erilainen kuin Y:ssä.
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
|
function
rotular
(
objeto_grafico,
texto,
inicio=[0,0],
altura=10.0,
proporcion=1.0,
tipo_letra=“SircuitoRegularMedium”,
color_texto=“#000000”,
color_fondo=“#FFFFFF”
)
{
var escala_horizontal=parseFloat(getComputedStyle(objeto_grafico).height)/parseFloat(getComputedStyle(objeto_grafico).width);
nuevo_objeto_svg=document.createElementNS(“http://www.w3.org/2000/svg”,‘text’);
nuevo_objeto_svg.setAttribute(“transform”,“scale(“+escala_horizontal+“,1.0)”); // scale permite cambiar la escala en X e Y
//nuevo_objeto_svg.setAttribute(“transform”,”scaleX(“+escala_horizontal+”)”); // Como se sabe que sólo cambia la escala en X, se puede usar scaleX
nuevo_objeto_svg.setAttribute(“x”,inicio[0]);
nuevo_objeto_svg.setAttribute(“y”,inicio[1]);
nuevo_objeto_svg.setAttribute(“font-family”,tipo_letra);
nuevo_objeto_svg.setAttribute(“font-size”,altura);
nuevo_objeto_svg.setAttribute(“fill”,color_texto);
nuevo_objeto_svg.textContent=texto;
objeto_grafico.appendChild(nuevo_objeto_svg);
}
//rotular(document.getElementById(“cosa_svg”),”HOLA”,[10,10]);
|
SVG mahdollistaa useiden objektien ryhmittelyn muodostaen uuden komposiittielementin, joka tukee myös ominaisuuksia, kuten yksinkertaisia esineitä. Jos haluat käyttää samaa muunnosa objektisarjaan kerralla kunkin objektin sijaan, voit ryhmitellä ne tämän resurssin mukaan ja käyttää yhtä ominaisuutta transform
kaikille heille.
Kuten selitettiin puhuttaessa SVG-muoto, ryhmän elementit on suljettu tarrojen sisään <g>
y </g>
. Lisättävä kohteesta JavaScript elementtejä ryhmään SVG käytetään, kuten edellisestä esimerkistä näkyy, appendChild()
kun uusi objekti on määritetty.
Alkuperän määrittämiseksi muunnoksia käytettäessä ominaisuutta voidaan käyttää objekteissa SVG transform-origin
, jonka arvo on sen pisteen X- ja Y-koordinaatit, josta muunnos alkaa. Jos muunnoksen alkuperän arvoa ei ole nimenomaisesti ilmoitettu (verkkoselaimessa), käytetään koordinaattien keskipistettä. Valitettavasti tätä kirjoitettaessa muunnosten käyttäytymisen määrittäminen muulla kuin oletuslähteellä ei ole homogeenista eri selaimissa, ja sitä tulee käyttää varoen.
Yhdessä mittakaavamuutoksen kanssa scale
On muitakin, kuten kierto rotation
ja liikkeen kanssa translate
, jotka tarjoavat a vaihtoehto graafiselle esitykselle: sen sijaan, että hankit uusia koordinaatteja, voit esittää ne omassa avaruudessaan ja muuttaa kaavion sopivaksi muotoon, jossa haluat esittää ne.
Lisää viittauksia kaavioon
Nyt kun kaavion pääosa on ratkaistu piirtämällä arvot profiililla ja täytetyllä alueella, sitä voidaan täydentää sen lukemista helpottavien viitteiden avulla. Esimerkkinä aloitetaan piirtämällä joitain vaakasuuntaisia viitteitä (viivoja), jotka merkitsevät suurimmat ja pienimmät hyväksyttävät arvot sekä halutun arvon. Kuten selitettiin, voit lisätä objektit kohteeseen SVG suoraan JavaScript tai sisällytä ne manuaalisesti koodiin HTML ja muokkaa niitä myöhemmin -sovelluksella JavaScript.
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
|
var CONTENEDOR_SVG; // Objeto SVG que contiene el gráfico que representa los valores monitorizados por los sensores en la IoT
var NS=“http://www.w3.org/2000/svg”; // Nombre del espacio de nombres (name space NS)
var ANCHO_CAJA=100.0; // Ancho del objeto SVG (aunque al dibujarlo con el código HTML tomará otras dimensiones
var ALTO_CAJA=100.0; // Alto del objeto SVG (aunque al dibujarlo con el código HTML tomará otras dimensiones
var VALOR_MAXIMO=10.0; // Mayor valor admisible en el gráfico SVG. Los valores mayores se saldrán del gráfico salvo por un margen que permite tener una idea de la tendencia
var VALOR_MINIMO=–5.0; // Menor valor admisible en el gráfico SVG. Los valores menores se saldrán del gráfico salvo por un margen que permite tener una idea de la tendencia
var VALOR_DESEADO=5.0; // Mejor valor del parámetro medido (temperatura). Sirve para tener una idea rápida de cómo de correcto es el estado del sistema
var MARGEN_VALOR=1.0; // Zona por encima del valor mayor y por debajo del valor menor que se representa para tener una idea aproximada de la tendencia cuando los datos monitorizados rebasen los valores máximo y/o mínimo
function inicializar_grafico()
{
CONTENEDOR_SVG=document.getElementById(“contenedor_svg”);
crear_referencia_horizontal_svg(VALOR_MAXIMO,“#FF0000”);
crear_referencia_horizontal_svg(VALOR_DESEADO,“#00FF00”);
crear_referencia_horizontal_svg(VALOR_MINIMO,“#0000FF”);
}
function crear_referencia_horizontal_svg
(
altura=0.0,
color=“#000000”,
grosor=0.5,
opacidad=1.0
)
{
var altura_corregida=ALTO_CAJA–(altura+MARGEN_VALOR–VALOR_MINIMO)*ALTO_CAJA/(Math.abs(VALOR_MAXIMO–VALOR_MINIMO)+MARGEN_VALOR*2);
var referencia_horizontal=document.createElementNS(NS,‘line’);
referencia_horizontal.setAttribute(“x1”,0.0);
referencia_horizontal.setAttribute(“x2”,ANCHO_CAJA);
referencia_horizontal.setAttribute(“y1”,altura_corregida);
referencia_horizontal.setAttribute(“y2”,altura_corregida);
referencia_horizontal.style.stroke=color;
referencia_horizontal.style.strokeWidth=grosor;
referencia_horizontal.style.strokeOpacity=opacidad;
CONTENEDOR_SVG.appendChild(referencia_horizontal);
}
//inicializar_grafico();
|
Vaikuttaa loogiselta merkitä nämä vaakasuuntaiset viittaukset tekstillä, joka selventää niiden edustamaa arvoa. Voit korostaa tekstiä käyttämällä suorakulmioita, jotka erottuvat taustasta ja grafiikasta. Koska teksteihin on sovellettava mittakaavamuunnosta muodonmuutoksen kompensoimiseksi, ne kaikki voidaan ryhmitellä objektiksi, johon asteikkoa sovelletaan; Suurin etu tällä tavalla on se, että niitä voidaan muokata yhdellä toiminnolla, jos graafisäilön (selainikkunan) kokoa muutetaan ja asteikko korjaa suhdetta.
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
// Este código de ejemplo usa constantes para hacerlo más legible a desarrolladores de aplicaciones para microcontroladores de series pequeñas. La opción más recomendable, y más propia del estilo JavaScript, es crear un objeto cuyas propiedades serían las constantes y que incluiría los métodos (aquí funciones) que generan o modifican el gráfico o en este caso las referencias
var CONTENEDOR_SVG; // Objeto SVG que contiene el gráfico que representa los valores monitorizados por los sensores en la IoT
var NS=“http://www.w3.org/2000/svg”; // Nombre del espacio de nombres (name space NS)
var ANCHO_CAJA=100.0; // Ancho del objeto SVG (aunque al dibujarlo con el código HTML tomará otras dimensiones
var ALTO_CAJA=100.0; // Alto del objeto SVG (aunque al dibujarlo con el código HTML tomará otras dimensiones
var TIEMPO_REPRESENTADO=30000; // Milisegundos visibles en el gráfico empezando en el valor mayor (fecha y hora del último valor monitorizado)
var VALOR_MAXIMO=10.0; // Mayor valor admisible en el gráfico SVG. Los valores mayores se saldrán del gráfico salvo por un margen que permite tener una idea de la tendencia
var VALOR_MINIMO=–5.0; // Menor valor admisible en el gráfico SVG. Los valores menores se saldrán del gráfico salvo por un margen que permite tener una idea de la tendencia
var VALOR_OPTIMO=5.0; // Mejor valor del parámetro medido (temperatura). Sirve para tener una idea rápida de cómo de correcto es el estado del sistema
var MARGEN_VALOR=2.0; // Zona por encima del valor mayor y por debajo del valor menor que se representa para tener una idea aproximada de la tendencia cuando los datos monitorizados rebasen los valores máximo y/o mínimo
var desplazamiento_valor=desplazamiento(Date.now());
var escala_valor=escala();
var TIPOGRAFIA=“SircuitoRegularMedium”; // Tipografía con la que se rotula todo el gráfico (se usa una constante buscando la uniformidad, pero se puede rotular usando diferentes tipos de letra si es necesario)
var ALTURA_TEXTO=10.0; // Altura de los textos en valor absoluto (píxeles)
var COLOR_MINIMO=“#621D87”; // Color de la referencia que indica el valor mínimo
var COLOR_OPTIMO=“#1D8762”; // Color de la referencia que indica el valor máximo
var COLOR_MAXIMO=“#871E35”; // Color de la referencia que indica el valor óptimo
var COLOR_TIPOGRAFIA=“#A8C3EA”; // Color del tipo de letra con que se rotulan las referencias
var GROSOR_REFERENCIA=0.5; // Grosor de la línea que se dibuja como referencia en valor absoluto (píxeles)
var OPACIDAD_REFERENCIA=1.0; // Opacidad de la línea de referencia. Si se dibuja sobre el gráfico con cierta transparencia permite ver el dibujo bajo ella
var RELLENO_FONDO_REFERENCIA=4.0; // Margen entre el fondo de la referencia y el texto medido en valor absoluto (la línea empieza en el margen izquierdo y recorre todo el gráfico)
var MARGEN_FONDO_REFERENCIA=10.0; // Separación de la referencia y el borde izquierdo del gráfico medido en valor absoluto (la línea empieza en el margen izquierdo y recorre todo el gráfico)
var ANCHO_FONDO_REFERENCIA=34.0; // Medida horizontal del rectángulo que hace de fondo al texto de la referencia medido en valor absoluto
function proporcion_grafico()
{
return parseFloat(getComputedStyle(CONTENEDOR_SVG).height)/parseFloat(getComputedStyle(CONTENEDOR_SVG).width); // La escala debe calcularse cada vez ya que no se sabe si se ha redimensionado el objeto HTML que contiene al objeto SVG y que le da el tamaño
}
function medida_grafico()
{
var proporcion=[]; // Coeficiente que calcula la medida absoluta en píxeles en función del ancho/alto base del gráfico y de la representación en la página web // Coeficiente que calcula la medida absoluta en píxeles en función del ancho/alto base del gráfico y de la representación en la página web
proporcion[0]=ANCHO_CAJA/parseFloat(getComputedStyle(CONTENEDOR_SVG).width);
proporcion[1]=ALTO_CAJA/parseFloat(getComputedStyle(CONTENEDOR_SVG).height);
return proporcion;
}
function desplazamiento(valor_mayor)
{
var desplazamiento_valor=[];
desplazamiento_valor[0]=valor_mayor–TIEMPO_REPRESENTADO; // Valor desde el que se empieza a contar el tiempo: el valor mayor (último) menos el rango de tiempo representado
desplazamiento_valor[1]=MARGEN_VALOR–VALOR_MINIMO; // Valor menor mostrado (al menor se le añade un margen para visualizar el principio de los valores fuera del rango permitido)
return desplazamiento_valor;
}
function escala()
{
var escala_valor=[];
escala_valor[0]=ANCHO_CAJA/TIEMPO_REPRESENTADO; // Coeficiente que multiplica a los valores horizontales (tiempo) para calcular las coordenadas X
escala_valor[1]=ALTO_CAJA/(Math.abs(VALOR_MAXIMO–VALOR_MINIMO)+MARGEN_VALOR*2); // Coeficiente que multiplica a los valores (vertical) para calcular las coordenadas Y
return escala_valor;
}
function crear_referencia_horizontal_svg
(
posicion=0.0,
color_dibujo=“#000000”,
grosor_linea=GROSOR_REFERENCIA,
opacidad_linea=OPACIDAD_REFERENCIA,
color_texto=COLOR_TIPOGRAFIA,
altura_texto=ALTURA_TEXTO
)
{
var proporcion_horizontal=proporcion_grafico(); // La escala debe calcularse cada vez ya que no se sabe si se ha redimensionado el objeto HTML que contiene al objeto SVG y que le da el tamaño
var coeficiente_medida=medida_grafico();
var posicion_corregida=ALTO_CAJA–(posicion+desplazamiento_valor[1])*escala_valor[1];
var referencia_horizontal=document.createElementNS(NS,‘line’); // El orden en el que se crean los objetos determina qué tapa (lo último) y que es tapado (lo primero)
var fondo_referencia=document.createElementNS(NS,‘rect’); // El rectángulo (opaco) se creará después de la línea (que puede ser un poco transparente) para definir con claridad el fondo del texto
var texto_referencia=document.createElementNS(NS,‘text’); // El texto se creará en último lugar para que quede sobre los otros objetos
referencia_horizontal.setAttribute(“x1”,0.0);
referencia_horizontal.setAttribute(“x2”,ANCHO_CAJA);
referencia_horizontal.setAttribute(“y1”,posicion_corregida);
referencia_horizontal.setAttribute(“y2”,posicion_corregida);
referencia_horizontal.style.stroke=color_dibujo;
referencia_horizontal.style.strokeWidth=grosor_linea*coeficiente_medida[1];
referencia_horizontal.style.strokeOpacity=opacidad_linea;
CONTENEDOR_SVG.appendChild(referencia_horizontal); // Añadir la línea de referencia lo más abajo
fondo_referencia.setAttribute(“x”,MARGEN_FONDO_REFERENCIA*coeficiente_medida[0]);
fondo_referencia.setAttribute(“y”,posicion_corregida–(ALTURA_TEXTO+RELLENO_FONDO_REFERENCIA*2.0)*coeficiente_medida[1]/2.0);
fondo_referencia.setAttribute(“width”,ANCHO_FONDO_REFERENCIA*coeficiente_medida[0]);
fondo_referencia.setAttribute(“height”,(ALTURA_TEXTO+RELLENO_FONDO_REFERENCIA*2.0)*coeficiente_medida[1]);
fondo_referencia.style.fill=color_dibujo;
fondo_referencia.style.fillOpacity=1.0;
fondo_referencia.style.strokeWidth=0;
CONTENEDOR_SVG.appendChild(fondo_referencia);
texto_referencia.setAttribute(“x”,(MARGEN_FONDO_REFERENCIA+RELLENO_FONDO_REFERENCIA)*coeficiente_medida[0]/proporcion_horizontal);
texto_referencia.setAttribute(“y”,posicion_corregida+ALTURA_TEXTO/2.0*coeficiente_medida[1]);
texto_referencia.setAttribute(“font-family”,TIPOGRAFIA);
texto_referencia.setAttribute(“font-size”,ALTURA_TEXTO*coeficiente_medida[1]);
texto_referencia.setAttribute(“fill”,COLOR_TIPOGRAFIA);
texto_referencia.setAttribute(“transform”,“scale(“+proporcion_horizontal+“,1.0)”);
texto_referencia.textContent=(posicion>=0?“+”:“”)+posicion;
CONTENEDOR_SVG.appendChild(texto_referencia);
}
function inicializar_grafico()
{
CONTENEDOR_SVG=document.getElementById(“contenedor_svg”);
crear_referencia_horizontal_svg(VALOR_MAXIMO,COLOR_MAXIMO);
crear_referencia_horizontal_svg(VALOR_OPTIMO,COLOR_OPTIMO);
crear_referencia_horizontal_svg(VALOR_MINIMO,COLOR_MINIMO);
}
//inicializar_grafico();
|
Yllä olevassa esimerkkikoodissa on useita mielenkiintoisia näkökohtia. Ensinnäkin kommentoi, että vakioita (globaalimuuttujia) on käytetty, jotta esimerkki olisi helpompi lukea ohjelmoinnista tuleville käyttäjille. mikro-ohjaimet en C vuonna C + +. Kuten myöhemmin nähdään, paras tapa ohjelmoida se JavaScript Se käyttäisi näitä arvoja sisältäviä objekteja ja menetelmiä, jotka hallitsevat tämän esimerkin tai kaavion viittauksia yleensä tuotantojärjestelmässä.
Toisaalta geneerisemmän koodin edistämiseksi on kehitetty erillisiä toimintoja, jotka laskevat eri kertoimet, jotka korjaavat graafin osuuden tekstin säätämiseksi. proporcion_grafico()
, arvojen asteikko niiden vaihteluvälistä riippuen escala()
ja korjauskerroin mittauksille, jotka tunnetaan absoluuttisina arvoina, kuten mittauksille viitteissä medida_grafico()
.
Tämän koodin lukemisen pitäisi auttaa selventämään kontekstia, jossa tällainen sovellus toimii, joka piirtää grafiikkaa reaaliajassa ja jonka on oltava joustava esitettäväksi erilaisissa graafisissa yhteyksissä (eri kokoja ja mittasuhteita ainakin). Ensinnäkin objektit on generoitava SVG, joko "manuaalisesti" koodissa HTML, joko koodin kautta JavaScript ja joka tapauksessa viittaukset näihin objekteihin on myöhemmin hankittava niiden manipuloimiseksi JavaScript jotta voidaan piirtää uusia kaavioita ja jo piirretyn graafin esitystapaa voidaan mukauttaa sen esittämisvälineen muutokseen.
Toinen viite, joka voi auttaa helposti tulkitsemaan kuvaajaa, ovat pisteet, jotka edustavat tiettyjä arvoja (viivan solmut). Tässä esimerkissä, jossa edustamme yhtä suuruutta, symbolin valinta ei ole kriittinen, mutta jos useita eri arvoja asetetaan päällekkäin etsimään korrelaatiota, on mielenkiintoista erottaa toisistaan muiden resurssien, kuten värin, käytön lisäksi. , piirtämällä erilaisia symboleja. Viivasolmussa käytettävän grafiikan kokoa ja mittasuhteita on muutettava, kuten esimerkiksi teksteissä tapahtuu niin, että sen mitat ovat absoluuttisia ja että sen mittasuhteet säilyvät, vaikka sen sisältämän laatikon mittasuhteet muuttuisivat.
Edellisessä esimerkissä näimme jo, kuinka eri kertoimet lasketaan piirustuksen osuuden skaalaamiseksi ja korjaamiseksi; Mitä tulee graafin solmujen tai kärkien symbolien hallinnan toteuttamiseen, mahdollinen ratkaisu voi olla objektien tallentaminen SVG vektoriksi ja muokata sen sijaintia, kun kaavio päivitetään lukemalla uusi arvo tai kun se piirretään uudelleen muuttamalla säilön kokoa. Ensimmäisessä tapauksessa sen asemaa olisi muutettava ja toisessa sen suhdetta omaisuuteen transform
ja arvo scale
. Seuraava koodi on toiminnon muunnos actualizar_grafico()
sisällyttääkseen graafin kärkipisteiden symbolien uudelleensijoituksen.
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
52
53
54
55
56
57
58
59
60
61
62
|
function actualizar_grafico_puntos
(
grafico, // Objeto SVG con el que se dibuja la gráfico
coordenada, // Matriz con las coordenadas del trazado formada por pares [tiempo,valor] ordenados primero el más antiguo (tiempo menor) último el más nuevo
puntos, // Matriz con los objetos SVG que se representan en los nodos de la línea (los valores reales)
tiempo_total_representado, // Tiempo total representado por la gráfico (en milisegundos)
valor_maximo, // Valor máximo aceptable antes de emitir una alarma
valor_minimo, // Valor mínimo aceptable antes de emitir una alarma
margen_valor, // Cantidad extra que se representa sobre/bajo el valor máximo/mínimo
parametro_cerrado, // Valor booleano que indica si el trazado se cierra o no (por defecto false)
parametro_ancho_caja, // Ancho de la caja que contiene la gráfico (por defecto 100.0)
parametro_alto_caja // Alto de la caja que contiene la gráfico (por defecto 100.0)
)
{
var cerrado=parametro_cerrado||false; // Valor booleano que indica si el trazado se cierra o no (por defecto false)
var ancho_caja=parametro_ancho_caja||100.0; // Ancho de la caja que contiene la gráfico (por defecto 100.0)
var alto_caja=parametro_alto_caja||100.0; // Alto de la caja que contiene la gráfico (por defecto 100.0)
var coordenadas_trazado=“M “; // Cadena de texto que representa la propiedad “d” del trazado SVG
var desplazamiento=[]; // Desplazamientos X e Y para posicionar el tiempo y el valor representado dentro del rango del gráfico
var escala=[]; // Coeficientes X e Y para calcular el tamaño al representar el gráfico
var sin_recortar=true; // False si la gráfico se sale de la caja (si se sale, si recorta, se hace false para no seguir dibujando puntos)
var contador_valor=coordenada.length–1; // Variable para recorrer los valores (índice)
var posicion=[]; // Variable intermedia (para hacer más legible el código) con la que calcular la posición horizontal y vertical de un punto del trazado
escala[0]=ancho_caja/tiempo_total_representado; // Coeficiente que multiplica a los valores horizontales (tiempo) para calcular las coordenadas X
escala[1]=alto_caja/(Math.abs(valor_maximo–valor_minimo)+margen_valor*2); // Coeficiente que multiplica a los valores (vertical) para calcular las coordenadas Y
desplazamiento[0]=coordenada[coordenada.length–1][0]–tiempo_total_representado; // Valor desde el que se empieza a contar el tiempo: el valor mayor (último) menos el rango de tiempo representado
desplazamiento[1]=margen_valor–valor_minimo; // Valor menor mostrado (al menor se le añade un margen para visualizar el principio de los valores fuera del rango permitido)
if(cerrado) // Si se dibuja un path (trazado) cerrado…
{
coordenadas_trazado+=ancho_caja+“,”+alto_caja+” L “; // …se empieza por la parte inferior de la caja
}
while(contador_valor>=0&&sin_recortar) // Mientras queden valores por representar y no se haya llegado al borde izquierdo del gráfico…
{
posicion[0]=(coordenada[contador_valor][0]–desplazamiento[0])*escala[0]; // Calcular la X restando al tiempo el desplazamiento y convirtiéndolo a la escala del gráfico con el coeficiente horizontal
posicion[1]=alto_caja–(coordenada[contador_valor][1]+desplazamiento[1])*escala[1]; // Calcular la Y restando del alto de la caja (la Y crece hacia abajo en SVG)
punto[contador_valor].setAttribute(“cx”,posicion[0]);
punto[contador_valor].setAttribute(“cy”,posicion[1]);
coordenadas_trazado+=posicion[0]+“,”+posicion[1]; // Formar la coordenada con la X y la Y
if(posicion[0]>0) // Si no se ha rebasado el margen izquierdo…
{
coordenadas_trazado+=contador_valor>0?” L “:“”; // …y quedan valores que represntar, añadir una nueva línea (código L) para el próximo
}
else // Si se ha rebasado el margen izquierdo…
{
sin_recortar=false; // …abandonar el modo sin recorte (lo que terminará de calcular coordenadas)
}
contador_valor—; // Pasar al siguiente valor
}
if(cerrado) // Si se dibuja un trazado (path) cerrado…
{
coordenadas_trazado+=” L “+posicion[0]+“,”+alto_caja+” Z”; // …se termina por la parte inferior de la caja y se añade Z para cerrarlo en SVG
}
grafico.setAttribute(“d”,coordenadas_trazado); // Cambiar las coordenadas del trazado (propiedad “d”) por las que se han calculado
for(;contador_valor>=0;contador_valor—)
{
punto[contador_valor].setAttribute(“cx”,–10000);
punto[contador_valor].setAttribute(“cy”,0);
}
}
|
Toimintoon tehty muutoksia actualizar_grafico()
saadaksesi uuden toiminnon actualizar_grafico_puntos()
Ne on korostettu edellisen esimerkin koodissa. Ensin rivillä 5 otamme objektien vektorin SVG parametrina. Tämä vektori sisältää symbolit, jotka on sijoitettava uudelleen kaavion uusiin solmuihin.
Riveillä 39 ja 40 annetaan keskuksen uudet koordinaatit, cx
y cy
, niihin arvoihin, jotka ovat edustettuina. Jos symboli ei perustuisi keskelle, on luultavasti tarpeen lisätä offset sisään cx
puolet leveydestä ja sisään cy
puolet korkeudesta sijoittaaksesi ne uudelleen tarkalleen kuvaajan solmuun.
Riveillä 57–61 pisteet, jotka vastaavat koordinaatteja, joita ei piirretä, koska ne on leikattu pois vasemmasta reunasta, sijoitetaan uudelleen kuvaajan ulkopuolelle. Koordinaatti cy
nollaan ja siitä cx
mihin tahansa negatiiviseen numeroon (suurempi kuin itse piste), jotta se ei näy, kun se leikataan, kuten kaavion vasen osa, ikkunan SVG.
Hallitse kaaviota objektista JavaScriptin avulla
Kaikki tähän mennessä selitetyt toiminnot voidaan integroida objektiin hallitaksesi kuvaajaa tyylillä, joka on tyypillisempi uusille versioille. JavaScript. Tällä toteutusvaihtoehdolla on se lisäetu, että se yksinkertaistaa useiden eri arvoisten kaavioiden sisällyttämistä samalle verkkosivulle.
Ennen kuin keskustelemme toteutuksesta, käydään läpi yleisimmät tavat luoda objekteja JavaScript ja joitain toimintojen erityispiirteitä, jotka vaikuttavat ehdotukseen IoT-sensorigrafiikan piirtämiseksi.
On jo selitetty, että uusi tapa luoda esineitä JavaScript (saatavana versiosta 5 alkaen ECMAScript) koostuu käytöstä Object.create
, jota pitäisi tottua käyttämään "klassisen" sijaan new
, joka tietysti toimii edelleen oikein, vaikka sen tarkoitus onkin enemmän simuloida kielten tyyliä luokkapohjaisilla objekteilla (JavaScript perustaa objektien luomisen prototyyppeihin) kuin toimiva vaihtoehto.
1
2
3
4
5
6
7
8
9
10
|
<!DOCTYPE html>
<html lang=“es”>
<head>
<meta charset=“utf-8”>
<title>Crear objetos con new o con Objetct.create</title>
<script type=“text/javascript” src=“https://polaridad.es/javascript-grafico-svg-sensor-internet-de-las-cosas-iot/crear_objetos.js”></script>
</head>
<body onload=“empezar();”>
</body>
</html>
|
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
|
function Objeto_clasico(primero,segundo)
{
this.primero=primero||1;
this.segundo=segundo||2;
this.hacer_algo=function()
{
console.log(“El objeto clásico le saluda (primero=”+this.primero+” y segundo=”+this.segundo+“)”);
}
}
var Objeto_ES5=
{
primero:10,
segundo:20,
hacer_algo:
function()
{
console.log(“El objeto ES5 le saluda (primero=”+this.primero+” y segundo=”+this.segundo+“)”);
}
}
var objeto_clasico=new Objeto_clasico();
var objeto_ES5=Object.create(Objeto_ES5);
function empezar()
{
console.log(“Objeto clásico (“+objeto_clasico.primero+“,”+objeto_clasico.segundo+“)”);
console.log(“Objeto ES5 (“+objeto_ES5.primero+“,”+objeto_ES5.segundo+“)”);
objeto_clasico.hacer_algo();
objeto_ES5.hacer_algo();
}
|
Edellinen koodi antaa sinun muistaa erot objektien luomisen välillä Object.create
O con new
. Se myös korostaa sitä, että vaikka toiminto, jolla objekti on luotu new
voi olla missä tahansa koodissa, objektin on oltava jo olemassa ennen kuin se voidaan instantoida Object.create
(ES5_Object-objekti ei ole funktio).
Riveillä 3 ja 4 oletusarvon asettaminen ominaisuuksille funktiossa, jolla objekti luodaan new
, jokainen ominaisuus on määritetty vastaavan argumentin arvoon tai (||
), jos argumentteja ei ole välitetty, eli jos ne ovat määrittelemättömiä (undefined
), koska tämä seikka arvioidaan false
, oletusarvo on määritetty.
Konteksti, jossa toiminto suoritetaan JavaScript herättää kaksi asiaa, jotka on tärkeää pitää mielessä ja jotka voivat myös olla hämmentäviä käytettäessä tätä ohjelmointikieltä työskenneltyään muiden kanssa, kuten esim. C o C + +, meidän tapauksessamme. Konteksti sisältää funktion laajuudessa määritellyt muuttujat (ja globaalit), mikä muuten herättää mielenkiintoisen käsitteen, "sulkemiset", jotka muodostavat kokonaisen ohjelmointityylin JavaScript. Se sanoi, että se oli odotettavissa this
, joka viittaa objektiin, kun sitä käytetään sen määrittelevän koodin sisällä, suorituskonteksti, jossa se on määritelty, säilyy, mutta sen käyttämä konteksti on konteksti, josta funktio kutsutaan. Tämä käyttäytyminen on useimmissa tapauksissa läpinäkyvää, mutta kahdessa tilanteessa se voi olla hämmentävää: toisen funktion sisällä määritetty funktio ja objektin tapahtumasta kutsuttu menetelmä. window
.
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
|
var primero=“Primero global”;
var segundo=“Segundo global”;
var Contexto=
{
primero:“Primero en contexto”,
segundo:“Segundo en contexto”,
probar:
function()
{
console.log(“Primero en contexto: “+this.primero);
console.log(“Segundo en contexto: “+this.segundo);
function probar_dentro()
{
console.log(“Primero dentro: “+this.primero);
console.log(“Segundo dentro: “+this.segundo);
}
probar_dentro();
}
}
var probador=Object.create(Contexto);
probador.probar();
/*
Primero en contexto: Primero en contexto
Segundo en contexto: Segundo en contexto
Primero dentro: Primero global
Segundo dentro: Segundo global
*/
|
Edellistä koodia suoritettaessa lopussa oleva kommentoitu teksti näkyy konsolissa. Kaksi merkittyä riviä kuvastavat käyttäytymistä, joka voi olla hämmentävää: funktion suorituskontekstia probar_dentro()
ei probar()
, kuten saattaa odottaa, mutta window
, joka näyttää yleiset muuttujat, ei samannimisen ominaisuuksia. Jos et halua tällaista toimintaa, luo vain muuttuja korkeimman tason funktioon ja määritä se this
, kuten seuraavassa koodissa.
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
|
var primero=“Primero global”;
var segundo=“Segundo global”;
var Contexto=
{
primero:“Primero en contexto”,
segundo:“Segundo en contexto”,
probar:
function()
{
var esto=this;
console.log(“Primero en contexto: “+esto.primero);
console.log(“Segundo en contexto: “+esto.segundo);
function probar_dentro()
{
console.log(“Primero dentro: “+esto.primero);
console.log(“Segundo dentro: “+esto.segundo);
}
probar_dentro();
}
}
var probador=Object.create(Contexto);
probador.probar();
/*
Primero en contexto: Primero en contexto
Segundo en contexto: Segundo en contexto
Primero dentro: Primero en contexto
Segundo dentro: Segundo en contexto
*/
|
Ohjataksesi suorituskontekstia, kun menetelmää kutsutaan tapahtumasta window
, esimerkiksi muuttamalla selainikkunan kokoa, toinen erikoisuus JavaScript: mahdollisuus ohjelmoida "funktiotehtaita", eli toimintoja, jotka luovat muita toimintoja ja palauttavat ne return
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
var Contexto=
{
prueba:“objeto”, // La propiedad prueba es de los objetos Contexto
llamar:
function()
{
esto=this;
return function()
{
console.log(“H + “+(Date.now()–hora)+” Contexto: “+esto.prueba);
};
}
}
var prueba=“global”; // Esta variable prueba es global (window.prueba)
var hora=Date.now();
var probador=Object.create(Contexto);
var cosa=probador.llamar();
var pesadez=setInterval(cosa,3000);
setTimeout(function(){clearInterval(pesadez)},30100); // Desactivar la llamada periódica
|
Yllä olevassa esimerkkikoodissa menetelmä llamar()
kohteista Contexto
Se ei tee työtä, mutta palauttaa anonyymin toiminnon, joka huolehtii siitä. Varmistaaksesi, että kaikki toimii odotetulla tavalla, on olemassa globaali muuttuja, jolla on sama nimi kuin funktion konsolissa näyttämällä ominaisuudella. Jos konteksti on oikea, ominaisuuden arvo näytetään, ei globaalin muuttujan arvo.
JavaScript Yritä korjata puolipisteet, jotka jätetään pois lauseiden lopusta. Tämä mahdollistaa rennon kirjoitustyylin, mutta on kaksiteräinen miekka, jota on käsiteltävä huolellisesti. Useimmissa tapauksissa voit käyttää sulkeita tai edeltää tapaa, jolla tämä aiheuttaa useille riveille JavaScript tulkitsee koodin; Siksi esimerkin rivi 8 sisältää function
takana return
, jos olisin käyttänyt toista riviä, merkitys olisi hyvin erilainen. Mielestäni luettavin ratkaisu on käyttää välimuuttujaa (välttämätöntä) kuten seuraavassa versiossa; Ilmeisesti, kun käyttäytyminen on ymmärretty, päätös vastaa ohjelmoijaa.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
var Contexto=
{
prueba:“objeto”, // La propiedad prueba es de los objetos Contexto
llamar:
function()
{
esto=this;
var variable_auxiliar=
function()
{
console.log(“H + “+(Date.now()–hora)+” Contexto: “+esto.prueba);
};
return variable_auxiliar;
}
}
var prueba=“global”; // Esta variable prueba es global (window.prueba)
var hora=Date.now();
var probador=Object.create(Contexto);
var cosa=probador.llamar();
var pesadez=setInterval(cosa,3000);
setTimeout(function(){clearInterval(pesadez)},30100);
|
Samassa mielessä lausekkeen arvioiminen funktiona, eli funktion palauttaminen eikä funktion palauttaman arvon palauttaminen; viimeisen esimerkin rivillä 21 (se oli edellisen rivillä 19) se pysähtyy clearInterval
kanssa kutsuttu funktio setInterval
. Jotta se toimisi 30 sekuntia, pysäytystä lykätään setTimeout
, joka puolestaan tarvitsee funktion ensimmäisenä argumenttina; toimittamaan suorituksen parametrina clearInterval
muuttujan kanssa, joka sisältää jaksollisen kutsun (eikä funktiota clearInterval
) on se, mitä varten viimeisellä rivillä oleva anonyymi funktio luodaan.
Valinta kirjoitetaanko koodi integroimalla funktiomäärittelyn, kompaktimman (kuten rivillä 21) tai käyttämällä apumuuttujaa, mielestäni luettavampaa (kuten riveillä 19 ja 20), suorituskyky vaihtelee vähän ja riippuu enemmän tyylistä ja luettavuudesta huolto.
Testaaksesi koodia, ennen kuin sinulla on tietoja palvelimella, voit käyttää satunnaisten arvojen generaattoria halutulla alueella tai valmistaa taulukoita kontrolloiduilla arvoilla, jotka simuloivat toimintaa halutuissa olosuhteissa. Seuraava esimerkki käyttää yksinkertaista datageneraattoria koko alueella, minkä vuoksi ne näyttävät hieman liioitelluilta.
Voit testata lataa esimerkin koko koodi sisäänkirjoitetun web-sivun muodostama HTML, tyyli CSS ja koodi JavaScript. Jälkimmäinen on olennaisin, koska muut komponentit ovat vain minimaalista tukea, hyvin yksinkertaistettuja ja niitä on paljon enemmän kehitetty vastaavien osioiden artikkeleissa.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<!DOCTYPE html>
<html lang=“es”>
<head>
<meta charset=“utf-8”>
<title>Temperatura</title>
<script type=“text/javascript” src=“https://polaridad.es/javascript-grafico-svg-sensor-internet-de-las-cosas-iot/grafico.js”></script>
<link rel=“stylesheet” href=“estilo.css” type=“text/css” media=“all”>
</head>
<body onload=“iniciar_grafico(‘grafico’,’valor’,’fecha’);”>
<div id=“temperatura”>
<div id=“ultimo_valor”>
<div id=“fecha”></div>
<div id=“valor”></div>
</div>
<div id=“grafico”></div>
</div>
</body>
</html>
|
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
|
body
{
margin:0px 0px 0px 0px;
}
#ultimo_valor
{
box–sizing:border–box;
width:100%;
height:40px;
padding:8px 0px 8px 14px;
font–family:monospaced;
font–size:18px;
color:#205587;
background–color:#86A7D0;
}
#fecha
{
float:left;
margin–right:15px;
}
#valor
{
float:left;
}
#grafico
{
width:100%;
height:200px;
}
|
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
|
var Grafico=
{
contenedor_svg:void(0), // Objeto SVG con el que se dibuja el gráfico. Se inicializa con void(0) para asegurarse de que es === undefined al principio
contenedor_html:void(0), // Objeto HTML que contiene al objeto SVG con el gráfico (seguramente un div). Se inicializa con void(0) para asegurarse de que es === undefined al principio
contenedor_valor:void(0), // Objeto HTML en el que se muestra el último valor cargado del servidor
contenedor_fecha:void(0), // Objeto HTML para mostrar la fecha del último valor
pagina_servidor:“ultimo_valor_sensor.php”, // página en la que se consultan los datos
consulta:“fr1”, // Valor del parámetro con el que se consulta el servidor. La URL sería algo como http://servidoriot.com/ultimo_valor_sensor.php?zona=fr1
NS:“http://www.w3.org/2000/svg”, // Nombre del espacio de nombres (name space NS)
MINIMO:0, // Índice del menor valor admisible en el gráfico SVG. Los valores menores se saldrán del gráfico salvo por un margen que permite tener una idea de la tendencia
OPTIMO:1, // Índice del mejor valor del parámetro medido. Valor deseado para el parámetro monitorizado. Sirve para tener una idea rápida de cómo de correcto es el estado del sistema
MAXIMO:2, // Índice del mayor valor admisible en el gráfico SVG. Los valores mayores se saldrán del gráfico salvo por un margen que permite tener una idea de la tendencia
maximo_puntos:0, // Número máximo de vértices representados (pueden dibujarse menos si se recortan por la parte izquierda)
valor:[], // Últimos valores cargados del servidor
trazado:[], // Trazados representados (en principio se trata de representar uno con relleno y otro con línea)
cerrado:true, // Cuando vale true se dibuja el perfil y el área (la línea del gráfico y una zona rellena debajo). Cuando vale false solo se dibuja la línea
simbolo:[], // Objetos SVG utilizados para marcar los vértices de la línea (círculos)
linea_referencia:[], // Líneas horizontales en los valores de referencia
texto_referencia:[], // Objetos texto que rotulan los valores de referencia
fondo_referencia:[], // Rectángulos bajo los textos de los valores de referencia
medida_caja_svg:[100.0,100.0], // Ancho,Ancho del objeto SVG (aunque al dibujarlo con el código HTML tomará otras dimensiones ya que se dimensiona al 100% de su contenedor
correccion_caja_svg:[1.0,1.0], // Coeficientes para calcular la medida en el gráfico de un objeto del que se sabe el valor absoluto (Se usa el píxel como unidad)
tiempo_representado:0, // Milisegundos visibles en el gráfico empezando en el valor mayor (fecha y hora del último valor monitorizado)
valor_referencia:[0,0,0], // Valores de referencia [mínimo,óptimo,máximo]
margen_valor:0, // Zona por encima del valor mayor y por debajo del valor menor que se representa para tener una idea aproximada de la tendencia cuando los datos monitorizados rebasen los valores máximo y/o mínimo
escala_valor:[1.0,1.0], // Coeficientes que multiplican el valor monitorizado (y almacenado en el servidor) para calcular el representado según las dimensiones del gráfico
desplazamiento_valor:[0.0,0.0], // Desplazamiento que se suma al tiempo (X) y al valor (Y) para representarlo en el rango especificado para el gráfico
area_bajo_linea:true, // True para dibujar una zona rellena además del perfil (línea) del gráfico
medida_simbolo:[5,5], // Valor absoluto (en píxeles) del ancho y el alto del dibujo que se hace en los vértices de la línea del gráfico
tipografia:“sans-serif”, // Tipo de letra usado para rotular el gráfico (se usa solamente una tipografía por uniformidad)
altura_texto:10.0, // Altura de los textos en valor absoluto (píxeles). No todos los navegadores soportan todos los valores intermedios, será necesario coordinarlo con los valores que estén relacionados
escala_horizontal_texto:1, // Transformación que se aplica al texto para corregir la que implica la proporción del gráfico
color_fondo:“”, // Color de fondo del contenedor HTML del objeto SVG (Si es una cadena vacía no se cambia)
color_simbolos:“#000000”, // Color de los símbolos que se dibujan en los vértices de la línea del gráfico
color_referencia:[“#000000”,“#000000”,“#000000”], // Color de la referencia que indica el valor [mínimo,óptimo,máximo]
color_tipografia:“#FFFFFF”, // Color del tipo de letra con que se rotulan las referencias
grosor_trazado:4, // Grosor de la línea del gráfico
color_trazado:“#000000”, // Color de la línea del gráfico
color_relleno:“#000000”, // Color del relleno del gráfico
opacidad_relleno:1.0, // Opacidad del relleno del gráfico
grosor_referencia:0.5, // Grosor de la línea que se dibuja como referencia en valor absoluto (píxeles)
opacidad_referencia:1.0, // Opacidad de la línea de referencia. Si se dibuja sobre el gráfico con cierta transparencia permite ver el dibujo bajo ella
relleno_fondo_referencia:7.0, // Margen entre el fondo de la referencia y el texto medido en valor absoluto (la línea empieza en el margen izquierdo y recorre todo el gráfico)
margen_fondo_referencia:10.0, // Separación de la referencia y el borde izquierdo del gráfico medido en valor absoluto (la línea empieza en el margen izquierdo y recorre todo el gráfico)
ancho_fondo_referencia:50.0, // Medida horizontal del rectángulo que hace de fondo al texto de la referencia medido en valor absoluto
texto_valor:[“temperatura: “,” °C”], // Prefijo y sufico con los que se rotula el valor monitorizado
texto_hora:[“hora “,“”], // Prefijo y sufijo con los que se rotula la hora (cuando solamente se rotula la hora)
texto_fecha:[“”,“”], // Prefijo y sufijo con los que se rotula la fecha (cuando solamente se rotula la fecha)
texto_fecha_hora:[“el “,” a las “,” | “], // Prefijo con el que se rotula la hora, separador de fecha y hora y sufjo de la hora cuando se rotula la fecha y la hora
HORA:0, // Constante que representa la hora para el modo de la fecha/hora
FECHA:1, // Constante que representa la fehca para el modo de la fecha/hora
FECHA_Y_HORA:2, // Constante que representa rotular la fecha y la hora (para el modo de fecha/hora)
modo_fecha:2, // 0->hora, 1-> fecha 2-> fecha y hora
repetir:null, // Función llamada por setInterval
nueva_proporcion: // Calcular la nueva proporción (al iniciar y al redimensionar el contenedor del gráfico) para transformar el texto
function()
{
if(this.contenedor_svg!==undefined) // Se entiende que si no es undefined se ha asignado un objeto
{
if(this.contenedor_svg.nodeName===“svg”) // Si el objeto asignado es un SVG
{
this.escala_horizontal_texto=parseFloat(getComputedStyle(this.contenedor_svg).height)/parseFloat(getComputedStyle(this.contenedor_svg).width); // La escala debe calcularse cada vez ya que no se sabe si se ha redimensionado el objeto HTML que contiene al objeto SVG y que le da el tamaño
}
}
},
nueva_correccion_caja_svg:
function()
{
if(this.contenedor_svg!==undefined) // Se entiende que si no es undefined se ha asignado un objeto
{
if(this.contenedor_svg.nodeName.toLowerCase()===“svg”) // Si el objeto asignado es un SVG
{
this.correccion_caja_svg[0]=this.medida_caja_svg[0]/parseFloat(getComputedStyle(this.contenedor_svg).width);
this.correccion_caja_svg[1]=this.medida_caja_svg[1]/parseFloat(getComputedStyle(this.contenedor_svg).height);
}
}
},
nueva_escala:
function()
{
if(this.tiempo_representado>0) // Antes de inicializar el objeto el tiempo representado es cero
{
this.escala_valor[0]=this.medida_caja_svg[0]/this.tiempo_representado; // Coeficiente que multiplica a los valores horizontales (tiempo) para calcular las coordenadas X
this.escala_valor[1]=this.medida_caja_svg[1]/(Math.abs(this.valor_referencia[this.MAXIMO]–this.valor_referencia[this.MINIMO])+this.margen_valor*2); // Coeficiente que multiplica a los valores (vertical) para calcular las coordenadas Y
}
},
nuevo_desplazamiento:
function()
{
if(this.tiempo_representado>0) // Antes de inicializar el objeto el tiempo representado es cero
{
this.desplazamiento_valor[0]=this.valor[this.valor.length–1][0]–this.tiempo_representado; // Valor desde el que se empieza a contar el tiempo: el valor mayor (último) menos el rango de tiempo representado
this.desplazamiento_valor[1]=this.margen_valor–this.valor_referencia[this.MINIMO]; // Valor menor mostrado (al menor se le añade un margen para visualizar el principio de los valores fuera del rango permitido)
}
},
crear_svg: // Crear el objeto SVG dentro del objeto HTML
function()
{
if(this.contenedor_html!==null&&this.contenedor_html!==undefined) // Ya se ha asignado el objeto HTML
{
if(this.contenedor_html.nodeType===1) // Es un objeto HTML válido
{
// Color de fondo del objeto HTML
if(this.color_fondo!==“”)
{
this.contenedor_html.style.backgroundColor=this.color_fondo;
}
// Contenedor SVG
this.contenedor_svg=document.createElementNS(this.NS,“svg”); // Crear un objeto SVG
this.contenedor_svg.setAttribute(“width”,“100%”); // Ancho del objeto SVG
this.contenedor_svg.setAttribute(“height”,“100%”); // Alto del objeto SVG
this.contenedor_svg.setAttribute(“viewBox”,“0 0 “+this.medida_caja_svg[0]+” “+this.medida_caja_svg[1]); // Zona del SVG que se muestra
this.contenedor_svg.setAttribute(“preserveAspectRatio”,“none”); // No preservar la proporción para ocupar todo el objeto HTML que hace de contenedor
this.contenedor_html.appendChild(this.contenedor_svg); // Añadir al contenedor HTML el objeto SVG (que será el contenedor del gráfico)
// Trazado
this.trazado[0]=document.createElementNS(this.NS,“path”); // Crear el trazado que soporta el relleno
this.trazado[0].style.fill=this.color_relleno;
this.trazado[0].style.fillOpacity=this.opacidad_relleno;
this.trazado[0].style.stroke=“none”;
this.contenedor_svg.appendChild(this.trazado[0]); // Añadir el relleno al SVG
this.trazado[1]=document.createElementNS(this.NS,“path”); // Crear el trazado que soporta el perfil
this.trazado[1].setAttribute(“vector-effect”,“non-scaling-stroke”); // No mantener la proporción en el trazado (no deformarlo)
this.trazado[1].style.fill=“none”;
this.trazado[1].style.stroke=this.color_trazado;
this.trazado[1].style.strokeWidth=this.grosor_trazado;
//this.trazado[1].style.strokeOpacity=1.0; // La opacidad por defecto es 1.0
this.contenedor_svg.appendChild(this.trazado[1]); // Añadir el perfil al SVG
// Símbolos para los vértices
var ahora=Date.now()–30000; // Fecha y hora actual menos 30 segundos
for(var contador_vertices=0;contador_vertices<this.maximo_puntos;contador_vertices++)
{
this.valor[contador_vertices]=[];
this.valor[contador_vertices][0]=ahora; // Inicializar los valores a la fecha y hora actual menos 30 segundos
this.valor[contador_vertices][1]=this.valor_referencia[this.OPTIMO]; // Inicializar los valores al óptimo
this.simbolo[contador_vertices]=document.createElementNS(this.NS,“ellipse”); // Crear una elipse (círculo) para cada vértice
this.simbolo[contador_vertices].style.fill=this.color_simbolos;
this.simbolo[contador_vertices].style.fillOpacity=1.0;
this.simbolo[contador_vertices].style.stroke=“none”;
this.contenedor_svg.appendChild(this.simbolo[contador_vertices]); // Añadir el símbolo al SVG
}
//this.nuevo_desplazamiento(); // Necesario si se asignaran las alturas de las referencias
for(var contador_referencia=0;contador_referencia<this.valor_referencia.length;contador_referencia++)
{
// Línea de referencia
//var posicion_corregida=this.medida_caja_svg[1]-(this.valor_referencia[contador_referencia]+this.desplazamiento_valor[1])*this.escala_valor[1]; // Necesario si se asignaran las alturas de las referencias
this.linea_referencia[contador_referencia]=document.createElementNS(this.NS,“line”); // Crear la línea que representa el valor mínimo
this.linea_referencia[contador_referencia].style.stroke=this.color_referencia[contador_referencia];
this.linea_referencia[contador_referencia].style.strokeWidth=this.grosor_referencia;
this.linea_referencia[contador_referencia].style.strokeOpacity=this.opacidad_referencia;
this.linea_referencia[contador_referencia].setAttribute(“x1”,0.0); // Las líneas de referencia empiezan en el borde izquierdo…
this.linea_referencia[contador_referencia].setAttribute(“x2”,this.medida_caja_svg[0]); // …y terminan en el derecho
//this.linea_referencia[contador_referencia].setAttribute(“y1”,posicion_corregida); // Ambos extremos a la altura correspondiente a la referencia [mínimo,óptimo,máximo]
//this.linea_referencia[contador_referencia].setAttribute(“y2”,posicion_corregida); // Ambos extremos a la altura correspondiente a la referencia [mínimo,óptimo,máximo]
this.contenedor_svg.appendChild(this.linea_referencia[contador_referencia]);
// Rectángulo de fondo del texto que indica el valor de referencia
this.fondo_referencia[contador_referencia]=document.createElementNS(this.NS,‘rect’);
this.fondo_referencia[contador_referencia].style.fill=this.color_referencia[contador_referencia];
this.fondo_referencia[contador_referencia].style.fillOpacity=1.0;
this.fondo_referencia[contador_referencia].style.stroke=“none”;
this.contenedor_svg.appendChild(this.fondo_referencia[contador_referencia]);
// Texto de referencia
this.texto_referencia[contador_referencia]=document.createElementNS(this.NS,“text”); // Crear el texto para rotular la referencia
this.texto_referencia[contador_referencia].setAttribute(“font-family”,this.tipografia); // Asignar el tipo de letra
this.texto_referencia[contador_referencia].setAttribute(“fill”,this.color_tipografia); // Asignar el color
//this.texto_referencia[contador_referencia].textContent=””+(this.valor_referencia[contador_referencia]>=0?”+”:””)+this.valor_referencia[contador_referencia]; // Texto que se rotula (los valores máximo, óptimo y mínimo ya deben estar asignados)
this.contenedor_svg.appendChild(this.texto_referencia[contador_referencia]);
}
}
}
},
ajustar_prporcion:
function()
{
this.nueva_proporcion();
this.nueva_correccion_caja_svg();
var posicion_corregida;
for(var contador_vertices=0;contador_vertices<this.simbolo.length;contador_vertices++)
{
this.simbolo[contador_vertices].setAttribute(“rx”,this.medida_simbolo[0]*this.correccion_caja_svg[0]);
this.simbolo[contador_vertices].setAttribute(“ry”,this.medida_simbolo[1]*this.correccion_caja_svg[1]);
}
for(var contador_referencia=0;contador_referencia<this.valor_referencia.length;contador_referencia++)
{
posicion_corregida=this.medida_caja_svg[1]–(this.valor_referencia[contador_referencia]+this.desplazamiento_valor[1])*this.escala_valor[1];
this.fondo_referencia[contador_referencia].setAttribute(“x”,this.margen_fondo_referencia*this.correccion_caja_svg[0]);
this.fondo_referencia[contador_referencia].setAttribute(“y”,posicion_corregida–(this.altura_texto+this.relleno_fondo_referencia*2.0)*this.correccion_caja_svg[1]/2.0);
this.fondo_referencia[contador_referencia].setAttribute(“width”,this.ancho_fondo_referencia*this.correccion_caja_svg[0]);
this.fondo_referencia[contador_referencia].setAttribute(“height”,(this.altura_texto+this.relleno_fondo_referencia*2.0)*this.correccion_caja_svg[1]);
this.linea_referencia[contador_referencia].setAttribute(“y1”,posicion_corregida);
this.linea_referencia[contador_referencia].setAttribute(“y2”,posicion_corregida);
this.texto_referencia[contador_referencia].setAttribute(“transform”,“scale(“+this.escala_horizontal_texto+“,1.0)”);
this.texto_referencia[contador_referencia].setAttribute(“font-size”,this.altura_texto*this.correccion_caja_svg[1]);
this.texto_referencia[contador_referencia].setAttribute(“x”,(this.margen_fondo_referencia+this.relleno_fondo_referencia)*this.correccion_caja_svg[0]/this.escala_horizontal_texto);
this.texto_referencia[contador_referencia].setAttribute(“y”,posicion_corregida+this.altura_texto/2.0*this.correccion_caja_svg[1]);
this.texto_referencia[contador_referencia].textContent=(this.valor_referencia[contador_referencia]>=0?“+”:“”)+this.valor_referencia[contador_referencia]; // Texto que se rotula
}
},
rotar_valores:
function()
{
for(var contador_valor=0;contador_valor<this.valor.length–1;contador_valor++)
{
this.valor[contador_valor][0]=this.valor[contador_valor+1][0];
this.valor[contador_valor][1]=this.valor[contador_valor+1][1];
}
},
nuevo_valor_aleatorio:
function()
{
this.rotar_valores();
this.valor[this.valor.length–1][0]=this.valor[this.valor.length–2][0]+1000+Math.random()*1000; // El nuevo tiempo es el anterior más un segundo más un valor entre 0 y un segundo
this.valor[this.valor.length–1][1]=Math.random()*Math.abs(this.valor_referencia[this.MAXIMO]–this.valor_referencia[this.MINIMO])+this.valor_referencia[this.MINIMO]; // Un valor aleatorio entre el máximo y el mínimo
this.nuevo_desplazamiento(); // Cada nuevo valor cambia el desplazamiento en horizontal
this.dibujar_nuevo_valor(true);
this.dibujar_nuevo_valor(false);
this.rotular_nuevo_valor();
this.ritular_nueva_fecha();
},
cargar_nuevo_valor:
function()
{
var consulta=‘zona=”+this.consulta;
var resultado;
var ajax;
if(window.XMLHttpRequest)
{
ajax=new XMLHttpRequest(); // ajax=Object.create(XMLHttpRequest);
}
else // Versiones antiguas de MS Internet Explorer
{
ajax=new ActiveXObject(“Microsoft.XMLHTTP”);
}
ajax.onreadystatechange=
function()
{
if(ajax.readyState==4&&ajax.status==200&&ajax.responseType==“json”)
{
resultado=JSON.parse(ajax.responseText);
if(resultado.fecha>objeto_grafico.fecha[objeto_grafico.fecha.length–1])
{
this.rotar_valores();
this.valor[this.valor.length–1][0]=resultado.fecha;
this.valor[this.valor.length–1][1]=resultado.temperatura;
this.nuevo_desplazamiento(); // Cada nuevo valor cambia el desplazamiento en horizontal
this.dibujar_nuevo_valor(true);
this.dibujar_nuevo_valor(false);
this.rotular_nuevo_valor();
this.ritular_nueva_fecha();
}
}
}
ajax.open(“POST”,this.pagina_servidor);
ajax.setRequestHeader(“Method”,“POST “+this.pagina_servidor+” HTTP/1.1″);
ajax.setRequestHeader(“Content-type”,“application/x-www-form-urlencoded”);
ajax.setRequestHeader(“Content-length”,consulta.length);
ajax.setRequestHeader(“Connection”,“close”);
ajax.send(consulta);
},
rotular_nuevo_valor:
function()
{
var valor_redondeado=Math.round(this.valor[this.valor.length–1][1]*100.0)/100.0;
this.contenedor_valor.innerHTML=this.texto_valor[0]+valor_redondeado+this.texto_valor[1];
},
ritular_nueva_fecha:
function()
{
var fecha_lectura=new Date(this.valor[this.valor.length–1][0]);
var texto_fecha=this.texto_hora[0];
texto_fecha+=(fecha_lectura.getHours()<10?“0”:“”)+fecha_lectura.getHours();
texto_fecha+=“:”;
texto_fecha+=(fecha_lectura.getMinutes()<10?“0”:“”)+fecha_lectura.getMinutes();
texto_fecha+=“:”;
texto_fecha+=(fecha_lectura.getSeconds()<10?“0”:“”)+fecha_lectura.getSeconds();
texto_fecha+=this.texto_hora[1];
this.contenedor_fecha.innerHTML=texto_fecha;
},
dibujar_nuevo_valor: // Dibujar el gráfico cuando llega un nuevo valor (que estará almacenado en el vector valor
function(cerrado)
{
// Si cerrado es undefined se evalúa a false, que se toma como valor por defecto
var contador_valor=this.valor.length–1; // Variable para recorrer los valores (índice)
var sin_recortar=true; // False si la gráfico se sale de la caja (si se sale, si recorta, se hace false para no seguir dibujando puntos)
var posicion=[]; // Variable intermedia (para hacer más legible el código) con la que calcular la posición horizontal y vertical de un punto del trazado
var coordenadas_trazado=“M “; // Cadena de texto que representa la propiedad “d” del trazado SVG
if(cerrado) // Si el trazado que se está dibujando está cerrado (no confundir con this.cerrado que determina si se dibujan los dos trazados, la línea y el relleno)
{
coordenadas_trazado+=this.medida_caja_svg[0]+“,”+this.medida_caja_svg[1]+” L “; // …se empieza por la parte inferior de la caja
}
while(contador_valor>=0&&sin_recortar) // Mientras queden valores por representar y no se haya llegado al borde izquierdo del gráfico…
{
posicion[0]=(this.valor[contador_valor][0]–this.desplazamiento_valor[0])*this.escala_valor[0]; // Calcular la X restando al tiempo el desplazamiento y convirtiéndolo a la escala del gráfico con el coeficiente horizontal
posicion[1]=this.medida_caja_svg[1]–(this.valor[contador_valor][1]+this.desplazamiento_valor[1])*this.escala_valor[1]; // Calcular la Y restando del alto de la caja (la Y crece hacia abajo en SVG)
this.simbolo[contador_valor].setAttribute(“cx”,posicion[0]);
this.simbolo[contador_valor].setAttribute(“cy”,posicion[1]);
coordenadas_trazado+=posicion[0]+“,”+posicion[1]; // Formar la coordenada con la X y la Y
if(posicion[0]>0) // Si no se ha rebasado el margen izquierdo…
{
coordenadas_trazado+=contador_valor>0?” L “:“”; // …y quedan valores que representar, añadir una nueva línea (código L) para el próximo
contador_valor—; // Pasar al siguiente valor
}
else // Si se ha rebasado el margen izquierdo…
{
sin_recortar=false; // …abandonar el modo sin recorte (lo que terminará de calcular coordenadas)
}
}
if(cerrado) // Si se dibuja un trazado (path) cerrado…
{
coordenadas_trazado+=” L “+posicion[0]+“,”+this.medida_caja_svg[1]+” Z”; // …se termina por la parte inferior de la caja y se añade Z para cerrarlo en SVG
}
this.trazado[cerrado?0:1].setAttribute(“d”,coordenadas_trazado); // Cambiar las coordenadas del trazado (propiedad “d”) por las que se han calculado
for(;contador_valor>=0;contador_valor—)
{
this.simbolo[contador_valor].setAttribute(“cx”,–10000);
this.simbolo[contador_valor].setAttribute(“cy”,0);
}
}
}
var temperatura_frigorifico;
function iniciar_grafico(nombre_objeto_grafico,nombre_objeto_valor,nombre_objeto_fecha)
{
temperatura_frigorifico=Object.create(Grafico);
temperatura_frigorifico.contenedor_html=document.getElementById(nombre_objeto_grafico);
temperatura_frigorifico.contenedor_valor=document.getElementById(nombre_objeto_valor);
temperatura_frigorifico.contenedor_fecha=document.getElementById(nombre_objeto_fecha);
temperatura_frigorifico.color_fondo=“#A8C3EA”;
temperatura_frigorifico.color_trazado=“#205587”;
temperatura_frigorifico.grosor_trazado=3;
temperatura_frigorifico.color_relleno=“#205587”;
temperatura_frigorifico.opacidad_relleno=0.5;
temperatura_frigorifico.color_simbolos=“#205587”;
temperatura_frigorifico.color_referencia[Grafico.MINIMO]=“#621D87”;
temperatura_frigorifico.color_referencia[Grafico.OPTIMO]=“#1D8762”;
temperatura_frigorifico.color_referencia[Grafico.MAXIMO]=“#871E35”;
temperatura_frigorifico.grosor_referencia=1.5;
temperatura_frigorifico.opacidad_referencia=0.5;
temperatura_frigorifico.tipografia=“monospaced”;
temperatura_frigorifico.color_tipografia=“#A8C3EA”;
temperatura_frigorifico.cerrado=true; // Dibujar una línea y una zona rellena debajo (true por defecto)
temperatura_frigorifico.maximo_puntos=32; // Un espacio de 30 segundos representados con un intervalo mínimo de 1 segundo necesitan como máximo 31 puntos, se añade uno por seguridad (por si algún valor monitorizado estuviera por debajo del segundo)
temperatura_frigorifico.crear_svg();
temperatura_frigorifico.nueva_correccion_caja_svg();
temperatura_frigorifico.tiempo_representado=30000;
temperatura_frigorifico.valor_referencia[Grafico.MINIMO]=–5;
temperatura_frigorifico.valor_referencia[Grafico.OPTIMO]=5;
temperatura_frigorifico.valor_referencia[Grafico.MAXIMO]=10;
temperatura_frigorifico.margen_valor=3;
temperatura_frigorifico.nueva_escala();
temperatura_frigorifico.nuevo_desplazamiento(); // El desplazamiento se (re)calcula cada vez que se añade un valor
temperatura_frigorifico.ajustar_prporcion();
window.addEventListener(“resize”,function(){temperatura_frigorifico.ajustar_prporcion()}); // Versión moderna
temperatura_frigorifico.repetir=setInterval(function(){temperatura_frigorifico.nuevo_valor_aleatorio()},1000);
}
|
Post Comment