bartbutenaers / node-red-contrib-ui-svg

A Node-RED widget node to show interactive SVG (vector graphics) in the dashboard
Apache License 2.0
94 stars 27 forks source link
:warning: This svg node for the old AngularJs dashboard won't be maintained anymore! Due to lack of free time I can only work on the new svg node for the new VueJs dashboard. Note that the new svg node is still in experimental phase!

node-red-contrib-ui-svg

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

Special thanks to Stephen McLaughlin, my partner in crime for this node!

And also, lots of credits to Joseph Liard, the author of DrawSvg for his assistance!

:warning: Please have a look at the "Getting started" tutorial on the wiki

Install

Run the following npm command in your Node-RED user directory (typically ~/.node-red):

npm install node-red-contrib-ui-svg

It is advised to use Dashboard version 2.16.3 or above.

Introduction to SVG

Scalable Vector Graphics (SVG) is an XML-based vector image format for two-dimensional graphics with support for interactivity and animation. We won't explain here how it works, because the internet is full of information about it.

An SVG drawing contains a series of SVG elements, which will be rendered by the browser from top to bottom. For example:

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

The browser will first draw the (background) image, then the circle (on top of the image), and so on ...

Each of those SVG elements has attributes (fill colour, ...), can respond to events (clicked, ...) and can be animated (e.g. shrink...).

Node usage

:boom: HAVE A LOOK AT THE WIKI FOR STEP-BY-STEP TUTORIALS

This node can be used to visualize all kind of graphical stuff in the Node-RED dashboard. This can range from simple graphics (e.g. a round button, ...) to very complex graphics (floorplans, industrial processes, piping, wiring, ...). But even those complex graphics will consist out of several simple graphical shapes. For example, a floorplan is in fact a simple image of your floor, and a series of other SVG elements (e.g. Fontawesome icons) drawn on top of that (background) image.

Simply deploy your SVG string in the config screen, and the Node-RED dashboard will render your vector graphics:

svg_demo

But what if you are not familiar with the SVG syntax. Do not worry, we have integrated a DrawSvg drawing editor in the config screen of our node.

Config screen tabsheets

The node's config screen consists of a series of tab sheets:

Control via messages

Most of the SVG information can be manipulated by sending input messages to this node.

Some general msg guidelines:

Supported commands:

Enable/disable the SVG

The Node-RED dashboard allows to enable/disable ui widgets by injecting a message with msg.enabled set to a boolean true or false. This can also be used to enable or disable all user input in an SVG drawing. Note that all next injected messages will keep being processed while the node is disabled, like with all other UI nodes (i.e. standard behaviour).

svg_enable

[{"id":"8734fd29475b3ca3","type":"inject","z":"bf0833e74936a0c1","name":"Enable","props":[{"p":"enabled","v":"true","vt":"bool"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","_mcu":{"mcu":false},"x":750,"y":80,"wires":[["662f5a4f61d45302"]]},{"id":"0793ba691f3622e3","type":"debug","z":"bf0833e74936a0c1","name":"Events","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","_mcu":{"mcu":false},"x":1090,"y":80,"wires":[]},{"id":"7f880977992bf324","type":"inject","z":"bf0833e74936a0c1","name":"Disable","props":[{"p":"enabled","v":"false","vt":"bool"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","_mcu":{"mcu":false},"x":750,"y":140,"wires":[["662f5a4f61d45302"]]},{"id":"662f5a4f61d45302","type":"ui_svg_graphics","z":"bf0833e74936a0c1","group":"e8509dc7be30844e","order":1,"width":0,"height":0,"svgString":"<svg x=\"0\" y=\"0\" height=\"100%\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:svg=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n   <text id=\"clickable_text\" x=\"40\" y=\"30\" style=\"font: italic 40px serif; fill: red;\">Click me!</text>\n</svg>","clickableShapes":[{"targetId":"#clickable_text","action":"click","payload":"Text clicked","payloadType":"str","topic":"clicked"}],"javascriptHandlers":[],"smilAnimations":[],"bindings":[],"showCoordinates":false,"autoFormatAfterEdit":false,"showBrowserErrors":false,"showBrowserEvents":false,"enableJsDebugging":false,"sendMsgWhenLoaded":false,"noClickWhenDblClick":false,"outputField":"payload","editorUrl":"//drawsvg.org/drawsvg.html","directory":"","panning":"disabled","zooming":"disabled","panOnlyWhenZoomed":false,"doubleClickZoomEnabled":false,"mouseWheelZoomEnabled":false,"dblClickZoomPercentage":150,"cssString":"div.ui-svg svg{\n    color: var(--nr-dashboard-widgetColor);\n    fill: currentColor !important;\n}\ndiv.ui-svg path {\n    fill: inherit;\n}","name":"","_mcu":{"mcu":false},"x":920,"y":80,"wires":[["0793ba691f3622e3"]]},{"id":"e8509dc7be30844e","type":"ui_group","name":"Svg disable demo","tab":"d8520920.0128d8","order":4,"disp":true,"width":"12","collapse":false,"className":"","_mcu":{"mcu":false}},{"id":"d8520920.0128d8","type":"ui_tab","name":"Home","icon":"dashboard","order":3,"disabled":false,"hidden":false}]

Various stuff

Fontawesome icons

Fontawesome icons are used widely in Node-RED and are in fact little SVG drawings on their own. They are a very easy way e.g. to represent devices on a floorplan. Such an icon can easily be added via DrawSvg, as demonstrated in this animation:

icons via drawsvg

By specifying an identifier for the icon (like in the above animation), the icon can be updated afterwards via input messages (like any other SVG element).

When you want to enter your SVG source manually (without using DrawSvg), there is another mechanism provided:

  1. Search the Fontawesome website for an icon that fits your needs. For example, 'fa-video-camera'.

  2. Create a text element (with font family "FontAwesome") containing that icon name:

    <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. The result will be the FontAwesome icon at the specified location:

    icon

Some remarks:

Display images

In an SVG drawing, an "image" element can be used to display an image inside an SVG drawing. See this tutorial on the wiki for more information!

Troubleshooting

Some tips and tricks to solve known problems:

  1. When SVG path elements get the same colour as the dashboard theme, like in this example where the shapes become blue:

    Dashboard color

    You can avoid this by applying the fill colour as a style attribute (e.g. <element style="fill:red" ... />) to the path, instead of as a normal attribute (e.g. <element fill="red" ... />). And the normal fill attribute on an SVG path will get overwritten by the dashboard theme colour...

    Remark: drawings created with DrawSvg are already correct, but some third-party editors use the fill attribute.

  2. Some basic input messages validation has been added on the server-side, and validation errors will be showed in the debug side-panel.

  3. See the DrawSvg how to show client-side errors in your Node-RED debug panel.

    Remark: when N drawings are visible now (e.g. running in N dashboards simultaneously), then N duplicate messages will be displayed (where N can be 0 is no dashboards are open...).

  4. If you have doubts that this node is generating the requested SVG DOM structure, you might have a look at it. Here is briefly explained how to do it using Chrome:

    1. Open the developer tools of your browser, starting from your dashboard window.
    2. Right click on your SVG drawing in the dashboard, and select "Inspect".
    3. Now you should be able to see the generated SVG DOM tree.
  5. When the "show browser errors on the server" has been activated, the error messages will appear in the left Debug sidebar. However if lots of messages are being injected, it is difficult to determine which error belongs to which message. To assist with that, the error message will contain the message id (which caused that error). So simply put a debug node (to display the input messages), and compare the message id to find the related message:

    message id