[ANNOUNCE] node-red-contrib-ui-svg (beta) : new features

Hi folks,

Should really get started soon with the 2.0.0 release of the SVG node. My partner @Steve-Mcl and me had some feature requests in the past to add the ability for adding/removing SVG elements dynamically, by injecting input messages. So I implemented that tonight...

For those who want to play with it, the beta release can be installed from our Github account:

npm install bartbutenaers/node-red-contrib-ui-svg#panzoom

Some of the possibilities:

  • New commands for "add_element" and "remove_element".
  • Ability to specify a parent element or not (i.e. add by default to the root svg).
  • Ability to replace an existing element by a new element (by specifying the existing id).
  • Remove multiple elements with a single command, via a CSS selector.

The upper two Inject nodes in the following flow show the usage for a single element id, and the next two Inject nodes for multiple id's at once (via CSS selector):

svg_add_remove_via_msg

[{"id":"2b26f529.49dbfa","type":"ui_svg_graphics","z":"4ae15451.7b2f5c","group":"5a9e7538.2c2fbc","order":2,"width":"6","height":"6","svgString":"<svg x=\"0\" y=\"0\" height=\"300\" viewBox=\"0 0 300 300\" width=\"300\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:svg=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n</svg>","clickableShapes":[{"targetId":"#circle_1","action":"click","payload":"#circle_1","payloadType":"str","topic":"#circle_1"}],"smilAnimations":[],"bindings":[],"showCoordinates":true,"autoFormatAfterEdit":false,"showBrowserErrors":false,"selectorAsElementId":true,"outputField":"payload","editorUrl":"http://drawsvg.org/drawsvg.html","directory":"","panEnabled":false,"zoomEnabled":false,"controlIconsEnabled":false,"dblClickZoomEnabled":false,"mouseWheelZoomEnabled":false,"name":"","x":1820,"y":160,"wires":[[]]},{"id":"4eaee1f9.e29a","type":"inject","z":"4ae15451.7b2f5c","name":"Add element \"newElement\"","topic":"","payload":"{\"command\":\"add_element\",\"elementType\":\"text\",\"elementId\":\"burglar\",\"elementAttributes\":{\"x\":\"50\",\"y\":\"60\",\"font-family\":\"FontAwesome\",\"font-size\":\"35\",\"text-anchor\":\"middle\",\"alignment-baseline\":\"middle\",\"stroke-width\":\"1\"},\"elementStyleAttributes\":{\"fill\":\"blue\",\"stroke\":\"black\"},\"textContent\":\"fa-video-camera\"}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"showConfirmation":false,"confirmationLabel":"","x":1490,"y":160,"wires":[["2b26f529.49dbfa"]]},{"id":"13d4363.22c11ca","type":"inject","z":"4ae15451.7b2f5c","name":"Remove element","topic":"","payload":"{\"command\":\"remove_element\",\"elementId\":\"burglar\"}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"showConfirmation":false,"confirmationLabel":"","x":1460,"y":200,"wires":[["2b26f529.49dbfa"]]},{"id":"7b4a624b.97e90c","type":"function","z":"4ae15451.7b2f5c","name":"Set random coordinates","func":"// Generate random coordinates between 0 and 300\nvar x = Math.floor(Math.random() * 300);\nvar y = Math.floor(Math.random() * 300);\nmsg.payload.elementAttributes.x = x;\nmsg.payload.elementAttributes.y = y;\nmsg.payload.elementId = \"burglar_\" + Math.random();\nreturn msg;","outputs":1,"noerr":0,"x":1670,"y":300,"wires":[["2b26f529.49dbfa"]]},{"id":"9b51204a.ea4f9","type":"inject","z":"4ae15451.7b2f5c","name":"Add element","topic":"","payload":"{\"command\":\"add_element\",\"elementType\":\"text\",\"elementAttributes\":{\"font-family\":\"FontAwesome\",\"font-size\":\"35\",\"text-anchor\":\"middle\",\"alignment-baseline\":\"middle\",\"stroke-width\":\"1\"},\"elementStyleAttributes\":{\"fill\":\"blue\",\"stroke\":\"black\"},\"textContent\":\"fa-male\"}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"showConfirmation":false,"confirmationLabel":"","x":1450,"y":300,"wires":[["7b4a624b.97e90c"]]},{"id":"7bc4610d.d954c","type":"inject","z":"4ae15451.7b2f5c","name":"Remove all","topic":"","payload":"{\"command\":\"remove_element\",\"selector\":\"[id^=burglar]\"}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"showConfirmation":false,"confirmationLabel":"","x":1450,"y":260,"wires":[["2b26f529.49dbfa"]]},{"id":"5a9e7538.2c2fbc","type":"ui_group","z":"","name":"Boundingbox test","tab":"80f0e178.bbf4a","order":2,"disp":true,"width":"12","collapse":false},{"id":"80f0e178.bbf4a","type":"ui_tab","z":"","name":"Home","icon":"dashboard","order":1,"disabled":false,"hidden":false}]

As usual all constructive feedback is very welcome!
E.g. is the list of possibilities ok?
And it would be nice if somebody could offer me some use cases for the readme page, because I cannot think of anything useful for IOT :roll_eyes:

Have fun with it!
Bart

5 Likes

Small update on github.

Suppose you have specified an event handler in the "Events" tabsheet:

image

Which means you want every SVG element with id "burglar" to become clickable (i.e. get a "click" event handler).

When I now add - via an input message - an SVG element (with id "burglar") dynamically, it will become clickable since it has been defined in the "Event" tabsheet:

svg_add_remove_event_table

4 Likes

Another feature request is now implemented on the "panzoom" branch on Github: removing element attributes via an input message.

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

[{"id":"2399b014.7c6ad","type":"ui_svg_graphics","z":"4ae15451.7b2f5c","group":"2df28529.6748aa","order":2,"width":"12","height":"11","svgString":"<svg width=\"100%\" height=\"100%\" \n  xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">       \n  <image id=\"my_request\" href=\"https://www.securitymagazine.com/ext/resources/SEC/2016/0216/SEC0216-edu-feature-slide1_900px.jpg\" height=\"100%\" width=\"100%\" preserveAspectRatio=\"xMidYMid meet\"/>\n</svg>","clickableShapes":[],"smilAnimations":[],"bindings":[],"showCoordinates":false,"autoFormatAfterEdit":false,"showBrowserErrors":false,"selectorAsElementId":true,"outputField":"payload","editorUrl":"http://drawsvg.org/drawsvg.html","directory":"","panEnabled":false,"zoomEnabled":false,"controlIconsEnabled":false,"dblClickZoomEnabled":false,"mouseWheelZoomEnabled":false,"name":"","x":1200,"y":720,"wires":[[]]},{"id":"6e24eeff.683db","type":"inject","z":"4ae15451.7b2f5c","name":"Remove attribute","topic":"","payload":"{\"command\":\"remove_attribute\",\"elementId\":\"my_request\",\"attributeName\":\"visibility\"}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"showConfirmation":false,"confirmationLabel":"","x":980,"y":760,"wires":[["2399b014.7c6ad"]]},{"id":"196fb554.773beb","type":"inject","z":"4ae15451.7b2f5c","name":"Set attribute","topic":"","payload":"{\"command\":\"set_attribute\",\"elementId\":\"my_request\",\"attributeName\":\"visibility\",\"attributeValue\":\"hidden\"}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"showConfirmation":false,"confirmationLabel":"","x":970,"y":720,"wires":[["2399b014.7c6ad"]]},{"id":"2df28529.6748aa","type":"ui_group","z":"","name":"Default","tab":"60e30c13.98a7e4","order":1,"disp":true,"width":"12","collapse":false},{"id":"60e30c13.98a7e4","type":"ui_tab","z":"","name":"Attribute add/remove demo","icon":"dashboard","disabled":false,"hidden":false}]

Of course I could also have set the attribute value to "visible", but you get the point ...
If anybody has a better use case for my readme page, please let me know!

Now pruning my hedges with 32 degrees Celsius ...

1 Like

Beach weather, nice. :surfing_man:

1 Like