node-red-contrib-ui-svg

ДОВІДНИК З NODE-RED українською мовою

node-red-contrib-ui-svg

Джерело

A Node-RED widget node to show interactive SVG (vector graphics) in the dashboard.

Введення в SVG

Scalable Vector Graphics (SVG) - це формат векторних зображень на основі XML для двовимірної графіки з підтримкою інтерактивності та анімації. Ми не будемо тут пояснювати, як це працює, оскільки Інтернет наповнений інформацією про це.

Схема SVG містить ряд елементів SVG, які браузер буде відображати зверху вниз. Наприклад:

<svg ...>
  <image .../>
  <circle .../>
  <text .../>
</svg>

Браузер спочатку нарисує (фонове) зображення, потім коло (зверху зображення) і так далі …

Кожен із цих елементів SVG має атрибути (колір заливки, …), може реагувати на події (натискання, …) та може бути анімований (наприклад, зменшити …).

Використання вузла

💥 Подивіться на WIKI де показано посібник крок-за-кроком

Цей вузол можна використовувати для візуалізації всіх видів графічних матеріалів наNode-RED dashboard. Це може варіюватися від простої графіки (наприклад, кругла кнопка, …) до дуже складної графіки (схеми поверхонь, промислові процеси, трубопроводи, електропроводка, …). Але навіть ця складна графіка буде складатися з кількох простих графічних фігур. Наприклад, план поверху насправді є простим зображенням вашого поверху, а серія інших елементів SVG (наприклад, піктограми Fontawesome), намальованих поверх цього (фонового) зображення.

Просто розгорніть рядок SVG на екрані налаштування, і інформаційна панель Node-RED відобразить вашу векторну графіку:

svg_demo

Але що, якщо ви не знайомі з синтаксисом SVG. Не хвилюйтеся, ми інтегрували DrawSvg редактор малювання на екрані конфігурації нашого вузла.

Конфігураційні екрани

Екран конфігурації вузла складається з ряду вкладок, які описані нижче.

Editor

Editor tab sheet

DrawSvg - це безкоштовний редактор схем SVG, який повністю працюватиме у вашому браузері, тому установка не потрібна. Ми інтегрували DrawSvg у цей вузол, щоб дозволити користувачам редагувати SVG за допомогою чудової програми для рисування.

!!! DrawSvg - це безкоштовне програмне забезпечення. Зверніть увагу, що DrawSvg та онлайн-сервіс використовуються як є і без гарантії відсутності помилок !!!

launch_editor

Кроки для використання DrawSvg:

  1. Клацніть “Відкрити редактор SVG”, щоб показати SVG у DrawSvg редактор малювання.
  2. DrawSvg буде відкрито у спливаючому діалоговому вікні, і він буде візуалізувати джерело SVG (з цього вузла).
  3. Малюнок SVG можна редагувати.
  4. Ви можете проміжно зберегти свої зміни (до цього вузла), використовуючи кнопку “Зберегти” у верхньому правому куті спливаючого діалогового вікна.
  5. Як тільки закриється спливаюче діалогове вікно, з’явиться повідомлення. Там ви можете ігнорувати всі зміни (тобто вони вам більше не потрібні) або зберегти всі зміни (до цього вузла).
  6. Оновлене джерело SVG з’явиться на вкладці “SVG source” цього вузла.

За замовчуванням цей вузол використовуватиме безкоштовну онлайн-службу DrawSvg (див. “URL-адреса редактора” на вкладці “Налаштування”). Однак ми також можемо використовувати вузол node-red-contrib-drawsvg , який може локально розміщувати службу DrawSvg для офлайн-систем.

SVG

SVG tab sheet

editor

Введіть у цьому редакторі графіку SVG (на основі XML). Це можна зробити різними способами:

Однак:

Унизу аркуша вкладки “Джерело SVG” доступна низка кнопок:

buttons

Animation

Animation tab sheet

animation

SVG дозволяє користувачам анімувати атрибути елементів з часом. Наприклад, ви можете зробити так, щоб радіус кола зростав за 3 секунди з 10 пікселів до 40 пікселів.

Додавання анімації до графіки SVG можна виконати різними способами:

Event

Event tab sheet

event tabsheet

Сюди можна додати елемент SVG, щоб зробити цей елемент здатним перехопити одну з наступних подій:

Додаючи новий рядок на цій вкладці, потрібно ввести кілька властивостей:

За замовчуванням вміст зберігатиметься в msg.payload вихідного повідомлення. Однак, коли результат повинен потрапити в msg.anotherField, це поле повідомлення можна вказати вгорі аркуша вкладки:

image

