[Announce] node-red-contrib-ui-svg (final beta) UPDATE V1.2.1

@Bobo yeah, I had some difficulties with this & I am considering adding something into this contrib node that better handles it.

I dont fully remember the problems I had (something like full screen would only work first time after refresh or stop working after switching dashboard tabs).

For now, it is flaky - but if you manage to get a reliable demo working - please let us know.

Cheers.

Regardless of the demo, it is a great piece of work. :+1:

Ah ha now we are getting to it :smiley:

in a sense, yes, there is the ability to "update_text" (see built in info) which under the hood updates the content of a tag. If you referenced an element e.g. future_pages <g id="future_pages"> </g> you could execute an update_text function and add as much as you want.

e.g.
2019-10-17_11-41-56

Flow...

[{"id":"97bf246.d5ca6d8","type":"inject","z":"3391e156.d9d19e","name":"","topic":"","payload":"","payloadType":"date","repeat":"5","crontab":"","once":false,"onceDelay":0.1,"x":150,"y":1080,"wires":[["e2e37baf.9531b8"]]},{"id":"e2e37baf.9531b8","type":"function","z":"3391e156.d9d19e","name":"random mode generator","func":"let r1 = Math.floor(Math.random() * 5000) + 1000;  \n\nfunction randomItem(arr){\n    var len = arr.length;\n    var rand = Math.floor(Math.random() * len);\n    return arr[rand]\n}\n\nlet station = randomItem([\"STN10\",\"STN20\",\"STN30\",\"STN40\",\"STN50\",\"STN60\",\"STN70\",\"STN80\"]);\nlet mode = randomItem([\"auto\",\"manual\",\"fault\",\"auto\",\"other\",\"auto\",\"fault\",\"auto\"]);\nlet fault = randomItem([\"sensor fault\",\"coolant empty\",\"CP tripped\",\"over speed\",\"E-Stop\",\"Safety Mat\"]);\nlet other = randomItem([\"full\",\"waiting\",\"over cycle\"]);\n\nlet statusText = mode == \"other\" ? other : (mode == \"fault\" ? fault : mode);\n\nlet state = flow.get(\"state\") || {}\nif(!state[station]){\n    state[station] = {mode:\"manual\", status:\"manual\", count:0}    \n}\nstate[station].mode = mode;\nstate[station].status = statusText;\nflow.set(\"state\",state)\n\n//$(\"#STN50 > .background\").attr(\"fill\",\"url('#fault')\")\n//$(\"#STN50 > .status\").text(\"hi\")\n\nlet newmsg = {payload:[\n        {\n            \"command\": \"update_attribute\",\n            \"selector\": \"#\" + station + \" > .background\",\n            \"attributeName\": \"fill\",\n            \"attributeValue\": \"url('#\" + mode + \"')\"\n        },\n        {\n            \"command\": \"update_text\",\n            selector: \"#\" + station + \" > .status\",\n            textContent: statusText\n        },\n        {\n            \"command\": \"update_text\",\n            selector: \"#\" + station + \" > .count\",\n            textContent: state[station].count.toString()\n        }\n    ]\n}\n\n\nsetTimeout(function () {\n    node.send(newmsg)\n}, r1 - 100);\n\n    \n//return msg;","outputs":1,"noerr":0,"x":350,"y":1080,"wires":[["474cfd5a.60b584"]]},{"id":"474cfd5a.60b584","type":"ui_svg_graphics","z":"3391e156.d9d19e","group":"17b0dd6e.e23ec3","order":0,"width":"12","height":"9","svgString":"<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:svg=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" id=\"svghmi\" viewBox=\"0 -0.006988120265305042 320 180.01397705078125\" width=\"80%\" height=\"80%\">\n  <defs id=\"svgEditorDefs\">\n    <symbol xmlns=\"http://www.w3.org/2000/svg\" id=\"f015\" preserveAspectRatio=\"xMidYMid meet\" viewBox=\"0 0 576 512\">\n      <path d=\"M280.37 148.26L96 300.11V464a16 16 0 0 0 16 16l112.06-.29a16 16 0 0 0 15.92-16V368a16 16 0 0 1 16-16h64a16 16 0 0 1 16 16v95.64a16 16 0 0 0 16 16.05L464 480a16 16 0 0 0 16-16V300L295.67 148.26a12.19 12.19 0 0 0-15.3 0zM571.6 251.47L488 182.56V44.05a12 12 0 0 0-12-12h-56a12 12 0 0 0-12 12v72.61L318.47 43a48 48 0 0 0-61 0L4.34 251.47a12 12 0 0 0-1.6 16.9l25.5 31A12 12 0 0 0 45.15 301l235.22-193.74a12.19 12.19 0 0 1 15.3 0L530.9 301a12 12 0 0 0 16.9-1.6l25.5-31a12 12 0 0 0-1.7-16.93z\"/>\n    </symbol>\n    <polygon id=\"svgEditorIconDefs\" style=\"fill:rosybrown;\"/>\n  </defs>\n  <rect id=\"svgEditorBackground\" x=\"0\" y=\"0\" width=\"320\" height=\"180\" style=\"fill:none; stroke: none;\"/>\n  <defs>\n    <linearGradient spreadMethod=\"repeat\" y1=\"0\" x1=\"0.5\" y2=\"1\" x2=\"0.5\" id=\"auto\">\n      <stop offset=\"0\" stop-color=\"#00aa00\"/>\n      <stop offset=\"0.5\" stop-color=\"#00ff00\"/>\n      <stop offset=\"1\" stop-color=\"#00aa00\"/>\n    </linearGradient>\n    <linearGradient spreadMethod=\"repeat\" y1=\"0\" x1=\"0.5\" y2=\"1\" x2=\"0.5\" id=\"fault\">\n      <stop offset=\"0\" stop-color=\"#aa0000\"/>\n      <stop offset=\"0.5\" stop-color=\"#ff0000\"/>\n      <stop offset=\"1\" stop-color=\"#aa0000\"/>\n    </linearGradient>\n    <linearGradient spreadMethod=\"repeat\" y1=\"0\" x1=\"0.5\" y2=\"1\" x2=\"0.5\" id=\"other\">\n      <stop offset=\"0\" stop-color=\"#aaaa00\"/>\n      <stop offset=\"0.5\" stop-color=\"#ffff00\"/>\n      <stop offset=\"1\" stop-color=\"#aaaa00\"/>\n    </linearGradient>\n    <linearGradient spreadMethod=\"repeat\" y1=\"0\" x1=\"0.5\" y2=\"1\" x2=\"0.5\" id=\"manual\">\n      <stop offset=\"0\" stop-color=\"#0000aa\"/>\n      <stop offset=\"0.5\" stop-color=\"#0000ff\"/>\n      <stop offset=\"1\" stop-color=\"#0000aa\"/>\n    </linearGradient>\n  </defs>\n  <g display=\"inline\">\n    <title>background</title>\n    <rect x=\"0.000017590256192079323\" fill=\"#000000\" stroke-dasharray=\"null\" stroke-linejoin=\"null\" stroke-linecap=\"null\" y=\"0.7031467887925658\" width=\"320\" height=\"180\" id=\"svg_5\" stroke=\"#000000\"/>\n  <g id=\"home_button\" class=\"home_button\">\n      <rect x=\"243.175\" y=\"168.165\" style=\"fill:khaki;stroke:black;stroke-width:1px;\" id=\"e2_rectangle\" width=\"71.7319\" height=\"11.9569\" transform=\"matrix(1.04259 0 0 1.04259 -11.5347 -7.65778)\"/>\n      <use xlink:href=\"#f015\" x=\"243.513\" y=\"169.051\" width=\"12.2989\" height=\"9.93866\" id=\"e2_icon\" style=\"fill:rosybrown;\"/><text style=\"fill:black;font-family:Arial;font-size:10px;\" x=\"250.00698852539062\" y=\"171.73304748535156\" id=\"e4_texte\"/><text style=\"fill:black;font-family:Arial Black;font-size:12px;\" x=\"275.0726318359375\" y=\"175.89859008789062\" id=\"e5_texte\" transform=\"matrix(0.623201 0 0 0.623201 94.2814 67.0708)\" textLength=\"52.16404582508221\">Home</text>\n  </g>\n  </g>\n  <g display=\"inline\" id=\"page1\" class=\"page\">\n    <title>Main Overview</title>\n    <g id=\"STN10\" transform=\"matrix(1 0 0 1 0 -5.36688)\">\n      <rect class=\"background\" fill=\"url(#manual)\" x=\"3.20313\" y=\"28.83594\" width=\"77.25\" height=\"70.625\" rx=\"10\" ry=\"10\" stroke=\"#000000\" id=\"box_1\"/>\n      <text class=\"name\" fill=\"#ffffff\" stroke-width=\"0\" x=\"-39.92712\" y=\"62.62216\" id=\"svg_2\" font-size=\"24\" font-family=\"Sans-serif\" text-anchor=\"middle\" xml:space=\"preserve\" font-weight=\"bold\" transform=\"matrix(0.41754164704216323,0,0,0.4583333432674408,58.471179716401295,13.575520584359765) \" stroke=\"#ffffff\">Station 10</text>\n      <text class=\"status\" fill=\"#ffffff\" stroke-width=\"0\" x=\"-39.37879\" y=\"175.82813\" font-size=\"24\" font-family=\"Sans-serif\" text-anchor=\"middle\" xml:space=\"preserve\" font-weight=\"bold\" transform=\"matrix(0.41754164704216323,0,0,0.4583333432674408,58.471179716401295,13.575520584359765) \" stroke=\"#ffffff\" id=\"Status_STN10\">Manual</text>\n      <text class=\"count\" xml:space=\"preserve\" text-anchor=\"middle\" font-family=\"Sans-serif\" font-size=\"24\" id=\"count_1\" y=\"72.78907\" x=\"41.82814\" stroke-linecap=\"null\" stroke-linejoin=\"null\" stroke-dasharray=\"null\" stroke-width=\"0\" stroke=\"#000000\" fill=\"#000000\">0</text>\n    </g>\n    <g id=\"STN20\" transform=\"matrix(1 0 0 1 0 -5.36688)\">\n      <rect id=\"svg_24\" class=\"background\" fill=\"url(#manual)\" x=\"82.65625\" y=\"28.83594\" width=\"77.25\" height=\"70.625\" rx=\"10\" ry=\"10\" stroke=\"#000000\"/>\n      <text id=\"svg_25\" class=\"name\" fill=\"#ffffff\" stroke-width=\"0\" x=\"150.36079\" y=\"62.62215\" font-size=\"24\" font-family=\"Sans-serif\" text-anchor=\"middle\" xml:space=\"preserve\" font-weight=\"bold\" transform=\"matrix(0.41754164704216323,0,0,0.4583333432674408,58.471179716401295,13.575520584359765) \" stroke=\"#ffffff\">Station 20</text>\n      <text id=\"svg_26\" class=\"status\" fill=\"#ffffff\" stroke-width=\"0\" x=\"150.90912\" y=\"175.82812\" font-size=\"24\" font-family=\"Sans-serif\" text-anchor=\"middle\" xml:space=\"preserve\" font-weight=\"bold\" transform=\"matrix(0.41754164704216323,0,0,0.4583333432674408,58.471179716401295,13.575520584359765) \" stroke=\"#ffffff\">Manual</text>\n      <text id=\"svg_27\" class=\"count\" xml:space=\"preserve\" text-anchor=\"middle\" font-family=\"Sans-serif\" font-size=\"24\" y=\"72.78907\" x=\"121.28127\" stroke-linecap=\"null\" stroke-linejoin=\"null\" stroke-dasharray=\"null\" stroke-width=\"0\" stroke=\"#000000\" fill=\"#000000\">0</text>\n    </g>\n    <g id=\"STN30\" transform=\"matrix(1 0 0 1 0 -5.36688)\">\n      <rect id=\"svg_29\" class=\"background\" fill=\"url(#manual)\" x=\"161.54688\" y=\"28.83594\" width=\"77.25\" height=\"70.625\" rx=\"10\" ry=\"10\" stroke=\"#000000\"/>\n      <text id=\"svg_30\" class=\"name\" fill=\"#ffffff\" stroke-width=\"0\" x=\"339.30151\" y=\"62.62216\" font-size=\"24\" font-family=\"Sans-serif\" text-anchor=\"middle\" xml:space=\"preserve\" font-weight=\"bold\" transform=\"matrix(0.41754164704216323,0,0,0.4583333432674408,58.471179716401295,13.575520584359765) \" stroke=\"#ffffff\">Station 30</text>\n      <text id=\"svg_31\" class=\"status\" fill=\"#ffffff\" stroke-width=\"0\" x=\"339.84985\" y=\"175.82813\" font-size=\"24\" font-family=\"Sans-serif\" text-anchor=\"middle\" xml:space=\"preserve\" font-weight=\"bold\" transform=\"matrix(0.41754164704216323,0,0,0.4583333432674408,58.471179716401295,13.575520584359765) \" stroke=\"#ffffff\">Manual</text>\n      <text id=\"svg_32\" class=\"count\" xml:space=\"preserve\" text-anchor=\"middle\" font-family=\"Sans-serif\" font-size=\"24\" y=\"72.78907\" x=\"200.17189\" stroke-linecap=\"null\" stroke-linejoin=\"null\" stroke-dasharray=\"null\" stroke-width=\"0\" stroke=\"#000000\" fill=\"#000000\">0</text>\n    </g>\n    <g id=\"STN40\" transform=\"matrix(1 0 0 1 0 -5.36688)\">\n      <rect id=\"svg_3\" class=\"background\" fill=\"url(#manual)\" x=\"240.43751\" y=\"28.83594\" width=\"77.25\" height=\"70.625\" rx=\"10\" ry=\"10\" stroke=\"#000000\"/>\n      <text id=\"svg_4\" class=\"name\" fill=\"#ffffff\" stroke-width=\"0\" x=\"528.24226\" y=\"62.62216\" font-size=\"24\" font-family=\"Sans-serif\" text-anchor=\"middle\" xml:space=\"preserve\" font-weight=\"bold\" transform=\"matrix(0.41754164704216323,0,0,0.4583333432674408,58.471179716401295,13.575520584359765) \" stroke=\"#ffffff\">Station 40</text>\n      <text id=\"svg_6\" class=\"status\" fill=\"#ffffff\" stroke-width=\"0\" x=\"528.7906\" y=\"175.82813\" font-size=\"24\" font-family=\"Sans-serif\" text-anchor=\"middle\" xml:space=\"preserve\" font-weight=\"bold\" transform=\"matrix(0.41754164704216323,0,0,0.4583333432674408,58.471179716401295,13.575520584359765) \" stroke=\"#ffffff\">Manual</text>\n      <text id=\"svg_7\" class=\"count\" xml:space=\"preserve\" text-anchor=\"middle\" font-family=\"Sans-serif\" font-size=\"24\" y=\"72.78907\" x=\"279.06252\" stroke-linecap=\"null\" stroke-linejoin=\"null\" stroke-dasharray=\"null\" stroke-width=\"0\" stroke=\"#000000\" fill=\"#000000\">0</text>\n    </g>\n    <g id=\"STN50\" transform=\"matrix(1 0 0 1 0 -5.36688)\">\n      <rect id=\"svg_57\" class=\"background\" fill=\"url(#manual)\" x=\"3.20313\" y=\"102.24219\" width=\"77.25\" height=\"70.625\" rx=\"10\" ry=\"10\" stroke=\"#000000\"/>\n      <text id=\"svg_58\" class=\"name\" fill=\"#ffffff\" stroke-width=\"0\" x=\"-39.92712\" y=\"222.78125\" font-size=\"24\" font-family=\"Sans-serif\" text-anchor=\"middle\" xml:space=\"preserve\" font-weight=\"bold\" transform=\"matrix(0.41754164704216323,0,0,0.4583333432674408,58.471179716401295,13.575520584359765) \" stroke=\"#ffffff\">Station 50</text>\n      <text id=\"svg_59\" class=\"status\" fill=\"#ffffff\" stroke-width=\"0\" x=\"-39.37879\" y=\"335.98722\" font-size=\"24\" font-family=\"Sans-serif\" text-anchor=\"middle\" xml:space=\"preserve\" font-weight=\"bold\" transform=\"matrix(0.41754164704216323,0,0,0.4583333432674408,58.471179716401295,13.575520584359765) \" stroke=\"#ffffff\">Manual</text>\n      <text id=\"svg_60\" class=\"count\" xml:space=\"preserve\" text-anchor=\"middle\" font-family=\"Sans-serif\" font-size=\"24\" y=\"146.19532\" x=\"41.82814\" stroke-linecap=\"null\" stroke-linejoin=\"null\" stroke-dasharray=\"null\" stroke-width=\"0\" stroke=\"#000000\" fill=\"#000000\">0</text>\n    </g>\n    <g id=\"STN60\" transform=\"matrix(1 0 0 1 0 -5.36688)\">\n      <rect id=\"svg_62\" class=\"background\" fill=\"url(#manual)\" x=\"82.65625\" y=\"102.24219\" width=\"77.25\" height=\"70.625\" rx=\"10\" ry=\"10\" stroke=\"#000000\"/>\n      <text id=\"svg_63\" class=\"name\" fill=\"#ffffff\" stroke-width=\"0\" x=\"150.36079\" y=\"222.78124\" font-size=\"24\" font-family=\"Sans-serif\" text-anchor=\"middle\" xml:space=\"preserve\" font-weight=\"bold\" transform=\"matrix(0.41754164704216323,0,0,0.4583333432674408,58.471179716401295,13.575520584359765) \" stroke=\"#ffffff\">Station 60</text>\n      <text id=\"svg_64\" class=\"status\" fill=\"#ffffff\" stroke-width=\"0\" x=\"150.90912\" y=\"335.98721\" font-size=\"24\" font-family=\"Sans-serif\" text-anchor=\"middle\" xml:space=\"preserve\" font-weight=\"bold\" transform=\"matrix(0.41754164704216323,0,0,0.4583333432674408,58.471179716401295,13.575520584359765) \" stroke=\"#ffffff\">Manual</text>\n      <text id=\"svg_65\" class=\"count\" xml:space=\"preserve\" text-anchor=\"middle\" font-family=\"Sans-serif\" font-size=\"24\" y=\"146.19532\" x=\"121.28127\" stroke-linecap=\"null\" stroke-linejoin=\"null\" stroke-dasharray=\"null\" stroke-width=\"0\" stroke=\"#000000\" fill=\"#000000\">0</text>\n    </g>\n    <g id=\"STN70\" transform=\"matrix(1 0 0 1 0 -5.36688)\">\n      <rect id=\"svg_67\" class=\"background\" fill=\"url(#manual)\" x=\"161.54688\" y=\"102.24219\" width=\"77.25\" height=\"70.625\" rx=\"10\" ry=\"10\" stroke=\"#000000\"/>\n      <text id=\"svg_68\" class=\"name\" fill=\"#ffffff\" stroke-width=\"0\" x=\"339.30151\" y=\"222.78124\" font-size=\"24\" font-family=\"Sans-serif\" text-anchor=\"middle\" xml:space=\"preserve\" font-weight=\"bold\" transform=\"matrix(0.41754164704216323,0,0,0.4583333432674408,58.471179716401295,13.575520584359765) \" stroke=\"#ffffff\">Station 70</text>\n      <text id=\"svg_69\" class=\"status\" fill=\"#ffffff\" stroke-width=\"0\" x=\"339.84985\" y=\"335.98721\" font-size=\"24\" font-family=\"Sans-serif\" text-anchor=\"middle\" xml:space=\"preserve\" font-weight=\"bold\" transform=\"matrix(0.41754164704216323,0,0,0.4583333432674408,58.471179716401295,13.575520584359765) \" stroke=\"#ffffff\">Manual</text>\n      <text id=\"svg_70\" class=\"count\" xml:space=\"preserve\" text-anchor=\"middle\" font-family=\"Sans-serif\" font-size=\"24\" y=\"146.19532\" x=\"200.17189\" stroke-linecap=\"null\" stroke-linejoin=\"null\" stroke-dasharray=\"null\" stroke-width=\"0\" stroke=\"#000000\" fill=\"#000000\">0</text>\n    </g>\n    <g id=\"STN80\" transform=\"matrix(1 0 0 1 0 -5.36688)\">\n      <rect id=\"svg_72\" class=\"background\" fill=\"url(#manual)\" x=\"240.43751\" y=\"102.24219\" width=\"77.25\" height=\"70.625\" rx=\"10\" ry=\"10\" stroke=\"#000000\"/>\n      <text id=\"svg_73\" class=\"name\" fill=\"#ffffff\" stroke-width=\"0\" x=\"528.24226\" y=\"222.78124\" font-size=\"24\" font-family=\"Sans-serif\" text-anchor=\"middle\" xml:space=\"preserve\" font-weight=\"bold\" transform=\"matrix(0.41754164704216323,0,0,0.4583333432674408,58.471179716401295,13.575520584359765) \" stroke=\"#ffffff\">Station 80</text>\n      <text id=\"svg_74\" class=\"status\" fill=\"#ffffff\" stroke-width=\"0\" x=\"528.7906\" y=\"335.98721\" font-size=\"24\" font-family=\"Sans-serif\" text-anchor=\"middle\" xml:space=\"preserve\" font-weight=\"bold\" transform=\"matrix(0.41754164704216323,0,0,0.4583333432674408,58.471179716401295,13.575520584359765) \" stroke=\"#ffffff\">Manual</text>\n      <text id=\"svg_75\" class=\"count\" xml:space=\"preserve\" text-anchor=\"middle\" font-family=\"Sans-serif\" font-size=\"24\" y=\"146.19532\" x=\"279.06252\" stroke-linecap=\"null\" stroke-linejoin=\"null\" stroke-dasharray=\"null\" stroke-width=\"0\" stroke=\"#000000\" fill=\"#000000\">0</text>\n    </g>\n    <g id=\"MAIN_HEADER\" class=\"header_bar\">\n      <rect stroke=\"#000000\" class=\"background\" fill=\"url(#manual)\" x=\"0\" y=\"0\" width=\"320\" height=\"22\" id=\"svg_14\"/>\n      <text class=\"name\" fill=\"#ffffff\" stroke-width=\"0\" x=\"237.32815\" y=\"5.23012\" font-size=\"24\" font-family=\"Sans-serif\" text-anchor=\"middle\" xml:space=\"preserve\" font-weight=\"bold\" transform=\"matrix(0.41754164704216323,0,0,0.4583333432674408,58.471179716401295,13.575520584359765) \" stroke=\"#ffffff\" id=\"svg_15\">Main Overview</text>\n    </g>\n  </g>\n  <g id=\"page2\" display=\"none\" class=\"page\">\n    <title>Station 10 Overview</title>\n    <g id=\"STN10_HEADER\" class=\"header_bar\">\n      <rect stroke=\"#000000\" class=\"background\" fill=\"url(#manual)\" x=\"0\" y=\"0\" width=\"320\" height=\"22\"/>\n      <text class=\"name\" fill=\"#ffffff\" stroke-width=\"0\" x=\"236.24292\" y=\"6.73012\" font-size=\"24\" font-family=\"Sans-serif\" text-anchor=\"middle\" xml:space=\"preserve\" font-weight=\"bold\" transform=\"matrix(0.41754164704216323,0,0,0.4583333432674408,58.471179716401295,13.575520584359765) \" stroke=\"#ffffff\">Station 10</text>\n    </g>\n    <g id=\"STN10_Air\" transform=\"matrix(1 0 0 1 0 -5.36688)\">\n      <rect class=\"background\" fill=\"url(#auto)\" x=\"119.51562\" y=\"61.65625\" width=\"77.25\" height=\"70.625\" rx=\"10\" ry=\"10\" stroke=\"#000000\"/>\n      <text class=\"status\" fill=\"#ffffff\" stroke-width=\"0\" x=\"236.15508\" y=\"186.68609\" font-size=\"24\" font-family=\"Sans-serif\" text-anchor=\"middle\" xml:space=\"preserve\" font-weight=\"bold\" transform=\"matrix(0.41754164704216323,0,0,0.4583333432674408,58.471179716401295,13.575520584359765) \" stroke=\"#ffffff\">Air Supply</text>\n    </g>\n    <g id=\"STN10_Water\" transform=\"matrix(1 0 0 1 0 -5.36688)\">\n      <rect class=\"background\" fill=\"url(#auto)\" x=\"208.51562\" y=\"61.65625\" width=\"77.25\" height=\"70.625\" rx=\"10\" ry=\"10\" stroke=\"#000000\"/>\n      <text class=\"status\" fill=\"#ffffff\" stroke-width=\"0\" x=\"449.30747\" y=\"186.68609\" font-size=\"24\" font-family=\"Sans-serif\" text-anchor=\"middle\" xml:space=\"preserve\" font-weight=\"bold\" transform=\"matrix(0.41754164704216323,0,0,0.4583333432674408,58.471179716401295,13.575520584359765) \" stroke=\"#ffffff\">Water Supply</text>\n    </g>\n    <g id=\"STN10_ControlPower\" transform=\"matrix(1 0 0 1 0 -5.36688)\">\n      <rect class=\"background\" fill=\"url(#fault)\" x=\"32.51562\" y=\"61.65625\" width=\"77.25\" height=\"70.625\" rx=\"10\" ry=\"10\" stroke=\"#000000\"/>\n      <text class=\"status\" fill=\"#ffffff\" stroke-width=\"0\" x=\"27.79263\" y=\"186.68609\" font-size=\"24\" font-family=\"Sans-serif\" text-anchor=\"middle\" xml:space=\"preserve\" font-weight=\"bold\" transform=\"matrix(0.41754164704216323,0,0,0.4583333432674408,58.471179716401295,13.575520584359765) \" stroke=\"#ffffff\">Control Power</text>\n    </g>\n  </g>\n  <g display=\"none\" id=\"page3\" class=\"page\">\n  </g>\n\n</svg>","clickableShapes":[{"targetId":"#STN10","action":"click","payload":"page2","payloadType":"str","topic":"change_page"},{"targetId":".home_button","action":"click","payload":"page1","payloadType":"str","topic":"change_page"},{"targetId":"#STN20","action":"click","payload":"page3","payloadType":"str","topic":"change_page"}],"smilAnimations":[],"bindings":[],"showCoordinates":false,"autoFormatAfterEdit":false,"outputField":"payload","editorUrl":"http://drawsvg.org/drawsvg.html","directory":"","name":"","x":620,"y":1080,"wires":[["33a3bd1d.079462","725b90d9.b91ce"]]},{"id":"9b284c7d.74084","type":"function","z":"3391e156.d9d19e","name":"random count generator","func":"function randomInc(station, delayms){\n\n    setTimeout(function () {\n        var state = flow.get(\"state\") || {};\n        if(!state[station]){\n            state[station] = {count: 0}    \n        }\n        if(state[station].mode == \"auto\"){\n            state[station].count += 1;\n            flow.set(\"state\",state)\n            var newmsg = {\n                payload:{\n                    \"command\": \"update_text\",\n                    selector: \"#\" + station + \" > .count\",\n                    textContent: state[station].count.toString()\n                }\n            }\n            node.send(newmsg);\n        }\n        \n    }, delayms-5);\n}\n\nvar stns = [\"STN10\",\"STN20\",\"STN30\",\"STN40\",\"STN50\",\"STN60\",\"STN70\",\"STN80\"]\nvar i = 0;\nfor(i=0; i<stns.length; i++){\n    randomInc(stns[i], Math.floor(Math.random() * 1000) )\n}\n\n    \n//return msg;","outputs":1,"noerr":0,"x":350,"y":1120,"wires":[["474cfd5a.60b584"]]},{"id":"6f583b6.1bc37c4","type":"inject","z":"3391e156.d9d19e","name":"","topic":"","payload":"","payloadType":"date","repeat":"5","crontab":"","once":false,"onceDelay":0.1,"x":150,"y":1120,"wires":[["9b284c7d.74084"]]},{"id":"33a3bd1d.079462","type":"debug","z":"3391e156.d9d19e","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":790,"y":1080,"wires":[]},{"id":"4da7998b.5191a8","type":"function","z":"3391e156.d9d19e","name":"init  mode generator","func":"let stations = [\"STN10\",\"STN20\",\"STN30\",\"STN40\",\"STN50\",\"STN60\",\"STN70\",\"STN80\"];\nlet state = flow.get(\"state\") || {}\n\nfunction buildUpdates(station, state){\n    if(isNaN(state.count)){\n        state.count = 0;\n    }\n    msgData.push({\n                \"command\": \"update_attribute\",\n                \"selector\": \"#\" + station + \" > .background\",\n                \"attributeName\": \"fill\",\n                \"attributeValue\": \"url('#\" + (state.mode || \"manual\") + \"')\"\n            })\n    msgData.push({\n                \"command\": \"update_text\",\n                selector: \"#\" + station + \" > .status\",\n                textContent: state.status || \"manual\"\n            })\n    msgData.push({\n                \"command\": \"update_text\",\n                selector: \"#\" + station + \" > .count\",\n                textContent: state.count || \"0\"\n            })\n}\nlet msgData = [];\n\n[\"STN10\",\"STN20\",\"STN30\",\"STN40\",\"STN50\",\"STN60\",\"STN70\",\"STN80\"].forEach(function(station){\n    if(!state[station]){\n        state[station] = {mode:\"manual\", status:\"manual\", count:0}    \n    }\n    buildUpdates(station, state[station]);\n})\n\nflow.set(\"state\",state)\nmsg.payload = msgData;\nreturn msg;","outputs":1,"noerr":0,"x":330,"y":1040,"wires":[["474cfd5a.60b584","df202829.299b18"]]},{"id":"860389f0.892158","type":"inject","z":"3391e156.d9d19e","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"onceDelay":"0.5","x":150,"y":1040,"wires":[["4da7998b.5191a8"]]},{"id":"df202829.299b18","type":"debug","z":"3391e156.d9d19e","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":570,"y":1040,"wires":[]},{"id":"d1b28cc1.1c166","type":"comment","z":"3391e156.d9d19e","name":"HMI Demo with fake data. Click Title bar to full screen, click Station 10 for page 2","info":"","x":340,"y":1000,"wires":[]},{"id":"9b8bfcfb.37f47","type":"inject","z":"3391e156.d9d19e","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":220,"y":1200,"wires":[["7a445b20.f4fce4"]]},{"id":"7a445b20.f4fce4","type":"function","z":"3391e156.d9d19e","name":"create page3","func":"\nvar inner = `\n<title>Station 20 Overview</title>\n  <g id=\"STN20_HEADER\" class=\"header_bar\">\n   <rect stroke=\"#000000\" class=\"background\" fill=\"url(#manual)\" x=\"0\" y=\"0\" width=\"320\" height=\"22\"/>\n   <text class=\"name\" fill=\"#ffffff\" stroke-width=\"0\" x=\"236.24292\" y=\"6.73012\" font-size=\"24\" font-family=\"Sans-serif\" text-anchor=\"middle\" xml:space=\"preserve\" font-weight=\"bold\" transform=\"matrix(0.41754164704216323,0,0,0.4583333432674408,58.471179716401295,13.575520584359765) \" stroke=\"#ffffff\">Station 20</text>\n  </g>\n  <g id=\"STN20_Air\">\n   <rect class=\"background\" fill=\"url(#fault)\" x=\"119.51562\" y=\"61.65625\" width=\"77.25\" height=\"70.625\" rx=\"10\" ry=\"10\" stroke=\"#000000\"/>\n   <text class=\"status\" fill=\"#ffffff\" stroke-width=\"0\" x=\"236.15508\" y=\"186.68609\" font-size=\"24\" font-family=\"Sans-serif\" text-anchor=\"middle\" xml:space=\"preserve\" font-weight=\"bold\" transform=\"matrix(0.41754164704216323,0,0,0.4583333432674408,58.471179716401295,13.575520584359765) \" stroke=\"#ffffff\">Air Supply</text>\n  </g>\n  <g id=\"STN20_Water\">\n   <rect class=\"background\" fill=\"url(#auto)\" x=\"208.51562\" y=\"61.65625\" width=\"77.25\" height=\"70.625\" rx=\"10\" ry=\"10\" stroke=\"#000000\"/>\n   <text class=\"status\" fill=\"#ffffff\" stroke-width=\"0\" x=\"449.30747\" y=\"186.68609\" font-size=\"24\" font-family=\"Sans-serif\" text-anchor=\"middle\" xml:space=\"preserve\" font-weight=\"bold\" transform=\"matrix(0.41754164704216323,0,0,0.4583333432674408,58.471179716401295,13.575520584359765) \" stroke=\"#ffffff\">Water Supply</text>\n  </g>\n  <g id=\"STN20_ControlPower\">\n   <rect class=\"background\" fill=\"url(#auto)\" x=\"32.51562\" y=\"61.65625\" width=\"77.25\" height=\"70.625\" rx=\"10\" ry=\"10\" stroke=\"#000000\"/>\n   <text class=\"status\" fill=\"#ffffff\" stroke-width=\"0\" x=\"27.79263\" y=\"186.68609\" font-size=\"24\" font-family=\"Sans-serif\" text-anchor=\"middle\" xml:space=\"preserve\" font-weight=\"bold\" transform=\"matrix(0.41754164704216323,0,0,0.4583333432674408,58.471179716401295,13.575520584359765) \" stroke=\"#ffffff\">Control Power</text>\n  </g>\n\n`\n\nmsg.payload = [\n {\n    \"command\": \"update_text\",\n    \"selector\": \"#page3\",\n    \"textContent\": inner\n }\n]\n\nreturn msg;","outputs":1,"noerr":0,"x":370,"y":1200,"wires":[["474cfd5a.60b584"]]},{"id":"725b90d9.b91ce","type":"switch","z":"3391e156.d9d19e","name":"","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"change_page","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":550,"y":1260,"wires":[["5d6a998.7c63568"]]},{"id":"5d6a998.7c63568","type":"function","z":"3391e156.d9d19e","name":"change page by payload","func":"\nmsg.payload = [\n {  //1st, hide all pages\n    \"command\": \"update_attribute\",\n    \"selector\": \".page\",\n    \"attributeName\": \"display\",\n    \"attributeValue\": \"none\"\n },\n {   //2nd, show desired page\n    \"command\": \"update_attribute\",\n    \"selector\": \"#\" + msg.payload,\n    \"attributeName\": \"display\",\n    \"attributeValue\": \"inline\"\n }\n]\n\nreturn msg;","outputs":1,"noerr":0,"x":750,"y":1260,"wires":[["474cfd5a.60b584"]]},{"id":"74c0ab99.b6b7f4","type":"ui_button","z":"3391e156.d9d19e","name":"","group":"17b0dd6e.e23ec3","order":4,"width":"2","height":"1","passthru":false,"label":"Add page","tooltip":"","color":"","bgcolor":"","icon":"","payload":"true","payloadType":"bool","topic":"","x":210,"y":1260,"wires":[["7a445b20.f4fce4"]]},{"id":"17b0dd6e.e23ec3","type":"ui_group","z":"","name":"HMI","tab":"3c2499dc.db9136","disp":true,"width":"12","collapse":false},{"id":"3c2499dc.db9136","type":"ui_tab","z":"","name":"Home","icon":"dashboard"}]

Caveats

  • As click events and some other dynamic parts are created when the node is initialised, you cannot use the "Clickable" items inside the node for dynamically generated items (events are not attached) thats why in the demo i put an ugly home button in the SVG Source
2 Likes

Hmmm, I see the "add page" in the flow, and I see it in the dashboard outline that that config looks good too but it does not show up on the dashboard.

I also tried adding additional dashboard nodes. Even adding them on different tabs. None of them are showing up.

I also updated the dashboard to the newest version 2.17.1 and I am running NR v1.0.2. I will have to do some more playing as I might have stumbled upon a bug?

Do you see errors in the browse console log?

Just in the middle of my testing. It works great on a rPi but failing on Windows10. Using the same Chrome browser for both.

I will take a look at the logs.

Joe

Yes. Here it is:

WebSocket connection to 'ws://localhost:1880/ui/socket.io/?EIO=3&transport=websocket&sid=t5c3VErzo8WHVYSpAAAF' failed: Error during WebSocket handshake: Unexpected response code: 400
r.doOpen @ index.js:83

Joe,
Does anything else on your dashboard work? Because the websocket is internal dashboard stuff to communicate all data to the browser. We have no control about that...
Is this the Node-RED log (server side) or the console log of the browser (where the dashboard is displayed). Because both are relevant!

Nothing else on the dashboard other than the SVG itself is displaying. What i posted was form the Chrome console.

I typically use NR on rPis. I am not as familiar with running it on windows. I have searched but am unable to find how to view the NR log in Windows. Where is it?

Also, on running the exact same flow on rPi I can see the the "add page" button but when pressed it does nothing. No errors on the browser console or the NR log.

Joe

UPDATE - V1.2.0 V1.2.1 - final beta before publishing to NPM/Pallete (we hope)

  • update_attribute (and set_attribute) commands now support removing of attributes by sending empty attributeValue
  • new command type update_style / set_style ...
    • Named style attribute change: { "command": "update_style", "selector": ".camera", "attributeName": "fill", "attributeValue": "purple" }
    • Style object attribute(s) change: { "command": "update_style", "selector": ".camera", "style": { "fill": "blue", "transform": "rotate(5deg)" } }
    • of course this update_style / set_style also supports removing any styles that are forcing the color e.g. {"command":"update_style", "selector":".camera", "style":{"fill":"","transform":""}}

demo.
Watch the oddness (svg+attr+css priorities) where color/fill/attribute/style are initially set in SVG source. However this new functionality (and with this flow as a demo) we can demonstrate workarounds and capabilities...

Flow

[{"id":"ce0b967b.2280e8","type":"debug","z":"116cddab.f8a6f2","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":430,"y":200,"wires":[]},{"id":"854d7903.b244a8","type":"inject","z":"116cddab.f8a6f2","name":"set_attribute fill red","topic":"","payload":"{\"command\":\"set_attribute\",\"selector\":\".camera\",\"attributeName\":\"fill\",\"attributeValue\":\"red\"}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":160,"wires":[["cadd2431.a59568"]]},{"id":"dd18275c.ed0918","type":"inject","z":"116cddab.f8a6f2","name":"update_style fill purple","topic":"","payload":"{\"command\":\"update_style\",\"selector\":\".camera\",\"attributeName\":\"fill\",\"attributeValue\":\"purple\"}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":220,"wires":[["cadd2431.a59568"]]},{"id":"55189bc0.d79c34","type":"inject","z":"116cddab.f8a6f2","name":"update_style fill blue AND rotate 5","topic":"","payload":"{\"command\":\"update_style\",\"selector\":\".camera\",\"style\":{\"fill\":\"blue\",\"transform\":\"rotate(5deg)\"}}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":180,"y":280,"wires":[["cadd2431.a59568"]]},{"id":"ea3e1c6b.f248c","type":"inject","z":"116cddab.f8a6f2","name":"update_style multiple - remove color & rotate","topic":"","payload":"{\"command\":\"update_style\",\"selector\":\".camera\",\"style\":{\"fill\":\"\",\"transform\":\"\"}}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":210,"y":340,"wires":[["cadd2431.a59568"]]},{"id":"f7a9d42d.993a98","type":"inject","z":"116cddab.f8a6f2","name":"remove attributes & style - color, fill, rotate","topic":"","payload":"[{\"command\":\"set_attribute\",\"selector\":\".camera\",\"attributeName\":\"fill\",\"attributeValue\":\"\"},{\"command\":\"set_attribute\",\"selector\":\".camera\",\"attributeName\":\"color\",\"attributeValue\":\"\"},{\"command\":\"set_style\",\"selector\":\".camera\",\"attributeName\":\"fill\",\"attributeValue\":\"\"},{\"command\":\"set_style\",\"selector\":\".camera\",\"attributeName\":\"rotate\",\"attributeValue\":\"\"},{\"command\":\"set_style\",\"selector\":\".camera\",\"attributeName\":\"color\",\"attributeValue\":\"\"}]","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":200,"y":400,"wires":[["cadd2431.a59568"]]},{"id":"f6d4c7c5.3281f8","type":"inject","z":"116cddab.f8a6f2","name":"set_style color orange","topic":"","payload":"{\"command\":\"set_style\",\"selector\":\".camera\",\"attributeName\":\"color\",\"attributeValue\":\"orange\"}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":100,"wires":[["cadd2431.a59568"]]},{"id":"cadd2431.a59568","type":"ui_svg_graphics","z":"116cddab.f8a6f2","group":"ebcbf9c5.11fbf8","order":1,"width":0,"height":0,"svgString":"<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:svg=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0\" y=\"0\" height=\"100\" viewBox=\"0 0 200 100\" width=\"200\" preserveAspectRatio=\"xMidYMid meet\">\n  <rect id=\"svgEditorBackground\" x=\"0\" y=\"0\" width=\"100\" height=\"100\" style=\"fill:none; stroke: none;\" />\n  <defs id=\"svgEditorDefs\">\n    <symbol xmlns=\"http://www.w3.org/2000/svg\" id=\"f03d\" preserveAspectRatio=\"xMidYMid meet\" viewBox=\"0 0 576 512\">\n      <path d=\"M336.2 64H47.8C21.4 64 0 85.4 0 111.8v288.4C0 426.6 21.4 448 47.8 448h288.4c26.4 0 47.8-21.4 47.8-47.8V111.8c0-26.4-21.4-47.8-47.8-47.8zm189.4 37.7L416 177.3v157.4l109.6 75.5c21.2 14.6 50.4-.3 50.4-25.8V127.5c0-25.4-29.1-40.4-50.4-25.8z\" />\n    </symbol>\n    <polygon id=\"svgEditorIconDefs\" style=\"fill:rosybrown;\" />\n  </defs>\n  <use class=\"camera\" style=\"colour:silver;\" xlink:href=\"#f03d\" x=\"12.595355033874512\" y=\"5.487990379333496\" width=\"21.7916\" height=\"22.1596\" id=\"mijn_icoon\" transform=\"matrix(1.20715 0 0 1.20715 -5.5721 -2.67466)\" />\n  <use class=\"camera\" style=\"fill:silver;\" xlink:href=\"#f03d\" x=\"12.776228904724121\" y=\"26.766639709472656\" width=\"21.7916\" height=\"22.1596\" id=\"mijn_icoon\" transform=\"matrix(1.20715 0 0 1.20715 -5.5721 -2.67466)\" />\n  <use class=\"camera\" fill=\"silver\" xlink:href=\"#f03d\" x=\"12.916482925415039\" y=\"45.98122787475586\" width=\"21.7916\" height=\"22.1596\" id=\"cam2\" transform=\"matrix(1.20715 0 0 1.20715 -5.5721 -2.67466)\" />\n  <text style=\"fill:var(--nr-dashboard-widgetTextColor);font-family:Arial;font-size:20px;\" x=\"45.168331146240234\" y=\"44.669822692871094\" id=\"e1_texte\" transform=\"matrix(1.20715 0 0 1.20715 -5.5721 -2.67466)\">style fill</text>\n  <text style=\"fill:var(--nr-dashboard-widgetTextColor);font-family:Arial;font-size:20px;\" x=\"44.11644744873047\" y=\"62.55198287963867\" id=\"e2_texte\" transform=\"matrix(1.20715 0 0 1.20715 -5.5721 -2.67466)\">attribute fill</text>\n  <text style=\"fill:var(--nr-dashboard-widgetTextColor);font-family:Arial;font-size:20px;\" x=\"45.543025970458984\" y=\"23.158767700195312\" id=\"e3_texte\" transform=\"matrix(1.20715 0 0 1.20715 -5.5721 -2.67466)\">style color</text>\n</svg>","clickableShapes":[{"targetId":"#mijn_icoon","action":"click","payload":"my payload","payloadType":"str","topic":"my topic"}],"smilAnimations":[],"bindings":[],"showCoordinates":false,"autoFormatAfterEdit":false,"outputField":"mycustomfield","editorUrl":"http://drawsvg.org/drawsvg.html","directory":"","name":"","x":400,"y":160,"wires":[["ce0b967b.2280e8"]]},{"id":"ebcbf9c5.11fbf8","type":"ui_group","z":"","name":"Hikvision","tab":"39ae8d86.d9fa72","disp":true,"width":"6","collapse":false},{"id":"39ae8d86.d9fa72","type":"ui_tab","z":"","name":"Camera","icon":"dashboard","disabled":false,"hidden":false}]
edit...
V1.2.1 pushed to github because someone forgot to update doumentation
4 Likes

This is the end of our beta testing phase. We have now published the SVG node on NPM, so please add your feedback on our new discussion.

1 Like