# Graph shapes and single point

**URL:** <https://discourse.nodered.org/t/graph-shapes-and-single-point/90041>\
**Category:** Dashboard\
**Tags:** dashboard-2\
**Created:** [7 August 2024 18:19 UTC](https://discourse.nodered.org/t/graph-shapes-and-single-point/90041 "2024-08-07T18:19:10Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![KSum](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/ksum/32/78579_2.png) [@KSum](https://discourse.nodered.org/u/KSum)\
**Post date:** [7 August 2024 18:19 UTC](https://discourse.nodered.org/t/graph-shapes-and-single-point/90041/1 "2024-08-07T18:19:10Z")

</div>

I have a sensor which will real-time provide X,Y Coordinates or multiple items. I want to visualize these on a Dashboard 2.0 and I also want to be able to show closed shape Zones on the same visualization. It appears I need to use a Template node. Can these use HTML Canvas tags? I tried but am not getting the drawn items. This works in the W3 School Try It editor. When I view this, however, I do not get the drawn shapes. The Circles would represent the Point, which will move as the sensor reports new coordinates. The Shape (there will be multiple) will remain constant.

**What I get on w# Schools Try It**  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/e/c/ec5c078b1dfd4ea1395660d1a50e203630cfd275.png)

**What I get in the Dashboard**  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/4/3/4306b63cc195115965902ea6a2503c1238d3b0d5.png)

```auto
    <h1>HTML5 Canvas - Draw a Shape</h1>

    <canvas id="myCanvas" width="200" height="125" style="border:1px solid #000000;">
        Sorry, your browser does not support canvas.
    </canvas>

    <script>
        // Create a canvas
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");

// Define a new path
ctx.beginPath();

// Set start-point
ctx.moveTo(20,20);

// Set sub-points
ctx.lineTo(100,20);
ctx.lineTo(175,100);
ctx.lineTo(20,100);

// Set end-point
ctx.lineTo(20,20);

// Draw it
ctx.stroke();

ctx.beginPath();
ctx.arc(95, 50, 4, 0, 2 * Math.PI);
ctx.stroke();

      var centerX = 75;
      var centerY = 105 / 2;
      var radius = 7;

      ctx.beginPath();
      ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
      ctx.fillStyle = 'green';
      ctx.fill();
      ctx.lineWidth = 5;
      ctx.strokeStyle = '#003300';
      ctx.stroke();

    </script>

```

---

<div class="post-metadata">

**Author:** ![KSum](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/ksum/32/78579_2.png) [@KSum](https://discourse.nodered.org/u/KSum)\
**Post date:** [8 August 2024 15:02 UTC](https://discourse.nodered.org/t/graph-shapes-and-single-point/90041/2 "2024-08-08T15:02:21Z")

</div>

Just a note: I tried this in a Dashboard 1 template node and it worked as expected. Both nodes are in this flow:

```auto
[{"id":"5256cc4fbc27859d","type":"ui-template","z":"7aaa3eef0c41b6c8","group":"c9385e59445930f8","page":"","ui":"","name":"","order":0,"width":0,"height":0,"head":"","format":" <h1>HTML5 Canvas - Draw a Shape</h1>\n\n <canvas id=\"myCanvas\" width=\"200\" height=\"125\" style=\"border:1px solid #000000;\">\n Sorry, your browser does not support canvas.\n </canvas>\n\n <script>\n // Create a canvas\nconst canvas = document.getElementById(\"myCanvas\");\nconst ctx = canvas.getContext(\"2d\");\n\n// Define a new path\nctx.beginPath();\n\n// Set start-point\nctx.moveTo(20,20);\n\n// Set sub-points\nctx.lineTo(100,20);\nctx.lineTo(175,100);\nctx.lineTo(20,100);\n\n// Set end-point\nctx.lineTo(20,20);\n\n// Draw it\nctx.stroke();\n\nctx.beginPath();\nctx.arc(95, 50, 4, 0, 2 * Math.PI);\nctx.stroke();\n\n\n var centerX = 75;\n var centerY = 105 / 2;\n var radius = 7;\n\n ctx.beginPath();\n ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);\n ctx.fillStyle = 'green';\n ctx.fill();\n ctx.lineWidth = 5;\n ctx.strokeStyle = '#003300';\n ctx.stroke();\n\n </script>\n","storeOutMessages":true,"passthru":true,"resendOnRefresh":true,"templateScope":"local","className":"","x":1680,"y":420,"wires":[[]]},{"id":"0234bbe826c64216","type":"inject","z":"7aaa3eef0c41b6c8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"<!DOCTYPE html> <html> <body> <h1>HTML5 Canvas - Draw a Shape</h1> <canvas id=\"myCanvas\" width=\"200\" height=\"125\" style=\"border:1px solid #000000;\"> Sorry, your browser does not support canvas. </canvas> <script> // Create a canvas const canvas = document.getElementById(\"myCanvas\"); const ctx = canvas.getContext(\"2d\"); // Define a new path ctx.beginPath(); // Set start-point ctx.moveTo(20,20); // Set sub-points ctx.lineTo(100,20); ctx.lineTo(175,100); ctx.lineTo(20,100); // Set end-point ctx.lineTo(20,20); // Draw it ctx.stroke(); ctx.beginPath(); ctx.arc(95, 50, 4, 0, 2 * Math.PI); ctx.stroke(); var centerX = 75; var centerY = 105 / 2; var radius = 7; ctx.beginPath(); ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false); ctx.fillStyle = 'green'; ctx.fill(); ctx.lineWidth = 5; ctx.strokeStyle = '#003300'; ctx.stroke(); </script> </body> </html>","payloadType":"str","x":1170,"y":420,"wires":[["5256cc4fbc27859d","07a0c69d7b003f4d"]]},{"id":"07a0c69d7b003f4d","type":"ui_template","z":"7aaa3eef0c41b6c8","group":"08ac9b242ae51e8c","name":"2","order":15,"width":"6","height":"6","format":" <h1>HTML5 Canvas - Draw a Shape</h1>\n\n <canvas id=\"myCanvas\" width=\"200\" height=\"125\" style=\"border:1px solid #000000;\">\n Sorry, your browser does not support canvas.\n </canvas>\n\n <script>\n // Create a canvas\nconst canvas = document.getElementById(\"myCanvas\");\nconst ctx = canvas.getContext(\"2d\");\n\n// Define a new path\nctx.beginPath();\n\n// Set start-point\nctx.moveTo(20,20);\n\n// Set sub-points\nctx.lineTo(100,20);\nctx.lineTo(175,100);\nctx.lineTo(20,100);\n\n// Set end-point\nctx.lineTo(20,20);\n\n// Draw it\nctx.stroke();\n\nctx.beginPath();\nctx.arc(95, 50, 4, 0, 2 * Math.PI);\nctx.stroke();\n\n\n var centerX = 75;\n var centerY = 105 / 2;\n var radius = 7;\n\n ctx.beginPath();\n ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);\n ctx.fillStyle = 'green';\n ctx.fill();\n ctx.lineWidth = 5;\n ctx.strokeStyle = '#003300';\n ctx.stroke();\n\n </script>\n","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","className":"","x":1670,"y":480,"wires":[[]]},{"id":"c9385e59445930f8","type":"ui-group","name":"Chart Examples","page":"0c9c3e89de66aaad","width":"6","height":"1","order":4,"showTitle":true,"className":"","visible":"true","disabled":"false"},{"id":"08ac9b242ae51e8c","type":"ui_group","name":"Default","tab":"2acb95821445c8af","order":1,"disp":true,"width":"6","collapse":false,"className":""},{"id":"0c9c3e89de66aaad","type":"ui-page","name":"Charts","ui":"4c2bb00f7172c414","path":"/charts","icon":"home","layout":"notebook","theme":"5075a7d8e4947586","order":27,"className":"","visible":"true","disabled":"false"},{"id":"2acb95821445c8af","type":"ui_tab","name":"Home","icon":"dashboard","disabled":false,"hidden":false},{"id":"4c2bb00f7172c414","type":"ui-base","name":"My 1st 2.0 Dashboard","path":"/dashboard","includeClientData":true,"acceptsClientConfig":["ui-notification","ui-control"],"showPathInSidebar":false,"navigationStyle":"default","titleBarStyle":"default"},{"id":"5075a7d8e4947586","type":"ui-theme","name":"Default Theme","colors":{"surface":"#ffffff","primary":"#0094CE","bgPage":"#eeeeee","groupBg":"#ffffff","groupOutline":"#cccccc"},"sizes":{"pagePadding":"12px","groupGap":"12px","groupBorderRadius":"4px","widgetGap":"12px"}}]

```

---

<div class="post-metadata">

**Author:** ![joepavitt](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/joepavitt/32/59722_2.png) [@joepavitt](https://discourse.nodered.org/u/joepavitt)\
**Post date:** [8 August 2024 16:17 UTC](https://discourse.nodered.org/t/graph-shapes-and-single-point/90041/3 "2024-08-08T16:17:59Z")

</div>

First thing of note is that _currently_ we require anything you want to render as HTML to be wrapped in a `<template>` block, e.g.

```html
<template>
    <h1>HTML5 Canvas - Draw a Shape</h1>

    <canvas id="myCanvas" width="200" height="125" style="border:1px solid #000000;">
        Sorry, your browser does not support canvas.
    </canvas>
</template>

```

Although, even when I've done this, it's still not running as I would expect - I _think_ this is to do without how our event lifecycle works, we render the HTML, but the JS is running _before_ the HTML is fully mounted/ready.

I'm still investigating this, and will update more soon.

---

<div class="post-metadata">

**Author:** ![joepavitt](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/joepavitt/32/59722_2.png) [@joepavitt](https://discourse.nodered.org/u/joepavitt)\
**Post date:** [8 August 2024 16:19 UTC](https://discourse.nodered.org/t/graph-shapes-and-single-point/90041/4 "2024-08-08T16:19:41Z")

</div>

As a quick sanity check I made it a bit more "Vue" by doing:

```auto
<template>
    <h1>HTML5 Canvas - Draw a Shape</h1>

    <canvas id="myCanvas" width="200" height="125" style="border:1px solid #000000;">
        Sorry, your browser does not support canvas.
    </canvas>
</template>

<script>
    export default {
        mounted () {
            // Create a canvas
            const canvas = document.getElementById("myCanvas");
            const ctx = canvas.getContext("2d");
            
            // Define a new path
            ctx.beginPath();
            
            // Set start-point
            ctx.moveTo(20,20);
            
            // Set sub-points
            ctx.lineTo(100,20);
            ctx.lineTo(175,100);
            ctx.lineTo(20,100);
            
            // Set end-point
            ctx.lineTo(20,20);
            
            // Draw it
            ctx.stroke();
            
            ctx.beginPath();
            ctx.arc(95, 50, 4, 0, 2 * Math.PI);
            ctx.stroke();
            
            var centerX = 75;
            var centerY = 105 / 2;
            var radius = 7;
            
            ctx.beginPath();
            ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
            ctx.fillStyle = 'green';
            ctx.fill();
            ctx.lineWidth = 5;
            ctx.strokeStyle = '#003300';
            ctx.stroke();
        }
    }
</script>

```

which causes the code in our `<script>` to run once the HTML has been loaded fully, but we shouldn't be forcing users/developers ot have to write in this fashion. Raw JS should still be supported, so I'll work out how we can make that so.

---

<div class="post-metadata">

**Author:** ![joepavitt](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/joepavitt/32/59722_2.png) [@joepavitt](https://discourse.nodered.org/u/joepavitt)\
**Post date:** [8 August 2024 17:30 UTC](https://discourse.nodered.org/t/graph-shapes-and-single-point/90041/5 "2024-08-08T17:30:36Z")

</div>

I've made a change in _when_ the generic JS runs, it'll now run as part of the `mounted` block, meaning that these references will work (I've explicitly tested with your initial code snippet too):

> <https://github.com/FlowFuse/node-red-dashboard/pull/1186>
>
> \## Description
> 
> \- We group any generic JS we find into a \`beforeCreate\` functi…on, which was then run in the \`beforeCreate\` lifecycle hook of VueJS. This was causing problems though if a user was trying to reference HTML elements in their component e.g. https://discourse.nodered.org/t/graph-shapes-and-single-point/90041/4 as the component hadn't yet been mounted.
> \- This PR moves the \`beforeCreate\` content (i.e. generic JS) into a new hok called \`js\`, and runs this code in \`mounted()\` instead so that the code \_can\_ reference HTML content

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [7 September 2024 17:31 UTC](https://discourse.nodered.org/t/graph-shapes-and-single-point/90041/6 "2024-09-07T17:31:04Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