Коли подія відбувається за таким елементом SVG, трапляються дві речі:

  1. Курсор миші зміниться під час наведення курсора на елемент, щоб візуалізувати, що елемент реагує на події.

  2. Щойно клацне елемент, із Node-RED буде надіслано вихідне повідомлення, в стандартному форматі:

    "elementId": "light_bulb_kitchen",
    "selector": "#light_bulb_kitchen",
    "event": {
       "type":"click",
       "svgX":28.02083396911621,
       "svgY":78.66666412353516,
       "pageX":1105,
       "pageY":310,
       "screenX":829,
       "screenY":304,
       "clientX":1105,
       "clientY":310,
       "bbox": [
          1076.979248046875,
          311.3333435058594,
          1136.979248046875,
          251.33334350585938
       ]
    }
    

    Координати (де відбувається подія) у вихідному повідомленні дозволяють наступним вузлам у потоці відображати інформацію в цьому місці. Наприклад, ми розробили node-red-contrib-ui-contextmenu , щоб показати спливаюче контекстне меню на інформаційній панелі над SVG малюнок у місці, де клацнули фігури. Наступна демонстрація пояснює цю комбінацію обох вузлів:

    2019-09-22_14-12-06

    [{"id":"107fa0c1.cb755f","type":"debug","z":"60ad596.8120ba8","name":"Floorplan output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":1340,"y":440,"wires":[]},{"id":"58329d91.3fc564","type":"ui_svg_graphics","z":"60ad596.8120ba8","group":"f014eb03.a3c618","order":1,"width":"14","height":"10","svgString":"<svg preserveAspectRatio=\"none\" x=\"0\" y=\"0\" viewBox=\"0 0 900 710\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:svg=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n  <image width=\"889\" height=\"703\" id=\"background\" xlink:href=\"https://www.roomsketcher.com/wp-content/uploads/2016/10/1-Bedroom-Floor-Plans.jpg\"/>\n  <circle id=\"pir_living\" cx=\"310\" cy=\"45\" r=\"5\" stroke-width=\"0\" fill=\"#FF0000\"/>\n  <text id=\"camera_living\" x=\"310\" y=\"45\" font-family=\"FontAwesome\" fill=\"blue\" stroke=\"black\" font-size=\"35\" text-anchor=\"middle\" alignment-baseline=\"middle\" stroke-width=\"1\"></text>\n</svg>","clickableShapes":[{"targetId":"#camera_living","action":"click","payload":"camera_living","payloadType":"str","topic":"camera_living"}],"smilAnimations":[],"bindings":[],"showCoordinates":false,"autoFormatAfterEdit":false,"outputField":"","editorUrl":"http://drawsvg.org/drawsvg.html","directory":"","name":"","x":1140,"y":440,"wires":[["107fa0c1.cb755f"]]},{"id":"f014eb03.a3c618","type":"ui_group","z":"","name":"Floorplan test","tab":"80068970.6e2868","disp":true,"width":"14","collapse":false},{"id":"80068970.6e2868","type":"ui_tab","z":"","name":"SVG","icon":"dashboard","disabled":false,"hidden":false}]
    

    Об’єкт msg.event містить кілька координат, що відповідають різним доступним системам координат у браузері:

    Coordinate systems

    • SVG координати - в межах редактора SVG, тобто відносно початку початку схеми SVG.

    • Client координати - в межах видимого вікна браузера.
    • Page координати - відносно верхньої частини поточної сторінки інформаційної панелі (яка стане видимою лише після прокрутки, оскільки вона занадто коротка для відображення у вікні браузера).
    • Screen координати - в межах екрану монітора.

    Примітка: msg.bbox містить обмежувальне поле (ліворуч/знизу/праворуч/зверху) елемента SVG, де відбувається подія

Замість того, щоб вказувати події на екрані налаштування, можна також додавати або видаляти події за допомогою вхідних повідомлень. Це пояснюється у розділі Control via messages нижче.

JS

JS tab sheet

JS tabsheet

Сюди можна додати елемент SVG, щоб зробити цей елемент здатним перехопити одну з подій: див. Розділ таблиці “Event”.

Додаючи новий рядок на цій вкладці, потрібно ввести кілька властивостей:

Зверніть увагу, що у кожному рядку є кнопка fullscreen для відображення коду Javascript у повноекранному редакторі з підсвічуванням синтаксису!

Коли подія відбувається за таким елементом SVG, трапляються дві речі:

  1. Курсор миші зміниться під час наведення курсора над елементом, щоб візуалізувати, що елемент реагує на події.
  2. Код Javascript буде виконаний на стороні dashboard.

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

Наступний приклад показує, як змінити колір кола при кожному натисканні на коло. Потік також показує, що обробник події Javascript можна видалити, а інший обробник події Javascript (для показу попередження) можна ввести через вхідне повідомлення:

javascript flow

[{"id":"89244415.be9278","type":"ui_svg_graphics","z":"a03bd3cf.177578","group":"5ae1b679.de89c8","order":4,"width":"0","height":"0","svgString":"<svg x=\"0\" y=\"0\" height=\"350\" viewBox=\"-0.04032258064515237 0 250.0806451612903 350\" width=\"250\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:svg=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" preserveAspectRatio=\"xMidYMid meet\">\n<circle id=\"my_circle\" cx=\"30\" cy=\"30\" r=\"25\" style=\"stroke: none; fill: #0000ff;\">\n</circle>\n</svg>","clickableShapes":[],"javascriptHandlers":[{"selector":"#my_circle","action":"click","sourceCode":"var letters = '0123456789ABCDEF';\n  var color = '#';\n  for (var i = 0; i < 6; i++) {\n    color += letters[Math.floor(Math.random() * 16)];\n  }\n\n$(\"#my_circle\")[0].style.fill = color;\n \n$scope.send({payload: color, topic: 'circle_color'})"}],"smilAnimations":[{"id":"","targetId":"","classValue":"","attributeName":"transform","transformType":"rotate","fromValue":"","toValue":"","trigger":"msg","duration":"1","durationUnit":"s","repeatCount":"0","end":"restore","delay":"1","delayUnit":"s","custom":""}],"bindings":[],"showCoordinates":false,"autoFormatAfterEdit":true,"showBrowserErrors":true,"showBrowserEvents":true,"outputField":"payload","editorUrl":"http://drawsvg.org/drawsvg.html","directory":"","panning":"disabled","zooming":"disabled","panOnlyWhenZoomed":false,"doubleClickZoomEnabled":false,"mouseWheelZoomEnabled":false,"name":"SVG with Javascript","x":540,"y":180,"wires":[["e06da0e0.2c837"]]},{"id":"d9df6292.785bc","type":"inject","z":"a03bd3cf.177578","name":"Show alert at click","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"command\":\"add_js_event\",\"event\":\"click\",\"selector\":\"#my_circle\",\"script\":\"alert('Click event handled on the client ...')\"}","payloadType":"json","x":230,"y":140,"wires":[["89244415.be9278"]]},{"id":"5074f893.d378d8","type":"inject","z":"a03bd3cf.177578","name":"Remove clicked event","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"command\":\"remove_js_event\",\"event\":\"click\",\"selector\":\"#my_circle\"}","payloadType":"json","x":240,"y":180,"wires":[["89244415.be9278"]]},{"id":"e06da0e0.2c837","type":"debug","z":"a03bd3cf.177578","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":750,"y":180,"wires":[]},{"id":"8572fad7.dd39b8","type":"inject","z":"a03bd3cf.177578","name":"change color at click","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"command\":\"add_js_event\",\"event\":\"click\",\"selector\":\"#my_circle\",\"script\":\"var letters = '0123456789ABCDEF';  var color = '#';  for (var i = 0; i < 6; i++) {    color += letters[Math.floor(Math.random() * 16)];  } $('#my_circle')[0].style.fill = color; $scope.send({payload: color, topic: 'circle_color'})\"}","payloadType":"json","x":230,"y":280,"wires":[["89244415.be9278"]]},{"id":"f678a359.157b4","type":"comment","z":"a03bd3cf.177578","name":"Multiline program ...","info":"","x":220,"y":240,"wires":[]},{"id":"5ae1b679.de89c8","type":"ui_group","name":"Press Demo","tab":"3667e211.c08f0e","order":1,"disp":true,"width":"5","collapse":false},{"id":"3667e211.c08f0e","type":"ui_tab","name":"Home","icon":"dashboard","order":1,"disabled":false,"hidden":false}]

