Создавайте и изменяйте SVG-графику данных от датчиков, подключенных к Интернету вещей, с помощью JavaScript.

Создавайте и изменяйте SVG-графику данных от датчиков, подключенных к Интернету вещей, с помощью JavaScript.

Создавайте и изменяйте SVG-графику данных от датчиков, подключенных к Интернету вещей, с помощью 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 (ИСО / МЭК 16262: 2011 на момент написания статьи)

    Переменные, основные типы данных и объекты в JavaScript

    В отличие от того, что происходит, например, в C + +, en JavaScript тип данных не включается при объявлении переменной а также тип, связанный с переменной, не фиксирован, возможно присвоение значения другого типа на протяжении всего выполнения программы.

    В предыдущем примере была объявлена ​​переменная «вещь» (без указания типа данных), затем присваиваются данные другого типа и с ними обращаются. typeof тип, который JavaScript что он истолковал. Для отладки кода вы можете написать его в консоли инспектора веб-браузера (это не повлияет на представление Интернета) с помощью console.log().

    Чтобы принудительно преобразовать данные в определенный тип, особенно текст в числовой, вы можете использовать такие функции, как parseInt() o parseFloat() которые преобразуются в целые числа или числа с плавающей запятой соответственно. Обратное преобразование можно выполнить с помощью String(), хотя это вряд ли необходимо, поскольку автоматического преобразования обычно достаточно. С parseFloat()Например, вы можете получить значение свойства веб-страницы, например ширину или высоту объекта, включающее единицы измерения; Таким образом, выражение parseFloat("50px"); в результате вернет 50, числовое значение.

    En JavaScript нет различия между двойными и одинарными кавычками; Тип данных в обоих случаях string, и каждый из них может включать другой без необходимости использования escape-кодов.

    В предыдущем примере видно, что переменная, если она была объявлена ​​(существует), но ей не было присвоено никакого значения, содержит неопределенный тип данных (undefined). Неназначенный объект имеет значение null; То есть объект существует, но не имеет ценности; переменная, которая ссылается на нее, не будет иметь typeof undefined Китайско object. Объект также может быть пустым, то есть не иметь значения NULL, но не иметь никаких свойств.

    к определить объект в 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() con Время 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 была вообще не нужна, но это хороший повод вспомнить область видимости переменной, который работает так, как вы ожидаете: переменная result существует только внутри функции double. В JavaScript также можно использовать letвместо var, чтобы ограничить переменную контекстом блока кода (заключенным в фигурные скобки, { y })

    Когда мы говорили об объектах в предыдущем разделе, не хватало чего-то фундаментального: свойства были определены, но методы не определены. Как и ожидалось, методы объекта — это функции, они не имеют имени и используются (вызываются) из имени (свойства), присвоенного определением объекта.

    В предыдущем примере уже существует метод view_temperature, который отображает значение свойства current_temperature через консоль. Это не очень полезно, но дает более полное представление о том, что такое определение объекта в JavaScript.

    Для доступа методов объекта (функций) к его свойствам используйте this, как в предыдущем примере в строке 11, при использовании свойства current_temperature.

    Доступ к объектной модели документа (DOM) с помощью JavaScript

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

    Наиболее используемая форма найти объект в документе HTML Это через метод getElementById(), которому в качестве аргумента передается id, который был указан при создании кода 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 который мы используем для построения графика датчиков Интернета вещей, вы можете использовать createElementNS (НС для пространство имен). Как объяснялось при разговоре о формате SVG, соответствующее ему пространство имен (для текущей версии) равно http://www.w3.org/2000/svg, который следует передать createElementNS в качестве аргумента вместе с типом элемента, svg, в этом случае.

    Una Альтернативой innerHTML добавить текст в качестве содержимого в элемент документа HTML это метод createTextNode() объект document. С помощью этой альтернативы вы можете создать новый текст (к которому позже осуществляется доступ, если он присвоен переменной), который включается в дерево объектов с помощью метода appendChild(). Как Альтернативой appendChild(), который добавляет новый контент в конец того, что уже существует в узле, к которому он добавляется, вы можете использовать метод insertBefore(), который добавляет новый объект поверх существующего. Носить insertBefore() вместо appendChild() предоставляет метод, который служит, например, для сортировать новые объекты перед существующими когда элемент должен находиться перед другим (как в списке) или перекрывать или перекрывать графическую структуру, в которой есть элементы, расположенные ближе к переднему или заднему плану.

    Реагируйте на события с помощью JavaScript

    Когда путь использовать веб-страницу в качестве контейнера для графиков датчиков, подключенных к Интернету вещей это было использовано onload В этикетке <body> чтобы начать рисовать график. Это свойство, связанное с объектами кода HTML, относится к события JavaScript. Как уже объяснялось, он выполняет функцию после загрузки страницы. Хотя это было связано с кодом HTML чтобы лучше помнить об этом, это можно было бы написать в коде JavaScript в качестве body.onload=dibujar; siendo dibujar имя функции, которая должна запускаться при загрузке веб-страницы.

    В самых последних версиях JavaScript события могут быть связаны с функциями, используя addEventListener с форматом objeto.addEventListener(evento,función); или используя синтаксис objeto.evento=función; который работает и в старых реализациях. Чтобы отменить связь функции, связанной с событием, у вас есть removeEventListener который имеет тот же формат, что и addEventListener.

    JavaScript Он способен реагировать на множество событий, которые могут произойти на веб-странице. Например, он может обнаружить щелчок по элементу. HTML con onmousedownили при нажатии кнопки onclick, при нажатии клавиши с onkeydown, управляя полосой прокрутки с помощью onscroll. Для нашей цели нам достаточно обнаружить загрузку страницы с помощью onload и его изменение размера с помощью onresize. Мы свяжем эти события с объектами body y window из DOM соответственно. Первое можно назначить в коде HTML, как видно, и второй в коде JavaScript внутри функции, вызванной первой, и с форматом window.onresize=redimensionar; siendo redimensionar функция, которая будет вызываться каждый раз, когда окно меняет размер.

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

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

    В предыдущем примере введен метод alert который служит для отображения предупреждающего знака. Хотя в прошлом он широко использовался, в настоящее время он практически запрещен в коде. JavaScript из-за того, насколько агрессивно (навязчиво) закрывать веб-страницу диалоговым окном.

    В программе, написанной для микроконтроллер небольшой серии (такой, как та, что на тарелке Arduino Uno) обычно используются глобальные переменные, как в предыдущем примере в JavaScript, поскольку код краток и не особо запутан, поскольку во многих случаях функции реализуются ad hoc и поскольку использование глобальных переменных позволяет очень простым и интуитивно понятным образом прогнозировать использование памяти, что критично в системах с небольшим количеством ресурсов. . Вместо, en JavaScript Обычно использование глобальных переменных сводят к минимуму. потому что ему не нужно торопливо использовать память, поскольку он нормально работает на ЦП с ресурсами, намного превосходящими ресурсы 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 номер е (≃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 Логарифм е по основанию 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: 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 и содержит график, координаты которого изменяются, чтобы соответствовать новым загруженным данным.

    В примере этого предложения, помимо обновления чертежа, также обновляется текст на веб-странице, который показывает дату и значение последних измеренных данных для каждого графика.

    На стороне сервера имеется база данных, содержащая информацию что датчики, подключенные к Интернету вещей, отслеживают. Эта база данных считывается запросом объекта XMLHttpRequest отвечая информацией, закодированной в Формат JSON, хотя название используемого метода предполагает связь с форматом XML.

    В первом уроке Polaridad.es по Хранение данных Интернета вещей Вы можете увидеть пример инфраструктуры для управления со стороны сервера информацией, предоставляемой устройствами, подключенными к Интернету вещей. В этой серии статей в качестве ресурса используется сервер. апаш из которого вы можете использовать язык программирования 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 на сервер состоит из открыть соединение con open указание типа и страницы (необязательно имя пользователя и пароль), подготовить заголовки протокола с setRequestHeader y отправить запрос con send. Заголовок HTTP Content-length вам нужно будет знать длину запроса (количество символов), которая рассчитывается с помощью length.

    Когда запрос AJAX готово, функция, связанная с событием, выполняется onreadystatechange. Вместо назначения функции в предыдущем примере на лету определяется анонимная функция, которая будет управлять приемом данных, поступающих с сервера. Прежде всего в строке 18 проверяется, что статус запроса «завершен», что соответствует значению 4 собственности readyState, что статус «ОК» HTTP-протокол (код 200), которые можно получить из имущества status и что полученные данные Формат JSON, консультации по объекту недвижимости responseType.

    После проверки того, что статус ответа соответствует ожиданиям, в строке 20 предыдущего примера создает объект с результатом, преобразуя текст JSON. В ответе предусмотрен возврат даты, это позволяет нам увидеть, был ли результат, который отправляет сервер, уже ранее представлен на графике, что проверяется в строке 21. Если данные новые, в строке 23 Функция, которая отвечает за перерисовку графика с учетом новой информации.

    Идея предложения этого метода чтения заключается в том, что данные будут обновляться очень часто. Если представленная информация соответствует долгосрочному периоду (например, температуре дня или недели), можно реализовать первоначальный запрос, который собирает все доступные данные, а затем другой, аналогичный показанному в примере, который обновляет их в корреспондент периода.

    Генерация случайных данных для тестирования

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

    Вместо чтения информации из базы данных, приведенный выше пример генерирует ее случайным образом и передает в функцию, отвечающую за рисование графика. Придуманные данные представляют собой вектор, образованный датой, выраженной в виде значения в миллисекундах, моментом записи информации датчика и контролируемыми данными, которые находятся между максимальным значением и минимальным значением.

    В этом примере при генерации даты она может быть задержана до одной секунды (1000 миллисекунд) относительно даты на момент изобретения. Как Math.random() генерирует число от 0.0 до 1.0, умножая его на 1000, получается число от 0 до 1000, которое затем преобразуется в целое число. Таким же образом значение получается путем умножения случайного числа на диапазон (максимум минус минимум) и сложения минимума.

    Нарисуйте график датчиков Интернета вещей с помощью графика SVG.

    Поскольку мы увидели, как мы можем получить значения, которые мы хотим представить (температуру в примере), и их временное местоположение, которое можно выразить вместе в виде координат, в примере ниже показана функция для рисования пути. который соединяет эти точки и, возможно, цветную область, ограниченную этой линией вверху. Результат будет похож на следующее изображение.

    Пример графика, созданного с помощью SVG и JavaScript для представления данных от датчиков Интернета вещей.

    Горизонтальная ось (X) графика представляет время, а вертикальная ось (Y) — значения, которые отслеживают датчики, подключенные к Интернету вещей. Горизонтальный интервал составляет несколько секунд, поскольку в этом предложении график обновляется очень часто (например, каждую секунду), чтобы предоставлять информацию о состоянии датчиков практически в реальном времени.

    В предыдущем коде есть два интересных аспекта: во-первых, расчет, позволяющий адаптировать диапазон представленных значений и, во-вторых, строительство недвижимости 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 con 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. Последнее наиболее актуально, так как остальные компоненты имеют лишь минимальную поддержку, очень упрощены и гораздо более подробно описаны в статьях в соответствующих разделах.

    Оставить комментарий

    Вы могли пропустить