How to make an svg circle element on click, in a mustache template, output topic/payload?

I could spare a couple of hours today to advance a little in this interesting use case.

I added the capability to toggle status via editor, dashboard switches (in case clicking is really troubled), svg clicking and MQTT. Also added the capability to persist the status.

It is getting better. I haveto leave now for a meeting but I will spare some additional time tomorrow to fix issues and bugs (may happen as I coded in hurry today).

a-07

[{"id":"3a7650b3.10396","type":"tab","label":"Flow 3","disabled":false,"info":""},{"id":"450245a.f0d83bc","type":"comment","z":"3a7650b3.10396","name":"https://codepen.io/alsheuski/pen/BKpZpK","info":"","x":220,"y":300,"wires":[]},{"id":"9ce61744.5c2968","type":"comment","z":"3a7650b3.10396","name":"https://www.d3indepth.com/shapes/#arc-generator","info":"","x":250,"y":260,"wires":[]},{"id":"48432f9b.7784e","type":"template","z":"3a7650b3.10396","name":"","field":"template","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"<!DOCTYPE html>\n\n<html>\n\n<head>\n\n<style>\n\n    svg {\n      background-color: white;\n      margin-left: auto;\n      margin-right: auto;\n      display: block;\n    }\n\n    :root {\n        --colourNorth: {{ColourNorth}};\n        --colourEast:  {{ColourEast}};\n        --colourSouth: {{ColourSouth}};\n        --colourWest:  {{ColourWest}};\n    }\n    \n    .myicon {\n        font-family: \"FontAwesome\";\n        font-size: 30px;\n    }\n    \n    #lightNorth {\n        fill: var(--colourNorth, \"dimgray\");\n    }\n    \n    #lightEast {\n        fill: var(--colourEast, \"dimgray\");\n    }\n    \n    #lightSouth {\n        fill: var(--colourSouth, \"dimgray\");\n    }\n    \n    #lightWest {\n        fill: var(--colourWest, \"dimgray\");\n    }\n      \n</style>\n\n</head>\n\n<body>\n\n    <script>\n    let w = 200;\n    let h = 200;\n\n    var svg = d3.select(\"#T1_LAB\")\n        .append(\"svg\")\n        .attr(\"width\", w)\n        .attr(\"height\", h);\n    \nvar arc1 = d3.svg.arc()\n      .innerRadius(40)\n      .outerRadius(60)\n      .startAngle(45 * Math.PI/180) \n      .endAngle(-45 * Math.PI/180); \n  \n  var arc2 = d3.svg.arc()\n      .innerRadius(40)\n      .outerRadius(60)\n      .startAngle(45 * Math.PI/180) \n      .endAngle(135 * Math.PI/180);  \n  \n  var arc3 = d3.svg.arc()\n      .innerRadius(40)\n      .outerRadius(60)\n      .startAngle(135 * Math.PI/180) \n      .endAngle(225 * Math.PI/180);  \n  \n  var arc4 = d3.svg.arc()\n      .innerRadius(40)\n      .outerRadius(60)\n      .startAngle(-45 * Math.PI/180)  \n      .endAngle(-135 * Math.PI/180);    \n\nvar path1 = svg.append('path')\n      .attr('d', arc1)\n      .attr('stroke', 'black')\n      .attr('stroke-width', 3)\n      .attr('transform', 'translate('+ w/2 + ','+ h/2 +')')\n      .attr('id', 'lightNorth');\n  \n  var path2 = svg.append('path')\n      .attr('d', arc2)\n      .attr('stroke', 'black')\n      .attr('stroke-width', 3)\n      .attr('transform', 'translate('+ w/2 + ','+ h/2 +')')\n      .attr('id', 'lightEast');\n  \n  var path3 = svg.append('path')\n      .attr('d', arc3)\n      .attr('stroke', 'black')\n      .attr('stroke-width', 3)\n      .attr('transform', 'translate('+ w/2 + ','+ h/2 +')')\n      .attr('id', 'lightSouth');\n  \n  var path4 = svg.append('path')\n      .attr('d', arc4)\n      .attr('stroke', 'black')\n      .attr('stroke-width', 3)\n      .attr('transform', 'translate('+ w/2 + ','+ h/2 +')')\n      .attr('id', 'lightWest');\n  \n  var innerCircle = svg.append('circle')\n      .attr('cx', w/2)\n      .attr('cy', h/2)\n      .attr('r', 40)\n      .attr('fill', 'dimgray');\n  \n  var textCenter = svg.append('text')\n    .attr('y', 10 + h/2)\n    .attr('x', w/2)\n    .attr('text-anchor', 'middle')\n    .attr('class', 'myicon')\n    .attr('fill', 'yellow')\n    .text('\\uf0eb');\n  \n    </script>\n  \n    <script>\n        (function(scope){\n            d3.selectAll('path').on('click', handleClick);\n            function handleClick(x, y) {\n                //d3.select('.status').text('You clicked on element ' + y);\n                scope.send({\"svg\": y});\n            };\n        })(scope);\n  </script>\n  \n  </body>\n  </html>\n  ","output":"str","x":1200,"y":860,"wires":[["588b77c7.af5168"]]},{"id":"588b77c7.af5168","type":"ui_template","z":"3a7650b3.10396","group":"66ff152c.aabe1c","name":"","order":5,"width":"0","height":"0","format":"","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":1360,"y":860,"wires":[["90e6a058.8aa4a"]]},{"id":"15995eb0.d06221","type":"comment","z":"3a7650b3.10396","name":"https://fontawesome.com/cheatsheet?from=io","info":"","x":230,"y":220,"wires":[]},{"id":"f5b95d60.6036d","type":"ui_switch","z":"3a7650b3.10396","name":"","label":"South","tooltip":"","group":"66ff152c.aabe1c","order":2,"width":"2","height":"1","passthru":true,"decouple":"false","topic":"","style":"","onvalue":"South-ON","onvalueType":"str","onicon":"","oncolor":"","offvalue":"South-OFF","offvalueType":"str","officon":"","offcolor":"","x":550,"y":840,"wires":[["fd3a9a85.6601a8"]]},{"id":"230650d8.c04d3","type":"ui_switch","z":"3a7650b3.10396","name":"","label":"East","tooltip":"","group":"66ff152c.aabe1c","order":3,"width":"2","height":"1","passthru":true,"decouple":"false","topic":"","style":"","onvalue":"East-ON","onvalueType":"str","onicon":"","oncolor":"","offvalue":"East-OFF","offvalueType":"str","officon":"","offcolor":"","x":570,"y":960,"wires":[["562e6a61.7c00b4"]]},{"id":"ae659c8e.4f30b","type":"ui_switch","z":"3a7650b3.10396","name":"","label":"West","tooltip":"","group":"66ff152c.aabe1c","order":4,"width":"2","height":"1","passthru":true,"decouple":"false","topic":"","style":"","onvalue":"West-ON","onvalueType":"str","onicon":"","oncolor":"","offvalue":"West-OFF","offvalueType":"str","officon":"","offcolor":"","x":570,"y":1100,"wires":[["ba27bcb8.1fdcd"]]},{"id":"25726618.c37dfa","type":"ui_switch","z":"3a7650b3.10396","name":"","label":"North","tooltip":"","group":"66ff152c.aabe1c","order":1,"width":"2","height":"1","passthru":true,"decouple":"false","topic":"","style":"","onvalue":"North-ON","onvalueType":"str","onicon":"","oncolor":"","offvalue":"North-OFF","offvalueType":"str","officon":"","offcolor":"","x":550,"y":720,"wires":[["e5975c56.88e99"]]},{"id":"e5975c56.88e99","type":"change","z":"3a7650b3.10396","name":"Set Global North","rules":[{"t":"set","p":"stateLightColourNorth","pt":"global","to":"payload = \"North-ON\" ? \"lime\" : \"dimgray\"","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":740,"y":720,"wires":[["e4cc9f07.d5ac4"]]},{"id":"fd3a9a85.6601a8","type":"change","z":"3a7650b3.10396","name":"Set Global South","rules":[{"t":"set","p":"stateLightColourSouth","pt":"global","to":"payload = \"South-ON\" ? \"lime\" : \"dimgray\"","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":750,"y":840,"wires":[["e4cc9f07.d5ac4"]]},{"id":"562e6a61.7c00b4","type":"change","z":"3a7650b3.10396","name":"Set Global East","rules":[{"t":"set","p":"stateLightColourEast","pt":"global","to":"payload = \"East-ON\" ? \"lime\" : \"dimgray\"","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":760,"y":960,"wires":[["e4cc9f07.d5ac4"]]},{"id":"ba27bcb8.1fdcd","type":"change","z":"3a7650b3.10396","name":"Set Global West","rules":[{"t":"set","p":"stateLightColourWest","pt":"global","to":"payload = \"West-ON\" ? \"lime\" : \"dimgray\"","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":760,"y":1100,"wires":[["e4cc9f07.d5ac4"]]},{"id":"e4cc9f07.d5ac4","type":"change","z":"3a7650b3.10396","name":"Read ALL Global","rules":[{"t":"set","p":"ColourNorth","pt":"msg","to":"stateLightColourNorth","tot":"global"},{"t":"set","p":"ColourSouth","pt":"msg","to":"stateLightColourSouth","tot":"global"},{"t":"set","p":"ColourEast","pt":"msg","to":"stateLightColourEast","tot":"global"},{"t":"set","p":"ColourWest","pt":"msg","to":"stateLightColourWest","tot":"global"}],"action":"","property":"","from":"","to":"","reg":false,"x":1010,"y":860,"wires":[["48432f9b.7784e"]]},{"id":"9ea196a2.cd73d8","type":"change","z":"3a7650b3.10396","name":"Read Global North","rules":[{"t":"set","p":"payload","pt":"msg","to":"$globalContext(\"stateLightColourNorth\") = \"lime\" ? \"North-ON\" : \"North-OFF\"","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":370,"y":720,"wires":[["25726618.c37dfa"]]},{"id":"f9fe4fbc.e7232","type":"change","z":"3a7650b3.10396","name":"Read Global South","rules":[{"t":"set","p":"payload","pt":"msg","to":"$globalContext(\"stateLightColourSouth\") = \"lime\" ? \"South-ON\" : \"South-OFF\"","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":370,"y":840,"wires":[["f5b95d60.6036d"]]},{"id":"3b56dab8.d70986","type":"change","z":"3a7650b3.10396","name":"Read Global East","rules":[{"t":"set","p":"payload","pt":"msg","to":"$globalContext(\"stateLightColourEast\") = \"lime\" ? \"East-ON\" : \"East-OFF\"","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":390,"y":960,"wires":[["230650d8.c04d3"]]},{"id":"cb099813.77cef8","type":"change","z":"3a7650b3.10396","name":"Read Global West","rules":[{"t":"set","p":"payload","pt":"msg","to":"$globalContext(\"stateLightColourWest\") = \"lime\" ? \"West-ON\" : \"West-OFF\"","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":390,"y":1100,"wires":[["ae659c8e.4f30b"]]},{"id":"6fdd86f5.b3c698","type":"inject","z":"3a7650b3.10396","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":130,"y":900,"wires":[["9ea196a2.cd73d8","f9fe4fbc.e7232","3b56dab8.d70986","cb099813.77cef8"]]},{"id":"3b464a52.6b97e6","type":"mqtt in","z":"3a7650b3.10396","name":"","topic":"light/south","qos":"2","datatype":"auto","broker":"48db4072.21411","x":400,"y":780,"wires":[["f5b95d60.6036d"]]},{"id":"66f0fa22.a52b04","type":"mqtt in","z":"3a7650b3.10396","name":"","topic":"light/north","qos":"2","datatype":"auto","broker":"48db4072.21411","x":400,"y":660,"wires":[["25726618.c37dfa"]]},{"id":"3916bdab.054932","type":"mqtt in","z":"3a7650b3.10396","name":"","topic":"light/east","qos":"2","datatype":"auto","broker":"48db4072.21411","x":420,"y":900,"wires":[["230650d8.c04d3"]]},{"id":"628f354e.81ebbc","type":"mqtt in","z":"3a7650b3.10396","name":"","topic":"light/west","qos":"2","datatype":"auto","broker":"48db4072.21411","x":420,"y":1040,"wires":[["ae659c8e.4f30b"]]},{"id":"4132998a.f30538","type":"mqtt out","z":"3a7650b3.10396","name":"","topic":"light/north","qos":"","retain":"","broker":"48db4072.21411","x":1920,"y":540,"wires":[]},{"id":"fe996956.9f75a8","type":"inject","z":"3a7650b3.10396","name":"North - ON","topic":"","payload":"North-ON","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":1740,"y":540,"wires":[["4132998a.f30538"]]},{"id":"58db93cf.879e5c","type":"inject","z":"3a7650b3.10396","name":"North - OFF","topic":"","payload":"North-OFF","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":1710,"y":500,"wires":[["4132998a.f30538"]]},{"id":"14a78b66.b59e05","type":"inject","z":"3a7650b3.10396","name":"East - ON","topic":"","payload":"East-ON","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":1760,"y":860,"wires":[["8df202da.6b228"]]},{"id":"a8caf5c9.c4cbb8","type":"inject","z":"3a7650b3.10396","name":"East - OFF","topic":"","payload":"East-OFF","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":1760,"y":900,"wires":[["8df202da.6b228"]]},{"id":"718c3b9c.50aa14","type":"inject","z":"3a7650b3.10396","name":"South - ON","topic":"","payload":"South-ON","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":1760,"y":660,"wires":[["85e47bb3.225b78"]]},{"id":"9cd44e8b.89047","type":"inject","z":"3a7650b3.10396","name":"South - OFF","topic":"","payload":"South-OFF","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":1750,"y":700,"wires":[["85e47bb3.225b78"]]},{"id":"14da5bf3.efd674","type":"inject","z":"3a7650b3.10396","name":"West - ON","topic":"","payload":"West-ON","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":1780,"y":1020,"wires":[["e9dcca4a.c7cd48"]]},{"id":"cafe3086.15c5c","type":"inject","z":"3a7650b3.10396","name":"West - OFF","topic":"","payload":"West-OFF","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":1770,"y":1060,"wires":[["e9dcca4a.c7cd48"]]},{"id":"8df202da.6b228","type":"mqtt out","z":"3a7650b3.10396","name":"","topic":"light/east","qos":"","retain":"","broker":"48db4072.21411","x":1960,"y":940,"wires":[]},{"id":"85e47bb3.225b78","type":"mqtt out","z":"3a7650b3.10396","name":"","topic":"light/south","qos":"","retain":"","broker":"48db4072.21411","x":1950,"y":740,"wires":[]},{"id":"e9dcca4a.c7cd48","type":"mqtt out","z":"3a7650b3.10396","name":"","topic":"light/west","qos":"","retain":"","broker":"48db4072.21411","x":1960,"y":1100,"wires":[]},{"id":"90e6a058.8aa4a","type":"switch","z":"3a7650b3.10396","name":"","property":"svg","propertyType":"msg","rules":[{"t":"eq","v":"7","vt":"num"},{"t":"eq","v":"9","vt":"num"},{"t":"eq","v":"8","vt":"num"},{"t":"eq","v":"10","vt":"num"}],"checkall":"true","repair":false,"outputs":4,"x":1510,"y":860,"wires":[["79ac90.cf69137"],["85714e75.af532"],["ae07aaa1.8636b8"],["b5d6c009.c6dab"]]},{"id":"79ac90.cf69137","type":"change","z":"3a7650b3.10396","name":"Toggle North","rules":[{"t":"set","p":"payload","pt":"msg","to":"$globalContext(\"stateLightColourNorth\") = \"lime\" ? \"North-OFF\" : \"North-ON\"","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":1710,"y":580,"wires":[["4132998a.f30538"]]},{"id":"85714e75.af532","type":"change","z":"3a7650b3.10396","name":"Toggle South","rules":[{"t":"set","p":"payload","pt":"msg","to":"$globalContext(\"stateLightColourSouth\") = \"lime\" ? \"South-OFF\" : \"South-ON\"","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":1750,"y":740,"wires":[["85e47bb3.225b78"]]},{"id":"ae07aaa1.8636b8","type":"change","z":"3a7650b3.10396","name":"Toggle East","rules":[{"t":"set","p":"payload","pt":"msg","to":"$globalContext(\"stateLightColourEast\") = \"lime\" ? \"East-OFF\" : \"East-ON\"","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":1750,"y":940,"wires":[["8df202da.6b228"]]},{"id":"b5d6c009.c6dab","type":"change","z":"3a7650b3.10396","name":"Toggle East","rules":[{"t":"set","p":"payload","pt":"msg","to":"$globalContext(\"stateLightColourWest\") = \"lime\" ? \"West-OFF\" : \"West-ON\"","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":1770,"y":1100,"wires":[["e9dcca4a.c7cd48"]]},{"id":"66ff152c.aabe1c","type":"ui_group","z":"","name":"LAB","tab":"ce29ad0.9250a5","order":3,"disp":false,"width":"8","collapse":false},{"id":"48db4072.21411","type":"mqtt-broker","z":"","name":"HIVE","broker":"broker.hivemq.com","port":"1883","clientid":"","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"ce29ad0.9250a5","type":"ui_tab","z":"","name":"T1","icon":"dashboard","disabled":false,"hidden":false}]
1 Like

I just identified a condition that leads to the behavior you mentioned. I need now to take some time to investigate and understand. For a couple of weeks I wont be able to test this on a Raspberry, only on Windows. Once a have some clue why this is happening I will, most likely, open a new thread to request support for additional testing (in other environments) to validate the findings.

In case you should want an object that actually works :slight_smile:

I produced one in PowerPoint.

            <svg width="100%" height="50em" overflow="hidden" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
                <defs>
                    <clipPath id="clip0">
                        <path d="M0 0 1280 0 1280 720 0 720Z" fill-rule="evenodd" clip-rule="evenodd"/>
                    </clipPath>
                </defs>
                <g clip-path="url(#clip0)">
                    <rect x="0" y="0" width="1280" height="720" fill="#FFFFFF"/>
                    <path fill="#D0CECE" d="M117.035 117.187C244.039-9.81666 449.953-9.81666 576.956 117.187 703.96 244.191 703.96 450.105 576.956 577.108 449.953 704.112 244.039 704.112 117.035 577.108-9.96869 450.105-9.96866 244.191 117.035 117.187Z" stroke="#767171" stroke-width="13.3333" stroke-linejoin="round" stroke-miterlimit="10" fill-rule="evenodd"/>
                    <path id="B1" @click="doClickSegment" fill="#4472C4" d="M573.023 573.213C448.158 698.078 245.712 698.078 120.847 573.213 120.306 572.672 119.768 572.13 119.231 571.586L346.935 347.125Z" fill-rule="evenodd"/>
                    <path id="B2" @click="doClickSegment" fill="#FFC000" d="M120.845 574.484C-4.02173 449.618-4.02173 247.17 120.844 122.304 121.385 121.763 121.927 121.224 122.472 120.688L346.935 348.394Z" fill-rule="evenodd"/>
                    <path id="B3" @click="doClickSegment" fill="#ED7D31" d="M120.885 120.999C245.75-3.86591 448.196-3.86591 573.061 120.999 573.601 121.539 574.14 122.082 574.677 122.626L346.973 347.087Z" fill-rule="evenodd"/>
                    <path id="B4" @click="doClickSegment" fill="#70AD47" d="M573.061 121.037C697.926 245.902 697.926 448.348 573.061 573.213 572.521 573.753 571.978 574.292 571.434 574.829L346.973 347.125Z" fill-rule="evenodd"/>
                    <path d="M574.85 115.081 117.035 577.108" stroke="#767171" stroke-width="13.3333" stroke-miterlimit="8" fill="none" fill-rule="evenodd"/>
                    <path d="M0 0 654.153 2.31685" stroke="#767171" stroke-width="13.3333" stroke-miterlimit="8" fill="none" fill-rule="evenodd" transform="matrix(-0.707107 -0.707107 -0.707107 0.707107 576.956 577.108)"/>
                    <path d="M230.185 233.613C292.793 171.005 394.158 170.864 456.591 233.297 519.024 295.73 518.883 397.096 456.275 459.704 393.668 522.311 292.302 522.453 229.869 460.02 167.436 397.586 167.577 296.221 230.185 233.613Z" stroke="#767171" stroke-width="13.3333" stroke-linejoin="round" stroke-miterlimit="10" fill="#D0CECE" fill-rule="evenodd"/>
                    <text font-family="Venus Rising,Venus Rising_MSFontService,sans-serif" font-weight="700" font-size="59" transform="translate(313.968 136)">N
                        <tspan x="-1.62927" y="463">S</tspan>
                        <tspan x="245.677" y="228">E</tspan>
                        <tspan x="-258.065" y="228">W</tspan>
                    </text>
                </g>
            </svg>
        </div>


I expect it could be further simplified, also something needs to be done about the text as it gets in the way of the clicks. However, the click areas are now correct.

Obviously the SVG contains some VueJS code @click="doClickSegment" which you would need to translate into Angular if you want to use this with Dashboard.

The function doClickSegment goes into the methods and looks like:

        doClickSegment: function(event) {
            console.log('***EVENT***', event.target.id, event)

            uibuilder.send({
                'topic':'east',
                'payload':'toggle',
                'event':event,
            })
        },

Doesn't do much but hopefully gives you some ideas.

1 Like