Що призведе до цього:

javascript flow demo

Основна різниця між подіями на вкладці “Event” та подіями Javascript на вкладці “JS”:

Зверніть увагу, що між подіями на обох таблицях є деяке перекриття:

Binding

Binding tab sheet

Як пояснено в розділі Керування за допомогою повідомлень”, що наведений нижче, цим вузлом можна керувати за допомогою вхідних повідомлень. Наприклад, змінити колір заливки кола з ідентифікатором “mycircle” на зелений. Як результат, вхідні повідомлення повинні містити багато інформації (ідентифікатор елемента, ім’я атрибута, значення атрибута …), щоб цей вузол знав, що ви хочете зробити. Це означає, що потік стане досить складним, оскільки для розміщення всієї цієї інформації в повідомленні потрібно багато додаткових вузлів.

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

bindings

Вхідні прив’язки можуть бути додані для прив’язки джерел (= полів вхідних повідомлень) до пунктів призначення (= значення атрибута елемента/тексту).

Потрібно ввести кілька властивостей:

Наприклад:

Binding example

Коли, напр. вхідне повідомлення містить msg.payload.position.x, тоді для цього значення (250) буде встановлено атрибут” x “елемента SVG з ідентифікатором” camera_living “.

Наступний потік показує наведений вище приклад прив’язки в дії:

Binding demo

[{"id":"c9ab8554.337588","type":"debug","z":"60ad596.8120ba8","name":"Floorplan output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":1380,"y":440,"wires":[]},{"id":"56869c57.d65c74","type":"ui_svg_graphics","z":"60ad596.8120ba8","group":"d4ee73ea.a7676","order":1,"width":"14","height":"10","svgString":"<svg preserveAspectRatio=\"none\" x=\"0\" y=\"0\" viewBox=\"0 0 900 710\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:svg=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n  <image width=\"889\" height=\"703\" id=\"background\" xlink:href=\"https://www.roomsketcher.com/wp-content/uploads/2016/10/1-Bedroom-Floor-Plans.jpg\" />\n  <text id=\"banner\" x=\"10\" y=\"16\" fill=\"black\" stroke=\"black\" font-size=\"35\" text-anchor=\"left\" alignment-baseline=\"middle\" stroke-width=\"1\">This is the #banner</text>\n  <circle id=\"pir_living\" cx=\"310\" cy=\"45\" r=\"5\" stroke-width=\"0\" fill=\"#FF0000\" />\n  <text id=\"camera_living\" x=\"310\" y=\"45\" font-family=\"FontAwesome\" fill=\"grey\" stroke=\"black\" font-size=\"35\" text-anchor=\"middle\" alignment-baseline=\"middle\" stroke-width=\"1\"></text>\n</svg> ","clickableShapes":[{"targetId":"#camera_living","action":"click","payload":"camera_living","payloadType":"str","topic":"camera_living"}],"smilAnimations":[],"bindings":[{"selector":"#banner","bindSource":"payload.title","bindType":"text","attribute":""},{"selector":"#camera_living","bindSource":"payload.position.x","bindType":"attr","attribute":"x"},{"selector":"#camera_living","bindSource":"payload.camera.colour","bindType":"attr","attribute":"fill"}],"showCoordinates":false,"autoFormatAfterEdit":false,"outputField":"","editorUrl":"http://drawsvg.org/drawsvg.html","directory":"","name":"","x":1180,"y":440,"wires":[["c9ab8554.337588"]]},{"id":"62a285fb.bd046c","type":"inject","z":"60ad596.8120ba8","name":"databind","topic":"databind","payload":"{\"camera\":{\"colour\":\"yellow\"},\"position\":{\"x\":320},\"title\":\"databind strikes again\"}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":980,"y":460,"wires":[["56869c57.d65c74"]]},{"id":"132d184e.ff0ab8","type":"inject","z":"60ad596.8120ba8","name":"databind","topic":"databind","payload":"{\"camera\":{\"colour\":\"green\"},\"position\":{\"x\":250},\"title\":\"New banner title by databind\"}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":980,"y":420,"wires":[["56869c57.d65c74"]]},{"id":"d4ee73ea.a7676","type":"ui_group","z":"","name":"Floorplan test","tab":"b4bb5633.ba92b8","disp":true,"width":"14","collapse":false},{"id":"b4bb5633.ba92b8","type":"ui_tab","z":"","name":"SVG","icon":"dashboard","disabled":false,"hidden":false}]

Зверніть увагу, що існує ще один спосіб реалізації прив’язки даних (без використання таблиці “Binding”), за допомогою атрибутів користувача всередині джерела SVG:

Settings

Settings tab sheet

Відображення координат

Коли вибрано цей параметр, відображатиметься підказка, яка відображатиме поточне розташування миші (тобто координати X та Y):

svg_tooltip_coordinates

Ця опція була введена для спрощення розкладки під час ручного редагування рядка SVG (без зовнішнього інструменту малювання SVG). Без цієї опції визначення місця розташування ваших фігур вимагало б багато обчислень або здогадок …

Примітка: розташування вимірюється в системі координат SVG, що означає, що початок координат (X = Y = 0) знаходиться у верхньому лівому куті вашого креслення.

Автоматичне форматування джерела SVG після збереження змін у редакторі SVG

