Skip to content

Create gauges using the canvas gauges library

Julian Knight edited this page Feb 13, 2023 · 2 revisions

The canvas-gauges library allows you to create a nice-looking gauge (dial or linear) using vanilla HTML and JavaScript. Here is an example.

UPDATE: Please also see this Node-RED Forum thread for extended versions of this along with a low-code method and a more complete coded method that automatically creates the gauges for you. 🧙‍♂️

Add a uibuilder node by importing from the Node-RED examples - the "blank" example is fine. Change the inject node, add a topic and change the payload to be a JSONata expression field containing $formatInteger($random() * 100, "0") so that you get a new random number each time you press the input button. Set it to auto-repeat if you prefer.

Once the uibuilder node has been given a url and deployed, you can now edit your front-end code like so:

index.html

<!doctype html>
<html lang="en"><head>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>Canvas Gauges Example - Node-RED uibuilder</title>
    <meta name="description" content="Node-RED uibuilder - Canvas Gauges Example">
    <link rel="icon" href="./images/node-blue.ico">

    <!-- Your own CSS (defaults to loading uibuilders css)-->
    <link type="text/css" rel="stylesheet" href="./index.css" media="all">

    <!-- #region Supporting Scripts. These MUST be in the right order. Note no leading / - socket.io no longer needed  -->
    <script defer src="../uibuilder/uibuilder.iife.min.js"></script>
    <script defer src="https://cdn.jsdelivr.net/npm/[email protected]/gauge.min.js"></script>
    <script defer src="./index.js">/* OPTIONAL: Put your custom code in that */</script>
    <!-- #endregion -->

</head><body class="uib">
    
    <h1>uibuilder Canvas Gauges Example</h1>

    <div id="more"><!-- '#more' is used as a parent for dynamic HTML content in examples --></div>

    <canvas id="gauge-radial-1"></canvas>

    <pre id="msg" class="syntax-highlight">Waiting for a message from Node-RED</pre>

</body></html>

index.js

// @ts-nocheck

'use strict'

// https://github.com/Mikhus/canvas-gauges
var gauge = new RadialGauge({
    renderTo: 'gauge-radial-1',
    highlights: [
        { "from": 0, "to": 60, "color": "rgba(0,255,0)" },
        { "from": 60, "to": 80, "color": "rgba(255,255,0)" },
        { "from": 80, "to": 100, "color": "rgba(255,0,0)" }
    ],
    width: 300,
    height: 300,
    units: "°C",
    minValue: 0,
    maxValue: 100,
    majorTicks: [0,10,20,30,40,50,60,70,80,90,100],
    minorTicks: 10,
    strokeTicks: true,
    colorPlate: "#fff",
    borderShadowWidth: 0,
    borders: false,
    needleType: "arrow",
    needleWidth: 2,
    needleCircleSize: 7,
    needlCircleOuter: true,
    needleCircleInner: false,
    animationDuration: 1500,
    animationRule: "linear",
    valueBox: true,
    valueInt: 2,
    valueDec: 2,
}).draw()
// var gauge = new LinearGauge({
//     renderTo: 'gauge-radial-1'
// }).draw()

// Listen for incoming messages from Node-RED
uibuilder.onChange('msg', function(msg) {
    // Dump the msg as text to the "msg" html element
    const eMsg = $('#msg')
    if (eMsg) eMsg.innerHTML = uibuilder.syntaxHighlight(msg)

    gauge.value = msg.payload
    gauge.update({
        title: msg.topic
    })
})

Note that while the gauge value can be dynamically updated, most of the gauge does not dynamically update (for efficiency - this is part of the gauge design, not uibuilder). To update other parts of the gauge dynamically, you need to use the gauge.update function. See the canvas-gauges documentation for details.

Customisation

See the canvas-gauge documentation for details on how to customise the display.

Note that this WIKI entry was written using uibuilder v6.

Clone this wiki locally