Generuokite ir keiskite SVG duomenų grafiką iš jutiklių, prijungtų prie daiktų interneto naudojant „JavaScript“.
Šioje paskutinėje straipsnių ciklo dalyje apie piešimą grafika su duomenimis iš jutiklių, prijungtų prie daiktų interneto, laikas pakalbėti apie tai, kaip sukurti ar modifikuoti naudojant JavaScript brėžiniai formatu SVG ir kai kurie elementai HTML kurie tarnauja kaip konteineris arba pateikia grafikos papildomos informacijos.
Šios pamokos tiksliniai vartotojai turi suformuoti elektronikos ir kompiuterių programavimo profilį. mikrovaldikliai, jie gali būti nepažįstami HTML, CSS o SVG; Dėl šios priežasties ankstesnėse dalyse buvo trumpai supažindinama su kalba ar atitinkama technologija. Šioje paskutinėje dalyje požiūris yra šiek tiek kitoks, nes skaitytojai tikrai žino, kaip programuoti, gali būti, kad naudojant kalbą C + + kad, kaip JavaScript, bendrina pagrindinę sintaksę su C ir tai gali būti laikoma nuoroda praleisti daugumą pagrindinių programavimo sąvokų ir taip sutelkti dėmesį į skirtumus ir konkretų naudojimą, kuris mus domina kuriant jutiklių grafiką daiktų internete.
Pavadinimas rodo pirmąjį skirtumą: JavaScript Tai programavimo kalba scenarijus (brūkšnelis) ir taip yra interpretuojama, jo kompiliuoti nereikia; kontekstas, kuriame scenarijus (pvz., interneto naršyklė) skaitys, išvers ir vykdys užsakymus. Tiksliau sakant, daugeliu atvejų yra a vykdymo laiko kompiliavimas (JIT), bet kodo rašymo procesui JavaScript Mums tai neturi įtakos, tiesiog parašome kodą ir jis gali veikti.
Pavadinime taip pat yra pirmoji painiava: JavaScript neturi nė menkiausio ryšio su Java. Iš pradžių, kai jis buvo sukurtas "Netscape" savo naršyklei ji pirmiausia buvo vadinama „Mocha“, o vėliau – mažiau klaidinančia „LiveScript“. Sėkmingai įdiegus naršyklėse ir jas peržengus, jis buvo standartizuotas kaip ECMASCRIPT (Jei norite ECMA-262, 6 versija rašymo metu) tapti neutraliu jį įgyvendinančių naršyklių atžvilgiu. Šiuo metu taip pat yra standartas ISO nuo 5 versijos, 2011 (ISO / IEC 16262: 2011 rašant straipsnį)
Kintamieji, pagrindiniai duomenų tipai ir objektai „JavaScript“.
Skirtingai nuo to, kas atsitinka, pavyzdžiui, C + +, en JavaScript duomenų tipas neįtraukiamas deklaruojant kintamąjį o taip pat su kintamuoju susijęs tipas nėra fiksuotas, viso programos vykdymo metu galima priskirti kitokio tipo reikšmę.
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
|
Ankstesniame pavyzdyje kintamasis "daiktas" buvo deklaruotas (nenurodant duomenų tipo), tada priskiriami kitokio tipo duomenys ir jie yra peržiūrimi typeof
tokio tipo JavaScript kad jis interpretavo. Norėdami derinti kodą, galite įrašyti jį į žiniatinklio naršyklės inspektoriaus pultą (tai neturės įtakos žiniatinklio pateikimui) console.log()
.
Norėdami priversti duomenis konvertuoti į konkretų tipą, ypač tekstą į skaitinius, galite naudoti tokias funkcijas kaip parseInt()
o parseFloat()
kurie atitinkamai konvertuojami į sveikuosius arba slankiojo kablelio skaičius. Galima atlikti priešingą konversiją String()
, nors vargu ar to prireiks, nes paprastai pakanka automatinio konvertavimo. Su parseFloat()
Pavyzdžiui, galite gauti tinklalapio ypatybės reikšmę, pvz., objekto plotį arba aukštį, apimantį vienetus; Tokiu būdu išraiška parseFloat("50px");
grąžins 50, skaitinę reikšmę.
En JavaScript nėra skirtumo tarp dvigubų ir viengubų kabučių; Duomenų tipas abiem atvejais yra string
, ir kiekvienas iš jų gali įtraukti kitą, nereikalaujant pabėgimo kodų.
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
|
Ankstesniame pavyzdyje matyti, kad kintamasis, kai jis buvo deklaruotas (egzistuoja), bet jam nebuvo priskirta jokia reikšmė, turi neapibrėžtą duomenų tipą (undefined
). Nepriskirtas objektas turi vertę null
; Tai yra, objektas egzistuoja, bet be vertės; kintamasis, nurodantis jį, neturėtų a typeof
undefined
bet object
. Objektas taip pat gali būti tuščias, ty ne nulinis, bet neturėti jokių savybių.
į apibrėžti objektą JavaScript yra uždėti petnešomis ({
y }
) savybės arba metodai, atskirti dvitaškiu (:
) nuosavybės pavadinimas nuosavybės vertė ir kableliu (,
) skirtingos savybės. Daugiau informacijos apie šį objekto išraiškos būdą rasite straipsnyje apie JSON formatas.
Nors galite naudoti sintaksę, kuri gali paskatinti galvoti kitaip, en JavaScript Nėra klasių, o prototipaiTai yra, kad objektas paveldėtų savybes ir metodus, sukuriamas kitas objektas (prototipas), kurį kiti (vaikai) naudoja kaip nuorodą. Sintaksė, artimiausia stiliui JavaScript naudoti prototipą yra Object.create
nors taip pat galima (o kartais ir naudinga) naudoti new
kaip ir kitose objektiškai orientuotose kalbose.
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));
|
į užklausa, ar vienas objektas yra kito egzempliorius, jei naudojate jį kaip prototipą, jei paveldėsite jo savybes, trumpai tariant, galite naudoti instanceof
(sukurta su new
) o isPrototypeOf
(sukurta su Object.create
), kuris įvertins teisingą, kai objektas naudoja prototipą, ir klaidingą, kai ne.
Kai objektas buvo sukurtas naudojant kitą kaip prototipą, ty kai objektas buvo sukurtas, jis gali būti pridėti naujų savybių arba nepaisyti prototipo ypatybių naudojant taškų sintaksę, kaip nurodyta gato.peso=2.5
.
La masyvai JavaScript Jie skiriasi nuo tų, kuriuos tikriausiai žinote C. Pirmiausia jie deklaruojami nenurodant jų ilgio, tik su atidarymo ir uždarymo laužtiniais skliaustais ([
y ]
), komponentai gali būti nevienalyčiai (skirtingi duomenų tipai tame pačiame masyve) ir naujų elementų galima pridėti neapsiribojant. Matricos iš JavaScript iš tikrųjų yra elementų sąrašai (rinkiniai), į kuriuos nurodomas skaitine rodykle arba pavadinimu. Masyve vienu metu gali būti skaitinių indeksų ir elementų pavadinimų, tačiau įprasta naudoti objektus (ypatybes), kad būtų galima išnaudoti antrąjį tipą.
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
|
Kaip matyti ankstesniame pavyzdyje, norėdami sužinoti, ar kintamasis atitinka masyvo egzempliorių (tai yra masyvo objektas), galite naudoti instanceof
, kaip jau buvo naudojama su bendraisiais objektais arba naujesnėse versijose JavaScript galite kreiptis Array.isArray()
Norėdami pasiekti masyvo elementus, galite naudoti jo indeksą (matriz[7]
) arba pagal nuosavybės pavadinimą su pavadinimu laužtiniuose skliaustuose (matriz["nombre"]
) arba naudojant įprastą taškų sintaksę objektams (matriz.nombre
). Kadangi pavadinimas yra teksto eilutė, jį sudaryti galima naudoti išraišką, įskaitant kintamuosius. Norėdami pereiti per masyvą su savybėmis, galima naudoti kilpą su formatu 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
*/
|
Tai įdomu mūsų tikslui gydyti objektas Date
, su kuriuo galite nurodyti ir valdyti datą ir laiką JavaScript. Objektas gali būti sukurtas be duomenų, todėl jam reikės dabartinės datos ir laiko, arba jis gali būti sukurtas nurodant datą kaip reikšmę, arba milisekundėmis nuo 1 m. sausio 1970 d. (pvz., Unix laikas arba POSIX laikas bet išreiškiama milisekundėmis, o ne sekundėmis) arba nurodant atskiras metų, mėnesio, dienos, valandos vertes...
Objektas apima visą seriją užklausos arba datos ir laiko nustatymo metodai:
-
now()
Grąžina dabartinę datą ir laiką, išreikštą milisekundėmis nuo 1 m. sausio 1970 d -
getTime()
|setTime()
Atitinkamai gauna arba keičia laiko reikšmę milisekundėmis nuo 1 m. sausio 1970 d.valueOf()
, kuris yra daugumoje objektų esantis metodas, taip pat gaunama atitinkamo Datos objekto reikšmė, pvzgetTime()
su Unix laikas arba POSIX laikas išreikštas ms. -
getMilliseconds()
|setMilliseconds()
Naudojamas užklausai arba trupmeninei milisekundžių objekto daliai nustatytiDate
ant kurio jis vykdomas. Jei konsultuojamasi, gauta reikšmė yra nuo 0 iki 999, tačiau galima priskirti didesnes reikšmes, kurios kaupsis bendroje datoje ir laiku, todėl, kaip ir kiti gavimo metodai, ji padeda padidinti objekto vertę.Date
(arba sumažinkite, jei naudojamos neigiamos reikšmės). -
getSeconds()
|setSeconds()
Atitinkamai grąžina arba pakeičia objekto sekundžių reikšmęDate
. -
getMinutes()
|setMinutes()
Naudojamas pasikonsultuoti arba nustatyti objekto minutesDate
. -
getHours()
|setHours()
Leidžia konsultuotis arba keisti objekto valandas (nuo 0 iki 23).Date
. -
getDay()
Grąžina datos savaitės dieną, išreikštą reikšme nuo 0 iki 6 (nuo sekmadienio iki šeštadienio). -
getDate()
|setDate()
Grąžina arba pakeičia objekto mėnesio dienąDate
ant kurių jis taikomas. -
getMonth()
|setMonth()
Naudojamas norint pasikonsultuoti ar keisti objekto mėnesio numerįDate
. -
getFullYear()
|setFullYear()
Užklausa arba nustatoma metų reikšmė objekte, kuriame yra data ir laikas.
Ankstesni metodai Date
įtraukti versiją UTC kad būtų galima tiesiogiai dirbti su visuotiniu laiku, neatliekant tarpinių skaičiavimų. Ta prasme, pvz. getHours()
turi versiją getUTCHours()
o getMilliseconds()
alternatyva getUTCMilliseconds()
dirbti alternatyviai oficialiu (teisiniu) arba visuotiniu laiku. Su getTimezoneOffset()
Galite žinoti skirtumą tarp visuotinio laiko ir vietinio oficialaus laiko.
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 funkcijos
Jei skaitote tai, tikrai žinote, kaip programuoti. mikrovaldikliai en C , C + + ir žinoti funkcijos sąvoką. Nors pagrindinė idėja ta pati, in JavaScript Jų apibrėžimo ir naudojimo būdas šiek tiek skiriasi. Pirmiausia jau buvo pasakyta, JavaScript Jame nėra aiškiai naudojami duomenų tipai, todėl jums nereikia jų nurodyti apibrėžiant funkciją. Sekti, Funkcijos pavadinimas nėra privalomas, jos gali būti anoniminės. Jie gali būti susieti su kintamuoju, kad juos būtų galima iškviesti, bet tai gali būti ir nebūtina, nes kartais naudinga juos iškviesti iš karto, o skliaustai ir parametrai pridedami po funkcijos apibrėžimo.
Norėdami apibrėžti funkciją, priešdėlis function
, jei taikoma, skliausteliuose parašykite pavadinimą, argumentus (parametrai, perduodami funkcijai) ir kodą, kuris bus vykdomas, kai funkcija bus iškviesta skliaustuose.
1
2
3
4
5
|
function doble(numero)
{
var resultado=numero*2;
return resultado;
}
|
Žinoma, ankstesniame pavyzdyje kintamojo „rezultatas“ visai nereikėjo, tačiau tai yra geras pasiteisinimas prisiminti kintama apimtis, kuris veikia taip, kaip tikitės: kintamasis „rezultatas“ egzistuoja tik funkcijoje „double“. Į JavaScript taip pat galima naudoti let
, vietoj var
, kad kintamasis būtų įtrauktas į kodo bloko kontekstą (uždengtas riestiniais skliaustais, {
y }
)
Kalbant apie objektus ankstesniame skyriuje, trūko kažko esminio: savybės buvo apibrėžtos, bet metodai neapibrėžti. Kaip tikėtasi, objekto metodai yra funkcijos, jie neturi pavadinimo ir yra naudojami (iššaukiami) iš (nuosavybės) pavadinimo, priskirto objekto apibrėžime.
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”);
}
}
|
Ankstesniame pavyzdyje jau yra metodas „view_temperature“, kuris konsolėje rodo „current_temperature“ ypatybės reikšmę. Tai nėra labai naudinga, bet suteikia išsamesnį supratimą apie tai, koks yra objekto apibrėžimas JavaScript.
Norėdami pasiekti objekto (funkcijų) metodus prie jo savybių, naudokite this
, kaip ir ankstesniame pavyzdyje 11 eilutėje, kai naudojama ypatybė „current_temperature“.
Pasiekite dokumento objekto modelį (DOM) naudodami „JavaScript“.
nuo JavaScript Turite prieigą prie tinklalapio, kuriame jis veikia, turinio, taip pat kai kurių naršyklės, kuri rodo tą puslapį, aspektų, nors ir ne prie sistemos išteklių. Duomenų struktūra, palaikanti ypatybes ir metodus, iš kurių pasiekiama JavaScript lango objekto dalis, konkrečiai, objekto (dokumento) turinys HTML) atitinka objektą document
. Nors kartais jis naudojamas aiškumo dėlei, nebūtina prieš metodus ar ypatybes nurodyti langą, pakanka, pavyzdžiui, naudoti document
, nereikia rašyti šakninio objekto pavadinimo, kaip nurodyta window.document
, kol yra nuoroda į dabartinį langą.
Dažniausiai naudojama forma rasti objektą dokumente HTML Tai yra per metodą getElementById()
, kuriam kaip argumentas perduodamas ID, kuris buvo nurodytas kuriant kodą HTML. Iš to, kas buvo paaiškinta ankstesniuose skyriuose, nesunku manyti, kad taip pat galite pasiekti objekto viduje esančius komponentus document
naudojant taškų sintaksę (document.componente
) arba skliausteliuose naudojant abu pavadinimus (document["componente"]
), naudingiausias, pvz., skaitinis indeksas, sunkiai naudojamas ir nepraktiškas pasiekiant rankiniu būdu sukurto tinklalapio turinį.
su JavaScript tu gali gauti elementą, kuriame yra kitas elementas (elementas arba pirminis mazgas) konsultuoti savo turtą parentNode
arba jūsų nuosavybė parentElement
, skirtumas tas, kad pirminis elementas (parentElement
) paskutinio eilutės elemento DOM Tai yra niekinis (null
) ir pirminį mazgą (parentNode
) yra pats dokumentas (document
).
į pakeisti elemento turinį HTML, pavyzdžiui, etiketės <div>
, Galima naudoti innerHTML
ir norėdami pakeisti jo savybes, galite pasirinkti priskirti jai kitą klasę className
arba atskirai pakeisti jo savybes style
. Nebūtinai naudinga peržiūrėti tinklalapio elemento rodomą stilių style
nes tai gali priklausyti nuo kelių veiksnių arba tiesiog nebuvo aiškiai nurodyta. Norint patikrinti elemento, galiausiai rodomo tinklalapyje, stilių, naudojamas metodas getComputedStyle.
Į dokumento elementą HTML Jai gali būti priskirtos kelios klasės, kad būtų galima nustatyti jo išvaizdą ir elgesį valdyti objekto klasių sąrašą iš JavaScript galite kreiptis classList
kuri siūlo metodus add
norėdami įtraukti naują klasę į sąrašą, remove
jį pašalinti, toggle
pakeisti jį arba peržiūrėti elemento klasių sąrašo turinį item
ir contains
, kuris grąžina klasę, kuri užima tam tikrą vietą sąraše, ir reikšmę true
o false
ar tam tikra klasė yra sąraše, ar ne.
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”)
}
|
Ankstesniame pavyzdyje jis yra su getElementById
objektas, kuriuo norite manipuliuoti (elementas <div>
už jo id
), prieš keičiant išvaizdą, turinys ištrinamas priskiriant su innerHTML
tuščią teksto eilutę, jai priskiriama nauja klasė className
ir jo stilius yra pakeistas style
priklausomai nuo turinio vertės (temperatūros), keičiant spalvą, jei taikoma, per nuosavybę color
. Nustačius aspektą, reikšmė vėl įrašoma naudojant innerHTML
.
Antroje aukščiau pateikto pavyzdžio dalyje (9–19 eilutės) pasiekiamas kodo elementas HTML naudojant sintaksę document[]
ir nuosavybė id
elemento, kad pakeistumėte jo klasių sąrašą naudodami metodą classList.remove()
ir su metoduclassList.add()
, remiantis kelių užklausų, atliekamų atliekant sąlyginius vykdymus, rezultatais, kuriuos jie lygina naudodami classList.contains()
.
Kada tai vyksta nurodyti elementą HTML keli kartų per visą kodą JavaScript, tai šiek tiek efektyviau priskirti jį kintamajam arba vietoj pavadinimo naudokite jo rodyklę, nes kitu atveju metodas, kurį naudotumėte JavaScript norint jį gauti kiekvieną kartą, tektų ieškoti jo pavadinimo, o tai užtruktų šiek tiek daugiau laiko nei tuo atveju, jei būtų pasiekiamas kintamasis.
į pridėti naujų objektų į dokumentą HTML, juos pirmiausia galima sukurti naudojant metodą createElement
de document
ir vėliau įtraukite juos į likusius elementus toje medžio vietoje, kuri yra būtina appendChild
. Norėdami sukurti objektą XML, kaip daiktai SVG kuriuos naudojame piešdami IoT jutiklių diagramą, galite naudoti createElementNS
(NS už vardų erdvė). Kaip paaiškinta kalbant apie formatą SVG, ją atitinkanti vardų sritis (dabartinei versijai) yra http://www.w3.org/2000/svg
, kuri turėtų būti perduota createElementNS
kaip argumentą kartu su elemento tipu, svg
, tokiu atveju.
A alternatyva innerHTML
norėdami pridėti tekstą kaip dokumento elemento turinį HTML yra metodas createTextNode()
Objektas document
. Su šia alternatyva galite sukurti naują tekstą (kuris vėliau pasiekiamas, jei jis priskirtas kintamajam), kuris įtraukiamas į objektų medį naudojant metodą appendChild()
, Kaip alternatyva appendChild()
, kuris prideda naują turinį prie to, kas jau yra mazge, prie kurio jis pridėtas, pabaigos, galite naudoti metodas insertBefore()
, kuris prideda naują objektą prieš esamą. Nešioti insertBefore()
vietoj appendChild()
pateikia metodą, kuris tarnauja, pavyzdžiui rūšiuoti naujus objektus prieš esamus kai elementas turi būti prieš kitą (kaip sąraše) arba dengti arba dengtas grafinėje struktūroje, kurioje yra elementų arčiau priekinio plano ar fono.
Reaguokite į įvykius naudodami „JavaScript“.
Kai būdas naudoti tinklalapį kaip daiktų interneto prijungtų jutiklių grafikų konteinerį jis buvo naudojamas onload
Etiketėje <body>
kad pradėtumėte braižyti grafiką. Ši savybė, susieta su kodo objektais HTML, nurodo Renginiai JavaScript. Kaip jau buvo paaiškinta, ji atlieka funkciją, kai puslapis įkeliamas. Nors jis buvo susietas su kodu HTML kad tai būtų labiau atmintyje, tai galėjo būti įrašyta kode JavaScript kaip body.onload=dibujar;
esamas dibujar
funkcijos, kuri turėtų būti paleista, kai tinklalapis įkeliamas, pavadinimas.
Naujausiose versijose JavaScript įvykius galima susieti su funkcijomis naudojant addEventListener
su formatu objeto.addEventListener(evento,función);
arba naudojant sintaksę objeto.evento=función;
kuris veikia ir senesnėse versijose. Norėdami atsieti su įvykiu susietą funkciją, turite removeEventListener
kurios formatas toks pat kaip addEventListener
.
JavaScript Jis gali reaguoti į daugybę įvykių, kurie gali įvykti tinklalapyje. Pavyzdžiui, jis gali aptikti, kada spustelėjamas elementas HTML su onmousedown
, arba spustelėjus onclick
, kai paspaudžiamas klavišas su onkeydown
, valdydami slinkties juostą su onscroll
. Mūsų tikslams mums to užtenka aptikti puslapio įkėlimą onload
ir jo dydžio keitimas su onresize
. Šiuos įvykius susiesime su objektais body
y window
del DOM atitinkamai. Pirmasis gali būti priskirtas kode HTML, kaip matyti, ir antrasis kode JavaScript funkcijos viduje, kurią iškviečia pirmasis, ir su formatu window.onresize=redimensionar;
esamas redimensionar
funkcija, kuri bus iškviesta kiekvieną kartą, kai keičiasi lango dydis.
Po tam tikro laiko paleiskite
JavaScript turi du išteklius vykdymas atidėtas: setTimeout
, kuri atlieka funkciją po laiko intervalo ir setInterval
kuri vykdys funkciją kas tam tikrą laiko intervalą. Abu metodai reikalauja kaip parametrų (1) iškviestos funkcijos ir (2) laiko intervalo, išreikšto milisekundėmis. Norėdami sustabdyti jų veikimą, šių funkcijų grąžintą rezultatą galite priskirti kintamiesiems ir perduoti juos kaip argumentą clearTimeout
O. clearInterval
kai nenorite jų iškviesti dar kartą (arba kai nenorite, kad jie būtų įvykdyti pirmą kartą) setTimeout
o setInterval
atitinkamai.
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
}
|
Ankstesniame pavyzdyje pateiktas metodas alert
kuris skirtas rodyti įspėjamąjį ženklą. Nors jis buvo plačiai naudojamas praeityje, šiuo metu jis beveik uždraustas kode JavaScript dėl to, kaip agresyvu (įkyru) yra tinklalapį uždengti dialogo langeliu.
Programoje, parašytoje a mikrovaldiklis mažos serijos (pvz., esančios lėkštėje). Arduino One) įprasta naudoti visuotinius kintamuosius, kaip ir ankstesniame pavyzdyje JavaScript, kadangi kodas yra trumpas ir ne itin painus, nes daug kartų funkcijos įgyvendinamos ad hoc, o globalių kintamųjų naudojimas leidžia labai paprastai ir intuityviai numatyti atminties naudojimą, o tai labai svarbu sistemose, turinčiose mažai išteklių. . Vietoj to, en JavaScript Įprasta iki minimumo sumažinti visuotinių kintamųjų naudojimą. nes nereikia skubinti atminties naudojimo, nes ji normaliai veikia a CPU kurių ištekliai yra daug pranašesni už a MCU, nes tikėtina, kad jis egzistuoja kartu su daugybe trečiosios šalies kodų, su kuriais jis turi veikti netrukdydamas, ir kadangi tai yra atvira sistema, negalima numatyti būsimo vykdymo konteksto (programa mikrovaldiklis „small“ visiškai nustato jo veikimą, nepridedant daugiau kodo, kai jis veikia) ir todėl, kad programų matmenys gali apsunkinti skaitymą, jei kodas neapima jo veikimo, todėl metodai tampa kiek įmanoma savarankiškesni.
Matematinės operacijos su JavaScript Math objektu
Objekte sugrupuoti sudėtingesnio matematinio skaičiavimo matematiniai veiksmai Math
. Šis objektas naudojamas tiesiogiai, nebūtina jo kartoti, kad būtų naudojami metodai ar savybės (konstantos), kurias jis įtraukia.
Math.abs(n)
Absoliuti parametro n reikšmėMath.acos(n)
n parametro arckozinas (rezultatas radianais)Math.asin(n)
n parametro arcsinusas (rezultatas radianais)Math.atan(n)
n parametro arktangentas (rezultatas radianais)Math.atan2(n,m)
Arktangentas n/m (rezultatas radianais)Math.ceil(n)
Suapvalinkite parametrą iki artimiausio sveikojo skaičiaus į viršųMath.cos(α)
Parametro α kosinusas (α radianais)Math.E
e numeris (≃2.718281828459045)Math.exp(n)
e pakelta iki parametro n: enMath.floor(n)
Suapvalinkite parametrą n iki artimiausio sveikojo skaičiaus žemynMath.log(n)
Parametro n natūralusis logaritmas (bazė e).Math.LN2
Natūralusis logaritmas (e bazė) iš 2 (≃0.6931471805599453)Math.LN10
Natūralusis logaritmas (e bazė) iš 10 (≃2.302585092994046)Math.LOG2E
2 bazės e logaritmas (≃1.4426950408889634)Math.LOG10E
10 bazės e logaritmas (≃0.4342944819032518)Math.max(a,b,c,…)
Didžiausia perduodamų parametrų sąrašo reikšmėMath.min(a,b,c,…)
Mažiausia perduotų parametrų sąrašo reikšmėMath.PI
Skaičius π (≃3.141592653589793)Math.pow(n,m)
Pirmasis parametras n pakeltas į antrąjį parametrą m: nmMath.random()
(Beveik) atsitiktinis skaičius nuo 0.0 iki 1.0Math.round(n)
Suapvalinkite parametrą n iki artimiausio sveikojo skaičiausMath.sin(α)
Parametro α sinusas (α radianais)Math.sqrt(n)
Kvadratinė šaknis iš parametro nMath.SQRT1_2
Kvadratinė šaknis iš 1/2 (≃0.7071067811865476)Math.SQRT2
Kvadratinė šaknis iš 2 (≃1.4142135623730951)Math.tan(α)
Parametro α liestinė (α radianais)
Įkelti duomenis iš serverio su AJAX
IoT saugomos informacijos piešimo metodas yra laikas nuo laiko įkelti duomenis iš serverio ir perbraižyti diagramą, kurioje jie pavaizduoti. Duomenims iš serverio nuskaityti naudojama technologija AJAX (asinchroninis JavaScript ir XML) per objektą XMLHttpRequest
de JavaScript. Duomenų grafiko braižymas atliekamas pakartotinai naudojant objektą SVG kuri jau yra kode HTML ir jame yra diagrama, kurios koordinatės modifikuotos, kad jos atitiktų naujus įkeltus duomenis.
Šio pasiūlymo pavyzdyje, be brėžinio atnaujinimo, tinklalapyje taip pat atnaujinamas tekstas, kuriame rodoma kiekvieno grafiko paskutinių išmatuotų duomenų data ir reikšmė.
Serverio pusėje yra duomenų bazė, kurioje yra informacija kad prie daiktų interneto prijungti jutikliai stebėjo. Šią duomenų bazę nuskaito objekto užklausa XMLHttpRequest
atsakydami su informacija, užkoduota JSON formatas, nors naudojamo metodo pavadinimas rodo ryšį su formatu XML.
Pirmoje polaridad.es mokymo programoje apie IoT duomenų saugykla Galite matyti infrastruktūros pavyzdį, skirtą valdyti iš serverio prie daiktų interneto prijungtų įrenginių teikiamą informaciją. Šioje straipsnių serijoje serveris naudojamas kaip šaltinis apache iš kurios galite naudoti programavimo kalbą PHP pasiekti duomenų bazę MySQL o MariaDB. Serveriuose, naudojamuose daiktų internetui palaikyti, labai dažnai galima rasti duomenų bazių MongoDB (NoSQL) ir programavimo kalba JavaScript apie Node.js kaip programinės įrangos infrastruktūra.
Kita funkcija yra atsakinga už naujausių duomenų užklausą iš vieno iš jutiklių iš serverio. Funkcijos iškvietime objektas naudojamas kaip argumentas JavaScript kuri palaiko nupieštus duomenis. Jei tas pats grafikas vaizduoja kelias reikšmes, pavyzdžiui, norint vizualiai ieškoti koreliacijos, serveriui gali būti pateikta užklausa grąžinti kelias vienu metu, o tai yra optimalesnis metodas dėl serverio veikimo būdo. HTTP protokolas.
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);
}
|
Trečioje ankstesnio pavyzdžio eilutėje paruošiama užklausa, kuri bus pateikta serveriui, kurioje bus perduodamas argumentas „zona“, kurio reikšmė bus stebimos vietos pavadinimas arba kodas, nes informacija apie plotas gali egzistuoti toje pačioje duomenų bazėje.skirtingi jutikliai (pavyzdžiui, termometrai, matuojantys temperatūrą skirtingose patalpose). Parametras, perduotas ankstesnei funkcijai, objektui su diagramos duomenimis, turėtų apimti ypatybę su patalpos pavadinimu („name_suffix“).
Tarp 7 ir 14 ankstesnio kodo eilučių, objektas XMLHttpRequest
kuris saugomas kintamajame „ajax“. Prieš pasirinkdami, kaip sukurti objektą, atliekate paiešką window
jeigu XMLHttpRequest
nebuvo pasiekiamas (tai, kas nutiko senose „Microsoft Explorer“ versijose ir, nors ji gerokai atsilieka, yra alternatyvų pavyzdys, kaip sukurti objektą naudojant (saviškesnę) sintaksę) Object.create
o new
, panašiai kaip ir kitose į objektus orientuotose kalbose.
Kad atsakymą būtų galima tvarkyti nedelsiant, prieš pateikiant užklausą serveriui, 15–26 eilutėse parengiamas jį apdorojantis kodas.
Būdas atlikti užklausą HTTP serverį sudaro atidaryti ryšį su open
nurodant tipą ir puslapį (pasirinktinai vartotojo vardą ir slaptažodį), paruošti antraštes protokolo su setRequestHeader
y išsiųsti prašymą su send
. Antraštė HTTP Content-length
turėsite žinoti užklausos ilgį (simbolių skaičių), kuri apskaičiuojama naudojant length
.
Kai prašymas AJAX yra paruošta, su įvykiu susijusi funkcija vykdoma onreadystatechange
. Vietoj funkcijos priskyrimo ankstesniame pavyzdyje anoniminė funkcija apibrėžiama skrydžio metu, kuri valdys iš serverio gaunamų duomenų priėmimą. Visų pirma, 18 eilutėje patikrinama, ar užklausos būsena yra „baigta“, o tai atitinka reikšmę 4
turto readyState
, kad būsena yra „Gerai“. HTTP protokolas (kodas 200
), kurį galima gauti iš turto status
ir kad gauti duomenys yra JSON formatas, konsultuoja nekilnojamąjį turtą responseType
.
Kai patikrinama, ar atsakymo būsena yra tokia, kokios tikimasi, ankstesnio pavyzdžio 20 eilutėje sukuria objektą su rezultatu, konvertuodamas tekstą JSON. Atsakyme tikimasi grąžinti datą, kuri leidžia mums pamatyti, ar serverio išsiųstas rezultatas jau buvo pateiktas grafike, kuris patikrinamas 21 eilutėje. Jei duomenys nauji, 23 eilutėje iškviečiama funkcija, atsakinga už grafiko perpiešimą nauja informacija.
Siūlant šį skaitymo metodą, duomenys yra atnaujinami labai dažnai. Jei pateikta informacija atitinka ilgalaikį laikotarpį (pvz., dienos ar savaitės temperatūra), gali būti įgyvendinta pradinė užklausa, kuri surenka visus turimus duomenis, o tada – panašią į pavyzdyje pateiktą, kuri ją atnaujina laikotarpio korespondentas.
Generuokite atsitiktinius duomenis testavimui
Kai visa serverio ir kliento infrastruktūra bus paruošta, tokia funkcija kaip ankstesniame skyriuje bus atsakinga už duomenų skaitymą ir grafiko sudarymą su jais, bet Bandymo etape gali būti praktiškiau naudoti atsitiktinius skaičius kontroliuojamame diapazone kad pamatytumėte, ar rašomas kodas teisingas. Ši funkcija gali būti pavyzdys, kaip gauti duomenis kuriant galutinę programą.
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);
}
|
Užuot nuskaitę informaciją iš duomenų bazės, aukščiau pateiktame pavyzdyje jie sugeneruojami atsitiktinai ir perduodami funkcijai, atsakingai už grafiko piešimą. Išrasti duomenys yra vektorius, sudarytas iš datos, išreikštos reikšme milisekundėmis, jutiklio informacijos įrašymo momento ir stebimų duomenų, kurie yra tarp didžiausios ir minimalios reikšmės.
Šiame pavyzdyje, generuojant datą, ji gali būti atidėta iki vienos sekundės (1000 milisekundžių), atsižvelgiant į datą išradimo metu. Kaip Math.random()
sugeneruoja skaičių nuo 0.0 iki 1.0, padauginus jį iš 1000, gaunamas skaičius nuo 0 iki 1000, kuris vėliau paverčiamas sveikuoju skaičiumi. Lygiai taip pat vertė gaunama atsitiktinį skaičių padauginus iš diapazono (maksimalaus minuso minimumo) ir pridedant minimumą.
Nubraižykite daiktų interneto jutiklių grafiką naudodami SVG diagramą
Kadangi matėme, kaip galime gauti norimas pavaizduoti reikšmes (temperatūra, pavyzdyje) ir jų laikinę vietą, kurios gali būti išreikštos kartu koordinačių forma, toliau pateiktame pavyzdyje parodyta funkcija nubrėžti kelią. kuris jungia tuos taškus ir pasirinktinai spalvotą sritį, kurią riboja ta linija viršuje. Rezultatas būtų toks kaip toliau pateiktame paveikslėlyje.
Diagramos horizontalioji ašis (X) žymi laiką, o vertikali ašis (Y) – vertes, kurias stebėjo prie daiktų interneto prijungti jutikliai. Horizontalus intervalas yra kelios sekundės, nes pagal šį pasiūlymą grafikas atnaujinamas labai dažnai (pavyzdžiui, kas sekundę), kad būtų pateikta beveik realiojo laiko informacija apie jutiklių būseną.
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
}
|
Ankstesniame kode yra du įdomūs aspektai, pirmiausia skaičiavimas, kuris leidžia pritaikyti pateikiamų verčių diapazoną ir, antra, nekilnojamojo turto statyba d
kuri nurodo išdėstymo taškų koordinates (path
).
Norint pritaikyti pateikiamų reikšmių diapazoną, jos perkeliamos iš minimumo ir padidinamos taip, kad matomas dydis atitiktų grafiko dydį. Laiko atveju poslinkis gaunamas atimant diapazoną, kurį norite rodyti iš ilgiausio laiko (datos ir laiko, artimiausio dabartiniam) (pavyzdyje 20 sekundžių). Temperatūros verčių poslinkis yra mažesnio diapazono (vienas laipsnis) atėmus mažiausią vertę, todėl toliau pateikti duomenys yra labiausiai panašūs į mažiausią leidžiamą vertę, tačiau paliekant ribą, leidžiančią įvertinti tuos, kurie tai daro. praeiti
Koeficientas, padauginantis laiko reikšmes, norint gauti horizontalias grafiko koordinates, gaunamas padalijus bendrą grafiko plotį (pavyzdyje 100 vienetų) iš nurodyto laiko intervalo (pavyzdyje 20 sekundžių). Norint gauti koeficientą su skaliarinėmis temperatūros vertėmis, reikia atsiminti, kad rodomas diapazonas eina nuo ribos, esančios žemiau minimalios vertės, iki ribos, viršijančios maksimalią, vienu laipsniu abiem atvejais. Tokiu būdu vertikalaus mastelio koeficientas gaunamas padalijus grafiko aukštį (pavyzdyje 100 vienetų) iš didžiausios vertės, atėmus mažiausią ir viršutinę ir apatinę paraštę. Kadangi šios vertės gali visiškai išsivystyti esant neigiamai temperatūrai, mes naudojame Math.abs()
naudoti absoliučią skirtumo vertę.
Nuosavybė d
Objektas path
Jis konstruojamas sujungiant teksto taškų koordinates. Prieš kiekvieną koordinačių porą yra kodas SVG L
, kuri nubrėžia liniją nuo dabartinės padėties iki absoliučios vertės, kurią nurodo koordinatės. X ir Y reikšmės yra atskirtos kableliais ir kiekviena operacija SVG yra atskirtas tarpu nuo kito.
Norėdami pradėti maketą, naudokite kodą M
(pereiti prie absoliučios koordinatės). Uždarojo ir užpildyto sklypo atveju pradedate apatiniame dešiniajame kampe, o atvirame brėžinyje, kuriame brėžiamas duomenų profilis, pradedate nuo paskutinės pateiktos reikšmės (paskutinės). Norėdami užbaigti uždarą maketą, naudojamas kodas Z
kaip paskutinį tašką pridedant tašką, kurio X koordinatės reikšmė yra tokia pati kaip paskutinis linijos taškas, o kaip Y koordinatė – mažiausia rodoma reikšmė.
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
);
}
|
Šiame pavyzdyje funkcija dibujar_grafico()
, kuris yra iškvietimas įkeliant puslapį, gauna pradines vertes, kurias reikia patikrinti (ne paskutinę realiojo laiko reikšmę) ir parengia diapazoną, kuriame duomenys bus pateikiami: 20 sekundžių (20000 15 ms) horizontaliai ir 5 °C vertikaliai nuo -10°C iki +XNUMX°C su vienu laipsniu viršutine ir apatine parašte. Skambinkite du kartus actualizar_grafico()
, pirmuoju praėjimu true
kaip argumentą, kuris rodo, kad diagrama turi būti uždaryta, kad būtų vaizduojama užpildyta sritis, o antrą kartą ji praeina false
nubrėžti liniją. Kiekvienu atveju objektas path
modifikuotas yra tas, kuris turi atitinkamą išvaizdą, pirmuoju atveju yra užpildytas ir be kraštinės, o antruoju atveju yra tam tikras linijos storis ir be užpildymo.
Funkcija actualizar_grafico()
dirbti prie objekto SVG kuris naudoja šį kodą kaip konteinerį HTML. Objektas SVG yra du keliai: vienas skirtas linijai, o kitas užpildytam plotui nubrėžti. Įkeliant tinklalapį iš elemento <body>
automatiškai iškviečiama ankstesnė funkcija, dibujar_grafico()
renginio dėka 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>
|
10 kodo eilutėje HTML aukščiau, stiliuje nustatytas 820 px plotis (pavyzdžiui) ir 150 px aukštis (tai, ką galutinėje versijoje patartina daryti su klase ir dokumentu CSS). Keista, kad 13 ir 14 eilutės apibrėžia objekto dydį SVG kaip 100 % plotis ir aukštis (kuris geriausiai atitinka lango matmenis, 100×100). Kaip jau minėta, to priežastis yra visada dirbti su žinomais matmenimis ir prie jų pritaikyti pateikiamas reikšmes. Kitos alternatyvos būtų kiekvieną kartą apskaičiuoti grafiko erdvę ir iš naujo koreguoti reikšmes arba priverstinai nustatyti grafiko matmenis, kurių dokumentas turės laikytis.
Pasirinkę grafiką, kurio matmenys keičiasi pagal kodą HTML, būtina įtraukti turtą vector-effect
su verte non-scaling-stroke
kad būtų išvengta linijų storio deformacijos, kai grafikas tinklalapyje, kuriame jis rodomas, neišlaiko pasirinktų 1:1 proporcijų, kaip buvo ankstesniame pasiūlyme.
Norėdami „apkarpyti“ grafiką ir rodyti tik pasirinktą sritį, naudokite viewBox
. Šiuo atveju pasirinkome matyti grafiko dalį, kuri prasideda nuo 0,0 (viršutiniame kairiajame kampe) ir matuoja 100 x 100 žemyn ir į dešinę. Brėžinio dalis, esanti koordinatėse su neigiamomis reikšmėmis arba didesnėmis nei 100, nebus rodoma tinklalapyje, net jei jos yra objekte SVG
Pridėkite naujų elementų prie SVG brėžinio
Ankstesniame pavyzdyje funkcija actualizar_grafico()
naudoti išdėstymą SVG į kurią keičiama nuosavybės teisė d
, kuri išreiškia koordinačių grandinę. Alternatyva būtų sukurti visą objektą kiekvieną kartą, kai jis perbraižytas. Pirmosios parinkties pranašumas yra tas, kad grafinė išvaizda (pvz., storis ar spalva) yra apibrėžta kode HTML, apribojimas yra tas, kad objektai turi būti sukurti anksčiau.
Norėdami sukurti SVG objektus, naudokite createElementNS()
, kuri leidžia įtraukti vardų erdvė. Toliau pateiktame pavyzdyje sukuriamas naujas teksto objektas (text
) ir yra susietas su elementu SVG kuri jau yra kode HTML svetainės. Sukūrus naują elementą, priskiriamos jo savybės setAttribute()
ir pridedama prie SVG su 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]);
|
Pakeiskite piešimo elementų proporciją
Jei bandėte pažymėti funkciją ankstesniame skyriuje pateiktame pavyzdyje, pamatysite, kad tekstas atrodo deformuotas, kai objekto proporcija tinklalapyje (width
y height
Iš kodo HTML) nėra lygus vaizduojamo ploto (viewBox
). Norint pritaikyti proporciją, būtina žinoti objekto išmatavimus SVG dėl kurio galite sužinoti objekto stilių arba konteinerį HTML, jei objektas SVG perduoti šį turtą. Nuosavybės priskyrimas transform
į daiktus SVG kurios priklauso nuo proporcijos, deformacija gali būti ištaisyta taikant mastelio keitimo operaciją scale()
kurioje koeficientas X skiriasi nuo Y koeficientas.
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 leidžia sugrupuoti kelis objektus ir sudaryti naują sudėtinį elementą, kuris taip pat palaiko savybes, kaip paprasti objektai. Norėdami tą pačią transformaciją taikyti objektų serijai iš karto, o ne kiekvienam objektui atskirai, galite juos sugrupuoti pagal šį šaltinį ir pritaikyti vieną ypatybę transform
jiems visiems.
Kaip paaiškinta kalbant apie SVG formatu, grupės elementai yra įtraukti į etiketes <g>
y </g>
. Norėdami pridėti iš JavaScript elementai grupei SVG naudojamas, kaip matyti ankstesniame pavyzdyje, appendChild()
kai naujas objektas yra apibrėžtas.
Norint nustatyti kilmę taikant transformacijas, savybė gali būti naudojama objektams SVG transform-origin
, kurios reikšmė yra taško, nuo kurio prasideda transformacija, X ir Y koordinatės. Jei transformacijos kilmės reikšmė nėra aiškiai nurodyta (žiniatinklio naršyklėje), naudojamas koordinačių centras. Deja, rašymo metu transformacijų elgsenos nurodymas naudojant kitą šaltinį nei numatytasis nėra vienodas visose naršyklėse ir turėtų būti naudojamas atsargiai.
Kartu su masto transformacija su scale
Yra ir kitų, tokių kaip sukimasis su rotation
ir judėjimas su translate
, kurie siūlo a grafinio vaizdavimo alternatyva: užuot gavę naujas koordinates, galite jas pavaizduoti savo erdvėje ir transformuoti grafiką, kad jis atitiktų formatą, kuriuo norite jas pavaizduoti.
Pridėkite nuorodas į diagramą
Dabar, kai pagrindinė grafiko dalis išspręsta nubraižant reikšmes su profiliu ir užpildyta sritis, ją galima papildyti nuorodomis, kurios padeda ją nuskaityti. Pavyzdžiui, pradėkime nuo kelių horizontalių nuorodų (linijų), kurios žymi didžiausias ir mažiausias priimtinas reikšmes bei norimą reikšmę. Kaip paaiškinta, galite pasirinkti pridėti objektus prie SVG tiesiai iš JavaScript arba įtraukite juos į kodą rankiniu būdu HTML ir vėliau pakeiskite juos naudodami 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();
|
Atrodo logiška šias horizontalias nuorodas pažymėti tekstu, paaiškinančiu jų atstovaujamą vertę. Norėdami paryškinti tekstą, galite naudoti stačiakampius, kurie išsiskirs iš fono ir grafikos. Kadangi, norint kompensuoti deformaciją, tekstai turės būti keičiami masteliu, juos visus galima sugrupuoti į objektą, kuriam bus pritaikyta skalė; Pagrindinis šio būdo privalumas yra galimybė juos modifikuoti viena operacija, jei keičiamas grafiko konteinerio (naršyklės lango) dydis ir keičiama proporcija, kurią ištaiso mastelis.
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();
|
Aukščiau pateiktame kodo pavyzdyje yra keletas įdomių aspektų. Visų pirma, pakomentuokite, kad konstantos (pasauliniai kintamieji) buvo panaudotos tam, kad pavyzdys būtų lengviau skaitomas vartotojams iš programavimo. mikrovaldikliai en C , C + +. Kaip bus matyti vėliau, optimalus būdas jį užprogramuoti JavaScript Tai būtų objektų, kuriuose būtų šios reikšmės, ir metodų naudojimas, kurie valdytų nuorodas šiame pavyzdyje arba grafiką, apskritai, gamybos sistemoje.
Kita vertus, tobulinant, koks būtų bendresnis kodas, buvo sukurtos atskiros funkcijos, apskaičiuojančios skirtingus koeficientus, koreguojančius grafiko proporcijas, kad pakoreguotų tekstą. proporcion_grafico()
, verčių skalė, priklausanti nuo jų diapazono escala()
ir pataisos koeficientas matavimams, kurie žinomi absoliučia verte, pvz., matavimai atskaitose medida_grafico()
.
Šio kodo skaitymas turėtų padėti išsiaiškinti kontekstą, kuriame veikia tokia programa, kuri piešia grafiką realiuoju laiku ir turi būti lanksti, kad ją būtų galima pateikti įvairiuose grafiniuose kontekstuose (bent jau įvairių dydžių ir proporcijų). Visų pirma, objektai turi būti sugeneruoti SVG, arba „rankiniu būdu“ kode HTML, arba per kodą JavaScript ir bet kuriuo atveju vėliau reikia gauti nuorodas į šiuos objektus, kad jais būtų galima manipuliuoti JavaScript kad būtų galima nubraižyti naujus grafikus ir pritaikyti jau nubraižyto grafiko vaizdavimą prie terpės, kurioje jis pateikiamas, pasikeitimo.
Kita nuoroda, kuri gali padėti lengvai interpretuoti grafiką, yra taškai, kurie reiškia konkrečias reikšmes (linijos mazgai). Šiame pavyzdyje, kuriame atstovaujame vieną dydį, simbolio pasirinkimas nėra labai svarbus, tačiau jei koreliacijai ieškoti dedamos kelios skirtingos reikšmės, įdomu atskirti, be kitų išteklių, pvz., spalvos, naudojimo. , piešdami skirtingus simbolius. Linijos mazgo grafikai turi būti modifikuoti pagal dydį ir proporcijas, kaip, pavyzdžiui, su tekstais, kad jo matmenys būtų absoliutūs ir kad jo proporcijos būtų išlaikytos net pasikeitus jame esančio langelio proporcijoms.
Ankstesniame pavyzdyje jau matėme, kaip apskaičiuoti skirtingus koeficientus, kad būtų pakeista skalė ir ištaisyta brėžinio proporcija; Kalbant apie tai, kaip įgyvendinti grafo mazgų ar viršūnių simbolių valdymą, galimas sprendimas būtų saugoti objektus SVG į vektorių ir modifikuoti jo padėtį, kai grafikas atnaujinamas nuskaitant naują reikšmę arba kai jis perbraižytas keičiant konteinerio dydį. Pirmuoju atveju reikėtų pakeisti jo padėtį, o antruoju – proporciją su nuosavybe transform
ir vertė scale
. Šis kodas yra funkcijos modifikacija actualizar_grafico()
įtraukti grafiko viršūnių simbolių pozicionavimą.
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);
}
}
|
Funkcijoje atlikti pakeitimai actualizar_grafico()
gauti naują funkciją actualizar_grafico_puntos()
Jie yra paryškinti ankstesnio pavyzdžio kode. Pirma, 5 eilutėje paimame objektų vektorių SVG kaip parametras. Šiame vektoriuje bus simboliai, kuriuos reikia pakeisti naujuose grafiko mazguose.
39 ir 40 eilutėse priskiriamos naujos centro koordinatės, cx
y cy
, toms vertybėms, kurios yra atstovaujamos. Jei simbolis nebuvo pagrįstas centru, tikriausiai reikės pridėti poslinkį cx
pusė pločio ir į cy
pusės aukščio, kad juos tiksliai pakeistumėte grafiko mazge.
57–61 eilutėse taškai, atitinkantys koordinates, kurios nėra nubrėžtos, nes yra nupjautos kairiojo krašto, perkeliamos už grafiko ribų. Koordinatė cy
iki nulio ir kad iš cx
į bet kurį neigiamą skaičių (didesnį už patį tašką), kad jis nebūtų rodomas, kai jis, kaip ir kairioji grafiko dalis, iškirptas lango SVG.
Tvarkykite diagramą iš objekto naudodami „JavaScript“.
Visas iki šiol paaiškintas operacijas galima integruoti į objektą, kad būtų galima valdyti grafiką stiliumi, labiau būdingu naujoms versijoms. JavaScript. Ši įgyvendinimo alternatyva turi papildomą pranašumą, nes supaprastina kelių skirtingų reikšmių grafikų įtraukimą į tą patį tinklalapį.
Prieš aptardami įgyvendinimą, apžvelkime dažniausiai naudojamus objektų kūrimo būdus JavaScript ir kai kuriuos funkcijų ypatumus, turinčius įtakos pasiūlymui piešti daiktų interneto jutiklių grafiką.
Jau buvo paaiškinta, kad naujas objektų kūrimo būdas in JavaScript (pasiekiama nuo 5 versijos ECMASCRIPT) susideda iš naudojimo Object.create
, kurį reikėtų priprasti naudoti vietoj „klasikinio“ new
, kuris, žinoma, vis dar veikia teisingai, nors jo tikslas yra labiau imituoti kalbų stilių su klasės objektais (JavaScript objektų kūrimą grindžia prototipais) nei veikianti alternatyva.
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();
}
|
Ankstesnis kodas leidžia prisiminti skirtumus tarp objektų kūrimo naudojant Object.create
o pa new
. Tai taip pat padeda pabrėžti, kad nors funkcija, su kuria objektas yra sukurtas new
gali būti bet kurioje kode, objektas jau turi egzistuoti, kad būtų galima jį sukurti Object.create
(ES5_Object objektas nėra funkcija).
3 ir 4 eilutėse, norėdami nustatyti numatytąją reikšmę funkcijos, kuri sukuria objektą, ypatybių new
, kiekviena savybė priskiriama atitinkamo argumento vertei arba (||
), jei argumentai nebuvo perduoti, tai yra, jei jie neapibrėžti (undefined
), nes ta aplinkybė vertinama kaip false
, priskiriama numatytoji reikšmė.
Kontekstas, kuriame vykdoma funkcija JavaScript iškelia du klausimus, kuriuos svarbu nepamiršti ir kurie taip pat gali kelti painiavą naudojant šią programavimo kalbą po darbo su kitais, pvz. C o C + +, mūsų atveju. Kontekstas apima funkcijos apimtyje apibrėžtus kintamuosius (ir globalius), kurie, beje, iškelia įdomią koncepciją, „uždarymus“, kurie nustato visą programavimo stilių. JavaScript. Sakė, to buvo galima tikėtis this
, kuris nurodo objektą, kai naudojamas jį apibrėžiančiame kode, vykdymo kontekstas, kuriame jis buvo apibrėžtas, išlaikomas, tačiau naudojamas kontekstas, iš kurio iškviečiama funkcija. Šis elgesys daugeliu atvejų yra skaidrus, tačiau yra dvi aplinkybės, kuriomis jis gali būti painus: funkcija, apibrėžta kitos funkcijos viduje, ir metodas, iškviestas iš objekto įvykio. 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
*/
|
Vykdant ankstesnį kodą, konsolėje rodomas pabaigoje komentuojamas tekstas. Dvi pažymėtos eilutės atspindi elgesį, kuris gali būti painus: funkcijos vykdymo kontekstas probar_dentro()
ne probar()
, kaip ir galima tikėtis, bet window
, kuris rodo visuotinius kintamuosius, o ne to paties pavadinimo savybes. Jei nenorite tokio elgesio, tiesiog sukurkite aukščiausio lygio funkcijos kintamąjį ir priskirkite jį this
, kaip nurodyta kitame kode.
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
*/
|
Norėdami valdyti vykdymo kontekstą, kai metodas iškviečiamas iš įvykio window
, pavyzdžiui, pakeitus naršyklės lango dydį, dar vienas ypatumas JavaScript: galimybė programuoti „funkcijų gamyklas“, tai yra funkcijas, kurios generuoja kitas funkcijas, su jas grąžinant 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
|
Aukščiau pateiktame pavyzdiniame kode metodas llamar()
objektų Contexto
Jis neatlieka darbo, bet grąžina anoniminę funkciją, kuri juo rūpinasi. Norėdami patikrinti, ar viskas veikia taip, kaip tikėtasi, yra visuotinis kintamasis, kurio pavadinimas yra toks pat kaip ir ypatybė, kurią funkcija rodo konsolėje; Jei kontekstas teisingas, bus rodoma ypatybės, o ne visuotinio kintamojo reikšmė.
JavaScript Pabandykite ištaisyti kabliataškius, kuriuos praleidžiame sakinių pabaigoje. Tai leidžia rašyti ramiai, bet yra dviašmenis kardas, su kuriuo reikia elgtis atsargiai. Daugeliu atvejų, kad išvengtumėte nepageidaujamų poveikių, kuriuos tai sukelia išraiškose, kurios užima kelias eilutes, galite naudoti skliaustus arba pateikti prieš tai, kaip JavaScript interpretuos kodą; Štai kodėl 8 pavyzdžio eilutė apima function
gale return
, jei būčiau naudojęs kitą eilutę, reikšmė būtų labai skirtinga. Mano nuomone, skaitomiausias sprendimas yra naudoti tarpinį (nepakeičiamą) kintamąjį, kaip nurodyta tolesnėje versijoje; Akivaizdu, kad supratus elgesį, sprendimas atitinka programuotoją.
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);
|
Ta pačia prasme, vertinant išraišką kaip funkciją, tai yra, grąžinant funkciją, o ne reikšmę, kurią funkcija grąžina; paskutinio pavyzdžio 21 eilutėje (buvo ankstesnio 19 eilutėje) jis sustoja clearInterval
funkcija, vadinama su setInterval
. Kad jis veiktų 30 sekundžių, sustojimas atidedamas setTimeout
, kuriai savo ruožtu reikia funkcijos kaip pirmojo argumento; pateikti vykdymą kaip parametrą clearInterval
su kintamuoju, kuriame yra periodinis iškvietimas (o ne funkcija clearInterval
) yra tai, kam sukurta anoniminė funkcija paskutinėje eilutėje.
Pasirinkimas: rašyti kodą integruojant funkcijos apibrėžimą, kompaktiškesnį (kaip 21 eilutėje) arba naudoti pagalbinį kintamąjį, mano nuomone, lengviau skaitomą (kaip 19 ir 20 eilutėse), našumas mažai skiriasi ir priklauso nuo stiliaus bei skaitomumo. priežiūra.
Norėdami išbandyti kodą, prieš turėdami duomenų serveryje, galite naudoti norimo diapazono atsitiktinių verčių generatorių arba paruošti lenteles su kontroliuojamomis reikšmėmis, kurios imituoja veikimą norimomis sąlygomis. Šiame pavyzdyje naudojamas paprastas duomenų generatorius visame diapazone, todėl jie atrodo šiek tiek perdėti.
Norėdami išbandyti, galite atsisiųskite visą pavyzdžio kodą sudarytas iš tinklalapio, parašyto HTML, stilius CSS ir kodas JavaScript. Pastarasis yra aktualiausias, nes kiti komponentai yra tik minimali pagalba, labai supaprastinti ir yra daug labiau išplėtoti atitinkamų skyrių straipsniuose.
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);
}
|
Rašyti komentarą