Під час редагування джерела SVG за допомогою DrawSvg, маніпульований SVG Джерело не дуже красиве: джерело SVG буде містити порожні рядки, декілька елементів SVG в одному рядку … Це джерело SVG можна прикрасити вручну за допомогою кнопки “Format SVG” або автоматично (щоразу, коли відкриється діалогове вікно DrawSvg вікно закривається - активуючи цей прапорець.

Показувати помилки браузера на сервері

На жаль, не всі види помилок можна перевірити на сервері, але натомість вони виникатимуть на стороні клієнта. Наприклад, коли надходить вхідне повідомлення, але для зазначеного селектора не вдається знайти жодного елемента SVG. В результаті ваш малюнок не буде оновлено, і у версії 1.xx вам довелося самостійно з’ясувати, що йде не так … Звичайно, ви можете подивитися у журналі консолі браузера, щоб подивитися на помилки на стороні клієнта. Однак у деяких системах (наприклад, у смартфонах Android) отримати доступ до цього журналу консолі дуже важко (якщо ви не налаштували віддалене з’єднання через USB за допомогою браузера на робочому столі).

Щоб спростити усунення несправностей, помилки на стороні клієнта з’являться на панелі налагодження Node-RED, коли цей прапорець активовано. Але майте на увазі, що якщо у вас одночасно видно N малюнків (коли ваша інформаційна панель наразі відображається у N браузерах), то ви отримаєте N помилок замість 1 …

Показувати події браузера на сервері

Скоріше подібний до попереднього варіанту (про помилки браузера), за винятком того, що тут події браузера (click, …) реєструються на сервері:

[Browser event

Enable JS event debugging

Коли цей параметр активний (і ви відкрили інструменти розробки свого веб -переглядача), налагоджувач браузера автоматично зупиниться, коли буде виконано обробник подій JS. Це дозволяє експериментувати з кодом Javascript у реальному часі, щоб вирішити проблеми з цим кодом.

Перегляньте вікі сторінку для отримання додаткової інформації про налагодження коду JS.

Send output msg when the client is (re)loaded

Коли цей параметр активний, вихідне повідомлення надсилатиметься щоразу, коли (відновлюватиметься) віджет на стороні клієнта. Це може бути корисним, щоб ініціювати потік, щоб розпочати попереднє завантаження даних у креслення SVG, коли воно відкривається. Вихідне повідомлення буде виглядати так:

   "payload": <the id of the SVG node>,
   "topic": "loaded"

Editor URL

Це URL-адреса, де знаходиться екземпляр редактора DrawSvg розміщено. За замовчуванням це поле містить посилання на офіційну систему DrawSvg cloud, але також може містити посилання на локальну установку DrawSvg (розміщену через node-red- contrib-drawsvg вузол).

Майте на увазі, що це безкоштовна система, тому немає ніякої гарантії щодо наявності хмарної системи!

Directory

Цей каталог вашої локальної системи (де працює ваш екземпляр Node-RED) можна використовувати, щоб зробити ваші локальні зображення доступними як на інформаційній панелі, так і в редакторі потоків.

Pan and zoom

Доступна низка опцій для панорамування та масштабування, що корисно для великих креслень (наприклад, будівель, технологічних потоків …):

Наступна демонстрація показує, як переміщати та змінювати масштаб за допомогою миші (коліщатко миші та перетягування):

svg_panzoom_mouse

When a touch device has been detected, panning and zoom through touch events is also supported. Thanks to tkirchm for getting us started with these new features! The following hand gestures are currently supported:

gestures

It is also possible to control panning and zooming via input messages, as explained in the section Control via messages below. The following example flow shows how to control panning and zooming from the flow editor (using Inject nodes) and via the dashboard (using dashboard button widgets):

Pan zoom flow

[{"id":"a289199.a1714e8","type":"debug","z":"4ae15451.7b2f5c","name":"Floorplan output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":2140,"y":380,"wires":[]},{"id":"32dfda30.706666","type":"ui_svg_graphics","z":"4ae15451.7b2f5c","group":"8d1b9121.83b3c","order":1,"width":"14","height":"10","svgString":"<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:svg=\"http://www.w3.org/2000/svg\" width=\"600px\" height=\"500px\" preserveAspectRatio=\"xMidYMid meet\"><defs id=\"svgEditorDefs\"><polygon id=\"svgEditorShapeDefs\" style=\"fill:rosybrown;stroke:black;vector-effect:non-scaling-stroke;stroke-width:1px;\"/></defs><rect id=\"svgEditorBackground\" x=\"0\" y=\"0\" width=\"100%\" height=\"100%\" style=\"fill: none; stroke: none;\"/><circle id=\"e1_circle\" cx=\"100\" cy=\"100\" style=\"fill:rosybrown;stroke:black;stroke-width:1px;\" r=\"25.8069758011\"/><text style=\"fill:black;font-family:Arial;font-size:20px;\" x=\"94\" y=\"105\" id=\"e2_texte\">A</text><text style=\"fill:black;font-family:Arial;font-size:20px;\" x=\"104\" y=\"98\" id=\"e3_texte\"/><circle id=\"e2_circle\" cx=\"200\" cy=\"100\" style=\"fill:rosybrown;stroke:black;stroke-width:1px;\" r=\"25.8069758011\"/><text style=\"fill:black;font-family:Arial;font-size:20px;\" x=\"193\" y=\"107\" id=\"e4_texte\">B</text><text style=\"fill:black;font-family:Arial;font-size:20px;\" x=\"195\" y=\"97\" id=\"e5_texte\"/><circle id=\"e3_circle\" cx=\"100\" cy=\"200\" style=\"fill:rosybrown;stroke:black;stroke-width:1px;\" r=\"25.8069758011\"/><text style=\"fill:black;font-family:Arial;font-size:20px;\" x=\"93\" y=\"206\" id=\"e6_texte\">F</text><circle id=\"e4_circle\" cx=\"200\" cy=\"200\" style=\"fill:rosybrown;stroke:black;stroke-width:1px;\" r=\"25.8069758011\"/><circle id=\"e5_circle\" cx=\"100\" cy=\"300\" style=\"fill:rosybrown;stroke:black;stroke-width:1px;\" r=\"25.8069758011\"/><circle id=\"e6_circle\" cx=\"200\" cy=\"300\" style=\"fill:rosybrown;stroke:black;stroke-width:1px;\" r=\"25.8069758011\"/><circle id=\"e7_circle\" cx=\"302\" cy=\"102\" style=\"fill:rosybrown;stroke:black;stroke-width:1px;\" r=\"25.8069758011\"/><text style=\"fill:black;font-family:Arial;font-size:20px;\" x=\"293\" y=\"109\" id=\"e7_texte\">C</text><circle id=\"e8_circle\" cx=\"402\" cy=\"102\" style=\"fill:rosybrown;stroke:black;stroke-width:1px;\" r=\"25.8069758011\"/><text style=\"fill:black;font-family:Arial;font-size:20px;\" x=\"397\" y=\"108\" id=\"e8_texte\">D</text><circle id=\"e9_circle\" cx=\"300\" cy=\"200\" style=\"fill:rosybrown;stroke:black;stroke-width:1px;\" r=\"25.8069758011\"/><text style=\"fill:black;font-family:Arial;font-size:20px;\" x=\"295\" y=\"208\" id=\"e9_texte\">H</text><circle id=\"e10_circle\" cx=\"400\" cy=\"200\" style=\"fill:rosybrown;stroke:black;stroke-width:1px;\" r=\"25.8069758011\"/><circle id=\"e11_circle\" cx=\"300\" cy=\"300\" style=\"fill:rosybrown;stroke:black;stroke-width:1px;\" r=\"25.8069758011\"/><circle id=\"e12_circle\" cx=\"402\" cy=\"302\" style=\"fill:rosybrown;stroke:black;stroke-width:1px;\" r=\"25.8069758011\"/><circle id=\"e13_circle\" cx=\"100\" cy=\"400\" style=\"fill:rosybrown;stroke:black;stroke-width:1px;\" r=\"25.8069758011\"/><circle id=\"e14_circle\" cx=\"200\" cy=\"400\" style=\"fill:rosybrown;stroke:black;stroke-width:1px;\" r=\"25.8069758011\"/><circle id=\"e15_circle\" cx=\"300\" cy=\"400\" style=\"fill:rosybrown;stroke:black;stroke-width:1px;\" r=\"25.8069758011\"/><circle id=\"e16_circle\" cx=\"400\" cy=\"400\" style=\"fill:rosybrown;stroke:black;stroke-width:1px;\" r=\"25.8069758011\"/><circle id=\"e17_circle\" cx=\"500\" cy=\"100\" style=\"fill:rosybrown;stroke:black;stroke-width:1px;\" r=\"25.8069758011\"/><text style=\"fill:black;font-family:Arial;font-size:20px;\" x=\"493\" y=\"106\" id=\"e17_texte\">E</text><circle id=\"e18_circle\" cx=\"500\" cy=\"200\" style=\"fill:rosybrown;stroke:black;stroke-width:1px;\" r=\"25.8069758011\"/><circle id=\"e19_circle\" cx=\"500\" cy=\"300\" style=\"fill:rosybrown;stroke:black;stroke-width:1px;\" r=\"25.8069758011\"/><circle id=\"e20_circle\" cx=\"500\" cy=\"400\" style=\"fill:rosybrown;stroke:black;stroke-width:1px;\" r=\"25.8069758011\"/><text style=\"fill:black;font-family:Arial;font-size:20px;\" x=\"93\" y=\"307\" id=\"e1_texte\">K</text><text style=\"fill:black;font-family:Arial;font-size:20px;\" x=\"93\" y=\"406\" id=\"e10_texte\">P</text><text style=\"fill:black;font-family:Arial;font-size:20px;\" x=\"191\" y=\"208\" id=\"e11_texte\">G</text><text style=\"fill:black;font-family:Arial;font-size:20px;\" x=\"193\" y=\"307\" id=\"e12_texte\">L</text><text style=\"fill:black;font-family:Arial;font-size:20px;\" x=\"193\" y=\"406\" id=\"e13_texte\">Q</text><text style=\"fill:black;font-family:Arial;font-size:20px;\" x=\"494\" y=\"308\" id=\"e14_texte\">O</text><text style=\"fill:black;font-family:Arial;font-size:20px;\" x=\"492\" y=\"406\" id=\"e15_texte\">T</text><text style=\"fill:black;font-family:Arial;font-size:20px;\" x=\"493\" y=\"207\" id=\"e16_texte\">J</text><text style=\"fill:black;font-family:Arial;font-size:20px;\" x=\"392\" y=\"207\" id=\"e18_texte\">I</text><text style=\"fill:black;font-family:Arial;font-size:20px;\" x=\"396\" y=\"309\" id=\"e19_texte\">N</text><text style=\"fill:black;font-family:Arial;font-size:20px;\" x=\"393\" y=\"407\" id=\"e20_texte\">S</text><text style=\"fill:black;font-family:Arial;font-size:20px;\" x=\"293\" y=\"306\" id=\"e21_texte\">M</text><text style=\"fill:black;font-family:Arial;font-size:20px;\" x=\"292\" y=\"407\" id=\"e22_texte\">R</text><text style=\"fill:black;font-family:Arial;font-size:20px;\" x=\"82.55244445800781\" y=\"26.68446922302246\" id=\"e23_texte\">100</text><text style=\"fill:black;font-family:Arial;font-size:20px;\" x=\"182.9540252685547\" y=\"27.42818832397461\" id=\"e24_texte\">200</text><text style=\"fill:black;font-family:Arial;font-size:20px;\" x=\"285.5868225097656\" y=\"27.42818832397461\" id=\"e25_texte\">300</text><text style=\"fill:black;font-family:Arial;font-size:20px;\" x=\"385.2447204589844\" y=\"26.684473037719727\" id=\"e26_texte\">400</text><text style=\"fill:black;font-family:Arial;font-size:20px;\" x=\"484.1588134765625\" y=\"27.428176879882812\" id=\"e27_texte\">500</text><text style=\"fill:black;font-family:Arial;font-size:20px;\" x=\"8.180865287780762\" y=\"106.26204681396484\" id=\"e28_texte\">100</text><text style=\"fill:black;font-family:Arial;font-size:20px;\" x=\"8.92458724975586\" y=\"204.4324493408203\" id=\"e29_texte\">200</text><text style=\"fill:black;font-family:Arial;font-size:20px;\" x=\"6.693431854248047\" y=\"306.3215026855469\" id=\"e30_texte\">300</text><text style=\"fill:black;font-family:Arial;font-size:20px;\" x=\"9.668293952941895\" y=\"405.23565673828125\" id=\"e31_texte\">400</text><text style=\"fill:black;font-family:Arial;font-size:20px;\" x=\"40.160640716552734\" y=\"25.197044372558594\" id=\"e32_texte\"/><path d=\"M4.848484684596244,-1.5151515315403765v-2l4,4l-4,4v-2h-4v-4Z\" style=\"fill:rosybrown; stroke:black; vector-effect:non-scaling-stroke;stroke-width:1px;\" id=\"e37_shape\" transform=\"matrix(3.06783 0 0 3.06783 50.9445 18.8755)\"/><path d=\"M3.000000026913421,2.5000000672835476h2l-4,4l-4,-4h1.9999999999999998v-4h4Z\" style=\"fill:rosybrown; stroke:black; vector-effect:non-scaling-stroke;stroke-width:1px;\" id=\"e38_shape\" transform=\"matrix(2.97486 0 0 2.97486 22.3115 63.1265)\"/><text style=\"fill:black;font-family:Arial;font-size:20px;\" x=\"35.698360443115234\" y=\"28.171905517578125\" id=\"e39_texte\">X</text><text style=\"fill:black;font-family:Arial;font-size:20px;\" x=\"19.336605072021484\" y=\"54.94566345214844\" id=\"e40_texte\">Y</text></svg>","clickableShapes":[{"targetId":"#mycircle","action":"click","payload":"cam living clicked","payloadType":"str","topic":"camera_living"}],"smilAnimations":[],"bindings":[{"selector":"#e26_texte","bindSource":"payload.title","bindType":"text","attribute":""}],"showCoordinates":false,"autoFormatAfterEdit":false,"showBrowserErrors":false,"selectorAsElementId":false,"outputField":"","editorUrl":"https://drawsvg.org/drawsvg.html","directory":"","panning":"both","zooming":"enabled","panOnlyWhenZoomed":false,"doubleClickZoomEnabled":true,"mouseWheelZoomEnabled":true,"name":"","x":1940,"y":380,"wires":[["a289199.a1714e8"]]},{"id":"91163354.31b2f","type":"inject","z":"4ae15451.7b2f5c","name":"Zoom in","topic":"","payload":"{\"command\":\"zoom_in\"}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":1480,"y":260,"wires":[["32dfda30.706666"]]},{"id":"8c7c165f.dee1a8","type":"inject","z":"4ae15451.7b2f5c","name":"Zoom out","topic":"","payload":"{\"command\":\"zoom_out\"}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":1480,"y":300,"wires":[["32dfda30.706666"]]},{"id":"d984058a.02d818","type":"inject","z":"4ae15451.7b2f5c","name":"Zoom 200%","topic":"","payload":"{\"command\":\"zoom_by_percentage\",\"percentage\":200}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":1490,"y":340,"wires":[["32dfda30.706666"]]},{"id":"62277e70.5c676","type":"inject","z":"4ae15451.7b2f5c","name":"Zoom point (x=300, y=300) 200%","topic":"","payload":"{\"command\":\"zoom_by_percentage\",\"percentage\":200,\"x\":300,\"y\":300}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":1550,"y":380,"wires":[["32dfda30.706666"]]},{"id":"365d5483.fa174c","type":"inject","z":"4ae15451.7b2f5c","name":"Pan to point (x=200 / y= 100)","topic":"","payload":"{\"command\":\"pan_to_point\",\"x\":200,\"y\":100}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":1540,"y":420,"wires":[["32dfda30.706666"]]},{"id":"4d1e70dd.f51f3","type":"inject","z":"4ae15451.7b2f5c","name":"Pan to direction (x=200, y= 100)","topic":"","payload":"{\"command\":\"pan_to_direction\",\"x\":200,\"y\":100}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":1550,"y":460,"wires":[["32dfda30.706666"]]},{"id":"79ebf8c1.adadd8","type":"inject","z":"4ae15451.7b2f5c","name":"Reset","topic":"","payload":"{\"command\":\"reset_panzoom\"}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"showConfirmation":false,"confirmationLabel":"","x":1470,"y":220,"wires":[["32dfda30.706666"]]},{"id":"61be354.f7175cc","type":"ui_button","z":"4ae15451.7b2f5c","name":"Reset","group":"8d1b9121.83b3c","order":4,"width":"3","height":"1","passthru":false,"label":"Reset","tooltip":"","color":"","bgcolor":"","icon":"","payload":"{\"command\":\"reset_panzoom\"}","payloadType":"json","topic":"","x":1730,"y":140,"wires":[["32dfda30.706666"]]},{"id":"d43dfb27.a0f308","type":"ui_button","z":"4ae15451.7b2f5c","name":"Zoom in","group":"8d1b9121.83b3c","order":4,"width":"3","height":"1","passthru":false,"label":"Zoom in","tooltip":"","color":"","bgcolor":"","icon":"","payload":"{\"command\":\"zoom_in\"}","payloadType":"json","topic":"","x":1740,"y":180,"wires":[["32dfda30.706666"]]},{"id":"ef78f0f5.c44b3","type":"ui_button","z":"4ae15451.7b2f5c","name":"Zoom out","group":"8d1b9121.83b3c","order":4,"width":"3","height":"1","passthru":false,"label":"Zoom out","tooltip":"","color":"","bgcolor":"","icon":"","payload":"{\"command\":\"zoom_out\"}","payloadType":"json","topic":"","x":1740,"y":220,"wires":[["32dfda30.706666"]]},{"id":"8d1b9121.83b3c","type":"ui_group","z":"","name":"Pan/zoom test","tab":"5021fcf2.ee7ac4","order":1,"disp":true,"width":"14","collapse":false},{"id":"5021fcf2.ee7ac4","type":"ui_tab","z":"","name":"SVG","icon":"dashboard","disabled":false,"hidden":false}]

Which results in this dashboard behaviour:

svg_panzoom_demo

Notice the different behaviour between the two types of buttons in this flow:

Caution: make sure the panning and zooming is enabled in the Settings tab sheet, otherwise it will not be possible to control panning and zooming via input messages!

Керування через повідомлення

Більшість інформації SVG можна обробляти, надсилаючи вхідні повідомлення на цей вузол.

Деякі загальні рекомендації щодо повідомлень:

Підтримувані команди

Update/set an attribute value

Update/set an attribute value via msg

Значення атрибутів елементів SVG можна додавати/змінювати за допомогою вхідного повідомлення:

Наприклад, камера візуалізується піктограмою FontAwesome (текст), яка має кілька атрибутів (x, y, fill …):

<text id="camera_living" x="310" y="45" font-family="FontAwesome" fill="blue" stroke="black" ...>

Наступний потік демонструє, як змінити значення атрибута ‘fill’ та ‘rotation’ за допомогою вхідних повідомлень:

2019-09-22_15-21-49

Update/set a style attribute value

Update/set a style attribute value via msg

Значення стилю елементів SVG можна додавати/змінювати за допомогою вхідного повідомлення:

"payload": { 
   "command": "update_style", 
   "selector": ".camera", 
   "attributeName": "fill", 
   "attributeValue": "purple" 
}

Зауважте, що обидві команди update_style та set_style будуть оновлювати значення існуючого атрибута стилю елемента SVG або створювати атрибут стилю, коли він ще не існує. Отже, немає різниці між обома командами (всупереч set_attribute та update_attribute). Дійсно, оскільки завжди існуватимуть стилі SVG за замовчуванням та за бажанням вбудовані та зовнішні стилі SVG, атрибути стилю завжди будуть існувати …

Замість додавання/зміни одного значення атрибута стилю, можна також додати/змінити весь атрибут стилю одночасно. У цьому випадку “style” потрібно вказати замість “attributeName”:

Remove an attribute

Remove an attribute via msg

An attribute of an SVG element can be removed via an input message:

The following demo shows to set an attribute “visibility” (with value “hidden”), and then removing that same attribute via a second Inject button:

svg_remove_attribute

Although of course it would make more sense to achieve the same effect, by keeping the attribute and update its value from “visible” to “hidden”.

Replace an attribute value

Replace an attribute value via msg

Частина значень атрибутів елементів SVG може бути замінена іншим рядком за допомогою вхідного повідомлення.

"payload": {
   "command": "replace_attribute",
   "selector": "#some_path",
   "attributeName": "d",
   "regex": "[a-z][^a-z]*",
   "replaceValue": "v20"
}

Попередня команда зміниться <path d="M256.409,423.964v48" ...> в <path d="M256.409,423.964v20" ...>.

Set text content

Set text content via msg

Текстовий вміст (або внутрішній html) елемента SVG можна встановити за допомогою вхідного повідомлення:

"payload": {
    "command": "update_text",
    "selector": "#myRect > .faultMessage",
    "textContent": "Hello from a command message"
}

Коли команда вказується всередині теми, ви можете просто надіслати текст у корисному навантаженні:

{
    "topic": "update_text|#myRect > .faultMessage",
    "payload": "hello"
}

Можливі деякі різні умови найменування:

Це може бути використано, наприклад, для показу значень датчика, як у цьому потоці:

svg_thermometer

Get text content

Get text content via msg

Текстовий вміст (або внутрішній html) елемента SVG можна отримати за допомогою вхідного повідомлення:

"payload": {
    "command": "get_text",
    "selector": "#myText"
}

Текст (и) буде надіслано у корисному навантаженні вихідного повідомлення у вигляді масиву.

Start/stop animations

Start/stop animations via msg

Існуючу анімацію можна запустити/зупинити за допомогою вхідного повідомлення, за допомогою значення дії start або stop:

"payload": {
   "command": "trigger_animation",
   "selector": "#myAnimation",
   "action": "start"
}

Зауважте, що вам потрібно вказати на вкладці “Animations”, які анімації будуть запускатися за допомогою вхідних повідомлень:

Msg trigger

Такі повідомлення дозволяють створювати динамічні ефекти, як у наведеній нижче демонстрації:

Animation control

Add events

Add events via msg

Якщо елементам SVG завжди потрібно реагувати на сторону сервера на подію (наприклад, клацання), ці елементи слід перелічити на вкладці “Події”. Однак у деяких випадках потрібно зробити так, щоб елементи SVG відповідали лише тимчасово на події, що може бути досягнуто шляхом додавання подій до елементів SVG за допомогою вхідного повідомлення.

"payload": {
   "command"  : "add_event",
   "event"    : "click",
   "selector" : "#circle_2", 
   "payload"  : "circle 2 has been clicked", // Content of the output message payload
   "topic"    : "CIRCLE_CLICKED" // Content of the output message topic
}]

Надсилаючи це вхідне повідомлення, коло стане інтерактивним.

Зауваження:

Remove events

Remove events via msg

Подію (обробник) можна видалити з елемента SVG за допомогою вхідного повідомлення:

"payload": {
   "command"  : "remove_event",
   "event"    : "click",
   "selector" : "#circle_1"
}

Add Javascript events

Add Javascript events via msg

Коли елементам SVG завжди потрібно реагувати на стороні клієнта на подію (наприклад, клацання), ці елементи слід перелічити на вкладці “JS”. Однак у деяких випадках потрібно зробити так, щоб елементи SVG відповідали лише тимчасово за допомогою Javascript на події, що може бути досягнуто шляхом додавання подій до елементів SVG за допомогою вхідного повідомлення.

"payload": {
   "command"  : "add_js_event",
   "event"    : "click",
   "selector" : "#circle_2", 
   "script"   : "alert('circle 2 has been clicked');" // The Javascript code that needs to be executed
}]

Надсилаючи це вхідне повідомлення, коло стане інтерактивним. Вказаний код Javascript буде виконано на стороні клієнта (тобто всередині інформаційної панелі), як тільки подія станеться.

Зауваження:

javascript errors

Remove Javascript events

Remove Javascript events via msg

Подію (обробник) Javascript можна видалити з елемента SVG за допомогою вхідного повідомлення:

"payload": {
   "command"  : "remove_js_event",
   "event"    : "click",
   "selector" : "#circle_1"
}

Add elements

Add elements via msg

Зазвичай елементи SVG повинні існувати весь час, визначаючи їх на вкладці “SVG”. Однак може знадобитися динамічне додавання елементів SVG, чого можна досягти за допомогою вхідних повідомлень:

"payload": {
   "command": "add_element", 
   "elementType": "circle",
   "elementId": "extra_circle", 
   "elementAttributes": [
      "cx": "100",
      "cy": "50",
      "r": "30"
   ],
   "elementStyleAttributes": [
      "fill": "red",
      "stroke": "black"
   ],
   "textContent": "my content"
}

Деякі зауваження щодо вхідного повідомлення:

Коли аркуш вкладки “Event” вже містить селектор CSS, який відповідає цьому новому елементу, цей новий елемент автоматично отримує ці обробники подій.

Наступна демонстрація показує, як створити піктограму кожного разу, коли натискається кнопка (і видалити їх потім):

svg_add_remove_via_msg

Remove elements

Remove elements via msg

Елемент SVG можна видалити за допомогою вхідного повідомлення:

"payload": {
   "command": "remove_element", 
   "elementId": "circle_1"
}

Вказавши властивість selector (замість властивості elementId), можна видалити відразу кілька елементів за допомогою однієї команди.

Update (input) value

Update (input) value via msg

Значення (foreign) вхідного елемента можна оновити за допомогою вхідного повідомлення:

"payload": {
    "command": "update_value",
    "selector": "#temp_living",
    "value": 17
}

Вказавши властивість selector (замість властивості elementId), можна оновити значення кількох (foreign) вхідних елементів одночасно за допомогою однієї команди.

Set entire SVG

Set entire SVG via msg

Можна встановити весь малюнок SVG за допомогою вхідного повідомлення, щоб замінити поточний малюнок:

"payload": {
    "command": "replace_svg",
    "svg": "<svg height=\"140\" width=\"140\"><circle id=\"myShape\" cx=\"50\" cy=\"50\" r=\"40\" fill=\"yellow\"/></svg>"
}

Зауважте, що потрібно уникнути усіх лапок (") навколо атрибутів імен атрибутів, косою рискою ` \ ` у полі повідомлення “svg”. Наприклад замініть width ="140" на width =\"140\". Якщо цього недостатньо в деяких браузерах, ви можете знайти додаткові поради тут. Будь ласка, повідомте мені про це, щоб я міг оновити цю документацію тут!

Наступний приклад показує, як можна замінити весь SVG:

image

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

Get entire SVG

Get entire SVG via msg

Можна отримати весь малюнок SVG за допомогою вхідного повідомлення.

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

"payload":{"command":"get_svg"}

У наведеному нижче прикладі показано, як оновити малюнок (наприклад, оновити колір кола до синього) та отримати весь SVG (містить оновлений колір). Коли активується вузол Inject, буде надіслано N вихідних повідомлень (коли креслення видно в N сеансах інформаційної панелі). Коли використовується кнопка приладової панелі, буде надіслано 1 вихідне повідомлення (надходить із сеансу інформаційної панелі, де натискається кнопка):

Get SVG

The output message will contain the SVG as XML in the payload field: SVG in output

Zoom in/out

Zoom in/out via msg

Як пояснювалося вище (у розділі Pan and zoom) , можна збільшити/зменшити за допомогою вхідного повідомлення:

"payload": {
   "command": "zoom_in"
}

Or the reverse is also possible:

"payload": {
   "command": "zoom_out"
}

Or zoom by a percentage, for example 130% (which means a factor 1.3):

"payload": {
   "command": "zoom_by_percentage",
   "percentage": 130
}

Optionally coordinates can be specified, to zoom in on that specific point by a specified percentage:

"payload": {
   "command": "zoom_by_percentage",
   "percentage": 130,
   "x": 300,
   "y": 400
}

Panning

Panning via msg

As explained above (in the Pan and zoom section), it is possible to pan absolute to a specified point via an input message:

"payload": {
   "command": "pan_to_point",
   "x": 300,
   "y": 400
}

Or it is also possible to pan relative in a specified direction:

"payload": {
   "command": "pan_to_direction",
   "x": 300,
   "y": 400
}

Reset pan/zoom

Reset pan/zoom via msg

Reset the pan to the original x and y position, and reset the zoom to the initial scale via an input message:

"payload": {
   "command": "reset_panzoom"
}

Різне

Fontawesome icons

Значки Fontawome які широко використовуються в Node-RED насправді самі по собі є невеликими малюнками SVG. Вони є дуже простим способом, напр. представляти пристрої на плані поверху. Таку піктограму можна легко додати за допомогою DrawSvg, як показано в цій анімації:

icons via drawsvg

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

Коли ви хочете ввести джерело SVG вручну (без використання DrawSvg), існує інший механізм:

  1. Знайдіть на веб-сайті Fontawesome значок, який відповідає вашим потребам. Наприклад, “fa-video-camera”.

  2. Створіть текстовий елемент (із сімейством шрифтів “FontAwesome”), що містить це ім’я піктограми:

    <text id="camera_living" x="310" y="45" font-family="FontAwesome" fill="blue" stroke="black" font-size="35" text-anchor="middle" alignment-baseline="middle" stroke-width="1">fa-video-camera</text>
    
  3. Результатом буде піктограма FontAwesome у вказаному місці:

    icon

Деякі зауваження:

Display images

У SVG-схемі елемент “image” може бути використаний для відображення зображення всередині схеми SVG. Дивіться цей підручник для отримання додаткової інформації!

Troubleshooting

Деякі поради та підказки для вирішення відомих проблем:

  1. Коли елементи SVG path отримують той самий колір, що і тема інформаційної панелі, як у цьому прикладі, коли фігури стають синіми:

    Dashboard color

    Цього можна уникнути, застосувавши колір заливки як атрибут style (наприклад, <element style =” fill: red “… />) до шляху, а не як звичайний атрибут (наприклад, <element fill =” red “… />). І звичайний атрибут `fill ‘на шляху SVG буде замінений кольором теми панелі інструментів …

    Примітка: малюнки, створені за допомогою DrawSvg, уже правильні, але деякі сторонні редактори використовують атрибут fill .

  2. Деякі основні перевірки вхідних повідомлень були додані на стороні сервера, а помилки перевірки відображатимуться на бічній панелі налагодження.

  3. Дивіться DrawSvg, як показати помилки на стороні клієнта у вашому Node-RED панелі налагодження.

    Примітка: коли зараз видно N малюнків (наприклад, працює одночасно на N інформаційних панелях), тоді відображатиметься N повторюваних повідомлень (де N може бути 0 - це не відкрито інформаційні панелі …).