Створюйте та змінюйте графіку SVG даних із датчиків, підключених до IoT за допомогою JavaScript

Створюйте та змінюйте графіку SVG даних із датчиків, підключених до IoT за допомогою JavaScript

Створюйте та змінюйте графіку SVG даних із датчиків, підключених до IoT за допомогою JavaScript

У цій останній частині циклу статей про малювання графіка з даними датчиків, підключених до Інтернету речей, настав час поговорити про те, як створити або змінити за допомогою JavaScript малюнки у форматі SVG і деякі з елементів HTML які служать контейнером або представляють додаткову інформацію до графіки.

Зміст

    Графіки даних від датчиків, підключених до контейнера Інтернету речей (IoT) у HTMLГрафіки даних датчиків, підключених до Інтернету речей (IoT), визначення зовнішнього вигляду в CSSГрафіки даних від датчиків, підключених до Інтернету речей (IoT), малювання за допомогою SVGГрафіки даних від датчиків, підключених до Інтернету речей (IoT). Генерація та модифікація за допомогою JavaScript

    Передбачається, що цільові користувачі цього підручника мають профіль електроніки та комп’ютерного програмування. мікроконтролери, вони можуть бути не знайомі HTML, CSS o SVG; З цієї причини в попередніх частинах було зроблено короткий вступ до мови або відповідної технології. У цій останній частині підхід дещо інший, оскільки читачі напевно знають, як програмувати, можливо, що використовуючи мову C + + що як JavaScript, спільний базовий синтаксис з C і це можна взяти як посилання, щоб пропустити більшість базових концепцій програмування та, таким чином, зосередитися на відмінностях і конкретному використанні, яке нас цікавить для створення сенсорної графіки в IoT.

    Назва дає ключ до першої відмінності: JavaScript Це мова програмування сценарій (дефіс) і як такий, він є інтерпретується, немає необхідності компілювати його; контекст, у якому сценарій (наприклад, веб-браузер) буде читати, перекладати та виконувати накази. Якщо бути точним, то в більшості випадків є компіляція під час виконання (JIT), але для процесу написання коду JavaScript Це не впливає на нас, ми просто пишемо код, і він може працювати.

    Назва також містить першу плутанину: JavaScript не має жодного відношення до Java. Спочатку, коли він був розроблений Netscape для свого браузера він спочатку називався Mocha, а потім менш заплутаним LiveScript. Після його успішного впровадження в браузери та виходу за їх межі, він був стандартизований як ECMAScript ( ECMA-262, версія 6 на момент написання), щоб стати нейтральним щодо браузерів, які його використовують. В даний час також існує стандарт ISO з версії 5, 2011 (ISO / IEC 16262: 2011 на момент написання статті)

    Змінні, основні типи даних та об’єкти в JavaScript

    На відміну від того, що відбувається, наприклад, в C + +, en JavaScript тип даних не включається під час оголошення змінної а також тип, пов’язаний зі змінною, не є фіксованим, можна призначати значення іншого типу під час виконання програми.

    У попередньому прикладі було оголошено змінну "thing" (без вказівки типу даних), потім присвоєно дані іншого типу, і вони консультуються з typeof тип що JavaScript що він інтерпретував. Щоб налагодити код, ви можете написати його на консолі інспектора веб-переглядача (що не вплине на представлення веб-сторінки) за допомогою console.log().

    Щоб примусово перетворити дані в певний тип, особливо текстові в числові, ви можете використовувати такі функції, як parseInt() o parseFloat() які перетворюються на цілі чи числа з плаваючою комою відповідно. Зворотне перетворення можна здійснити за допомогою String(), хоча це навряд чи буде потрібно, оскільки зазвичай достатньо автоматичного перетворення. с parseFloat()Наприклад, ви можете отримати значення властивості веб-сторінки, наприклад ширину або висоту об’єкта, яке включає одиниці; Таким чином вираз parseFloat("50px"); у результаті поверне 50, числове значення.

    En JavaScript немає різниці між подвійними та одинарними лапками; Тип даних в обох випадках string, і кожен з них може включати інший без потреби в кодах виходу.

    У попередньому прикладі можна побачити, що змінна, якщо вона була оголошена (існує), але їй не присвоєно жодного значення, містить невизначений тип даних (undefined). Непризначений об’єкт має значення null; Тобто об'єкт існує, але без вартості; змінна, яка посилається на неї, не матиме a typeof undefined sino object. Об’єкт також може бути порожнім, тобто не нульовим, але не мати жодних властивостей.

    в визначити об'єкт в JavaScript у дужках ({ y }) властивості або методи, розділені знаком двокрапки (:) назва властивості значення властивості та кома (,) різні властивості. Ви можете знайти більше інформації про цей спосіб вираження об’єкта в статті на Формат JSON.

    Хоча ви можете використовувати синтаксис, який може наштовхнути вас на іншу думку, en JavaScript Немає класів, крім прототипівТобто, щоб об’єкт успадкував властивості та методи, створюється інший об’єкт (прототип), який інші (дочірні) використовують як посилання. Синтаксис, найбільш близький до стилю JavaScript використовувати прототип Object.create хоча його також можна (і іноді корисно) використовувати new як і в інших об'єктно-орієнтованих мовах.

    в запит, якщо один об'єкт є екземпляром іншого, якщо ви використовуєте його як прототип, якщо ви успадковуєте його властивості, коротше кажучи, ви можете використовувати instanceof (створено за допомогою new) Або isPrototypeOf (створено за допомогою Object.create), який матиме значення true, коли об’єкт використовує прототип, і значення false, якщо він не використовує.

    Після створення об’єкта з використанням іншого як прототипу, тобто коли об’єкт створено, його можна додати нові властивості або змінити властивості прототипу використовуючи крапковий синтаксис, як у gato.peso=2.5.

    La масиви в JavaScript Вони відрізняються від тих, які ви, напевно, знаєте C. Почнемо з того, що вони оголошуються без необхідності вказувати їхню довжину, лише за допомогою знаків відкриття та закриття квадратних дужок ([ y ]), компоненти можуть бути неоднорідними (різні типи даних в одному масиві), а нові елементи можна додавати без обмежень. Матриці JavaScript фактично є списками (колекціями) елементів, до яких посилається цифровим індексом або назвою. Масив може одночасно містити числові індекси та імена елементів, але зазвичай використовують об’єкти (властивості) для використання другого типу.

    Як видно з попереднього прикладу, щоб дізнатися, чи відповідає змінна екземпляру масиву (це об’єкт масиву), ви можете використовувати instanceof, як це вже використовувалося з загальними об’єктами або, у новіших версіях JavaScript ви можете вдатися до Array.isArray()

    Для доступу до елементів масиву можна використовувати його індекс (matriz[7]) або за назвою властивості з іменем у квадратних дужках (matriz["nombre"]) або зі звичайним синтаксисом крапок для об’єктів (matriz.nombre). Оскільки ім'я є текстовим рядком, для його створення можна використовувати вираз, включаючи змінні. Для циклу по масиву з властивостями можна використовувати цикл із форматом for(propiedad in matriz).

    Для нашої мети цікаво лікувати об'єкт Date, за допомогою якого можна представляти дату й час і керувати ними JavaScript. Об’єкт можна створити без даних, тож він матиме поточну дату й час, або його можна створити, вказавши дату як значення, або в мілісекундах з 1 січня 1970 року (наприклад, Час Unix або POSIX але виражені в мілісекундах замість секунд) або вказуючи окремі значення року, місяця, дня, години...

    Об'єкт включає повну серію методи запиту або встановлення дати й часу:

    • now()
      Повертає поточну дату й час, виражені в мілісекундах з 1 січня 1970 року

    • getTime() | setTime()
      Отримує або змінює, відповідно, значення часу в мілісекундах з 1 січня 1970 року. Використання valueOf(), який є методом, присутнім у більшості об’єктів, також отримується значення відповідного об’єкта Date, наприклад getTime() з Час Unix або POSIX виражається в мс.

    • getMilliseconds() | setMilliseconds()
      Використовується для запиту або встановлення дробової частини мілісекунд об’єкта Date на якому він виконується. Якщо перевірити, отримане значення буде між 0 і 999, але можна призначити більші значення, які будуть накопичуватися в загальній даті та часі, тому, як і решта методів get, це служить для збільшення значення об’єкта. Date (або зменшити, якщо використовуються від'ємні значення).

    • getSeconds() | setSeconds()
      Повертає або змінює, відповідно, значення секунд об'єкта Date.

    • getMinutes() | setMinutes()
      Використовується для консультації або встановлення хвилин об’єкта Date.

    • getHours() | setHours()
      Дозволяє переглядати або змінювати години (від 0 до 23) об'єкта Date.

    • getDay()
      Повертає день тижня для дати, виражений значенням від 0 до 6 (з неділі по суботу).

    • getDate() | setDate()
      Повертає або змінює день місяця об’єкта Date на якому він нанесений.

    • getMonth() | setMonth()
      Використовується для перегляду чи зміни номера місяця об’єкта Date.

    • getFullYear() | setFullYear()
      Запитує або встановлює значення року для об’єкта, що містить дату та час.

    Попередні способи Date включити версію UTC мати можливість безпосередньо працювати з універсальним часом без необхідності виконувати проміжні обчислення. У цьому сенсі, наприклад, getHours() має версію getUTCHours() o getMilliseconds() альтернатива getUTCMilliseconds() альтернативно працювати з офіційним (законним) або універсальним часом. с getTimezoneOffset() Ви можете знати різницю, яка існує між універсальним часом і місцевим офіційним часом.

    Функції JavaScript

    Якщо ви читаєте це, ви точно знаєте, як програмувати. мікроконтролери en C про ан C + + і знати поняття функції. Хоча основна ідея та сама, в JavaScript Спосіб їх визначення та використання дещо інший. Для початку вже було сказано, JavaScript Він явно не використовує типи даних, тому вам не потрібно вказувати це під час визначення функції. Слідувати, Для функції необов’язково мати назву, вона може бути анонімною. Їх можна пов’язати зі змінною для їх виклику, але це також може бути необов’язковим, оскільки інколи корисно викликати їх негайно, для чого після визначення функції додаються дужки та параметри.

    Щоб визначити функцію, введіть префікс function, якщо застосовно, напишіть ім’я, аргументи (параметри, передані функції) у дужках і код, який буде виконано під час виклику функції, у дужках.

    Звичайно, у попередньому прикладі змінна "результат" взагалі не була потрібна, але це хороший привід запам'ятати область змінної, який працює так, як ви очікуєте: змінна "result" існує лише у функції "double". в JavaScript також можна використовувати let, замість var, щоб охопити змінну контекстом блоку коду (включений у фігурні дужки, { y })

    Говорячи про об’єкти в попередньому розділі, не вистачало чогось фундаментального: властивості були визначені, але методи не були визначені. Як і очікувалося, об'єктні методи є функціями, вони не мають імен і використовуються (викликаються) з імені (властивості), призначеного визначенням об’єкта.

    У попередньому прикладі вже існує метод «view_temperature», який відображає значення властивості «current_temperature» через консоль. Це не дуже корисно, але дає більш повне уявлення про те, що таке визначення об'єкта JavaScript.

    Для доступу методів об’єкта (функцій) до його властивостей використовуйте this, як і в попередньому прикладі в рядку 11, при використанні властивості «current_temperature».

    Доступ до об’єктної моделі документа (DOM) за допомогою JavaScript

    від JavaScript Ви маєте доступ до вмісту веб-сторінки, на якій вона працює, а також до деяких аспектів браузера, який відображає цю сторінку, але не до системних ресурсів. Структура даних, яка підтримує властивості та методи, з яких здійснюється доступ JavaScript частина об'єкта вікна, зокрема, зміст об’єкта (документ HTML) відповідає об’єкту document. Хоча це іноді використовується для ясності, немає необхідності передувати window методам або властивостям, щоб посилатися на них, достатньо, наприклад, використовувати document, немає необхідності писати назву кореневого об’єкта, як у window.document, доки є посилання на поточне вікно.

    Найбільш вживана форма знайти об’єкт у документі HTML Це через метод getElementById(), якому як аргумент передається ідентифікатор, який було вказано при створенні коду HTML. З того, що було пояснено в попередніх розділах, легко припустити, що ви також можете отримати доступ до компонентів всередині об’єкта document використовуючи крапковий синтаксис (document.componente) або в квадратних дужках із використанням імені (document["componente"]), найкорисніший, такий як числовий індекс, складний у використанні та непрактичний під час доступу до вмісту веб-сторінки, створеної вручну.

    з JavaScript ти можеш отримати елемент, який містить інший елемент (елемент або батьківський вузол) консультування вашої власності parentNode або вашу власність parentElementрізниця в тому, що батьківський елемент (parentElement) кінцевого елемента рядка DOM Це нуль (null) і батьківський вузол (parentNode) є самим документом (document).

    в змінити вміст елемента HTML, наприклад, етикетка <div>, Його можна використовувати innerHTML і щоб змінити його властивості, ви можете призначити йому інший клас className або змінювати його властивості окремо style. Переглядати стиль, який відображається елементом на веб-сторінці, не обов’язково корисно style оскільки це може залежати від кількох факторів або просто не було вказано явно. Щоб перевірити стиль елемента, який остаточно відображається на веб-сторінці, використовується метод getComputedStyle.

    До елемента документа HTML Йому можна призначити кілька класів, щоб визначити його зовнішній вигляд і поведінку керувати списком класів об'єкта з JavaScript ви можете вдатися до classList який пропонує методи add щоб додати новий клас до списку, remove щоб видалити його, toggle щоб замінити його або переглянути вміст списку класів елемента item і contains, який повертає клас, який займає певну позицію в списку, і значення true o false чи є певний клас у списку.

    У попередньому прикладі він розташований с getElementById об’єкт, яким ви хочете маніпулювати (елемент <div> за його id), перед зміною зовнішнього вигляду вміст видаляється шляхом призначення за допомогою innerHTML порожній текстовий рядок, йому призначається новий клас className і його стиль змінено за допомогою style залежно від значення вмісту (температура), змінюючи колір, якщо це можливо, через властивість color. Після встановлення аспекту значення знову записується за допомогою innerHTML.

    У другій частині наведеного вище прикладу (рядки з 9 по 19) здійснюється доступ до елемента коду HTML використовуючи синтаксис document[] і майно id елемента, щоб змінити його список класів за допомогою методу classList.remove() і з методомclassList.add(), на основі результатів кількох запитів, які виконуються в умовних виконаннях, за допомогою яких вони порівнюються classList.contains().

    Коли це буде посилатися на елемент HTML кілька разів у всьому коді JavaScript, це трохи ефективніше призначити його змінній або використовуйте його індекс замість назви, інакше метод, який ви б використовували JavaScript щоб отримати її щоразу, знадобиться шукати її ім’я, що затрачає трохи більше часу, ніж у випадку доступу до змінної.

    в додати нові об’єкти до документа HTML, їх можна спочатку створити за допомогою методу createElement de document і пізніше включити їх до решти елементів у тій точці дерева, яка потрібна appendChild. Щоб створити об'єкт XML, як предмети SVG який ми використовуємо для малювання графіка датчиків IoT, ви можете використовувати createElementNS (НС для простір імен). Як пояснюється при розмові про формат SVG, простір імен, який йому відповідає (для поточної версії), є http://www.w3.org/2000/svg, який слід передати createElementNS як аргумент разом із типом елемента, svg, в цьому випадку.

    Una альтернатива innerHTML щоб додати текст як вміст до елемента документа HTML це метод createTextNode() об'єкт document. За допомогою цієї альтернативи ви можете створити новий текст (до якого пізніше можна отримати доступ, якщо його присвоїти змінній), який включено в дерево об’єктів за допомогою методу appendChild(). Як альтернатива appendChild(), який додає новий вміст у кінець того, що вже існує у вузлі, до якого він додається, ви можете використовувати метод insertBefore(), який додає новий об’єкт перед існуючим. Носити insertBefore() замість appendChild() надає метод, який служить, наприклад, для сортувати нові об'єкти перед існуючими коли елемент має бути попереду іншого (як у списку) або покривати або бути покритим у графічній структурі, у якій є елементи ближче до переднього плану чи фону.

    Реагувати на події за допомогою JavaScript

    Коли шлях о використовувати веб-сторінку як контейнер для графіків підключених датчиків IoT це було використано onload На етикетці <body> щоб почати малювати графік. Це властивість, пов'язане з кодом об'єктів HTML, відноситься до Події JavaScript. Як уже пояснювалося, він виконує функцію, коли сторінка завантажується. Хоча це було пов'язано з кодом HTML щоб більше пам’ятати, це можна було б записати в коді JavaScript як body.onload=dibujar; буття dibujar ім'я функції, яка повинна запускатися під час завантаження веб-сторінки.

    В останніх версіях JavaScript події можна асоціювати з функціями за допомогою addEventListener з форматом objeto.addEventListener(evento,función); або за допомогою синтаксису objeto.evento=función; який також працює в старих реалізаціях. Щоб від’єднати функцію, пов’язану з подією, у вас є removeEventListener який має такий самий формат, як addEventListener.

    JavaScript Він здатний реагувати на безліч подій, які можуть відбуватися на веб-сторінці. Наприклад, він може визначити, коли клацнуто елемент HTML з onmousedownабо при натисканні за допомогою onclick, коли натиснуто клавішу з onkeydown, керуючи смугою прокрутки за допомогою onscroll. Для нашої мети нам цього достатньо виявити завантаження сторінки за допомогою onload і його зміна розміру з onresize. Ці події ми будемо пов’язувати з об’єктами body y window Дель DOM відповідно. Перший можна призначити в коді HTML, як видно, і другий у коді JavaScript всередині функції, викликаної першим і з форматом window.onresize=redimensionar; буття redimensionar функція, яка буде викликана кожного разу, коли вікно змінює розмір.

    Запустити через інтервал часу

    JavaScript має два ресурси для відстрочене виконання: setTimeout, який виконує функцію через інтервал часу і setInterval який буде виконувати функцію кожен певний інтервал часу. Обидва методи вимагають параметрів (1) викликаної функції та (2) інтервалу часу, вираженого в мілісекундах. Щоб зупинити їх роботу, ви можете призначити результат, що повертається цими функціями, змінним і передати їх як аргумент до clearTimeout або clearInterval коли ви не хочете викликати їх знову (або коли ви не бажаєте, щоб вони виконувалися вперше) setTimeout o setInterval відповідно.

    У попередньому прикладі представлено метод alert який служить для відображення попереджувального знака. Хоча він широко використовувався в минулому, зараз він майже заборонений у коді JavaScript через те, наскільки агресивним (нав’язливим) є закриття веб-сторінки діалоговим вікном.

    У програмі, написаній для a мікроконтролер невеликої серії (наприклад, на тарілці Arduino Uno) зазвичай використовують глобальні змінні, як у попередньому прикладі в JavaScript, оскільки код короткий і не особливо заплутаний, оскільки часто функції реалізуються ad hoc і оскільки використання глобальних змінних дає змогу передбачити використання пам’яті дуже простим та інтуїтивно зрозумілим способом, що є критичним у системах з невеликою кількістю ресурсів . Натомість en JavaScript Зазвичай використання глобальних змінних зводиться до мінімуму. оскільки йому не потрібно поспішати з використанням пам’яті, оскільки він працює нормально на a центральний процесор з ресурсами, значно перевершуючими ресурси a MCU, тому що він, ймовірно, співіснуватиме з великою кількістю стороннього коду, з яким він повинен працювати без втручання, і оскільки це відкрита система, майбутній контекст виконання неможливо передбачити (програма мікроконтролер small повністю визначає його роботу без додавання додаткового коду, коли він працює) і тому, що розміри додатків можуть ускладнити читання, якщо код не інкапсулює його роботу, роблячи методи максимально самодостатніми.

    Математичні операції з об’єктом JavaScript Math

    В об'єкт згруповані математичні операції більш складного математичного розрахунку 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 e число (≃2.718281828459045)
    • Math.exp(n) e піднесено до параметра n: en
    • Math.floor(n) Округліть параметр n до найближчого цілого числа вниз
    • Math.log(n) Натуральний логарифм (за основою e) параметра n
    • Math.LN2 Натуральний логарифм (за основою e) від 2 (≃0.6931471805599453)
    • Math.LN10 Натуральний логарифм (за основою e) від 10 (≃2.302585092994046)
    • Math.LOG2E Логарифм e за основою 2 (≃1.4426950408889634)
    • Math.LOG10E Логарифм e за основою 10 (≃0.4342944819032518)
    • Math.max(a,b,c,…) Найбільше значення зі списку переданих параметрів
    • Math.min(a,b,c,…) Найменше значення зі списку переданих параметрів
    • Math.PI Число π (≃3.141592653589793)
    • Math.pow(n,m) Перший параметр n піднято до другого параметра m: nm
    • Math.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 (асинхронний JavaScript і XML) через предмет XMLHttpRequest de JavaScript. Побудова графіка даних виконується повторним використанням об’єкта SVG який уже є в коді HTML і містить графік, координати якого змінено, щоб вони відповідали новим завантаженим даним.

    У прикладі цієї пропозиції, крім оновлення креслення, також оновлюється текст на веб-сторінці, який показує дату та значення останніх виміряних даних для кожного графіка.

    На стороні сервера є база даних, яка містить інформацію що датчики, підключені до IoT, контролювали. Ця база даних зчитується запитом об'єкта XMLHttpRequest відповідаючи інформацією, закодованою в Формат JSON, хоча назва використовуваного методу передбачає зв’язок із форматом XML.

    У першому посібнику polaridad.es про Зберігання даних IoT Ви можете побачити приклад інфраструктури для керування інформацією з боку сервера, яку надають пристрої, підключені до Інтернету речей. У цій серії статей сервер використовується як ресурс Apache з якого можна використовувати мову програмування PHP отримати доступ до бази даних MySQL o MariaDB. На серверах, які використовуються для підтримки IoT, дуже часто можна знайти бази даних MongoDB (NoSQL) і мова програмування JavaScript на Node.js як програмна інфраструктура.

    Наступна функція відповідає за запит останніх даних одного з датчиків із сервера. Під час виклику функції об’єкт використовується як аргумент JavaScript який підтримує намальовані дані. Якщо один і той самий графік представляє кілька значень, наприклад, для візуального пошуку кореляції, можна надіслати запит до сервера, щоб повернути декілька одночасно, більш оптимальний метод через спосіб роботи сервера. протокол HTTP.

    У третьому рядку попереднього прикладу готується запит, який буде зроблено на сервер, в якому буде переданий аргумент «зона», значенням якого буде назва або код моніторингового місця, оскільки інформація про в одній базі даних можуть співіснувати різні датчики (наприклад, термометри, які вимірюють температуру в різних кімнатах). Очікується, що параметр, переданий у попередню функцію, об’єкт із даними діаграми, міститиме властивість із назвою кімнати («name_suffix»).

    Між рядками 7 і 14 попереднього коду об’єкт XMLHttpRequest який зберігається у змінній "ajax". Перш ніж вибрати спосіб створення об'єкта, ви шукаєте window якщо XMLHttpRequest був недоступний (те, що сталося в старих версіях провідника Microsoft, і хоча він значно відстає, він служить прикладом альтернатив для створення об’єкта за допомогою (більш рідного) синтаксису. Object.create o newподібно до інших об’єктно-орієнтованих мов.

    Щоб мати можливість негайно керувати відповіддю, код, який її обробляє, готується в рядках з 15 по 26 перед тим, як надсилати запит серверу.

    Шлях зробити запит HTTP до сервера складається з відкрити з'єднання з open із зазначенням типу та сторінки (необов'язково ім'я користувача та пароль), підготувати заголовки протоколу с setRequestHeader y відправити запит з send. Заголовок HTTP Content-length вам знадобиться знати довжину запиту (кількість символів), яка обчислюється за допомогою length.

    Коли запит AJAX готовий, функція, пов’язана з подією, виконується onreadystatechange. Замість призначення функції в попередньому прикладі на льоту визначається анонімна функція, яка керуватиме отриманням даних, що надходять із сервера. Перш за все, у рядку 18 перевіряється статус запиту «завершено», що відповідає значенню 4 майна readyState, що статус "OK" для протокол HTTP (код 200), які можна отримати з майна status і що дані, які надійшли, є Формат JSON, консультуючи власність responseType.

    Переконавшись, що стан відповіді відповідає очікуванням, у рядку 20 попереднього прикладу створює об'єкт із результатом, перетворюючи текст JSON. Відповідь містить дату, яку потрібно повернути, це дозволяє нам побачити, чи результат, який надсилає сервер, уже був раніше представлений на графіку, який перевіряється в рядку 21. Якщо дані нові, у рядку 23 функція, яка відповідає за перемальовування графіка з новою інформацією.

    Ідея, коли пропонується цей метод читання, полягає в тому, що дані будуть оновлюватися дуже часто. Якщо представлена ​​інформація відповідає тривалому періоду (наприклад, температури за день або тиждень), можна реалізувати початковий запит, який збирає всі доступні дані, а потім запит, подібний до того, що в прикладі, який оновлює їх у кореспондент періоду.

    Генерувати випадкові дані для тестування

    Коли вся інфраструктура сервера та клієнта буде готова, функція, подібна до тієї, що описана в попередньому розділі, відповідатиме за читання даних і малювання з ними графіка, але На етапі тестування може бути практичніше використовувати випадкові числа в контрольованому діапазоні щоб перевірити, чи правильно написаний код. Наступна функція може слугувати прикладом для отримання даних під час створення кінцевої програми.

    Замість того, щоб читати інформацію з бази даних, наведений вище приклад генерує її випадковим чином і передає її функції, відповідальній за малювання графіка. Винайдені дані — це вектор, утворений датою, вираженою у вигляді значення в мілісекундах, моментом запису інформації датчика та даними моніторингу, які знаходяться між максимальним значенням і мінімальним значенням.

    У цьому прикладі під час генерування дати її можна затримати до однієї секунди (1000 мілісекунд) відносно дати на момент винаходу. як Math.random() генерує число від 0.0 до 1.0, множення його на 1000 дає число від 0 до 1000, яке потім перетворюється на ціле число. Таким же чином значення отримується множенням випадкового числа на діапазон (максимум мінус мінімум) і додаванням мінімуму.

    Намалюйте графік датчиків IoT за допомогою діаграми SVG

    Оскільки ми побачили, як ми можемо отримати значення, які ми хочемо представити (температура, у прикладі) та їхнє місцезнаходження в часі, які можуть бути виражені разом у формі координат, приклад нижче показує функцію для малювання шляху яка з’єднує ці точки, і, за бажанням, кольорову область, обмежену лінією вгорі. Результат буде схожий на наступне зображення.

    Приклад графіка, створеного за допомогою SVG і JavaScript для представлення даних з датчиків IoT

    Горизонтальна вісь (X) графіка представляє час, а вертикальна вісь (Y) – значення, які контролювали датчики, підключені до IoT. Горизонтальний інтервал становить кілька секунд, оскільки в цій пропозиції графік оновлюється дуже часто (наприклад, кожну секунду), щоб надати інформацію про стан датчиків майже в реальному часі.

    У попередньому коді є два цікаві аспекти, по-перше, обчислення, яке дозволяє адаптувати діапазон значень, які представлені а по-друге будівництво власності d який вказує координати точок на макеті (path).

    Щоб адаптувати діапазон представлених значень, вони переміщуються від мінімуму та масштабуються так, щоб видима величина відповідала розміру графіка. У випадку часу зсув отримується шляхом віднімання діапазону, який потрібно відобразити, із найдовшого часу (дата й час, найближчі до поточного) (20 секунд у прикладі). Зміщення значень температури є нижнім діапазоном (один градус) мінус найнижче значення, так що дані, наведені нижче, є найбільш схожими на найнижче дозволене значення, але залишають запас, який дозволяє нам оцінити ті, які відповідають .пас

    Коефіцієнт, який множить значення часу для отримання горизонтальних координат графіка, виходить шляхом ділення загальної ширини графіка (100 одиниць у прикладі) на представлений діапазон часу (20 секунд у прикладі). Щоб отримати коефіцієнт зі скалярними значеннями температури, слід пам’ятати, що представлений діапазон проходить від запасу нижче мінімального значення до запасу вище максимального, на один градус в обох випадках. Таким чином, коефіцієнт вертикального масштабу є результатом ділення висоти графіка (100 одиниць у прикладі) на максимальне значення мінус мінімальне плюс верхнє та нижнє поле. Оскільки ці значення могли повністю розвиватися при негативних температурах, ми використовуємо Math.abs() використовувати абсолютне значення різниці.

    Власність d об'єкт path Він будується шляхом об’єднання координат точок у тексті. Кожній парі координат передує код SVG L, який проводить лінію від поточної позиції до абсолютного значення, яке вказується координатами. Значення X і Y розділяються комами та кожною операцією SVG відокремлюється пробілом від наступного.

    Щоб почати макет, використовуйте код M (перейти до абсолютної координати). У випадку закритого та заповненого графіка ви починаєте знизу праворуч, у випадку відкритого графіка, який малює профіль даних, ви починаєте з останнього представленого значення (останнього). Для завершення закритого макета використовується код Z додаючи як останню точку ту, яка має те саме значення координати X, що й остання точка лінії, а як координату Y найменше представлене значення.

    У цьому прикладі функція dibujar_grafico(), який є викликом під час завантаження сторінки, отримує початкові значення для тестування (а не останнє значення в реальному часі) і готує діапазон, у якому дані будуть відображатися: 20 секунд (20000 мс) по горизонталі та 15°C у вертикально від -5°C до +10°C з верхнім і нижнім полем на один градус. Зробіть два дзвінки до actualizar_grafico(), у першому проході true як аргумент, який вказує, що діаграма повинна бути закрита, щоб представити заповнену область, і під час другого виклику вона пропускається false провести лінію. У кожному випадку об'єкт path модифікований – це той, який має відповідний вигляд, із заливкою і без рамки в першому випадку та з певною товщиною лінії і без заливки в другому.

    Функція actualizar_grafico() працювати над об'єктом SVG який використовує наступний код як контейнер HTML. Об'єкт SVG містить два шляхи, один для малювання лінії, а інший для малювання заповненої області. Під час завантаження веб-сторінки з елемента <body> попередня функція викликається автоматично, dibujar_grafico() завдяки події JavaScript onload.

    У рядку 10 коду HTML вище, ширина (як приклад) 820 px і висота 150 px встановлено в стилі (те, що в остаточній версії буде доцільно зробити з класом і документом CSS). Здається дивним, що рядки 13 і 14 визначають розмір об'єкта SVG наприклад 100% ширини та висоти (що найкраще відповідає розмірам вікна, 100×100). Як уже згадувалося, причина цього полягає в тому, щоб завжди працювати з відомими розмірами та коригувати представлені значення до них. Інші альтернативи полягають у тому, щоб кожного разу обчислювати простір графіка, а потім переналаштовувати значення або примусово фіксувати розміри для графіка, яких документ повинен буде дотримуватися.

    Вибравши графік, розміри якого змінюються відповідно до коду HTML, необхідно включити майно vector-effect з мужністю non-scaling-stroke щоб запобігти деформації товщини ліній, коли графік не підтримує вибрані пропорції 1:1 на веб-сторінці, на якій він відображається, як це відбувається в попередній пропозиції.

    Щоб «обрізати» графік і показати лише вибрану вами область, використовуйте viewBox. У цьому випадку ми вирішили побачити частину графіка, яка починається з 0,0 (верхній лівий кут) і має розміри 100x100 вниз і праворуч. Частина малюнка, розташована в координатах з від'ємними значеннями або більше 100, не буде відображатися на веб-сторінці, навіть якщо вони існують в об'єкті SVG

    Додайте нові елементи до малюнка SVG

    У попередньому прикладі функція actualizar_grafico() використовувати макет SVG на яку змінено право власності d, що виражає координатний ланцюг. Альтернативою було б створювати весь об’єкт кожного разу, коли він перемальовується. Перевага першого варіанту полягає в тому, що графічний вигляд (наприклад, товщина або колір) визначається в коді HTML, обмеження полягає в тому, що об’єкти мають бути створені раніше.

    Щоб створити об’єкти SVG, використовуйте createElementNS(), що дозволяє включати простір імен. У наведеному нижче прикладі створюється новий текстовий об’єкт (text) і пов’язаний з елементом SVG яка вже існує в коді HTML веб-сайту. Після створення нового елемента йому призначаються властивості setAttribute() і додається до SVG з appendChild().

    Змініть співвідношення елементів малюнка

    Якщо ви спробували додати позначки за допомогою функції в прикладі в попередньому розділі, ви побачили, що текст виглядає деформованим, коли пропорція об’єкта на веб-сторінці (width y height коду HTML) не дорівнює зображеній площі (viewBox). Щоб адаптувати пропорції, необхідно знати розміри об’єкта SVG для якого ви можете переглянути стиль об’єкта або контейнера HTML, якщо об'єкт SVG передати це майно. Передача права власності transform до об’єктів SVG які залежать від пропорції, деформацію можна виправити шляхом застосування операції масштабування scale() в якому коефіцієнт в X відрізняється від коефіцієнта в Y.

    SVG дозволяє згрупувати декілька об’єктів, утворюючи новий складений елемент, який також підтримує властивості, як прості предмети. Щоб застосувати ту саму трансформацію до серії об’єктів одночасно, а не до кожного об’єкта окремо, ви можете згрупувати їх відповідно до цього ресурсу та застосувати одну властивість transform всім їм.

    Як пояснюється при розмові про Формат SVG, елементи групи укладено в мітки <g> y </g>. Щоб додати з JavaScript елементів до групи SVG використовується, як видно з попереднього прикладу, appendChild() після визначення нового об’єкта.

    Для встановлення походження під час застосування перетворень властивість можна використовувати для об’єктів SVG transform-origin, значенням якого є координати X і Y точки, з якої починається перетворення. Якщо значення для джерела перетворення явно не вказано (у веб-браузері), використовується центр координат. На жаль, на момент написання статті вказівка ​​поведінки перетворень із використанням джерела, відмінного від джерела за замовчуванням, не є однорідним у різних браузерах, і його слід використовувати з обережністю.

    Поряд з масштабним перетворенням с scale Є й інші, наприклад ротація с rotation і рух с translate, які пропонують а альтернатива представленню графів: замість отримання нових координат ви можете представити їх у власному просторі та трансформувати графік відповідно до формату, у якому ви хочете їх представити.

    Додайте до діаграми посилання

    Тепер, коли основна частина графіка вирішена шляхом побудови значень із профілем і зафарбованою областю, її можна доповнити посиланнями, які допоможуть її читати. Як приклад, давайте почнемо з малювання деяких горизонтальних посилань (ліній), які позначають максимальні та мінімальні допустимі значення, а також бажане значення. Як пояснено, ви можете додати об’єкти до SVG прямо з JavaScript або включити їх вручну в код HTML і змінити їх пізніше за допомогою JavaScript.

    Здається логічним позначити ці горизонтальні посилання текстом, який пояснює значення, яке вони представляють. Для виділення тексту можна використовувати прямокутники, які будуть виділятися на тлі та малюнку. Оскільки тексти повинні бути масштабовані, щоб компенсувати деформацію, усі вони можуть бути згруповані в об’єкт, до якого буде застосовано масштаб; Основна перевага цього способу полягає в тому, що ви можете змінювати їх за одну операцію, якщо розмір контейнера графіка (вікна браузера) змінюється та змінюється ця пропорція, яку виправляє масштаб.

    У наведеному вище прикладі коду є кілька цікавих аспектів. Перш за все, зауважте, що константи (глобальні змінні) були використані, щоб зробити приклад більш зрозумілим для користувачів програмування. мікроконтролери en C про ан C + +. Як буде видно пізніше, оптимальний спосіб його програмування JavaScript Це було б використання об’єктів, які містили б ці значення, і методи, які б керували посиланнями в цьому прикладі або графі, загалом, у виробничій системі.

    З іншого боку, розробляючи більш загальний код, було розроблено окремі функції, які обчислюють різні коефіцієнти, які коригують пропорцію графіка для коригування тексту proporcion_grafico(), шкала значень в залежності від їх діапазону escala() і поправочний коефіцієнт для вимірювань, які відомі в абсолютному значенні, наприклад, вимірювання в еталонах medida_grafico().

    Прочитання цього коду має допомогти прояснити контекст, у якому працює подібна програма, яка малює графіку в реальному часі та має бути гнучкою для представлення в різних графічних контекстах (принаймні різних розмірів і пропорцій). Перш за все, об'єкти повинні бути згенеровані SVG, або "вручну" в коді HTML, або через код JavaScript і в будь-якому випадку посилання на ці об'єкти повинні бути згодом отримані для маніпулювання ними JavaScript щоб можна було намалювати нові графіки, а подання вже намальованого графіка можна адаптувати до зміни середовища, в якому він представлений.

    Іншим довідником, який може допомогти легко інтерпретувати графік, є точки, які представляють конкретні значення (вузли лінії). У цьому прикладі, де ми представляємо одну величину, вибір символу не є критичним, але якщо кілька різних значень накладаються для пошуку кореляції, це цікаво розрізнити, крім використання інших ресурсів, таких як колір , малюючи різні символи. Графіка, яка використовується для вузла лінії, повинна бути змінена за розміром і пропорціями, як це відбувається, наприклад, з текстами, щоб її розміри були абсолютними і щоб її пропорції зберігалися, навіть якщо змінюються розміри коробки, яку вона містить.

    У попередньому прикладі ми вже бачили, як обчислити різні коефіцієнти для зміни масштабу та виправлення пропорцій малюнка; Стосовно того, як реалізувати керування символами вузлів або вершин графа, можливим рішенням може бути зберігання об’єктів SVG у вектор і змінювати його положення, коли графік оновлюється шляхом зчитування нового значення, або коли він перемальовується шляхом зміни розміру контейнера. У першому випадку необхідно було б змінити його положення, а в другому — його співвідношення з майном transform і значення scale. Наступний код є модифікацією функції actualizar_grafico() включити зміну позиції символів вершини графа.

    Зміни, внесені до функції actualizar_grafico() щоб отримати нову функцію actualizar_grafico_puntos() Саме вони виділені в коді попереднього прикладу. Спочатку в рядку 5 ми беремо вектор об’єктів SVG як параметр. Цей вектор міститиме символи, які потрібно змінити в нових вузлах графа.

    У рядках 39 і 40 призначаються нові координати центру, cx y cy, до тих значень, які представлені. Якщо символ не базується на центрі, ймовірно, потрібно буде додати зсув cx половину ширини і в cy половини висоти, щоб перемістити їх точно на вузол графіка.

    У рядках з 57 по 61 точки, які відповідають координатам, які не намальовані, тому що вони обрізані лівим краєм, переміщуються за межі графіка. Координата cy до нуля і що з cx до будь-якого від’ємного числа (більшого за саму точку), щоб воно не відображалося під час розрізу, як ліва частина графіка, вікном SVG.

    Керуйте діаграмою з об’єкта за допомогою JavaScript

    Усі описані досі операції можна інтегрувати в об’єкт для керування графіком у стилі, більш типовому для нових версій JavaScript. Ця альтернатива реалізації має додаткову перевагу спрощення включення кількох графіків з різними значеннями на одній веб-сторінці.

    Перш ніж обговорювати реалізацію, давайте розглянемо найпоширеніші способи створення об’єктів JavaScript і деякі особливості функцій, які впливають на пропозицію для малювання графіки сенсора IoT.

    Уже пояснювалося, що новий спосіб створення об’єктів у JavaScript (доступно з версії 5 ECMAScript) складається з використання Object.create, які варто звикнути використовувати замість "класичних" new, який, звісно, ​​все ще працює правильно, хоча його метою є більше імітація стилю мов з об’єктами на основі класів (JavaScript базує створення об’єктів на прототипах), ніж робоча альтернатива.

    Попередній код дозволяє запам’ятати відмінності між створенням об’єктів за допомогою Object.create про кон new. Це також служить для того, щоб підкреслити, що, хоча функція, з якою створюється об’єкт new може бути будь-де в коді, об’єкт має вже існувати, перш ніж його можна буде створити Object.create (Об'єкт ES5_Object не є функцією).

    У рядках 3 і 4, щоб встановити значення за замовчуванням для властивостей у функції, яка створює об’єкт newкожній властивості присвоюється значення відповідного аргументу або (||), якщо не було передано жодних аргументів, тобто якщо вони невизначені (undefined), оскільки ця обставина оцінюється як false, призначається значення за умовчанням.

    Контекст, у якому виконується функція JavaScript порушує дві проблеми, які важливо мати на увазі, і які також можуть заплутати під час використання цієї мови програмування після роботи з іншими, наприклад C o C + +, в нашому випадку. Контекст включає змінні, визначені в області видимості функції (і глобальні), що, до речі, породжує цікаву концепцію, «замикання», що встановлює цілий стиль програмування в JavaScript. Тим не менш, цього можна було очікувати this, який посилається на об’єкт, коли він використовується в коді, який його визначає, контекст виконання, у якому він був визначений, зберігається, але той, який він використовує, є контекстом, з якого викликається функція. У більшості випадків ця поведінка прозора, але є дві обставини, за яких вона може заплутати: функція, визначена всередині іншої функції, і метод, викликаний із події об’єкта. window.

    Під час виконання попереднього коду в консолі відображається прокоментований текст у кінці. Дві позначені лінії відображають поведінку, яка може заплутати: контекст виконання функції probar_dentro() НЕ probar(), як і слід було очікувати, але window, який показує глобальні змінні, а не однойменні властивості. Якщо ви не бажаєте такої поведінки, просто створіть змінну у функції найвищого рівня та призначте її this, як у наступному коді.

    Щоб керувати контекстом виконання, коли метод викликається з події window, наприклад, змінивши розмір вікна браузера, ще одна особливість JavaScript: можливість програмування «фабрик функцій», тобто функцій, які генерують інші функції, повертаючи їх return.

    У наведеному вище прикладі коду метод llamar() об'єктів Contexto Він не виконує роботу, але повертає анонімну функцію, яка піклується про це. Щоб переконатися, що все працює належним чином, існує глобальна змінна з тим самим іменем, що й властивість, яку функція відображає в консолі; Якщо контекст правильний, буде відображено значення властивості, а не значення глобальної змінної.

    JavaScript Спробуйте виправити знаки крапки з комою, які ми пропускаємо в кінці речень. Це дозволяє створити невимушений стиль написання, але є палкою з двома кінцями, з якою потрібно поводитися обережно. У більшості випадків, щоб уникнути небажаних наслідків, які це спричиняє у виразах, які займають кілька рядків, ви можете використовувати дужки або ставити перед тим, як JavaScript буде інтерпретувати код; Ось чому рядок 8 прикладу включає function в задній частині return, якби я використав інший рядок, значення було б зовсім іншим. На мою думку, найбільш зрозумілим рішенням є використання проміжної (замінної) змінної, як у наступній версії; Очевидно, що як тільки поведінка зрозуміла, рішення відповідає програмісту.

    У тому ж сенсі оцінки виразу як функції, тобто повернення функції, а не значення, яке функція повертає; у рядку 21 останнього прикладу (це було в рядку 19 попереднього) він зупиняється на clearInterval функція, викликана за допомогою setInterval. Щоб він подіяв протягом 30 секунд, зупинка відкладається с setTimeout, який, у свою чергу, потребує функції як перший аргумент; щоб надати виконання як параметр clearInterval зі змінною, яка містить періодичний виклик (а не функцію clearInterval) – це те, для чого створено анонімну функцію в останньому рядку.

    Вибір між написанням коду з інтеграцією визначення функції, більш компактним (як у рядку 21) або використанням допоміжної змінної, на мою думку, більш читабельною (як у рядках 19 і 20) мало змінюється в продуктивності та залежить від стилю та читабельності для обслуговування.

    Щоб перевірити код, перш ніж мати дані на сервері, ви можете використовувати генератор випадкових значень у потрібному діапазоні або підготувати таблиці з контрольованими значеннями, які імітують роботу в потрібних умовах. У наступному прикладі використовується простий генератор даних у всьому діапазоні, тому вони виглядають дещо перебільшеними.

    Щоб перевірити, ви можете завантажити повний код прикладу утворена веб-сторінкою, написаною на HTML, стиль CSS і код JavaScript. Останній є найбільш актуальним, оскільки інші компоненти є лише мінімальною підтримкою, дуже спрощені та набагато більш розроблені в статтях у відповідних розділах.

    Дати коментар

    Можливо, ви пропустили