जावास्क्रिप्ट के साथ IoT से जुड़े सेंसर से डेटा के एसवीजी ग्राफिक्स बनाएं और संशोधित करें
ड्राइंग पर लेखों की श्रृंखला के इस अंतिम भाग में इंटरनेट ऑफ़ थिंग्स से जुड़े सेंसरों के डेटा वाले ग्राफ़िक्स, यह इस बारे में बात करने का समय है कि इसे कैसे उत्पन्न किया जाए या संशोधित किया जाए जावास्क्रिप्ट प्रारूप में चित्र एसवीजी और कुछ तत्व एचटीएमएल जो एक कंटेनर के रूप में कार्य करता है या जो ग्राफ़िक्स के लिए पूरक जानकारी प्रस्तुत करता है।
इस ट्यूटोरियल के लक्षित उपयोगकर्ताओं को एक इलेक्ट्रॉनिक्स और कंप्यूटर प्रोग्रामिंग प्रोफ़ाइल बनानी है। माइक्रोकंट्रोलर्स, हो सकता है वे परिचित न हों एचटीएमएल, सीएसएस o एसवीजी; इस कारण से, पिछली किश्तों में भाषा या संबंधित तकनीक का संक्षिप्त परिचय दिया गया था। इस अंतिम भाग में दृष्टिकोण थोड़ा अलग है, क्योंकि पाठक निश्चित रूप से जानते हैं कि प्रोग्राम कैसे करना है, यह संभव है कि भाषा का उपयोग किया जाए सी + + कैसे है कि जावास्क्रिप्ट, के साथ बुनियादी वाक्यविन्यास साझा करता है C और इसका उपयोग अधिकांश बुनियादी प्रोग्रामिंग अवधारणाओं को छोड़ने के लिए एक संदर्भ के रूप में किया जा सकता है और इस प्रकार उन अंतरों और विशिष्ट उपयोग पर ध्यान केंद्रित किया जा सकता है जो IoT में सेंसर ग्राफिक्स बनाने में हमारी रुचि रखते हैं।
नाम पहले अंतर का संकेत देता है: जावास्क्रिप्ट यह एक प्रोग्रामिंग भाषा है लिपि (हाइफ़न) और इस प्रकार, यह है व्याख्या की, इसे संकलित करने की कोई आवश्यकता नहीं है; वह संदर्भ जिसमें लिपि (उदाहरण के लिए, एक वेब ब्राउज़र) ऑर्डर को पढ़ेगा, अनुवाद करेगा और निष्पादित करेगा। सटीक होने के लिए, ज्यादातर मामलों में एक है रनटाइम संकलन (JIT), लेकिन कोड लेखन प्रक्रिया के लिए जावास्क्रिप्ट इसका हम पर कोई प्रभाव नहीं पड़ता, हम बस कोड लिखते हैं और यह काम कर सकता है।
नाम में पहला भ्रम भी है: जावास्क्रिप्ट से रत्ती भर भी रिश्ता नहीं है जावा. प्रारंभ में, जब इसे विकसित किया गया था नेटस्केप इसके ब्राउज़र के लिए, इसे पहले मोचा और फिर कम भ्रमित करने वाला लाइवस्क्रिप्ट कहा जाता था। ब्राउज़रों में इसके सफल कार्यान्वयन के बाद, और उन्हें पार करने के बाद, इसे मानकीकृत किया गया एकमा स्क्रिप्ट (वहाँ ईसीएमए-262, संस्करण 6 लेखन के समय) इसे लागू करने वाले ब्राउज़र के संबंध में तटस्थ होना। वर्तमान में भी एक मानक है आईएसओ संस्करण 5, 2011 से (ISO / IEC 16262: 2011 लेख लिखने के समय)
जावास्क्रिप्ट में वेरिएबल, बुनियादी डेटा प्रकार और ऑब्जेक्ट
जो होता है उसके विपरीत, उदाहरण के लिए, में सी + +, en जावास्क्रिप्ट वैरिएबल घोषित करते समय डेटा प्रकार शामिल नहीं होता है और किसी वेरिएबल से जुड़ा प्रकार भी निश्चित नहीं है, प्रोग्राम के निष्पादन के दौरान एक अलग प्रकार का मान निर्दिष्ट करना संभव है।
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 |
पिछले उदाहरण में, वेरिएबल "चीज़" घोषित किया गया है (डेटा प्रकार को इंगित किए बिना) फिर एक अलग प्रकार का डेटा असाइन किया गया है और इसके साथ परामर्श किया गया है typeof
वह प्रकार जावास्क्रिप्ट जिसकी उन्होंने व्याख्या की है. कोड को डीबग करने के लिए आप इसे वेब ब्राउज़र के इंस्पेक्टर कंसोल में लिख सकते हैं (जो वेब की प्रस्तुति को प्रभावित नहीं करेगा) console.log()
.
डेटा को एक विशिष्ट प्रकार में, विशेष रूप से टेक्स्ट को संख्यात्मक में परिवर्तित करने के लिए, आप जैसे फ़ंक्शंस का उपयोग कर सकते हैं parseInt()
o parseFloat()
जो क्रमशः पूर्णांकों या फ़्लोटिंग पॉइंट संख्याओं में परिवर्तित हो जाते हैं। इसके विपरीत रूपांतरण किया जा सकता है String()
, हालाँकि यह आवश्यक होने की संभावना नहीं है क्योंकि स्वचालित रूपांतरण आमतौर पर पर्याप्त होता है। साथ parseFloat()
उदाहरण के लिए, आप किसी वेब पेज प्रॉपर्टी का मूल्य प्राप्त कर सकते हैं, जैसे किसी ऑब्जेक्ट की चौड़ाई या ऊंचाई, जिसमें इकाइयां शामिल हैं; इस प्रकार, अभिव्यक्ति parseFloat("50px");
परिणामस्वरूप, 50, एक संख्यात्मक मान लौटाया जाएगा।
En जावास्क्रिप्ट दोहरे और एकल उद्धरण चिह्नों के बीच कोई अंतर नहीं है; दोनों मामलों में डेटा प्रकार है string
, और उनमें से प्रत्येक एस्केप कोड की आवश्यकता के बिना दूसरे को शामिल कर सकता है।
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 |
पिछले उदाहरण में यह देखा जा सकता है कि एक वेरिएबल, जब इसे घोषित किया गया है (मौजूद है) लेकिन कोई मान निर्दिष्ट नहीं किया गया है, इसमें एक अपरिभाषित डेटा प्रकार होता है (undefined
). एक अनअसाइन्ड ऑब्जेक्ट का मूल्य होता है null
; अर्थात्, वस्तु मौजूद है, लेकिन बिना मूल्य के; एक वेरिएबल जो इसे संदर्भित करता है, उसमें कोई नहीं होगा typeof
undefined
लेकिन object
. कोई वस्तु खाली भी हो सकती है, यानी शून्य नहीं लेकिन उसमें कोई गुण नहीं है।
पैरा किसी वस्तु को परिभाषित करें जावास्क्रिप्ट ब्रेसिज़ में संलग्न हैं ({
y }
) गुण या विधियाँ, कोलन चिह्न द्वारा अलग किए गए (:
) संपत्ति का नाम संपत्ति का मूल्य और अल्पविराम द्वारा (,
) विभिन्न गुण। आप किसी वस्तु को व्यक्त करने के इस तरीके के बारे में अधिक जानकारी इस लेख में पा सकते हैं JSON प्रारूप.
यद्यपि आप वाक्यविन्यास का उपयोग कर सकते हैं जो आपको अन्यथा सोचने पर मजबूर कर सकता है, en जावास्क्रिप्ट यहां कोई कक्षाएं नहीं बल्कि प्रोटोटाइप हैंअर्थात्, किसी वस्तु के गुणों और विधियों को प्राप्त करने के लिए, एक अन्य वस्तु (प्रोटोटाइप) बनाई जाती है जिसे अन्य (बच्चे) संदर्भ के रूप में उपयोग करते हैं। की शैली के सबसे करीब वाक्यविन्यास जावास्क्रिप्ट एक प्रोटोटाइप का उपयोग करना है Object.create
हालाँकि इसका उपयोग भी संभव है (और कभी-कभी उपयोगी भी)। new
जैसा कि अन्य वस्तु-उन्मुख भाषाओं में होता है।
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)); |
पैरा यदि एक वस्तु दूसरी वस्तु का उदाहरण है तो क्वेरी करें, यदि आप इसे एक प्रोटोटाइप के रूप में उपयोग करते हैं, यदि आपको इसके गुण विरासत में मिलते हैं, तो संक्षेप में, आप इसका उपयोग कर सकते हैं instanceof
(के साथ बनाया गया new
) या isPrototypeOf
(के साथ बनाया गया Object.create
) जो तब सत्य का मूल्यांकन करेगा जब ऑब्जेक्ट प्रोटोटाइप का उपयोग करता है और गलत जब ऐसा नहीं करता है।
एक बार जब किसी ऑब्जेक्ट को प्रोटोटाइप के रूप में दूसरे का उपयोग करके बनाया गया है, यानी, एक बार किसी ऑब्जेक्ट को इंस्टेंटियेट किया गया है, तो यह हो सकता है नए गुण जोड़ें या प्रोटोटाइप गुणों को ओवरराइड करें जैसे डॉट सिंटैक्स का उपयोग करना gato.peso=2.5
.
La में सरणियाँ जावास्क्रिप्ट वे उन लोगों से भिन्न हैं जिनके बारे में आप संभवतः जानते हैं C. आरंभ करने के लिए, उन्हें उनकी लंबाई इंगित करने की आवश्यकता के बिना, केवल वर्गाकार कोष्ठकों को खोलने और बंद करने के संकेतों के साथ घोषित किया जाता है ([
y ]
), घटक विषम हो सकते हैं (एक ही सरणी में विभिन्न डेटा प्रकार) और नए तत्वों को एक सीमा तक सीमित किए बिना जोड़ा जा सकता है। के आव्यूह जावास्क्रिप्ट वास्तव में जिन तत्वों की सूचियाँ (संग्रह) हैं संख्यात्मक सूचकांक या नाम से संदर्भित. एक सरणी में एक साथ संख्यात्मक सूचकांक और तत्व नाम हो सकते हैं, लेकिन दूसरे प्रकार का फायदा उठाने के लिए ऑब्जेक्ट (गुण) का उपयोग करना आम है।
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 |
जैसा कि पिछले उदाहरण में देखा जा सकता है, यह जानने के लिए कि क्या कोई वेरिएबल किसी सरणी के उदाहरण से मेल खाता है (यह एक सरणी ऑब्जेक्ट है) आप इसका उपयोग कर सकते हैं instanceof
, जैसा कि पहले से ही सामान्य वस्तुओं के साथ या, हाल के संस्करणों में उपयोग किया जा चुका है जावास्क्रिप्ट आप इसका सहारा ले सकते हैं Array.isArray()
सरणी के तत्वों तक पहुँचने के लिए आप इसके सूचकांक का उपयोग कर सकते हैं (matriz[7]
) या वर्गाकार कोष्ठक में नाम के साथ संपत्ति के नाम से (matriz["nombre"]
) या ऑब्जेक्ट के लिए सामान्य डॉट सिंटैक्स के साथ (matriz.nombre
). चूँकि नाम एक टेक्स्ट स्ट्रिंग है, इसलिए इसे बनाने के लिए चर सहित एक अभिव्यक्ति का उपयोग किया जा सकता है। गुणों के साथ एक सरणी के माध्यम से लूप करने के लिए, प्रारूप के साथ एक लूप का उपयोग किया जा सकता है 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 */ |
इलाज करना हमारे उद्देश्य के लिए दिलचस्प है उदेश्य Date
, जिसके साथ दिनांक और समय का प्रतिनिधित्व और प्रबंधन करना है जावास्क्रिप्ट. ऑब्जेक्ट को डेटा के बिना इंस्टेंट किया जा सकता है, इसलिए इसमें वर्तमान दिनांक और समय लगेगा, या इसे 1 जनवरी, 1970 से मिलीसेकंड में मान के रूप में दिनांक इंगित करके बनाया जा सकता है (जैसे कि यूनिक्स समय या पॉज़िक्स समय लेकिन सेकंड के बजाय मिलीसेकंड में व्यक्त किया जाता है) या वर्ष, माह, दिन, घंटे के अलग-अलग मान निर्दिष्ट करना...
ऑब्जेक्ट में पूरी श्रृंखला शामिल है दिनांक और समय पूछने या निर्धारित करने की विधियाँ:
-
now()
1 जनवरी 1970 से मिलीसेकंड में व्यक्त वर्तमान दिनांक और समय लौटाता है -
getTime()
|setTime()
1 जनवरी 1970 से क्रमशः मिलीसेकंड में समय मान प्राप्त करता है या बदलता है। उपयोग करनाvalueOf()
, जो अधिकांश वस्तुओं में मौजूद एक विधि है, संबंधित दिनांक वस्तु का मूल्य भी प्राप्त किया जाता है, जैसेgetTime()
साथ यूनिक्स समय या पॉज़िक्स समय एमएस में व्यक्त किया गया -
getMilliseconds()
|setMilliseconds()
ऑब्जेक्ट के भिन्नात्मक मिलीसेकंड भाग को क्वेरी करने या सेट करने के लिए उपयोग किया जाता हैDate
जिस पर इसे क्रियान्वित किया जाता है। यदि परामर्श किया जाए, तो प्राप्त मूल्य 0 और 999 के बीच है, लेकिन बड़े मान निर्दिष्ट किए जा सकते हैं जो कुल दिनांक और समय में जमा हो जाएंगे, इसलिए, बाकी प्राप्त विधियों की तरह, यह ऑब्जेक्ट के मूल्य को बढ़ाने का काम करता हैDate
(या यदि नकारात्मक मानों का उपयोग किया जाता है तो इसे कम करें)। -
getSeconds()
|setSeconds()
ऑब्जेक्ट के सेकंड का मान क्रमशः लौटाता या बदलता हैDate
. -
getMinutes()
|setMinutes()
वस्तु के मिनट्स को परामर्श देने या निर्धारित करने के लिए उपयोग किया जाता हैDate
. -
getHours()
|setHours()
आपको ऑब्जेक्ट के घंटों (0 से 23 तक) से परामर्श करने या संशोधित करने की अनुमति देता हैDate
. -
getDay()
दिनांक के लिए सप्ताह का दिन लौटाता है, जिसे 0 से 6 (रविवार से शनिवार) के मान के रूप में व्यक्त किया जाता है। -
getDate()
|setDate()
ऑब्जेक्ट के महीने का दिन लौटाता है या बदलता हैDate
जिस पर इसे लगाया जाता है. -
getMonth()
|setMonth()
वस्तु की माह संख्या से परामर्श या संशोधन करने के लिए उपयोग किया जाता हैDate
. -
getFullYear()
|setFullYear()
दिनांक और समय वाले ऑब्जेक्ट पर वर्ष का मान क्वेरी या सेट करता है।
के पिछले तरीके Date
एक संस्करण शामिल करें यूटीसी मध्यवर्ती गणना किए बिना सार्वभौमिक समय के साथ सीधे काम करने में सक्षम होना। उस अर्थ में, उदाहरण के लिए, getHours()
एक संस्करण है getUTCHours()
o getMilliseconds()
एक विकल्प getUTCMilliseconds()
आधिकारिक (कानूनी) या सार्वभौमिक समय के साथ वैकल्पिक रूप से काम करना। साथ getTimezoneOffset()
आप सार्वभौमिक समय और स्थानीय आधिकारिक समय के बीच मौजूद अंतर को जान सकते हैं।
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; |
जावास्क्रिप्ट कार्य
यदि आप इसे पढ़ रहे हैं तो आप निश्चित रूप से जानते हैं कि प्रोग्राम कैसे किया जाता है। माइक्रोकंट्रोलर्स en C ओ एन सी + + और फ़ंक्शन की अवधारणा को जानें। हालाँकि मूल विचार वही है जावास्क्रिप्ट इन्हें परिभाषित और उपयोग करने का तरीका थोड़ा अलग है। आरंभ करने के लिए, यह पहले ही कहा जा चुका है, जावास्क्रिप्ट यह स्पष्ट रूप से डेटा प्रकारों का उपयोग नहीं करता है इसलिए फ़ंक्शन को परिभाषित करते समय आपको इसे इंगित करने की आवश्यकता नहीं है. अनुकरण करना, किसी फ़ंक्शन के लिए नाम होना अनिवार्य नहीं है, वे गुमनाम हो सकते हैं. उन्हें लागू करने के लिए उन्हें एक वेरिएबल के साथ जोड़ा जा सकता है लेकिन यह आवश्यक भी नहीं हो सकता है क्योंकि, कभी-कभी, उन्हें तुरंत लागू करना उपयोगी होता है, जिसके लिए फ़ंक्शन की परिभाषा के बाद कोष्ठक और पैरामीटर जोड़े जाते हैं।
किसी फ़ंक्शन को परिभाषित करने के लिए, उपसर्ग function
, यदि लागू हो, तो कोष्ठक में नाम, तर्क (फ़ंक्शन में दिए गए पैरामीटर) और वह कोड लिखें जो फ़ंक्शन को ब्रेसिज़ में लागू करने पर निष्पादित किया जाएगा।
1 2 3 4 5 | function doble(numero) { var resultado=numero*2; return resultado; } |
निश्चित रूप से, पिछले उदाहरण में "परिणाम" चर की बिल्कुल भी आवश्यकता नहीं थी, लेकिन यह याद रखने का एक अच्छा बहाना है परिवर्तनशील दायरा, जो आपकी अपेक्षा के अनुरूप काम करता है: "परिणाम" वेरिएबल केवल "डबल" फ़ंक्शन के भीतर मौजूद है। में जावास्क्रिप्ट भी प्रयोग किया जा सकता है let
के बजाय var
, एक वेरिएबल को कोड ब्लॉक संदर्भ में स्कोप करने के लिए (घुंघराले ब्रेसिज़ में संलग्न, {
y }
)
पिछले अनुभाग में वस्तुओं के बारे में बात करते समय, कुछ मौलिक कमी थी: गुणों को परिभाषित किया गया है लेकिन तरीकों को परिभाषित नहीं किया गया है। आशा के अनुसार, ऑब्जेक्ट विधियाँ फ़ंक्शन हैं, उनका कोई नाम नहीं है और ऑब्जेक्ट परिभाषा द्वारा निर्दिष्ट (संपत्ति) नाम से उपयोग (आह्वान) किया जाता है।
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”); } } |
पिछले उदाहरण में, पहले से ही एक विधि है, "view_temperature", जो कंसोल के माध्यम से "current_temperature" संपत्ति का मूल्य प्रदर्शित करती है। यह बहुत उपयोगी नहीं है, लेकिन यह इस बात का अधिक संपूर्ण विचार देता है कि किसी वस्तु की परिभाषा कैसी है जावास्क्रिप्ट.
किसी ऑब्जेक्ट (फ़ंक्शन) के तरीकों को उसके गुणों तक पहुँचने के लिए, उपयोग करें this
, जैसा कि लाइन 11 पर पिछले उदाहरण में, "current_temperature" प्रॉपर्टी का उपयोग करते समय किया गया था।
जावास्क्रिप्ट के साथ दस्तावेज़ ऑब्जेक्ट मॉडल (डीओएम) तक पहुंचें
से जावास्क्रिप्ट आपके पास उस वेब पेज की सामग्री तक पहुंच है जिस पर वह चलता है, साथ ही ब्राउज़र के कुछ पहलुओं तक भी जो उस पेज को प्रदर्शित करता है, हालांकि सिस्टम संसाधनों तक नहीं। डेटा संरचना जो एक्सेस किए गए गुणों और विधियों का समर्थन करती है जावास्क्रिप्ट विंडो ऑब्जेक्ट का हिस्सा, विशेष रूप से, वस्तु की सामग्री (दस्तावेज़ एचटीएमएल) वस्तु से मेल खाता है document
. हालाँकि इसे कभी-कभी स्पष्टता के लिए उपयोग किया जाता है, लेकिन तरीकों या गुणों को संदर्भित करने के लिए विंडो से पहले होना आवश्यक नहीं है, उदाहरण के लिए, इसका उपयोग करना पर्याप्त है document
, जैसे कि रूट ऑब्जेक्ट का नाम लिखने की कोई आवश्यकता नहीं है window.document
, जब तक वर्तमान विंडो संदर्भित है।
का सर्वाधिक प्रयोग किया जाने वाला रूप है दस्तावेज़ के भीतर कोई ऑब्जेक्ट ढूंढें एचटीएमएल यह विधि के माध्यम से है getElementById()
, जिसमें कोड बनाते समय इंगित की गई आईडी को एक तर्क के रूप में पारित किया जाता है एचटीएमएल. पिछले अनुभागों में जो बताया गया था, उससे यह मान लेना आसान है कि आप ऑब्जेक्ट के अंदर के घटकों तक भी पहुंच सकते हैं document
डॉट सिंटैक्स का उपयोग करना (document.componente
) या कोष्ठक में दोनों नामों का प्रयोग किया गया है (document["componente"]
), सबसे उपयोगी, जैसे कि संख्यात्मक सूचकांक, मैन्युअल रूप से बनाए गए वेब पेज की सामग्री तक पहुंचने पर उपयोग करना मुश्किल और अव्यावहारिक।
साथ जावास्क्रिप्ट आप कर सकते हैं वह तत्व प्राप्त करें जिसमें कोई अन्य तत्व शामिल है (तत्व या मूल नोड) अपनी संपत्ति से परामर्श करना parentNode
या आपकी संपत्ति parentElement
अंतर यह है कि मूल तत्व (parentElement
) स्ट्रिंग के अंतिम तत्व का डोम यह शून्य है (null
) और मूल नोड (parentNode
) दस्तावेज़ ही है (document
).
पैरा किसी तत्व की सामग्री को संशोधित करें एचटीएमएल, उदाहरण के लिए एक लेबल का <div>
, इसे इस्तेमाल किया जा सकता है innerHTML
और इसके गुणों को बदलने के लिए आप इसे एक अलग वर्ग निर्दिष्ट करना चुन सकते हैं className
या इसके गुणों को व्यक्तिगत रूप से बदलें style
. वेब पेज पर किसी तत्व द्वारा प्रदर्शित शैली से परामर्श लेना आवश्यक रूप से उपयोगी नहीं है style
चूँकि यह कई कारकों पर निर्भर हो सकता है या स्पष्ट रूप से निर्दिष्ट नहीं किया गया है। वेब पेज पर अंततः प्रदर्शित किसी तत्व की शैली की जांच करने के लिए, getComputedStyle विधि का उपयोग किया जाता है.
किसी दस्तावेज़ तत्व के लिए एचटीएमएल इसके स्वरूप और व्यवहार को निर्धारित करने के लिए इसे कई कक्षाएं सौंपी जा सकती हैं किसी ऑब्जेक्ट की कक्षाओं की सूची प्रबंधित करें जावास्क्रिप्ट आप इसका सहारा ले सकते हैं classList
जो तरीके प्रदान करता है add
सूची में एक नया वर्ग जोड़ने के लिए, remove
इसे हटाने के लिए, toggle
इसे बदलने के लिए या किसी तत्व की वर्ग सूची की सामग्री से परामर्श करने के लिए item
और contains
, जो उस वर्ग को लौटाता है जो सूची में एक निश्चित स्थान और एक मान रखता है true
o false
कोई निश्चित वर्ग सूची में है या नहीं।
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”) } |
पिछले उदाहरण में यह इसके साथ स्थित है getElementById
जिस वस्तु में आप हेरफेर करना चाहते हैं (एक तत्व)। <div>
उसके लिए id
), रूप बदलने से पहले, सामग्री को असाइन करके हटा दिया जाता है innerHTML
एक खाली टेक्स्ट स्ट्रिंग, इसे एक नई कक्षा सौंपी गई है className
और इसकी शैली को संशोधित किया गया है style
सामग्री (तापमान) के मूल्य के आधार पर, संपत्ति के माध्यम से, यदि लागू हो, रंग बदलना color
. एक बार पहलू स्थापित हो जाने पर, मान को दोबारा उपयोग करके लिखा जाता है innerHTML
.
उपरोक्त उदाहरण के दूसरे भाग में (पंक्तियाँ 9 से 19) एक कोड तत्व तक पहुँचा गया है एचटीएमएल वाक्य रचना का उपयोग करना document[]
और संपत्ति id
विधि के साथ तत्व की वर्ग सूची को बदलने के लिए classList.remove()
और विधि के साथclassList.add()
, सशर्त निष्पादन में किए गए कई प्रश्नों के परिणाम के आधार पर, जिनकी वे उपयोग करके तुलना करते हैं classList.contains()
.
कब जा रहा है एक तत्व का संदर्भ लें एचटीएमएल कई पूरे कोड में कई बार जावास्क्रिप्ट, ये ज़रा सा है इसे किसी वेरिएबल पर निर्दिष्ट करना अधिक कुशल है या नाम के बजाय इसकी अनुक्रमणिका का उपयोग करें, अन्यथा, आप जिस विधि का उपयोग करेंगे जावास्क्रिप्ट इसे प्राप्त करने के लिए हर बार इसके नाम की खोज करने की आवश्यकता होगी, किसी वेरिएबल तक पहुंचने की तुलना में थोड़ा अधिक समय लगेगा।
पैरा दस्तावेज़ में नई वस्तुएँ जोड़ें एचटीएमएल, उन्हें पहले विधि से बनाया जा सकता है createElement
de document
और बाद में उन्हें पेड़ के उस बिंदु पर बाकी तत्वों के साथ शामिल करें जो आवश्यक है appendChild
. एक वस्तु बनाने के लिए एक्सएमएल, वस्तुओं की तरह एसवीजी जिसका उपयोग हम IoT सेंसर का ग्राफ़ खींचने के लिए करते हैं, आप उसका उपयोग कर सकते हैं createElementNS
(एनएस के लिए नाम स्थान). जैसा कि प्रारूप के बारे में बात करते समय बताया गया है एसवीजी, जो नामस्थान इससे मेल खाता है (वर्तमान संस्करण के लिए) वह है http://www.w3.org/2000/svg
, जिसे पारित किया जाना चाहिए createElementNS
तत्व प्रकार के साथ एक तर्क के रूप में, svg
, इस मामले में।
एक करने के लिए वैकल्पिक innerHTML
दस्तावेज़ तत्व में सामग्री के रूप में पाठ जोड़ने के लिए एचटीएमएल विधि है createTextNode()
वस्तु का document
. इस विकल्प से आप कर सकते हैं नया पाठ बनाएँ (जिसे बाद में एक्सेस किया जाता है यदि इसे एक वेरिएबल को सौंपा गया है) जिसे विधि के साथ ऑब्जेक्ट ट्री में शामिल किया गया है appendChild()
। जैसे करने के लिए वैकल्पिक appendChild()
, जो उस नोड में पहले से मौजूद सामग्री के अंत में नई सामग्री जोड़ता है जिसमें इसे जोड़ा गया है, आप इसका उपयोग कर सकते हैं प्रक्रिया insertBefore()
, जो मौजूदा ऑब्जेक्ट के सामने एक नया ऑब्जेक्ट जोड़ता है। घिसाव insertBefore()
के बजाय appendChild()
एक ऐसी विधि प्रदान करता है जो, उदाहरण के लिए, कार्य करती है नई वस्तुओं को मौजूदा वस्तुओं के सामने क्रमबद्ध करें जब एक तत्व दूसरे के सामने होना चाहिए (जैसा कि एक सूची में) या कवर किया जाना चाहिए या एक ग्राफिक संरचना में कवर किया जाना चाहिए जिसमें अग्रभूमि या पृष्ठभूमि के करीब तत्व हैं।
जावास्क्रिप्ट के साथ घटनाओं पर प्रतिक्रिया करें
जब का रास्ता IoT कनेक्टेड सेंसर ग्राफ़ के लिए एक कंटेनर के रूप में एक वेब पेज का उपयोग करें इसका उपयोग किया गया था onload
लेबल में <body>
ग्राफ बनाना शुरू करने के लिए. यह संपत्ति, कोड ऑब्जेक्ट से संबद्ध है एचटीएमएल, यह आपकी जानकारी के लिए है घटनाओं जावास्क्रिप्ट. जैसा कि पहले ही बताया गया है, पेज लोड होने पर यह एक फ़ंक्शन निष्पादित करता है। हालाँकि इसे कोड के साथ जोड़ा गया है एचटीएमएल इसे और अधिक ध्यान में रखने के लिए इसे कोड में लिखा जा सकता था जावास्क्रिप्ट जैसा body.onload=dibujar;
किया जा रहा है dibujar
उस फ़ंक्शन का नाम जिसे वेब पेज लोड होने पर प्रारंभ किया जाना चाहिए।
के नवीनतम संस्करणों में जावास्क्रिप्ट ईवेंट को फ़ंक्शंस का उपयोग करके संबद्ध किया जा सकता है addEventListener
प्रारूप के साथ objeto.addEventListener(evento,función);
या वाक्यविन्यास का उपयोग करना objeto.evento=función;
जो पुराने कार्यान्वयन में भी काम करता है। इवेंट से जुड़े फ़ंक्शन को अनलिंक करने के लिए, आपके पास है removeEventListener
जिसका प्रारूप भी वैसा ही है addEventListener
.
जावास्क्रिप्ट यह एक वेब पेज पर होने वाली अनेक घटनाओं पर प्रतिक्रिया करने में सक्षम है। उदाहरण के लिए, यह पता लगा सकता है कि किसी तत्व पर कब क्लिक किया गया है एचटीएमएल साथ onmousedown
, या जब क्लिक किया गया onclick
, जब किसी कुंजी को दबाया जाता है onkeydown
, स्क्रॉल बार को संचालित करके onscroll
. हमारे उद्देश्य के लिए यह हमारे लिए पर्याप्त है पेज लोड का पता लगाएं onload
और इसका आकार बदल रहा है onresize
. हम इन घटनाओं को वस्तुओं के साथ जोड़ेंगे body
y window
डेल डोम क्रमश। पहले को कोड में असाइन किया जा सकता है एचटीएमएल, जैसा कि देखा गया और कोड के भीतर दूसरा जावास्क्रिप्ट पहले द्वारा बुलाए गए फ़ंक्शन के अंदर और प्रारूप के साथ window.onresize=redimensionar;
किया जा रहा है redimensionar
वह फ़ंक्शन जिसे हर बार विंडो का आकार बदलने पर कॉल किया जाएगा।
एक समय अंतराल के बाद चलायें
जावास्क्रिप्ट के लिए दो संसाधन हैं स्थगित निष्पादन: setTimeout
, जो एक समय अंतराल के बाद एक फ़ंक्शन निष्पादित करता है और setInterval
जो प्रत्येक निश्चित समय अंतराल पर एक फ़ंक्शन निष्पादित करेगा. दोनों विधियों को पैरामीटर के रूप में (1) लागू फ़ंक्शन और (2) मिलीसेकंड में व्यक्त समय अंतराल की आवश्यकता होती है। उनके संचालन को रोकने के लिए, आप इन फ़ंक्शंस द्वारा लौटाए गए परिणाम को वेरिएबल्स पर निर्दिष्ट कर सकते हैं और उन्हें एक तर्क के रूप में पास कर सकते हैं clearTimeout
या clearInterval
जब आप उन्हें दोबारा लागू नहीं करना चाहते (या जब आप नहीं चाहते कि उन्हें पहली बार निष्पादित किया जाए) setTimeout
o setInterval
क्रमशः.
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 } |
पिछले उदाहरण में विधि का परिचय दिया गया है alert
जो एक चेतावनी संकेत प्रदर्शित करने का कार्य करता है। हालाँकि अतीत में इसका व्यापक रूप से उपयोग किया जाता था, वर्तमान में इसे कोड से लगभग प्रतिबंधित कर दिया गया है जावास्क्रिप्ट वेब पेज को डायलॉग बॉक्स से कवर करना कितना आक्रामक (दखल देने वाला) है।
के लिए लिखे गए एक प्रोग्राम में microcontroller एक छोटी श्रृंखला की (जैसे कि प्लेट पर एक)। अरुडिनो उनो) वैश्विक चर का उपयोग करना आम बात है, जैसा कि पिछले उदाहरण में है जावास्क्रिप्ट, चूंकि कोड संक्षिप्त है और विशेष रूप से भ्रमित करने वाला नहीं है, क्योंकि कई बार फ़ंक्शंस को तदर्थ लागू किया जाता है और क्योंकि वैश्विक चर का उपयोग बहुत ही सरल और सहज तरीके से मेमोरी उपयोग की भविष्यवाणी करना संभव बनाता है, जो कुछ संसाधनों वाले सिस्टम में महत्वपूर्ण है . बजाय, en जावास्क्रिप्ट वैश्विक चर के उपयोग को न्यूनतम संभव तक कम करना आम बात है। क्योंकि इसे मेमोरी उपयोग में तेजी लाने की आवश्यकता नहीं है, क्योंकि यह सामान्य रूप से चलता है सी पी यू की तुलना में कहीं बेहतर संसाधनों के साथ एमसीयू, क्योंकि यह बहुत सारे तृतीय-पक्ष कोड के साथ सह-अस्तित्व में रहने की संभावना है जिसके साथ इसे हस्तक्षेप किए बिना काम करना होगा और चूंकि यह एक खुली प्रणाली है, इसलिए भविष्य के निष्पादन संदर्भ की भविष्यवाणी नहीं की जा सकती है (ए का कार्यक्रम) microcontroller छोटा एक बार संचालन में आने के बाद अधिक कोड जोड़े बिना अपने संचालन को पूरी तरह से निर्धारित करता है) और क्योंकि यदि कोड अपने संचालन को समाहित नहीं करता है, तो अनुप्रयोगों के आयाम पढ़ना मुश्किल बना सकते हैं, जिससे विधियां यथासंभव स्व-निहित हो जाती हैं।
जावास्क्रिप्ट गणित ऑब्जेक्ट के साथ गणितीय संचालन
अधिक जटिल गणितीय गणना की गणितीय संक्रियाओं को वस्तु में समूहीकृत किया जाता है Math
. इस ऑब्जेक्ट का उपयोग सीधे तौर पर किया जाता है, इसमें शामिल तरीकों या गुणों (स्थिरांक) का उपयोग करने के लिए इसे तुरंत चालू करना आवश्यक नहीं है।
Math.abs(n)
पैरामीटर n का निरपेक्ष मानMath.acos(n)
पैरामीटर n का आर्ककोसाइन (रेडियंस में परिणाम)Math.asin(n)
पैरामीटर n की आर्कसाइन (रेडियंस में परिणाम)Math.atan(n)
पैरामीटर n का आर्कटिक (परिणाम रेडियन में)Math.atan2(n,m)
एन/एम का आर्कटिक (परिणाम रेडियन में)Math.ceil(n)
पैरामीटर को निकटतम पूर्णांक तक पूर्णांकित करेंMath.cos(α)
पैरामीटर α की कोज्या (रेडियंस में α)Math.E
ई नंबर (≃2.718281828459045)Math.exp(n)
e को पैरामीटर n: e तक बढ़ा दिया गया हैnMath.floor(n)
पैरामीटर n को निकटतम पूर्णांक तक नीचे की ओर गोल करेंMath.log(n)
पैरामीटर n का प्राकृतिक लघुगणक (आधार ई)।Math.LN2
2 का प्राकृतिक लघुगणक (आधार ई) (≃0.6931471805599453)Math.LN10
10 का प्राकृतिक लघुगणक (आधार ई) (≃2.302585092994046)Math.LOG2E
ई का आधार 2 लघुगणक (≃1.4426950408889634)Math.LOG10E
ई का आधार 10 लघुगणक (≃0.4342944819032518)Math.max(a,b,c,…)
पारित पैरामीटरों की सूची का सबसे बड़ा मानMath.min(a,b,c,…)
पारित पैरामीटरों की सूची का सबसे छोटा मानMath.PI
संख्या π (≃3.141592653589793)Math.pow(n,m)
पहले पैरामीटर n को दूसरे पैरामीटर m: n तक बढ़ाया गयाmMath.random()
(लगभग) 0.0 और 1.0 के बीच यादृच्छिक संख्याMath.round(n)
पैरामीटर n को निकटतम पूर्णांक तक गोल करेंMath.sin(α)
पैरामीटर α की ज्या (रेडियंस में α)Math.sqrt(n)
पैरामीटर n का वर्गमूलMath.SQRT1_2
1/2 का वर्गमूल (≃0.7071067811865476)Math.SQRT2
2 का वर्गमूल (≃1.4142135623730951)Math.tan(α)
पैरामीटर α की स्पर्श रेखा (रेडियंस में α)
AJAX के साथ सर्वर से डेटा लोड करें
IoT में संग्रहीत जानकारी को निकालने के लिए अपनाई जाने वाली विधि में समय-समय पर सर्वर से डेटा लोड करना और उस ग्राफ़ को फिर से बनाना शामिल है जिसके साथ उन्हें दर्शाया गया है। सर्वर से डेटा पढ़ने के लिए तकनीक का उपयोग किया जाता है AJAX (एसिंक्रोनस जावास्क्रिप्ट और XML) किसी वस्तु के माध्यम से XMLHttpRequest
de जावास्क्रिप्ट. डेटा ग्राफ़ को प्लॉट करना किसी ऑब्जेक्ट का पुन: उपयोग करके किया जाता है एसवीजी जो पहले से ही कोड में है एचटीएमएल और इसमें एक प्लॉट शामिल है जिसके निर्देशांक संशोधित किए गए हैं ताकि उन्हें लोड किए गए नए डेटा के अनुरूप बनाया जा सके।
इस प्रस्ताव के उदाहरण में, ड्राइंग को अपडेट करने के अलावा, वेब पेज पर एक टेक्स्ट भी अपडेट किया गया है जो प्रत्येक ग्राफ़ के लिए अंतिम मापा डेटा की तारीख और मूल्य दिखाता है।
सर्वर साइड पर एक डेटाबेस होता है जिसमें जानकारी होती है IoT से जुड़े सेंसर निगरानी कर रहे हैं। यह डेटाबेस ऑब्जेक्ट अनुरोध द्वारा पढ़ा जाता है XMLHttpRequest
में एन्कोड की गई जानकारी के साथ जवाब देना JSON प्रारूप, हालाँकि उपयोग की गई विधि का नाम प्रारूप के साथ संबंध का सुझाव देता है एक्सएमएल.
पहले pollaridad.es ट्यूटोरियल में IoT डेटा भंडारण आप इंटरनेट ऑफ थिंग्स से जुड़े उपकरणों द्वारा प्रदान की गई जानकारी को सर्वर साइड से प्रबंधित करने के लिए बुनियादी ढांचे का एक उदाहरण देख सकते हैं। लेखों की इस श्रृंखला में एक सर्वर को एक संसाधन के रूप में उपयोग किया जाता है अपाचे जिससे आप प्रोग्रामिंग लैंग्वेज का उपयोग कर सकते हैं PHP किसी डेटाबेस तक पहुँचने के लिए MySQL o MariaDB. IoT का समर्थन करने के लिए उपयोग किए जाने वाले सर्वर पर डेटाबेस ढूंढना बहुत आम है MongoDB (NoSQL) और प्रोग्रामिंग भाषा जावास्क्रिप्ट पर Node.js सॉफ़्टवेयर अवसंरचना के रूप में।
अगला फ़ंक्शन सर्वर से किसी एक सेंसर से नवीनतम डेटा का अनुरोध करने के लिए ज़िम्मेदार है। फ़ंक्शन कॉल में, ऑब्जेक्ट का उपयोग तर्क के रूप में किया जाता है जावास्क्रिप्ट जो निकाले गए डेटा का समर्थन करता है। यदि एक ही ग्राफ़ कई मानों का प्रतिनिधित्व करता है, उदाहरण के लिए किसी सहसंबंध की दृष्टि से खोज करने के लिए, तो सर्वर से कई मानों को एक साथ वापस करने का अनुरोध किया जा सकता है, जो सर्वर के काम करने के तरीके के कारण एक अधिक इष्टतम तरीका है। HTTP प्रोटोकॉल.
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); } |
पिछले उदाहरण की तीसरी पंक्ति में, सर्वर से की जाने वाली क्वेरी तैयार की जाती है, जिसमें तर्क "ज़ोन" पारित किया जाएगा, जिसका मान मॉनिटर किए गए स्थान का नाम या कोड होगा क्योंकि जानकारी के बारे में क्षेत्र एक ही डेटाबेस में सह-अस्तित्व में हो सकता है। विभिन्न सेंसर (उदाहरण के लिए, थर्मामीटर जो विभिन्न कमरों में तापमान मापते हैं)। पिछले फ़ंक्शन को दिए गए पैरामीटर, चार्ट डेटा वाले ऑब्जेक्ट में कमरे के नाम ("name_suffix") के साथ एक प्रॉपर्टी शामिल होने की उम्मीद है।
पिछले कोड की पंक्ति 7 और 14 के बीच, वस्तु XMLHttpRequest
जो वेरिएबल "ajax" में संग्रहीत है। ऑब्जेक्ट बनाने का तरीका चुनने से पहले, आप खोजें window
अगर XMLHttpRequest
उपलब्ध नहीं था (कुछ ऐसा जो माइक्रोसॉफ्ट के एक्सप्लोरर के पुराने संस्करणों में हुआ था और हालांकि यह बहुत पीछे है, यह (अधिक मूल) सिंटैक्स का उपयोग करके ऑब्जेक्ट बनाने के लिए विकल्पों के उदाहरण के रूप में कार्य करता है) Object.create
o new
, अन्य वस्तु-उन्मुख भाषाओं के समान।
प्रतिक्रिया को तुरंत प्रबंधित करने में सक्षम होने के लिए, इसे संभालने वाला कोड सर्वर से अनुरोध करने से पहले 15 से 26 पंक्तियों में तैयार किया जाता है।
का तरीका क्वेरी निष्पादित करें HTTP सर्वर से मिलकर बनता है एक कनेक्शन खोलें साथ open
प्रकार और पृष्ठ का संकेत (वैकल्पिक रूप से उपयोगकर्ता नाम और पासवर्ड), हेडर तैयार करें प्रोटोकॉल के साथ setRequestHeader
y अनुरोध भेजें साथ send
. हेडर HTTP Content-length
आपको क्वेरी की लंबाई (वर्णों की संख्या) जानने की आवश्यकता होगी, जिसकी गणना का उपयोग करके की जाती है length
.
जब अनुरोध AJAX तैयार है, इवेंट से जुड़ा फ़ंक्शन निष्पादित हो गया है onreadystatechange
. किसी फ़ंक्शन को निर्दिष्ट करने के बजाय, पिछले उदाहरण में एक अनाम फ़ंक्शन को तुरंत परिभाषित किया गया है जो सर्वर से आने वाले डेटा के रिसेप्शन का प्रबंधन करेगा। सबसे पहले, लाइन 18 पर, यह सत्यापित किया जाता है कि अनुरोध की स्थिति "समाप्त" है, जो मूल्य से मेल खाती है 4
संपत्ति का readyState
, कि स्थिति "ठीक" है HTTP प्रोटोकॉल (कोड 200
) जो संपत्ति से प्राप्त किया जा सकता है status
और जो डेटा आया है JSON प्रारूप, संपत्ति से परामर्श करना responseType
.
एक बार सत्यापित कर लें कि प्रतिक्रिया की स्थिति अपेक्षा के अनुरूप है, पिछले उदाहरण की पंक्ति 20 में परिणाम के साथ एक ऑब्जेक्ट बनाता है, पाठ को परिवर्तित करता है JSON. प्रतिक्रिया लौटाने की तारीख प्रदान करती है, इससे हमें यह देखने की अनुमति मिलती है कि सर्वर जो परिणाम भेजता है वह पहले से ही ग्राफ़ में दर्शाया गया था, जिसे लाइन 21 पर सत्यापित किया गया है। यदि डेटा नया है, तो लाइन 23 पर फ़ंक्शन जो नई जानकारी के साथ ग्राफ़ को फिर से बनाने के लिए जिम्मेदार कहा जाता है।
इस पढ़ने की विधि का प्रस्ताव करते समय विचार यह है कि डेटा को बहुत बार ताज़ा किया जाएगा। यदि प्रस्तुत की गई जानकारी लंबी अवधि (जैसे एक दिन या एक सप्ताह का तापमान) से मेल खाती है, तो एक प्रारंभिक अनुरोध लागू किया जा सकता है जो सभी उपलब्ध डेटा एकत्र करता है और फिर उदाहरण के समान, इसे अपडेट करता है। अवधि संवाददाता.
परीक्षण के लिए यादृच्छिक डेटा उत्पन्न करें
जब सारा सर्वर और क्लाइंट इंफ्रास्ट्रक्चर तैयार हो जाएगा, तो पिछले अनुभाग जैसा एक फ़ंक्शन डेटा को पढ़ने और उसके साथ ग्राफ़ खींचने का प्रभारी होगा, लेकिन परीक्षण चरण में नियंत्रित सीमा के भीतर यादृच्छिक संख्याओं का उपयोग करना अधिक व्यावहारिक हो सकता है यह देखने के लिए कि क्या लिखा जा रहा कोड सही है। अंतिम एप्लिकेशन बनाते समय डेटा प्राप्त करने के लिए निम्नलिखित फ़ंक्शन एक उदाहरण के रूप में काम कर सकता है।
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); } |
डेटाबेस से जानकारी पढ़ने के बजाय, उपरोक्त उदाहरण उन्हें यादृच्छिक रूप से उत्पन्न करता है और उन्हें ग्राफ़ खींचने के प्रभारी फ़ंक्शन में भेज देता है। आविष्कृत डेटा एक वेक्टर है जो मिलीसेकंड में मान के रूप में व्यक्त की गई तारीख, सेंसर जानकारी रिकॉर्ड करने के क्षण और मॉनिटर किए गए डेटा से बनता है, जो अधिकतम मान और न्यूनतम मान के बीच होता है।
इस उदाहरण में, तारीख बनाते समय आविष्कार के समय की तारीख के संबंध में इसमें एक सेकंड (1000 मिलीसेकंड) तक की देरी हो सकती है। जैसा Math.random()
0.0 और 1.0 के बीच एक संख्या उत्पन्न करता है, इसे 1000 से गुणा करने पर 0 और 1000 के बीच एक संख्या उत्पन्न होती है जिसे बाद में एक पूर्णांक में बदल दिया जाता है। उसी प्रकार, यादृच्छिक संख्या को श्रेणी (अधिकतम शून्य न्यूनतम) से गुणा करके और न्यूनतम जोड़कर मान प्राप्त किया जाता है।
एसवीजी प्लॉट के साथ IoT सेंसर ग्राफ़ बनाएं
चूँकि हमने देखा है कि हम उन मूल्यों को कैसे प्राप्त कर सकते हैं जिन्हें हम प्रदर्शित करना चाहते हैं (तापमान, उदाहरण में) और उनका अस्थायी स्थान, जिसे निर्देशांक के रूप में एक साथ व्यक्त किया जा सकता है, नीचे दिया गया उदाहरण पथ बनाने के लिए एक फ़ंक्शन दिखाता है जो उन बिंदुओं को जोड़ता है और वैकल्पिक रूप से शीर्ष पर उस रेखा द्वारा सीमांकित एक रंगीन क्षेत्र है। परिणाम निम्न छवि जैसा होगा.
ग्राफ़ का क्षैतिज अक्ष (X) समय का प्रतिनिधित्व करता है और ऊर्ध्वाधर अक्ष (Y) उन मानों का प्रतिनिधित्व करता है जो IoT से जुड़े सेंसर निगरानी कर रहे हैं। क्षैतिज अंतराल कुछ सेकंड का है क्योंकि इस प्रस्ताव में सेंसर की स्थिति पर लगभग वास्तविक समय की जानकारी प्रदान करने के लिए ग्राफ़ को बहुत बार (उदाहरण के लिए, हर सेकंड) अपडेट किया जाता है।
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 } |
पिछले कोड में दो दिलचस्प पहलू हैं, पहला गणना जो अनुमति देती है दर्शाए गए मानों की श्रेणी को अनुकूलित करें और दूसरी बात संपत्ति निर्माण d
जो लेआउट पर बिंदुओं के निर्देशांक को इंगित करता है (path
).
प्रस्तुत मानों की सीमा को अनुकूलित करने के लिए, उन्हें न्यूनतम से स्थानांतरित किया जाता है और स्केल किया जाता है ताकि दृश्यमान परिमाण ग्राफ़ के आकार से मेल खाए. समय के मामले में, ऑफसेट उस सीमा को घटाकर प्राप्त किया जाता है जिसे आप सबसे लंबे समय (वर्तमान के निकटतम तिथि और समय) (उदाहरण में 20 सेकंड) से प्रदर्शित करना चाहते हैं। तापमान मानों का विस्थापन निचली सीमा (एक डिग्री) से न्यूनतम मान को घटाकर होता है, ताकि नीचे दिखाया गया डेटा अनुमत न्यूनतम मान के सबसे समान हो, लेकिन एक मार्जिन छोड़ देता है जो हमें उन लोगों की सराहना करने की अनुमति देता है जो ऐसा करते हैं । उत्तीर्ण
ग्राफ़ के क्षैतिज निर्देशांक प्राप्त करने के लिए समय मानों को गुणा करने वाला गुणांक ग्राफ़ की कुल चौड़ाई (उदाहरण में 100 इकाइयाँ) को दर्शाई गई समय सीमा (उदाहरण में 20 सेकंड) से विभाजित करके प्राप्त किया जाता है। अदिश तापमान मानों के साथ गुणांक प्राप्त करने के लिए, यह याद रखना चाहिए कि दर्शाई गई सीमा न्यूनतम मान से नीचे के मार्जिन से अधिकतम, दोनों मामलों में एक डिग्री से ऊपर के मार्जिन तक जाती है। इस प्रकार, ऊर्ध्वाधर पैमाने का गुणांक ग्राफ़ की ऊंचाई (उदाहरण में 100 इकाइयाँ) को अधिकतम मान से विभाजित करने पर, न्यूनतम को घटाकर ऊपरी और निचले मार्जिन को जोड़ने से प्राप्त होता है। चूंकि ये मान नकारात्मक तापमान पर पूरी तरह से विकसित हो सकते हैं, इसलिए हम इसका उपयोग करते हैं Math.abs()
अंतर के निरपेक्ष मान का उपयोग करने के लिए.
संपत्ति d
वस्तु का path
इसका निर्माण किसी पाठ में बिंदुओं के निर्देशांकों को जोड़कर किया जाता है. निर्देशांक के प्रत्येक जोड़े के पहले एक कोड होता है एसवीजी L
, जो वर्तमान स्थिति से निरपेक्ष मान तक एक रेखा खींचता है जो निर्देशांक द्वारा इंगित किया जाता है। X और Y मान अल्पविराम और प्रत्येक ऑपरेशन द्वारा अलग किए जाते हैं एसवीजी अगले से एक स्थान द्वारा अलग किया गया है।
लेआउट प्रारंभ करने के लिए, कोड का उपयोग करें M
(पूर्ण समन्वय की ओर बढ़ें). बंद और भरे हुए प्लॉट के मामले में, आप नीचे दाईं ओर से शुरू करते हैं, खुले प्लॉट के मामले में जो डेटा प्रोफ़ाइल खींचता है, आप दर्शाए गए अंतिम मान (सबसे हालिया) से शुरू करते हैं। बंद लेआउट को ख़त्म करने के लिए कोड का उपयोग किया जाता है Z
अंतिम बिंदु के रूप में वह जोड़ना जिसका X निर्देशांक मान रेखा के अंतिम बिंदु के समान हो और Y निर्देशांक के रूप में दर्शाया गया सबसे छोटा मान हो।
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 ); } |
इस उदाहरण में, फ़ंक्शन dibujar_grafico()
, जो पृष्ठ लोड पर कॉल है, परीक्षण के लिए प्रारंभिक मान प्राप्त करता है (अंतिम वास्तविक समय मान नहीं) और वह सीमा तैयार करता है जिसमें डेटा प्रस्तुत किया जाएगा: 20 सेकंड (20000 एमएस) क्षैतिज रूप से और 15 डिग्री सेल्सियस में एक डिग्री ऊपर और नीचे के मार्जिन के साथ -5°C से +10°C तक लंबवत। को दो कॉल करें actualizar_grafico()
, पहले पास में true
एक तर्क के रूप में, जो इंगित करता है कि चार्ट को भरे हुए क्षेत्र का प्रतिनिधित्व करने के लिए बंद किया जाना चाहिए, और दूसरी कॉल पर यह पास हो जाता है false
रेखा खींचने के लिए. प्रत्येक मामले में, वस्तु path
संशोधित वह है जिसमें अनुरूप स्वरूप हो, पहले मामले में भराव और कोई सीमा न हो और दूसरे मामले में एक निश्चित रेखा की मोटाई हो और कोई भराव न हो।
समारोह actualizar_grafico()
किसी वस्तु पर काम करना एसवीजी जो एक कंटेनर के रूप में निम्नलिखित कोड का उपयोग करता है एचटीएमएल. जो वस्तु एसवीजी इसमें दो पथ हैं, एक रेखा खींचने के लिए और दूसरा भरे हुए क्षेत्र को खींचने के लिए। वेब पेज लोड करते समय, तत्व से <body>
पिछला फ़ंक्शन स्वचालित रूप से कॉल किया जाता है, dibujar_grafico()
घटना के लिए धन्यवाद जावास्क्रिप्ट onload
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | <!DOCTYPE html> <html lang=“es”> <head> <meta charset=“utf-8”> <title>Temperatura</title> <script type=“text/javascript” src=“https://polaridad.es/javascript-grafico-svg-sensor-internet-de-las-cosas-iot/grafico.js”></script> </head> <body onload=“dibujar_grafico();” style=“margin:0;”> <!– Cuerpo del documento HTML. Al cargar el contenido llama a la función JavaScript dibujar_grafico() –> <div id=“temperatura”> <div id=“bloque_temperatura” style=“width:820px;height:150px”> <svg id=“grafico_temperatura” width=“100%” height=“100%” viewBox=“0 0 100 100” preserveAspectRatio=“none”> <path id=“relleno_temperatura” d=“” style=“fill:#A8C3EA;stroke:none;” vector-effect=“non-scaling-stroke” /> <path id=“linea_temperatura” d=“” style=“fill:none;stroke:#205587;stroke-width:4;stroke-opacity:1;” vector-effect=“non-scaling-stroke” /> </svg> </div> </div> </body> </html> |
कोड की लाइन 10 पर एचटीएमएल ऊपर, शैली में 820 पीएक्स की चौड़ाई (उदाहरण के तौर पर) और 150 पीएक्स की ऊंचाई स्थापित की गई है (कुछ ऐसा, जिसे अंतिम संस्करण में, एक वर्ग और एक दस्तावेज़ के साथ करना उचित होगा) सीएसएस). यह अजीब लगता है कि पंक्तियाँ 13 और 14 वस्तु के आकार को परिभाषित करती हैं एसवीजी जैसे 100% चौड़ाई और ऊंचाई (जो विंडो आयामों से सबसे अच्छी तरह मेल खाती है, 100×100)। जैसा कि पहले ही उल्लेख किया गया है, ऐसा करने का कारण हमेशा ज्ञात आयामों के साथ काम करना और इसमें प्रस्तुत मूल्यों को समायोजित करना है। अन्य विकल्प हर बार ग्राफ़ के स्थान की गणना करना और फिर मानों को फिर से समायोजित करना या ग्राफ़ के लिए निश्चित आयामों को बाध्य करना होगा, जिसका दस्तावेज़ को पालन करना होगा।
ऐसे ग्राफ़ का चयन करना जिसके आयाम कोड के अनुसार बदलते हों एचटीएमएल, संपत्ति को शामिल करना आवश्यक है vector-effect
मान के साथ non-scaling-stroke
जब ग्राफ़ उस वेब पेज पर चयनित 1:1 अनुपात को बनाए नहीं रखता है जिस पर वह प्रदर्शित होता है, तो लाइन की मोटाई को विकृत होने से रोकने के लिए, जैसा कि पिछले प्रस्ताव में होता है।
ग्राफ़ को "क्रॉप" करने और केवल आपके द्वारा चुने गए क्षेत्र को दिखाने के लिए, इसका उपयोग करें viewBox
. इस मामले में हमने ग्राफ़ के उस हिस्से को देखना चुना है जो 0,0 (ऊपरी बाएँ कोने) से शुरू होता है और नीचे और दाईं ओर 100x100 मापता है। नकारात्मक मानों या 100 से अधिक के साथ समन्वय में स्थित ड्राइंग का हिस्सा वेब पेज पर प्रदर्शित नहीं किया जाएगा, भले ही वे ऑब्जेक्ट में मौजूद हों एसवीजी
एसवीजी ड्राइंग में नए तत्व जोड़ें
पिछले उदाहरण में, function actualizar_grafico()
एक लेआउट का उपयोग करें एसवीजी जिसका स्वामित्व बदल गया है d
, जो समन्वय श्रृंखला को व्यक्त करता है। इसका विकल्प यह होगा कि हर बार दोबारा बनाए जाने पर संपूर्ण ऑब्जेक्ट बनाया जाए। पहले विकल्प का लाभ यह है कि ग्राफिक उपस्थिति (जैसे मोटाई या रंग) को कोड में परिभाषित किया गया है एचटीएमएल, सीमा यह है कि वस्तुओं को पहले बनाया जाना चाहिए।
एसवीजी ऑब्जेक्ट बनाने के लिए, उपयोग करें createElementNS()
, जो इसमें शामिल करने की अनुमति देता है नाम स्थान. नीचे दिए गए उदाहरण में एक नया टेक्स्ट ऑब्जेक्ट बनाया गया है (text
) और एक तत्व से जुड़ा है एसवीजी जो पहले से ही कोड में मौजूद है एचटीएमएल वेबसाइट का. एक बार नया तत्व बन जाने के बाद, उसके गुण निर्दिष्ट कर दिए जाते हैं setAttribute()
और इसमें जोड़ा जाता है एसवीजी साथ 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]); |
ड्राइंग तत्वों के अनुपात को संशोधित करें
यदि आपने पिछले अनुभाग में उदाहरण में फ़ंक्शन के साथ लेबलिंग करने का प्रयास किया है, तो आपने देखा होगा कि वेब पेज पर ऑब्जेक्ट का अनुपात होने पर टेक्स्ट विकृत दिखाई देता है (width
y height
कोड का एचटीएमएल) प्रतिनिधित्व किए गए क्षेत्र के बराबर नहीं है (viewBox
). अनुपात को अनुकूलित करने के लिए वस्तु की माप जानना आवश्यक है एसवीजी जिसके लिए आप ऑब्जेक्ट की शैली, या कंटेनर से परामर्श ले सकते हैं एचटीएमएल, यदि वस्तु एसवीजी इस संपत्ति को स्थानांतरित करें. स्वामित्व सौंपना transform
वस्तुओं के लिए एसवीजी जो अनुपात पर निर्भर करता है, स्केलिंग ऑपरेशन लागू करके विकृति को ठीक किया जा सकता है scale()
जिसमें X का गुणांक Y से भिन्न है।
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]); |
एसवीजी कई वस्तुओं को एक नया समग्र तत्व बनाने के लिए समूहीकृत करने की अनुमति देता है जो गुणों का भी समर्थन करता है, साधारण वस्तुओं की तरह। प्रत्येक वस्तु को अलग-अलग करने के बजाय एक ही बार में वस्तुओं की श्रृंखला में समान परिवर्तन लागू करने के लिए, आप उन्हें इस संसाधन के अनुसार समूहित कर सकते हैं और एक ही संपत्ति लागू कर सकते हैं transform
उन सभी को.
जैसा कि बात करते समय बताया गया है एसवीजी प्रारूप, एक समूह के तत्व लेबल के भीतर संलग्न हैं <g>
y </g>
. से जोड़ने के लिए जावास्क्रिप्ट एक समूह में तत्व एसवीजी प्रयोग किया जाता है, जैसा कि पिछले उदाहरण में देखा गया है, appendChild()
एक बार नई वस्तु परिभाषित हो जाती है।
परिवर्तनों को लागू करते समय एक उत्पत्ति स्थापित करने के लिए, संपत्ति का उपयोग वस्तुओं पर किया जा सकता है एसवीजी transform-origin
, जिसका मान उस बिंदु के X और Y निर्देशांक हैं जहां से परिवर्तन शुरू होता है। यदि परिवर्तन की उत्पत्ति के लिए कोई मान स्पष्ट रूप से (वेब ब्राउज़र में) इंगित नहीं किया गया है, तो निर्देशांक केंद्र का उपयोग किया जाता है। दुर्भाग्य से, लेखन के समय, डिफ़ॉल्ट स्रोत के अलावा किसी अन्य स्रोत का उपयोग करके परिवर्तनों के व्यवहार को निर्दिष्ट करना सभी ब्राउज़रों में सजातीय नहीं है और इसका उपयोग सावधानी से किया जाना चाहिए।
पैमाने परिवर्तन के साथ-साथ scale
अन्य भी हैं, जैसे रोटेशन के साथ rotation
और के साथ आंदोलन translate
, जो एक प्रस्ताव देता है ग्राफ़ प्रतिनिधित्व का विकल्प: नए निर्देशांक प्राप्त करने के बजाय, आप उन्हें उनके स्वयं के स्थान में प्रस्तुत कर सकते हैं और ग्राफ़ को उस प्रारूप में फिट करने के लिए बदल सकते हैं जिसमें आप उन्हें प्रस्तुत करना चाहते हैं।
चार्ट में संदर्भ जोड़ें
अब जबकि ग्राफ़ का मुख्य भाग प्रोफ़ाइल और भरे हुए क्षेत्र के साथ मानों को प्लॉट करके हल किया गया है, इसे उन संदर्भों के साथ पूरा किया जा सकता है जो इसे पढ़ने में मदद करते हैं। उदाहरण के तौर पर, आइए कुछ क्षैतिज संदर्भ (रेखाएं) खींचकर शुरू करें जो अधिकतम और न्यूनतम स्वीकार्य मानों के साथ-साथ वांछित मान को भी चिह्नित करते हैं। जैसा कि बताया गया है, आप इसमें ऑब्जेक्ट जोड़ना चुन सकते हैं एसवीजी से सीधा जावास्क्रिप्ट या उन्हें कोड में मैन्युअल रूप से शामिल करें एचटीएमएल और बाद में उन्हें संशोधित करें जावास्क्रिप्ट.
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(); |
इन क्षैतिज संदर्भों को ऐसे पाठ के साथ लेबल करना तर्कसंगत लगता है जो उनके द्वारा दर्शाए गए मूल्य को स्पष्ट करता है। टेक्स्ट को हाइलाइट करने के लिए, आप आयतों का उपयोग कर सकते हैं जो पृष्ठभूमि और ग्राफ़िक से अलग दिखेंगे। चूंकि विकृति की भरपाई के लिए पाठों को स्केल करना होगा, उन सभी को एक ऑब्जेक्ट में समूहीकृत किया जा सकता है जिस पर स्केल लागू किया जाएगा; इसे इस तरह से करने का मुख्य लाभ यह है कि यदि ग्राफ़ कंटेनर (ब्राउज़र विंडो) का आकार बदल दिया जाता है और उस अनुपात को बदल दिया जाता है जिसे स्केल सही करता है तो उन्हें एक ही ऑपरेशन में संशोधित करने में सक्षम होना है।
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(); |
उपरोक्त उदाहरण कोड में कई दिलचस्प पहलू हैं। सबसे पहले, टिप्पणी करें कि प्रोग्रामिंग से आने वाले उपयोगकर्ताओं के लिए उदाहरण को अधिक पठनीय बनाने के लिए स्थिरांक (वैश्विक चर) का उपयोग किया गया है। माइक्रोकंट्रोलर्स en C ओ एन सी + +. जैसा कि बाद में देखा जाएगा, इसे प्रोग्राम करने का इष्टतम तरीका जावास्क्रिप्ट यह उन वस्तुओं का उपयोग करेगा जिनमें ये मान और विधियाँ शामिल होंगी जो इस उदाहरण या ग्राफ़ में संदर्भों को सामान्य रूप से उत्पादन प्रणाली में प्रबंधित करेंगी।
दूसरी ओर, अधिक सामान्य कोड क्या होगा, इसे आगे बढ़ाते हुए, अलग-अलग फ़ंक्शन विकसित किए गए हैं जो विभिन्न गुणांकों की गणना करते हैं जो पाठ को समायोजित करने के लिए ग्राफ़ के अनुपात को सही करते हैं proporcion_grafico()
, मानों का पैमाना उनकी सीमा पर निर्भर करता है escala()
और उन मापों के लिए एक सुधार कारक जो निरपेक्ष मूल्य में ज्ञात हैं, जैसे संदर्भों में माप medida_grafico()
.
इस कोड को पढ़ने से उस संदर्भ को स्पष्ट करने में मदद मिलेगी जिसमें इस तरह का एप्लिकेशन काम करता है, जो वास्तविक समय में ग्राफिक्स खींचता है और विभिन्न ग्राफिकल संदर्भों (कम से कम विभिन्न आकार और अनुपात) में प्रस्तुत करने के लिए लचीला होना चाहिए। सबसे पहले, वस्तुओं को उत्पन्न किया जाना चाहिए एसवीजी, या तो कोड में "मैन्युअल रूप से"। एचटीएमएल, या तो कोड के माध्यम से जावास्क्रिप्ट और किसी भी स्थिति में, इन वस्तुओं में हेरफेर करने के लिए उनका संदर्भ बाद में प्राप्त किया जाना चाहिए जावास्क्रिप्ट ताकि नए ग्राफ़ खींचे जा सकें और पहले से तैयार ग्राफ़ का प्रतिनिधित्व उस माध्यम में बदलाव के अनुसार अनुकूलित किया जा सके जिसमें इसे प्रस्तुत किया गया है।
एक अन्य संदर्भ जो किसी ग्राफ़ की आसानी से व्याख्या करने में मदद कर सकता है वह वे बिंदु हैं जो विशिष्ट मानों (रेखा के नोड्स) का प्रतिनिधित्व करते हैं। इस उदाहरण में, जिसमें हम एक एकल परिमाण का प्रतिनिधित्व करते हैं, प्रतीक का चुनाव महत्वपूर्ण नहीं है, लेकिन यदि सहसंबंध देखने के लिए कई अलग-अलग मान लगाए जाते हैं, तो रंग जैसे अन्य संसाधनों का उपयोग करने के अलावा, अंतर करना दिलचस्प है , विभिन्न प्रतीकों को चित्रित करके। लाइन नोड के लिए उपयोग किए जाने वाले ग्राफ़िक्स को आकार और अनुपात में संशोधित किया जाना चाहिए, जैसा कि उदाहरण के लिए, टेक्स्ट के साथ होता है, ताकि इसके आयाम निरपेक्ष हों और ताकि इसका अनुपात बनाए रखा जा सके, भले ही इसमें मौजूद बॉक्स के आयाम बदल जाएं। ग्राफ़िक।
पिछले उदाहरण में हमने पहले ही देखा था कि ड्राइंग के अनुपात को फिर से मापने और सही करने के लिए विभिन्न गुणांकों की गणना कैसे करें; ग्राफ़ के नोड्स या शीर्षों के प्रतीकों के प्रबंधन को कैसे कार्यान्वित किया जाए, इसके लिए एक संभावित समाधान वस्तुओं को संग्रहीत करना हो सकता है एसवीजी एक वेक्टर में और जब ग्राफ़ को एक नया मान पढ़कर अपडेट किया जाता है, या जब कंटेनर का आकार बदलकर इसे फिर से तैयार किया जाता है, तो इसकी स्थिति को संशोधित किया जाता है। पहले मामले में इसकी स्थिति को संशोधित करना होगा और दूसरे में संपत्ति के साथ इसके अनुपात को संशोधित करना होगा transform
और का मूल्य scale
. निम्नलिखित कोड फ़ंक्शन का एक संशोधन है actualizar_grafico()
ग्राफ़ शीर्ष प्रतीकों का पुनर्स्थापन शामिल करना।
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); } } |
फ़ंक्शन में किए गए संशोधन actualizar_grafico()
नया फ़ंक्शन प्राप्त करने के लिए actualizar_grafico_puntos()
वे पिछले उदाहरण के कोड में हाइलाइट किए गए हैं। सबसे पहले, पंक्ति 5 में, हम वस्तुओं का एक वेक्टर लेते हैं एसवीजी एक पैरामीटर के रूप में. इस वेक्टर में वे प्रतीक होंगे जिन्हें ग्राफ़ के नए नोड्स में पुनर्स्थापित करने की आवश्यकता है।
पंक्ति 39 और 40 में केंद्र के नए निर्देशांक निर्दिष्ट किए गए हैं, cx
y cy
, उन मूल्यों के लिए जिनका प्रतिनिधित्व किया जा रहा है। यदि प्रतीक केंद्र पर आधारित नहीं था, तो संभवतः इसमें एक ऑफसेट जोड़ना आवश्यक होगा cx
आधी चौड़ाई और अंदर cy
उन्हें ग्राफ़ नोड पर बिल्कुल पुनः स्थापित करने के लिए आधी ऊँचाई का।
पंक्तियों 57 से 61 में, वे बिंदु जो निर्देशांक के अनुरूप हैं, जो बाएं किनारे से कटे होने के कारण नहीं खींचे गए हैं, उन्हें ग्राफ़ के बाहर पुनर्स्थापित किया गया है। का समन्वय cy
शून्य और वह का cx
किसी भी ऋणात्मक संख्या (बिंदु से अधिक) ताकि कटने पर वह दिखाई न दे, जैसे कि ग्राफ़ के बाएँ भाग की खिड़की से एसवीजी.
जावास्क्रिप्ट के साथ किसी ऑब्जेक्ट से चार्ट प्रबंधित करें
अब तक समझाए गए सभी ऑपरेशनों को नए संस्करणों की अधिक विशिष्ट शैली के साथ ग्राफ़ को प्रबंधित करने के लिए एक ऑब्जेक्ट में एकीकृत किया जा सकता है जावास्क्रिप्ट. इस कार्यान्वयन विकल्प में एक ही वेब पेज पर विभिन्न मूल्यों के कई ग्राफ़ के समावेश को सरल बनाने का अतिरिक्त लाभ है।
कार्यान्वयन पर चर्चा करने से पहले, आइए ऑब्जेक्ट बनाने के सबसे सामान्य तरीकों की समीक्षा करें जावास्क्रिप्ट और फ़ंक्शन की कुछ ख़ासियतें जो IoT सेंसर ग्राफ़िक्स खींचने के प्रस्ताव को प्रभावित करती हैं।
यह पहले से ही समझाया गया था कि वस्तुओं को बनाने का नया तरीका जावास्क्रिप्ट (संस्करण 5 से उपलब्ध है एकमा स्क्रिप्ट) का उपयोग करना शामिल है Object.create
, जिसे "क्लासिक" के बजाय उपयोग करने की आदत डालनी चाहिए new
, जो निश्चित रूप से अभी भी सही ढंग से काम करता है, हालांकि इसका उद्देश्य वर्ग-आधारित वस्तुओं के साथ भाषाओं की शैली का अनुकरण करना अधिक है (जावास्क्रिप्ट कार्यशील विकल्प की तुलना में वस्तुओं के निर्माण को प्रोटोटाइप पर आधारित करता है)।
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(); } |
पिछला कोड आपको ऑब्जेक्ट बनाने के बीच के अंतर को याद रखने की अनुमति देता है Object.create
साथ new
. यह उस पर जोर देने का भी काम करता है, जबकि जिस फ़ंक्शन के साथ ऑब्जेक्ट बनाया गया है new
कोड में कहीं भी हो सकता है, ऑब्जेक्ट को इंस्टेंटियेट करने से पहले ही मौजूद होना चाहिए Object.create
(ES5_Object ऑब्जेक्ट कोई फ़ंक्शन नहीं है)।
पंक्ति 3 और 4 पर, फ़ंक्शन में गुणों के लिए एक डिफ़ॉल्ट मान सेट करने के लिए जो ऑब्जेक्ट बनाता है new
, प्रत्येक संपत्ति को संबंधित तर्क के मान पर असाइन किया गया है या (||
), यदि कोई तर्क पारित नहीं किया गया है, अर्थात, यदि वे अपरिभाषित हैं (undefined
), जैसा कि उस परिस्थिति का मूल्यांकन किया जाता है false
, डिफ़ॉल्ट मान असाइन किया गया है।
वह संदर्भ जिसमें कोई फ़ंक्शन निष्पादित किया जाता है जावास्क्रिप्ट दो मुद्दे उठाए गए हैं जिन्हें ध्यान में रखना महत्वपूर्ण है और दूसरों के साथ काम करने के बाद इस प्रोग्रामिंग भाषा का उपयोग करते समय यह भ्रमित करने वाला भी हो सकता है, जैसे कि C o सी + +, हमारे मामले में। संदर्भ में फ़ंक्शन के दायरे में परिभाषित चर (और वैश्विक वाले) शामिल हैं, जो, वैसे, एक दिलचस्प अवधारणा को जन्म देता है, "क्लोजर" जो संपूर्ण प्रोग्रामिंग शैली को स्थापित करता है जावास्क्रिप्ट. उन्होंने कहा, ऐसी उम्मीद की जा सकती है this
, जो ऑब्जेक्ट को संदर्भित करता है जब इसे परिभाषित करने वाले कोड के भीतर उपयोग किया जाता है, तो निष्पादन संदर्भ जिसमें इसे परिभाषित किया गया है, बनाए रखा जाता है लेकिन इसका उपयोग वह संदर्भ होता है जिससे फ़ंक्शन को कॉल किया जाता है। यह व्यवहार ज्यादातर मामलों में पारदर्शी है, लेकिन दो परिस्थितियाँ हैं जिनमें यह भ्रमित करने वाला हो सकता है: एक फ़ंक्शन जो किसी अन्य फ़ंक्शन के अंदर परिभाषित होता है और एक ऑब्जेक्ट इवेंट से बुलाई गई विधि। 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 */ |
पिछले कोड को निष्पादित करते समय, अंत में टिप्पणी किया गया पाठ कंसोल में प्रदर्शित होता है। दो चिह्नित पंक्तियाँ उस व्यवहार को दर्शाती हैं जो भ्रमित करने वाला हो सकता है: फ़ंक्शन निष्पादन संदर्भ probar_dentro()
नहीं probar()
, जैसा कि उम्मीद की जा सकती है, लेकिन window
, जो वैश्विक चर दिखाता है न कि समान नाम के गुण। यदि आप यह व्यवहार नहीं चाहते हैं, तो बस उच्चतम स्तर के फ़ंक्शन में एक वेरिएबल बनाएं और उसे असाइन करें this
, जैसा कि निम्नलिखित कोड में है।
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 */ |
जब किसी ईवेंट से कोई विधि कॉल की जाती है तो निष्पादन संदर्भ को नियंत्रित करने के लिए window
उदाहरण के लिए, ब्राउज़र विंडो का आकार बदलना, इसकी एक और ख़ासियत है जावास्क्रिप्ट: "फ़ंक्शन फैक्ट्रियां" प्रोग्रामिंग की संभावना, यानी, ऐसे फ़ंक्शन जो अन्य फ़ंक्शन उत्पन्न करते हैं, उन्हें वापस लौटाते हैं 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 |
उपरोक्त उदाहरण कोड में, विधि llamar()
डे लॉस ओब्जेक्टोस Contexto
यह काम नहीं करता है बल्कि एक अज्ञात फ़ंक्शन लौटाता है जो इसकी देखभाल करता है। यह सत्यापित करने के लिए कि सब कुछ अपेक्षा के अनुरूप काम करता है, एक वैश्विक वैरिएबल है जिसका नाम उस संपत्ति के समान है जिसे फ़ंक्शन कंसोल में प्रदर्शित करता है; यदि संदर्भ सही है, तो संपत्ति का मूल्य प्रदर्शित किया जाएगा, न कि वैश्विक चर का।
जावास्क्रिप्ट वाक्यों के अंत में छोड़े गए अर्धविराम चिह्नों को ठीक करने का प्रयास करें। यह एक आरामदायक लेखन शैली की अनुमति देता है लेकिन यह एक दोधारी तलवार है जिसे सावधानी से व्यवहार किया जाना चाहिए। ज्यादातर मामलों में, कई पंक्तियों में व्याप्त अभिव्यक्तियों में इससे उत्पन्न होने वाले अवांछनीय प्रभावों से बचने के लिए, आप कोष्ठक का उपयोग कर सकते हैं या जिस तरह से पहले आ सकते हैं जावास्क्रिप्ट कोड की व्याख्या करेगा; इसीलिए उदाहरण की पंक्ति 8 में शामिल है function
के पीछे return
, अगर मैंने दूसरी पंक्ति का उपयोग किया होता तो अर्थ बहुत अलग होता। मेरी राय में, सबसे पठनीय समाधान निम्नलिखित संस्करण में एक मध्यवर्ती (डिस्पेंसेबल) चर का उपयोग करना है; जाहिर है, एक बार व्यवहार समझ में आने के बाद, निर्णय प्रोग्रामर के अनुरूप होता है।
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); |
एक फ़ंक्शन के रूप में एक अभिव्यक्ति का मूल्यांकन करने के समान अर्थ में, एक फ़ंक्शन लौटाना, न कि वह मान जो फ़ंक्शन लौटाता है; पिछले उदाहरण की पंक्ति 21 पर (यह पिछले उदाहरण की पंक्ति 19 पर था) यह यहीं रुकता है clearInterval
फ़ंक्शन के साथ कॉल किया गया setInterval
. 30 सेकंड तक कार्य करने के लिए, स्टॉप को स्थगित कर दिया जाता है setTimeout
, जिसके बदले में पहले तर्क के रूप में एक फ़ंक्शन की आवश्यकता होती है; निष्पादन को एक पैरामीटर के रूप में वितरित करने के लिए clearInterval
उस वेरिएबल के साथ जिसमें आवधिक कॉल शामिल है (और फ़ंक्शन नहीं clearInterval
) अंतिम पंक्ति में अज्ञात फ़ंक्शन इसी के लिए बनाया गया है।
फ़ंक्शन परिभाषा को एकीकृत करने वाले कोड को लिखने के बीच का विकल्प, अधिक कॉम्पैक्ट (जैसा कि पंक्ति 21 में) या एक सहायक चर का उपयोग करना, मेरी राय में, अधिक पठनीय (जैसा कि पंक्तियों 19 और 20 में) प्रदर्शन में थोड़ा भिन्न होता है और अधिक शैली और पठनीयता पर निर्भर करता है रखरखाव।
कोड का परीक्षण करने के लिए, सर्वर पर डेटा रखने से पहले, आप वांछित सीमा में यादृच्छिक मानों के जनरेटर का उपयोग कर सकते हैं या नियंत्रित मानों के साथ तालिकाएँ तैयार कर सकते हैं जो वांछित परिस्थितियों में संचालन का अनुकरण करते हैं। निम्नलिखित उदाहरण संपूर्ण श्रेणी में एक सरल डेटा जनरेटर का उपयोग करता है, यही कारण है कि वे थोड़े अतिरंजित दिखाई देते हैं।
परीक्षण करने के लिए, आप कर सकते हैं उदाहरण का पूरा कोड डाउनलोड करें में लिखे गए एक वेब पेज द्वारा निर्मित एचटीएमएल, शैली सीएसएस और कोड जावास्क्रिप्ट. उत्तरार्द्ध सबसे अधिक प्रासंगिक है, क्योंकि अन्य घटक केवल न्यूनतम समर्थन हैं, बहुत सरल हैं और संबंधित अनुभागों के लेखों में बहुत अधिक विकसित हैं।
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); } |
टिप्पणी पोस्ट