JavaScript ile IoT'ye bağlı sensörlerden gelen verilerin SVG grafiklerini oluşturun ve değiştirin
Çizim üzerine makaleler serisinin bu son bölümünde Nesnelerin İnternetine bağlı sensörlerden gelen verileri içeren grafiklerile nasıl oluşturulacağı veya değiştirileceği hakkında konuşmanın zamanı geldi JavaScript formatındaki çizimler SVG ve bazı elementler HTML kap görevi gören veya grafiklere tamamlayıcı bilgiler sunan.
Bu eğitimin hedef kullanıcılarının bir elektronik ve bilgisayar programlama profili oluşturması gerekmektedir. mikrodenetleyicileraşina olmayabilirler HTML, CSS o SVG; Bu nedenle önceki bölümlerde dile veya ilgili teknolojiye kısa bir giriş yapıldı. Bu son kısımda yaklaşım biraz farklı, okuyucular mutlaka programlamayı bildikleri için dili kullanmaları mümkün. C + + bu nasıl JavaScript, temel sözdizimini şununla paylaşır: C ve temel programlama kavramlarının çoğunu atlamak ve böylece farklılıklara ve IoT'de sensör grafikleri oluşturmak için bizi ilgilendiren spesifik kullanıma odaklanmak için bir referans olarak kullanılabilir.
İsim ilk farka dair ipucu veriyor: JavaScript Bir programlama dilidir senaryo (tire) ve bu nedenle yorumlanır, derlemeye gerek yoktur; hangi bağlamda senaryo (örneğin bir web tarayıcısı) emirleri okuyacak, tercüme edecek ve uygulayacaktır. Kesin olmak gerekirse, çoğu durumda bir çalışma zamanı derlemesi (JIT), ancak kod yazma işlemi için JavaScript Bu bizi etkilemiyor, sadece kodu yazıyoruz ve çalışabiliyor.
İsim aynı zamanda ilk karışıklığı da içeriyor: JavaScript ile en ufak bir ilişkisi yok Java. Başlangıçta geliştirildiğinde Netscape tarayıcısı için önce Mocha, ardından daha az kafa karıştırıcı olan LiveScript olarak adlandırıldı. Tarayıcılarda başarılı bir şekilde uygulanıp onları aştıktan sonra şu şekilde standartlaştırıldı: ECMAScript (Için ECMA-262, sürüm 6 Bunu uygulayan tarayıcılara karşı tarafsız olmak için bu yazının yazıldığı sırada). Şu anda da bir standart var ISO sürüm 5, 2011'den itibaren (ISO / IEC 16262: 2011 makalenin yazıldığı sırada)
JavaScript'te değişkenler, temel veri türleri ve nesneler
Örneğin, olanlardan farklı olarak C + +, en JavaScript Bir değişken bildirilirken veri türü dahil edilmez ve ayrıca bir değişkenle ilişkili tür sabit değildir, programın yürütülmesi boyunca farklı türde bir değer atamak mümkündür.
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
|
Önceki örnekte, "şey" değişkeni bildirildi (veri tipi belirtilmeden), ardından farklı tipte bir veri atanır ve ona başvurulur. typeof
şu tip JavaScript yorumladığını söyledi. Kodun hatalarını ayıklamak için bunu web tarayıcısının denetçi konsoluna (web'in sunumunu etkilemeyecektir) yazabilirsiniz. console.log()
.
Verilerin belirli bir türe, özellikle de metinden sayısala dönüştürülmesini zorlamak için aşağıdaki gibi işlevleri kullanabilirsiniz: parseInt()
o parseFloat()
bunlar sırasıyla tam sayılara veya kayan noktalı sayılara dönüştürülür. Ters dönüşüm şu şekilde yapılabilir: String()
, ancak otomatik dönüştürme genellikle yeterli olduğundan gerekli olması pek olası değildir. İle parseFloat()
Örneğin, bir web sayfası özelliğinin, birimleri içeren bir nesnenin genişliği veya yüksekliği gibi değerini alabilirsiniz; Bu şekilde ifade parseFloat("50px");
sonuç olarak sayısal bir değer olan 50 değerini döndürecektir.
En JavaScript çift ve tek tırnak arasında fark yoktur; Her iki durumda da veri türü string
ve her biri kaçış kodlarına ihtiyaç duymadan diğerini içerebilir.
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
|
Önceki örnekte, bir değişkenin bildirildiği (var olduğu) ancak herhangi bir değer atanmadığı zaman, tanımlanmamış bir veri türü içerdiği görülebilir (undefined
). Atanmamış bir nesnenin değeri vardır null
; Yani nesne vardır ama değeri yoktur; ona referans veren bir değişkenin typeof
undefined
Çin object
. Bir nesne aynı zamanda boş olabilir, yani boş olmayabilir ancak herhangi bir özelliğe sahip olmayabilir.
Daha içinde bir nesne tanımlayın JavaScript parantez içine alınır ({
y }
) iki nokta üst üste işaretiyle ayrılmış özellikler veya yöntemler (:
) özellik adı özellik değeri ve virgülle (,
) farklı özellikler. Bir nesnenin bu şekilde ifade edilmesi hakkında daha fazla bilgiyi şu makalede bulabilirsiniz: JSON biçimi.
Aksini düşünmenize yol açabilecek sözdizimini kullanabilseniz de, en JavaScript Sınıflar yok ama prototipler varYani, bir nesnenin özellikleri ve yöntemleri miras alması için, diğerlerinin (çocukların) referans olarak kullandığı başka bir nesne (prototip) oluşturulur. Stiline en yakın sözdizimi JavaScript bir prototip kullanmak Object.create
kullanılması da mümkün (ve bazen faydalı) olmasına rağmen new
diğer nesne yönelimli dillerde olduğu gibi.
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));
|
Daha bir nesnenin diğerinin örneği olup olmadığını sorgula, eğer onu prototip olarak kullanırsanız, özelliklerini miras alırsanız, kısacası kullanabilirsiniz. instanceof
(ile oluşturuldu new
) o isPrototypeOf
(ile oluşturuldu Object.create
) nesne prototipi kullandığında true, kullanmadığında false olarak değerlendirilecektir.
Bir nesne bir başka nesneyi prototip olarak kullanarak yaratıldığında, yani bir nesne bir kez başlatıldığında, yeni özellikler ekleyin veya prototip özelliklerini geçersiz kılın olduğu gibi nokta sözdizimini kullanma gato.peso=2.5
.
La diziler JavaScript Muhtemelen tanıdığınız kişilerden farklılar C. Başlangıç olarak uzunluklarını belirtmeye gerek kalmadan sadece köşeli parantezlerin açma ve kapama işaretleri ile bildirilirler ([
y ]
), bileşenler heterojen olabilir (aynı dizide farklı veri türleri) ve yeni öğeler bir sınırla sınırlandırılmadan eklenebilir. matrisleri JavaScript aslında öğelerin listeleridir (koleksiyonlarıdır) sayısal bir indeks veya bir isimle referans verilir. Bir dizi aynı anda sayısal dizinler ve öğe adları içerebilir, ancak ikinci türden yararlanmak için nesnelerin (özelliklerin) kullanılması yaygındır.
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
|
Önceki örnekte görülebileceği gibi, bir değişkenin bir dizi örneğine (bu bir dizi nesnesidir) karşılık gelip gelmediğini bilmek için şunu kullanabilirsiniz: instanceof
genel nesnelerde veya daha yeni sürümlerde zaten kullanıldığı gibi JavaScript başvurabilirsin Array.isArray()
Dizinin elemanlarına erişmek için indeksini kullanabilirsiniz (matriz[7]
) veya köşeli parantez içindeki adla birlikte özellik adına göre (matriz["nombre"]
) veya nesneler için olağan nokta sözdizimi ile (matriz.nombre
). Ad bir metin dizesi olduğundan, onu oluşturmak için değişkenleri içeren bir ifade kullanılabilir. Özelliklere sahip bir dizide döngü yapmak için formata sahip bir döngü kullanılabilir 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
*/
|
Tedavi etme amacımız açısından ilginç nesne Date
tarih ve saati temsil edecek ve yönetecek olan JavaScript. Nesne veri olmadan oluşturulabilir, dolayısıyla geçerli tarih ve saati alır veya 1 Ocak 1970'ten bu yana milisaniye cinsinden bir değer olarak bir tarih belirtilerek oluşturulabilir (örneğin, Unix zamanı veya POSIX zamanı ancak saniye yerine milisaniye cinsinden ifade edilir) veya yıl, ay, gün, saat gibi ayrı değerler belirtilerek...
Nesne tam bir dizi içerir tarih ve saati sorgulama veya ayarlama yöntemleri:
-
now()
1 Ocak 1970'den bu yana milisaniye cinsinden ifade edilen geçerli tarih ve saati döndürür -
getTime()
|setTime()
1 Ocak 1970'den bu yana milisaniye cinsinden zaman değerini sırasıyla alır veya değiştirir.valueOf()
Çoğu nesnede bulunan bir yöntem olan, karşılık gelen Date nesnesinin değeri de elde edilir;getTime()
ile Unix zamanı veya POSIX zamanı ms cinsinden ifade edilir. -
getMilliseconds()
|setMilliseconds()
Nesnenin kesirli milisaniye kısmını sorgulamak veya ayarlamak için kullanılırDate
üzerinde yürütülür. Başvurulursa elde edilen değer 0 ile 999 arasındadır ancak toplam tarih ve saatte birikecek daha büyük değerler atanabilir, böylece diğer get yöntemleri gibi nesnenin değerini artırmaya hizmet eder.Date
(veya negatif değerler kullanılıyorsa azaltın). -
getSeconds()
|setSeconds()
Nesnenin saniye değerini sırasıyla döndürür veya değiştirirDate
. -
getMinutes()
|setMinutes()
Nesnenin tutanaklarına danışmak veya ayarlamak için kullanılırDate
. -
getHours()
|setHours()
Nesnenin saatlerine (0'dan 23'e kadar) bakmanıza veya değiştirmenize olanak tanırDate
. -
getDay()
Tarihe ilişkin haftanın gününü, 0'dan 6'ya (Pazar'dan Cumartesi'ye) kadar bir değer olarak ifade ederek döndürür. -
getDate()
|setDate()
Nesnenin ayın gününü döndürür veya değiştirirDate
hangisinde uygulanır. -
getMonth()
|setMonth()
Nesnenin ay numarasını incelemek veya değiştirmek için kullanılırDate
. -
getFullYear()
|setFullYear()
Tarih ve saati içeren nesnedeki yıl değerini sorgular veya ayarlar.
Daha önceki yöntemler Date
bir sürüm ekle UTC ara hesaplamalar yapmaya gerek kalmadan doğrudan evrensel zamanla çalışabilmek. Bu anlamda örneğin getHours()
bir sürümü var getUTCHours()
o getMilliseconds()
bir alternatif getUTCMilliseconds()
resmi (yasal) veya evrensel zamanla alternatif olarak çalışmak. İle getTimezoneOffset()
Evrensel saat ile yerel resmi saat arasındaki farkı biliyorsunuz.
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 işlevleri
Eğer bunu okuyorsanız kesinlikle nasıl programlanacağını biliyorsunuzdur. mikrodenetleyiciler en C içinde C + + ve fonksiyon kavramını bilir. Temel fikir aynı olsa da JavaScript Tanımlanma ve kullanılma şekilleri biraz farklıdır. Başlangıç olarak, zaten söylendi, JavaScript Açıkça veri türlerini kullanmadığından, işlevi tanımlarken belirtmenize gerek yoktur.. Takip etmek, Bir işlevin bir isme sahip olması zorunlu değildir; anonim olabilirler. Bunları çağırmak için bir değişkenle ilişkilendirilebilirler ancak bazen gerekli olmayabilir, çünkü bazen parantezlerin ve parametrelerin fonksiyonun tanımından sonra eklendiği hemen çağırmak yararlı olabilir.
Bir işlevi tanımlamak için önek function
, mümkünse adı, argümanları (fonksiyona iletilen parametreler) parantez içine ve fonksiyon çağrıldığında yürütülecek kodu parantez içine yazın.
1
2
3
4
5
|
function doble(numero)
{
var resultado=numero*2;
return resultado;
}
|
Elbette, önceki örnekte "sonuç" değişkenine hiç ihtiyaç duyulmamıştı, ancak bu, şunu hatırlamak için iyi bir bahanedir: değişken kapsam, beklediğiniz gibi çalışır: "sonuç" değişkeni yalnızca "double" işlevi içinde bulunur. İçinde JavaScript ayrıca kullanılabilir let
yerine var
, bir değişkeni kod bloğu bağlamına dahil etmek için (küme parantezleri içine alınmış, {
y }
)
Önceki bölümde nesnelerden bahsederken temel bir şey eksikti: özellikler tanımlanmış ancak yöntemler tanımlanmamıştı. Beklenildiği gibi, nesne yöntemleri işlevlerdir, adları yoktur ve nesne tanımı tarafından atanan (özellik) adından kullanılır (çağrılır).
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”);
}
}
|
Önceki örnekte, konsol aracılığıyla "current_temperature" özelliğinin değerini görüntüleyen "view_temperature" adında bir yöntem zaten mevcuttur. Pek kullanışlı değil ama bir nesnenin tanımının neye benzediğine dair daha eksiksiz bir fikir veriyor. JavaScript.
Bir nesnenin (işlevlerin) yöntemlerine özelliklerine erişmek için şunu kullanın: this
11. satırdaki önceki örnekte olduğu gibi, "current_temperature" özelliğini kullanırken.
Belge Nesne Modeline (DOM) JavaScript ile erişme
. JavaScript Sistem kaynaklarına olmasa da, üzerinde çalıştığı web sayfasının içeriğine ve o sayfayı görüntüleyen tarayıcının bazı özelliklerine erişebilirsiniz. Erişilen özellikleri ve yöntemleri destekleyen veri yapısı JavaScript pencere nesnesinin bir kısmı, özellikle nesnenin içeriği (belge HTML) nesneye karşılık gelir document
. Bazen netlik sağlamak için kullanılsa da, yöntem veya özelliklere atıfta bulunmak için bunların önüne pencere koymak gerekli değildir, örneğin şunu kullanmak yeterlidir: document
olduğu gibi kök nesnenin adını yazmaya gerek yoktur. window.document
Geçerli pencereye başvurulduğu sürece.
En çok kullanılan şekli belgede bir nesne bulma HTML Bu yöntem sayesinde getElementById()
, kod oluşturulurken belirtilen kimliğin argüman olarak iletildiği yer HTML. Önceki bölümlerde anlatılanlardan, nesnenin içindeki bileşenlere de erişebileceğinizi varsaymak kolaydır. document
nokta sözdizimini kullanarak (document.componente
) veya parantez içinde hem adı (document["componente"]
), sayısal dizin gibi en kullanışlı olanı, manuel olarak oluşturulmuş bir web sayfasının içeriğine erişirken kullanımı zor ve pratik değildir.
ile JavaScript yapabilirsiniz başka bir öğe içeren öğeyi alın (öğe veya ana düğüm) mülkünüzle ilgili danışmanlık parentNode
veya mülkünüz parentElement
fark, ana öğenin (parentElement
) dizenin son elemanının KARAR Bu boş (null
) ve ana düğüm (parentNode
) belgenin kendisidir (document
).
Daha bir öğenin içeriğini değiştirmek HTMLörneğin bir etiketinki <div>
, Kullanılabilir innerHTML
ve özelliklerini değiştirmek için ona farklı bir sınıf atamayı seçebilirsiniz. className
veya özelliklerini tek tek değiştirin style
. Web sayfasındaki bir öğe tarafından görüntülenen stile bakmak her zaman yararlı olmayabilir style
çünkü çeşitli faktörlere bağlı olabilir veya açıkça belirtilmemiş olabilir. Sonunda web sayfasında görüntülenen bir öğenin stilini kontrol etmek için getComputedStyle yöntemi kullanılır..
Bir belge öğesine HTML Görünümünü ve davranışını belirlemek için ona birkaç sınıf atanabilir. bir nesnenin sınıflarının listesini yönetmek JavaScript başvurabilirsin classList
yöntemleri sunan add
Listeye yeni bir sınıf eklemek için, remove
onu kaldırmak için, toggle
onu değiştirmek veya bir öğenin sınıf listesinin içeriğine bakmak için item
ve contains
listede belirli bir konumu kaplayan sınıfı ve bir değeri döndürür true
o false
Belirli bir sınıfın listede olup olmadığı.
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”)
}
|
Önceki örnekte şu konumda bulunur: getElementById
işlemek istediğiniz nesne (bir öğe <div>
onun için id
), görünümü değiştirmeden önce içerik ile atanarak silinir. innerHTML
boş bir metin dizesi, yeni bir sınıfa atanır className
ve stili şu şekilde değiştirildi: style
içeriğin değerine (sıcaklığa) bağlı olarak, varsa özellik aracılığıyla rengin değiştirilmesi color
. Görünüm oluşturulduktan sonra değer tekrar kullanılarak yazılır. innerHTML
.
Yukarıdaki örneğin ikinci bölümünde (9'dan 19'a kadar olan satırlar) bir kod öğesine erişilir. HTML sözdizimini kullanarak document[]
ve mülk id
Bu yöntemle sınıf listesini değiştirmek için öğenin classList.remove()
ve yöntemleclassList.add()
kullanarak karşılaştırdıkları, koşullu yürütmelerde gerçekleştirilen birkaç sorgunun sonucuna dayalıdır. classList.contains()
.
Ne zaman gidiyor bir öğeye atıfta bulunmak HTML varias kod boyunca kere JavaScript, Birazcık onu bir değişkene atamak daha verimli veya isim yerine indeksini kullanın, aksi takdirde kullanacağınız yöntem JavaScript bunu her seferinde elde etmek, adının aranmasını gerektirir ve bir değişkene erişildiğinden biraz daha fazla zaman harcar.
Daha belgeye yeni nesneler ekleme HTML, yöntemle ilk önce oluşturulabilirler createElement
de document
ve daha sonra bunları ağacın gerekli olduğu noktada geri kalan öğelere dahil edin. appendChild
. Bir nesne oluşturmak için XMLnesneler gibi SVG IoT sensörlerinin grafiğini çizmek için kullandığımız createElementNS
(NS için ad alanı). Format hakkında konuşurken açıklandığı gibi SVG, ona karşılık gelen ad alanı (geçerli sürüm için) http://www.w3.org/2000/svg
, iletilmesi gereken createElementNS
öğe türüyle birlikte bir argüman olarak, svg
, bu durumda.
bir alternatif innerHTML
bir belge öğesine içerik olarak metin eklemek için HTML yöntem bu createTextNode()
nesne document
. Bu alternatifle şunları yapabilirsiniz: yeni metin oluştur (bir değişkene atanırsa daha sonra erişilir) yöntemle nesne ağacına dahil edilir appendChild()
. olarak alternatif appendChild()
Yeni içeriği, eklendiği düğümde zaten mevcut olanın sonuna ekleyen, kullanabilirsiniz yöntem insertBefore()
, mevcut bir nesnenin önüne yeni bir nesne ekler. Giymek insertBefore()
yerine appendChild()
örneğin aşağıdakilere hizmet eden bir yöntem sağlar: yeni nesneleri mevcut nesnelerin önüne sıralayın bir öğenin diğerinin önünde olması (bir listede olduğu gibi) veya ön plana veya arka plana daha yakın öğelerin bulunduğu bir grafik yapıyı kaplaması veya kaplaması gerektiğinde.
Etkinliklere JavaScript ile tepki verme
Ne zaman yolu IoT bağlantılı sensör grafikleri için bir web sayfasını kapsayıcı olarak kullanma kullanılmış onload
Etikette <body>
Grafiği çizmeye başlamak için. Kod nesneleriyle ilişkili bu özellik HTML, şuna atıfta bulunur: Etkinlikler JavaScript. Daha önce açıklandığı gibi sayfa yüklendiğinde bir işlevi çalıştırır. Her ne kadar kodla ilişkilendirilmiş olsa da HTML daha akılda tutmak için kodda yazılmış olabilir JavaScript olarak body.onload=dibujar;
olma dibujar
web sayfası yüklendiğinde başlatılması gereken fonksiyonun adı.
En son sürümlerinde JavaScript olaylar işlevlerle ilişkilendirilebilir. addEventListener
format ile objeto.addEventListener(evento,función);
veya sözdizimini kullanarak objeto.evento=función;
bu aynı zamanda eski uygulamalarda da işe yarar. Etkinlikle ilişkili işlevin bağlantısını kaldırmak için, removeEventListener
ile aynı formata sahip olan addEventListener
.
JavaScript Bir web sayfasında meydana gelebilecek çok sayıda olaya tepki verme yeteneğine sahiptir. Örneğin bir öğeye ne zaman tıklandığını algılayabilir HTML ile onmousedown
veya ile tıklandığında onclick
ile bir tuşa basıldığında onkeydown
kaydırma çubuğunu kullanarak onscroll
. Amacımız açısından bu bizim için yeterli ile sayfa yükünü tespit et onload
ve yeniden boyutlandırılması onresize
. Bu olayları nesnelerle ilişkilendireceğiz. body
y window
del KARAR sırasıyla. İlki kodda atanabilir HTML, görüldüğü gibi ve koddaki ikinci JavaScript ilk tarafından çağrılan fonksiyonun içinde ve formatta window.onresize=redimensionar;
olma redimensionar
pencerenin boyutu her değiştiğinde çağrılacak işlev.
Belirli bir zaman aralığından sonra çalıştır
JavaScript için iki kaynağı var ertelenmiş yürütme: setTimeout
, belirli bir zaman aralığından sonra bir işlevi yürütür ve setInterval
her belirli zaman aralığında bir işlevi yürütecek olan. Her iki yöntem de parametre olarak (1) çağrılan işlevi ve (2) milisaniye cinsinden ifade edilen zaman aralığını gerektirir. İşlemlerini durdurmak için, bu işlevler tarafından döndürülen sonucu değişkenlere atayabilir ve bunları argüman olarak iletebilirsiniz. clearTimeout
oa clearInterval
onları tekrar çağırmak istemediğinizde (veya ilk kez çalıştırılmalarını istemediğinizde) setTimeout
o setInterval
sırasıyla.
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
}
|
Önceki örnekte yöntem tanıtılmıştır. alert
bir uyarı işareti göstermeye yarar. Geçmişte yaygın olarak kullanılmasına rağmen şu anda neredeyse koddan yasaklanmıştır. JavaScript web sayfasını bir iletişim kutusuyla kaplamanın ne kadar agresif (müdahaleci) olduğu nedeniyle.
için yazılmış bir programda mikrodenetleyici küçük bir serinin (tabaktaki gibi) Arduino Uno) önceki örnekte olduğu gibi global değişkenlerin kullanılması yaygındır. JavaScript, kod kısa olduğundan ve özellikle kafa karıştırıcı olmadığından, çoğu zaman işlevler geçici olarak uygulandığından ve küresel değişkenlerin kullanımı, az kaynağa sahip sistemlerde kritik olan, bellek kullanımını çok basit ve sezgisel bir şekilde tahmin etmeyi mümkün kıldığından . Yerine, en JavaScript Küresel değişkenlerin kullanımını mümkün olan en aza indirmek yaygındır. çünkü normal bir şekilde çalıştığı için bellek kullanımını aceleye getirmesi gerekmez. işlemci sahip olduğundan çok daha üstün kaynaklara sahip MCU, müdahale etmeden çalışması gereken birçok üçüncü taraf koduyla bir arada bulunması muhtemel olduğundan ve açık bir sistem olduğundan gelecekteki yürütme bağlamı tahmin edilemez (bir programın programı). mikrodenetleyici Small, çalışmaya başladıktan sonra daha fazla kod eklemeden çalışmasını tamamen belirler) ve uygulamaların boyutları, kodun çalışmasını kapsamaması durumunda okumayı zorlaştırabileceğinden, yöntemleri mümkün olduğunca kendi kendine yeten hale getirir.
JavaScript Math nesnesiyle matematiksel işlemler
Daha karmaşık matematiksel hesaplamaların matematiksel işlemleri nesnede gruplandırılmıştır. Math
. Bu nesne doğrudan kullanılır; içerdiği yöntemleri veya özellikleri (sabitleri) kullanmak için nesnenin başlatılmasına gerek yoktur.
Math.abs(n)
N parametresinin mutlak değeriMath.acos(n)
N parametresinin arkkosinüsü (radyan cinsinden sonuç)Math.asin(n)
N parametresinin ark sinüsü (radyan cinsinden sonuç)Math.atan(n)
N parametresinin arktanjantı (radyan cinsinden sonuç)Math.atan2(n,m)
N/m'nin arktanjantı (radyan cinsinden sonuç)Math.ceil(n)
Parametreyi yukarıya doğru en yakın tam sayıya yuvarlayınMath.cos(α)
α parametresinin kosinüsü (radyan cinsinden α)Math.E
e numarası (≃2.718281828459045)Math.exp(n)
e parametresine yükseltildi n: enMath.floor(n)
N parametresini en yakın aşağı tam sayıya yuvarlayınMath.log(n)
N parametresinin doğal logaritması (e tabanı)Math.LN2
2'nin doğal logaritması (e tabanı) (≃0.6931471805599453)Math.LN10
10'nin doğal logaritması (e tabanı) (≃2.302585092994046)Math.LOG2E
e'nin 2 tabanlı logaritması (≃1.4426950408889634)Math.LOG10E
e'nin 10 tabanlı logaritması (≃0.4342944819032518)Math.max(a,b,c,…)
Geçirilen parametreler listesinin en büyük değeriMath.min(a,b,c,…)
Geçirilen parametreler listesinin en küçük değeriMath.PI
Sayı π (≃3.141592653589793)Math.pow(n,m)
Birinci parametre n, ikinci parametre m'ye yükseltildi: nmMath.random()
(Neredeyse) 0.0 ile 1.0 arasında rastgele sayıMath.round(n)
N parametresini en yakın tam sayıya yuvarlayınMath.sin(α)
α parametresinin sinüsü (radyan cinsinden α)Math.sqrt(n)
N parametresinin kareköküMath.SQRT1_2
1/2'nin karekökü (≃0.7071067811865476)Math.SQRT2
2'nin karekökü (≃1.4142135623730951)Math.tan(α)
α parametresinin tanjantı (radyan cinsinden α)
AJAX ile sunucudan veri yükleme
IoT'de saklanan bilgilerin çizilmesi için izlenen yöntem, verilerin zaman zaman sunucudan yüklenmesi ve bunların temsil edildiği grafiğin yeniden çizilmesinden oluşur. Sunucudan veri okumak için teknoloji kullanılır AJAX (Eşzamansız JavaScript ve XML) bir nesne aracılığıyla XMLHttpRequest
de JavaScript. Veri grafiğinin çizilmesi bir nesnenin yeniden kullanılmasıyla yapılır SVG bu zaten kodda var HTML ve yüklenen yeni verilere karşılık gelecek şekilde koordinatları değiştirilen bir çizim içerir.
Bu öneri örneğinde, çizimin güncellenmesinin yanı sıra, web sayfasında her grafik için son ölçülen verinin tarihini ve değerini gösteren bir metin de güncellenmektedir.
Sunucu tarafında bilgilerin yer aldığı bir veritabanı bulunmaktadır. IoT'ye bağlı sensörlerin izlediğini. Bu veritabanı nesne isteği tarafından okunur XMLHttpRequest
kodlanmış bilgilerle yanıt vermek JSON biçimi, kullanılan yöntemin adı formatla bir ilişki olduğunu düşündürse de XML.
Polaridad.es'in ilk eğitiminde Nesnelerin İnterneti veri depolama Nesnelerin İnterneti'ne bağlı cihazların sağladığı bilgilerin sunucu tarafından yönetilmesine yönelik bir altyapı örneğini görebilirsiniz. Bu makale serisinde kaynak olarak bir sunucu kullanılıyor Apache programlama dilini kullanabileceğiniz PHP bir veritabanına erişmek için MySQL o MariaDB. IoT'yi desteklemek için kullanılan sunucularda veritabanları bulmak çok yaygındır. MongoDB (NoSQL) ve programlama dili JavaScript üzerinde node.js Yazılım altyapısı olarak.
Bir sonraki işlev, sunucudaki sensörlerden birinden en son verilerin talep edilmesinden sorumludur. İşlev çağrısında nesne argüman olarak kullanılır JavaScript çizilen verileri destekleyen. Aynı grafik birkaç değeri temsil ediyorsa, örneğin görsel olarak bir korelasyon aramak için, sunucuya aynı anda birden fazla değer döndürmesi için bir istekte bulunulabilir; bu, sunucunun çalışma şekli nedeniyle daha uygun bir yöntemdir. HTTP protokolü.
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);
}
|
Önceki örneğin üçüncü satırında, sunucuya yapılacak sorguda, izlenen yerin adı veya kodu olacak "zone" argümanının iletileceği sorgu hazırlanır. Aynı veri tabanında farklı sensörler (örneğin farklı odalardaki sıcaklığı ölçen termometreler) bir arada bulunabilir. Önceki işleve iletilen parametrenin, yani grafik verilerinin bulunduğu nesnenin, oda adını ("name_suffix") içeren bir özelliği içermesi beklenir.
Önceki kodun 7. ve 14. satırları arasında, nesne XMLHttpRequest
"ajax" değişkeninde saklanır. Nesnenin nasıl oluşturulacağını seçmeden önce arama yaparsınız window
kendi kendine XMLHttpRequest
mevcut değildi (Microsoft Explorer'ın eski sürümlerinde olan bir şeydi ve çok geride olmasına rağmen, nesneyi (daha yerel) sözdizimini kullanarak oluşturmak için alternatiflerin bir örneği olarak hizmet ediyor) Object.create
o new
diğer nesne yönelimli dillerdekine benzer.
Yanıtı anında yönetebilmek için, sunucuya istek yapılmadan önce 15'ten 26'ya kadar olan satırlarda onu işleyen kod hazırlanır.
Yolu sorguyu gerçekleştir HTTP sunucuya oluşur bir bağlantı aç ile open
türü ve sayfayı belirten (isteğe bağlı olarak kullanıcı adı ve şifre), başlıkları hazırla ile protokolün setRequestHeader
y isteği gönder ile send
. Başlık HTTP Content-length
kullanılarak hesaplanan sorgunun uzunluğunu (karakter sayısı) bilmeniz gerekir. length
.
Talep ne zaman AJAX hazır olduğunda, olayla ilişkili işlev yürütülür onreadystatechange
. Önceki örnekte, bir işlev atamak yerine, sunucudan gelen verilerin alımını yönetecek anonim bir işlev anında tanımlanmıştır. Öncelikle 18. satırda isteğin durumunun "tamamlandı" olduğu doğrulanır, bu da değere karşılık gelir. 4
mülkün readyState
durumunun "Tamam" olduğunu HTTP protokolü (kod 200
) mülkten edinilebilecek status
ve gelen veriler şöyle JSON biçimi, mülk danışmanlığı responseType
.
Yanıtın durumunun beklendiği gibi olduğu doğrulandıktan sonra, önceki örneğin 20. satırında sonucu içeren bir nesne oluşturur, metni dönüştürür JSON. Yanıt, döndürülecek bir tarih sağlar; bu, sunucunun gönderdiği sonucun daha önce grafikte temsil edilip edilmediğini görmemize olanak tanır ve bu, 21. satırda doğrulanır. Veriler yeniyse, 23. satırda. Grafiğin yeni bilgilerle yeniden çizilmesinden sorumludur denir.
Bu okuma yöntemini önerirken amaç, verilerin çok sık yenilenmesidir. Sunulan bilgi uzun bir döneme karşılık geliyorsa (bir günün veya bir haftanın sıcaklıkları gibi), mevcut tüm verileri toplayan bir ilk talep uygulanabilir ve ardından örnektekine benzer şekilde bu verileri güncelleyen bir talep uygulanabilir. Dönem muhabiri.
Test için rastgele veriler oluşturun
Tüm sunucu ve istemci altyapısı hazır olduğunda, önceki bölümdeki gibi bir fonksiyon veriyi okumaktan ve onunla grafiği çizmekten sorumlu olacak, ancak Test aşamasında kontrollü bir aralıktaki rastgele sayıları kullanmak daha pratik olabilir yazılan kodun doğru olup olmadığını görmek için Aşağıdaki fonksiyon, son uygulamayı oluştururken veri elde etmek için örnek teşkil edebilir.
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);
}
|
Yukarıdaki örnek, bilgileri bir veritabanından okumak yerine, bunları rastgele oluşturur ve grafiği çizmekten sorumlu fonksiyona iletir. İcat edilen veri, milisaniye cinsinden değer olarak ifade edilen bir tarih, sensör bilgilerinin kaydedildiği an ve maksimum değer ile minimum değer arasındaki izlenen verilerden oluşan bir vektördür.
Bu örnekte bir tarih üretilirken, buluş tarihindeki tarihe göre bir saniyeye (1000 milisaniye) kadar geciktirilebilmektedir. Gibi Math.random()
0.0 ile 1.0 arasında bir sayı üretir, bu sayının 1000 ile çarpılması 0 ile 1000 arasında bir sayı üretir ve bu sayı daha sonra bir tam sayıya dönüştürülür. Aynı şekilde rastgele sayının aralıkla (maksimum eksi minimum) çarpılıp minimumun eklenmesiyle değer elde edilir.
IoT sensörleri grafiğini SVG grafiğiyle çizin
Temsil etmek istediğimiz değerleri (örnekte sıcaklık) ve bunların koordinat şeklinde birlikte ifade edilebilecek zamansal konumlarını nasıl elde edebileceğimizi gördüğümüz için, aşağıdaki örnekte bir yol çizme fonksiyonu gösterilmektedir. bu noktaları birleştiren ve isteğe bağlı olarak üstteki o çizgiyle sınırlandırılan renkli bir alan. Sonuç aşağıdaki resimdeki gibi olacaktır.
Grafiğin yatay ekseni (X) zamanı, dikey ekseni (Y) ise IoT'ye bağlı sensörlerin izlediği değerleri temsil eder. Yatay aralık birkaç saniyedir, çünkü bu öneride grafik, sensörlerin durumu hakkında neredeyse gerçek zamanlı bilgi sağlamak üzere çok sık (örneğin her saniyede) güncellenmektedir.
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
}
|
Önceki kodda iki ilginç yön vardır; ilki, hesaplamaya izin veren hesaplamadır. temsil edilen değer aralığını uyarlayın ve ikincisi mülk inşaatı d
düzendeki noktaların koordinatlarını gösteren (path
).
Temsil edilen değer aralığını uyarlamak için, bunlar minimumdan hareket ettirilir ve görünür büyüklük grafiğin boyutuna karşılık gelecek şekilde ölçeklendirilir.. Zaman durumunda, uzaklık, görüntülemek istediğiniz aralığın en uzun zamandan (geçerli olana en yakın tarih ve saat) (örnekte 20 saniye) çıkarılmasıyla elde edilir. Sıcaklık değerlerinin yer değiştirmesi, alt aralıktan (bir derece) eksi en düşük değere eşittir, böylece aşağıda gösterilen veriler izin verilen en düşük değere en çok benzeyendir ancak izin verilenleri takdir etmemize izin veren bir marj bırakır. . geçmek
Grafiğin yatay koordinatlarını elde etmek için zaman değerlerini çarpan katsayı, grafiğin toplam genişliğinin (örnekte 100 birim) temsil edilen zaman aralığına (örnekte 20 saniye) bölünmesiyle elde edilir. Skaler sıcaklık değerleriyle katsayıyı elde etmek için, temsil edilen aralığın minimum değerin altındaki bir marjdan maksimumun üzerindeki bir marja (her iki durumda da bir derece) kadar gittiği unutulmamalıdır. Bu şekilde dikey ölçek katsayısı, grafiğin yüksekliğinin (örnekte 100 birim) maksimum değer eksi minimum artı üst ve alt kenar boşluğuna bölünmesiyle elde edilir. Bu değerler tamamen negatif sıcaklıklarda gelişebileceğinden, Math.abs()
farkın mutlak değerini kullanmak.
Özellikler d
nesne path
Bir metindeki noktaların koordinatlarının birleştirilmesiyle oluşturulur.. Her koordinat çiftinin önünde bir kod bulunur SVG L
Geçerli konumdan koordinatlarla gösterilen mutlak değere bir çizgi çizen. X ve Y değerleri virgülle ayrılır ve her işlem SVG diğerinden bir boşlukla ayrılır.
Düzeni başlatmak için kodu kullanın M
(mutlak bir koordinata gidin). Kapalı ve dolu grafik durumunda sağ alttan başlarsınız, veri profilini çizen açık grafik durumunda temsil edilen son değerle (en yeni) başlarsınız. Kapalı düzeni tamamlamak için kod kullanılır Z
son nokta olarak, çizginin son noktasıyla aynı X koordinat değerine sahip olanı ve Y koordinatı olarak temsil edilen en küçük değeri ekler.
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
);
}
|
Bu örnekte fonksiyon dibujar_grafico()
sayfa yükleme çağrısı olan , test edilecek başlangıç değerlerini alır (son gerçek zamanlı değeri değil) ve verilerin oluşturulacağı aralığı hazırlar: Yatay olarak 20 saniye (20000 ms) ve sıcaklıkta 15°C. -5°C ile +10°C arası dikey, bir derece üst ve alt kenar boşluğu. İki arama yapın actualizar_grafico()
, ilk geçişte true
grafiğin doldurulmuş bir alanı temsil edecek şekilde kapatılması gerektiğini belirten bir argüman olarak ve ikinci çağrıda geçer false
çizgiyi çizmek için. Her durumda nesne path
değiştirilmiş, ilk durumda dolgulu ve kenarlıksız, ikinci durumda ise belirli bir çizgi kalınlığı olan ve dolgusuz, karşılık gelen görünüme sahip olandır.
İşlevi actualizar_grafico()
bir nesne üzerinde çalışmak SVG aşağıdaki kodu konteyner olarak kullanan HTML. Nesne SVG biri çizgiyi çizmek için, diğeri ise doldurulmuş alanı çizmek için iki yol içerir. Web sayfasını yüklerken öğeden <body>
önceki işlev otomatik olarak çağrılır, dibujar_grafico()
etkinlik sayesinde 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>
|
Kodun 10. satırında HTML yukarıda, stilde 820 piksellik bir genişlik (örnek olarak) ve 150 piksellik bir yükseklik belirlenmiştir (son versiyonda bunun bir sınıf ve bir belge ile yapılması tavsiye edilecektir) CSS). 13 ve 14. satırların nesnenin boyutunu tanımlaması garip görünüyor SVG %100 genişlik ve yükseklik gibi (pencere boyutlarına en iyi uyan, 100×100). Daha önce de belirttiğimiz gibi bunu yapmanın nedeni her zaman bilinen boyutlarla çalışmak ve temsil edilen değerleri ona göre ayarlamaktır. Diğer alternatifler ise her seferinde grafiğin alanını hesaplamak ve ardından değerleri yeniden ayarlamak veya belgenin uyması gereken grafik için sabit boyutları zorlamak olacaktır.
Koda göre boyutları değişen bir grafik tercih etmiş olmak HTMLözelliği dahil etmek gerekir vector-effect
değeri ile non-scaling-stroke
önceki teklifte olduğu gibi, grafiğin görüntülendiği web sayfasında seçilen 1:1 oranlarını korumaması durumunda çizgi kalınlıklarının deforme olmasını önlemek için.
Grafiği "kırpmak" ve yalnızca seçtiğiniz alanı göstermek için şunu kullanın: viewBox
. Bu durumda grafiğin 0,0'dan başlayan (sol üst köşe) ve aşağı ve sağa doğru 100x100 ölçüsündeki kısmını görmeyi seçtik. Çizimin negatif değerli veya 100'den büyük koordinatlarda yer alan kısmı, nesnede bulunsa dahi web sayfasında görüntülenmeyecektir. SVG
SVG çizimine yeni öğeler ekleme
Önceki örnekte fonksiyon actualizar_grafico()
bir düzen kullan SVG sahipliğin değiştirildiği yer d
Koordinat zincirini ifade eden şey budur. Alternatif, her yeniden çizildiğinde nesnenin tamamını oluşturmak olabilir. İlk seçeneğin avantajı grafik görünümünün (kalınlık veya renk gibi) kodda tanımlanmış olmasıdır. HTMLsınırlaması nesnelerin önceden oluşturulmuş olması gerektiğidir.
SVG nesneleri oluşturmak için şunu kullanın: createElementNS()
dahil edilmesini sağlayan ad alanı. Aşağıdaki örnekte yeni bir metin nesnesi yaratılmıştır (text
) ve bir öğeyle ilişkilidir SVG kodda zaten mevcut olan HTML web sitesinin. Yeni eleman oluşturulduktan sonra özellikleri şu şekilde atanır: setAttribute()
ve eklenir SVG ile 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]);
|
Çizim öğelerinin oranını değiştirin
Bir önceki bölümdeki örnekte yer alan fonksiyonla etiketlemeyi denediyseniz, web sayfasındaki nesnenin oranı (orantısı) bozulduğunda metnin deforme göründüğünü görmüşsünüzdür.width
y height
kodun HTML) temsil edilen alanınkine eşit değildir (viewBox
). Orantıyı ayarlamak için nesnenin ölçülerini bilmek gerekir. SVG bunun için nesnenin veya kabın stiline başvurabilirsiniz HTMLeğer nesne SVG bu mülkü devredin. Sahiplik atama transform
nesnelere SVG Orana bağlı olarak deformasyon ölçeklendirme işlemi uygulanarak düzeltilebilir. scale()
burada X'teki katsayı Y'dekinden farklıdır.
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 özellikleri de destekleyen yeni bir kompozit eleman oluşturacak şekilde birçok nesnenin gruplandırılmasına olanak tanır, basit nesneler gibi. Aynı dönüşümü her nesneyi ayrı ayrı uygulamak yerine bir dizi nesneye aynı anda uygulamak için bunları bu kaynağa göre gruplandırabilir ve tek bir özellik uygulayabilirsiniz. transform
hepsine.
Bahsederken açıklandığı gibi SVG formatı, bir grubun elemanları etiketlerin içine alınır <g>
y </g>
. Şuradan eklemek için: JavaScript bir gruba ait öğeler SVG Önceki örnekte görüldüğü gibi kullanılır, appendChild()
yeni nesne tanımlandıktan sonra.
Dönüşümleri uygularken bir orijin oluşturmak için bu özellik nesneler üzerinde kullanılabilir. SVG transform-origin
Değeri dönüşümün başladığı noktanın X ve Y koordinatlarıdır. Dönüşümün orijini için bir değer açıkça belirtilmemişse (web tarayıcısında), koordinatların merkezi kullanılır. Ne yazık ki, bu yazının yazıldığı sırada, dönüşümlerin davranışını varsayılan kaynak dışında bir kaynak kullanarak belirlemek, tarayıcılar arasında homojen değildir ve dikkatli kullanılmalıdır.
Ölçek dönüşümüyle birlikte scale
Rotasyon gibi başkaları da var rotation
ve onunla birlikte hareket translate
, bir teklif grafik temsiline alternatif: Yeni koordinatlar elde etmek yerine bunları kendi uzaylarında temsil edebilir ve grafiği temsil etmek istediğiniz formata uyacak şekilde dönüştürebilirsiniz.
Grafiğe referanslar ekleyin
Artık grafiğin ana kısmı, değerlerin profil ve dolu alanla çizilmesiyle çözüldüğüne göre, okunmasına yardımcı olacak referanslarla tamamlanabilir. Örnek olarak, istenen değerin yanı sıra kabul edilebilir maksimum ve minimum değerleri işaretleyen bazı yatay referanslar (çizgiler) çizerek başlayalım. Açıklandığı gibi, nesneleri listeye eklemeyi seçebilirsiniz. SVG doğrudan JavaScript veya bunları manuel olarak koda ekleyin HTML ve bunları daha sonra şununla değiştirin: 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();
|
Bu yatay referansları temsil ettikleri değeri açıklayan bir metinle etiketlemek mantıklı görünüyor. Metni vurgulamak için arka plandan ve grafikten öne çıkacak dikdörtgenler kullanabilirsiniz. Deformasyonu telafi etmek için metinlerin ölçeklendirilmesi gerekeceğinden, bunların tümü ölçeğin uygulanacağı bir nesne halinde gruplandırılabilir; Bunu bu şekilde yapmanın temel avantajı, grafik kabı (tarayıcı penceresi) yeniden boyutlandırıldığında ve ölçeğin düzelttiği oranı değiştirdiğinde bunları tek bir işlemle değiştirebilmektir.
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();
|
Yukarıdaki örnek kodda birkaç ilginç yön vardır. Her şeyden önce, örneği programlamadan gelen kullanıcılar için daha okunaklı hale getirmek için sabitlerin (global değişkenler) kullanıldığını yorumlayın. mikrodenetleyiciler en C içinde C + +. Daha sonra görüleceği gibi, onu programlamanın en uygun yolu JavaScript Bir üretim sisteminde bu değerleri içerecek nesnelerin ve bu örnekteki referansları veya genel olarak grafiği yönetecek yöntemlerin kullanılması olacaktır.
Öte yandan, daha genel bir kod geliştirilerek, metni ayarlamak için grafiğin oranını düzelten farklı katsayıları hesaplayan ayrı işlevler geliştirilmiştir. proporcion_grafico()
, aralıklarına bağlı olarak değerlerin ölçeği escala()
ve referanslardaki ölçümler gibi mutlak değeri bilinen ölçümler için bir düzeltme faktörü medida_grafico()
.
Bu kodun okunması, grafikleri gerçek zamanlı olarak çizen ve çeşitli grafik bağlamlarında (en azından çeşitli boyut ve oranlarda) sunulmak üzere esnek olması gereken bunun gibi bir uygulamanın çalıştığı bağlamın netleştirilmesine yardımcı olacaktır. Her şeyden önce nesnelerin oluşturulması gerekir. SVG, kodda "manuel olarak" HTML, kod aracılığıyla JavaScript ve her durumda, bu nesnelere yapılan referanslar, bunları manipüle etmek için daha sonra elde edilmelidir. JavaScript böylece yeni grafikler çizilebilir ve önceden çizilmiş bir grafiğin temsili, sunulduğu ortamdaki bir değişikliğe uyarlanabilir.
Bir grafiğin kolayca yorumlanmasına yardımcı olabilecek diğer bir referans, belirli değerleri temsil eden noktalardır (doğrunun düğümleri). Tek bir büyüklüğü temsil ettiğimiz bu örnekte, bir sembolün seçimi kritik değildir, ancak korelasyon aramak için birkaç farklı değer üst üste bindirilirse, renk gibi diğer kaynakları kullanmanın yanı sıra ayırt etmek ilginç olabilir. , farklı semboller çizerek. Çizgi düğümü için kullanılan grafiklerin boyutları ve oranları, örneğin metinlerde olduğu gibi değiştirilmelidir, böylece boyutları mutlak olur ve içerdiği kutunun oranları grafiği değiştirse bile oranları korunur.
Önceki örnekte, çizimin oranını yeniden ölçeklendirmek ve düzeltmek için farklı katsayıların nasıl hesaplanacağını zaten gördük; Grafiğin düğümlerinin veya köşelerinin sembollerinin yönetiminin nasıl uygulanacağına ilişkin olası bir çözüm, nesnelerin saklanması olabilir. SVG bir vektöre dönüştürün ve grafik yeni bir değer okunarak güncellendiğinde veya kapsayıcı yeniden boyutlandırılarak yeniden çizildiğinde konumunu değiştirin. İlk durumda konumunun değiştirilmesi, ikinci durumda ise mülkle olan oranının değiştirilmesi gerekecektir. transform
ve değeri scale
. Aşağıdaki kod işlevin bir modifikasyonudur actualizar_grafico()
grafiğin köşe sembollerinin yeniden konumlandırılmasını dahil etmek.
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);
}
}
|
Fonksiyonda yapılan değişiklikler actualizar_grafico()
yeni işlevi almak için actualizar_grafico_puntos()
Bunlar önceki örneğin kodunda vurgulananlardır. İlk olarak 5. satırda nesnelerin bir vektörünü alıyoruz SVG parametre olarak. Bu vektör, grafiğin yeni düğümlerinde yeniden konumlandırılması gereken sembolleri içerecektir.
39. ve 40. satırlarda merkezin yeni koordinatları atanır, cx
y cy
, temsil edilen değerlerden olanlara. Sembol merkeze dayalı değilse muhtemelen bir uzaklık eklemek gerekli olacaktır. cx
genişliğin yarısı kadar ve cy
bunları tam olarak grafik düğümünde yeniden konumlandırmak için yüksekliğin yarısı kadar.
57'den 61'e kadar olan satırlarda, sol kenar tarafından kesildiği için çizilmeyen koordinatlara karşılık gelen noktalar grafiğin dışında yeniden konumlandırılır. Koordinatı cy
sıfıra ve buna cx
grafiğin sol kısmı gibi pencere tarafından kesildiğinde gösterilmemesi için herhangi bir negatif sayıya (noktadan büyük) SVG.
Grafiği JavaScript ile bir nesneden yönetin
Şu ana kadar açıklanan tüm işlemler, grafiğin yeni sürümlerine daha tipik bir stille yönetmek için bir nesneye entegre edilebilir. JavaScript. Bu uygulama alternatifi, farklı değerlere sahip birçok grafiğin aynı web sayfasına dahil edilmesini basitleştirme avantajına sahiptir.
Uygulamayı tartışmadan önce, nesneler oluşturmanın en yaygın yollarını gözden geçirelim. JavaScript ve IoT sensör grafiklerinin çizilmesine yönelik öneriyi etkileyen fonksiyonların bazı özellikleri.
Nesneleri yaratmanın yeni yolunun zaten açıklanmıştı. JavaScript (versiyon 5'ten beri mevcut) ECMAScript) kullanmaktan oluşur Object.create
"klasik" yerine kullanılmaya alışılması gereken new
Tabii ki hala doğru çalışıyor, ancak amacı daha çok dillerin stilini sınıf tabanlı nesnelerle simüle etmek olsa da (JavaScript (nesnelerin oluşturulmasını prototiplere dayandırır) çalışan bir alternatiften ziyade.
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();
}
|
Önceki kod, nesneleri oluşturma arasındaki farkları hatırlamanıza olanak tanır. Object.create
o con new
. Aynı zamanda nesnenin yaratıldığı işlevin de vurgulanmasına hizmet eder. new
Kodun herhangi bir yerinde olabilir, nesnenin başlatılabilmesi için nesnenin zaten mevcut olması gerekir. Object.create
(ES5_Object nesnesi bir işlev değildir).
3. ve 4. satırlarda, nesneyi oluşturan fonksiyondaki özelliklere varsayılan bir değer ayarlamak için new
, her özellik karşılık gelen bağımsız değişkenin değerine atanır veya (||
), eğer hiçbir argüman aktarılmadıysa, yani bunlar tanımsızsa (undefined
), bu durum şu şekilde değerlendirilmektedir: false
varsayılan değer atanır.
Bir fonksiyonun yürütüldüğü bağlam JavaScript akılda tutulması gereken ve başkalarıyla çalıştıktan sonra bu programlama dilini kullanırken kafa karıştırıcı olabilecek iki konuyu gündeme getiriyor; C o C + +, bizim durumumuzda. Bağlam, fonksiyonun kapsamında tanımlanan değişkenleri (ve global olanları) içerir; bu arada, ilginç bir kavramı gündeme getirir, tüm bir programlama stilini oluşturan "kapanışlar". JavaScript. Bununla birlikte, beklenebilir this
Onu tanımlayan kod içinde kullanıldığında nesneye atıfta bulunan, tanımlandığı yürütme bağlamı korunur, ancak kullandığı bağlam, işlevin çağrıldığı bağlamdır. Bu davranış çoğu durumda şeffaftır ancak kafa karıştırıcı olabileceği iki durum vardır: başka bir işlevin içinde tanımlanan bir işlev ve bir nesne olayından çağrılan bir yöntem. 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
*/
|
Önceki kodu çalıştırırken, sondaki yorumlu metin konsolda görüntülenir. İşaretli iki çizgi kafa karıştırıcı olabilecek davranışı yansıtır: işlev yürütme bağlamı probar_dentro()
değil probar()
beklenebileceği gibi, ancak window
, aynı adı taşıyan özellikleri değil, genel değişkenleri gösterir. Bu davranışı istemiyorsanız, en üst düzey fonksiyonda bir değişken oluşturup onu atamanız yeterlidir. this
, aşağıdaki kodda olduğu gibi.
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
*/
|
Bir olaydan bir yöntem çağrıldığında yürütme içeriğini kontrol etmek için window
örneğin tarayıcı penceresini yeniden boyutlandırmak, başka bir özelliktir. JavaScript: "işlev fabrikalarını", yani başka işlevler üreten işlevleri programlama ve bunları geri döndürme olanağı 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
|
Yukarıdaki örnek kodda yöntem llamar()
de los objeler Contexto
İşi yapmaz ancak işle ilgilenen anonim bir işlev döndürür. Her şeyin beklendiği gibi çalıştığını doğrulamak için işlevin konsolda görüntülediği özellikle aynı adı taşıyan bir genel değişken vardır; Bağlam doğruysa, genel değişkenin değeri değil, özelliğin değeri görüntülenecektir.
JavaScript Cümle sonlarında atladığımız noktalı virgül işaretlerini düzeltmeye çalışın. Bu, rahat bir yazı stili sağlar ancak dikkatli kullanılması gereken iki ucu keskin bir kılıçtır. Çoğu durumda, bunun birkaç satır kaplayan ifadelerde yarattığı istenmeyen etkilerden kaçınmak için parantez kullanabilir veya ifadenin önüne geçebilirsiniz. JavaScript kodu yorumlayacak; Bu nedenle örneğin 8. satırı şunları içerir: function
arka bölgesindeki return
Başka bir satır kullansaydım anlamı çok farklı olurdu. Bana göre en okunabilir çözüm aşağıdaki versiyondaki gibi bir ara (vazgeçilebilir) değişken kullanmaktır; Açıkçası, davranış anlaşıldıktan sonra karar programcıya karşılık gelir.
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);
|
Bir ifadeyi işlev olarak değerlendirmek, yani işlevin döndürdüğü değeri değil, işlevi döndürmekle aynı anlamda; son örneğin 21. satırında (önceki örneğin 19. satırındaydı) ile durur clearInterval
ile çağrılan fonksiyon setInterval
. 30 saniye süreyle etki edebilmesi için durdurma ertelenir. setTimeout
, bu da ilk argüman olarak bir fonksiyona ihtiyaç duyar; yürütmeyi parametre olarak teslim etmek clearInterval
periyodik çağrıyı içeren değişkenle (işlevle değil) clearInterval
), son satırdaki anonim işlevin ne için yaratıldığıdır.
İşlev tanımını entegre eden kodun daha kompakt şekilde yazılması (21. satırdaki gibi) veya bana göre daha okunabilir bir yardımcı değişken kullanılması (19. ve 20. satırdaki gibi) arasındaki seçim, performans açısından çok az farklılık gösterir ve daha fazla stile ve okunabilirliğe bağlıdır. Bakım.
Kodu test etmek için, sunucuda veri bulundurmadan önce, istenilen aralıkta rastgele değerler üreteci kullanabilir veya istenen koşullar altında çalışmayı simüle eden kontrollü değerlere sahip tablolar hazırlayabilirsiniz. Aşağıdaki örnekte tüm aralıkta basit bir veri oluşturucu kullanılmaktadır, bu nedenle biraz abartılı görünmektedirler.
Test etmek için şunları yapabilirsiniz: örneğin tam kodunu indirin yazılmış bir web sayfası tarafından oluşturulmuş HTML, stil CSS ve kod JavaScript. İkincisi en alakalı olanıdır, çünkü diğer bileşenler yalnızca minimum düzeyde destek sağlar, çok basitleştirilmiştir ve ilgili bölümlerdeki makalelerde çok daha fazla geliştirilmiştir.
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);
}
|
Yorum Ekle