First september give-away (let's create one gauge)

Did a bit prototyping to see if it will work for dashboard or not. For me the answer is - barely, but as work is already done, Ill just give it away who ever may like it.
It's a gauge - zero libraries, pure HTML and CSS.
It can be modified as you like however - it takes at least intermediate knowledge or understanding of HTML and CSS.

hotnipi-gauge.json (24.6 KB)

EDIT: Customized scales for one gauge so you can more easily understand what it takes .

25 Likes

Though I'm not "qualified" to use it I must say that it looks great!

Wow... nice scaleup on the realism!! I almost get the sense of curved class over the front

I would be honored to play around with that code... with my not quite intermediate :innocent: but growing, knowledge.

I will add at least one to my gauge collection :stuck_out_tongue: while I eventually merge some of my gauges into actual practical uses.

2 Likes

Using it does not take much, to modify it by your needs may be challenge but do examine the stuff and ask questions - the best in the world community here has plenty of wise guys, ready to help.

2 Likes

Nice looking gauge, thanks.
It looks like a frosted glass plate. There must be a button somewhere for the back-light.

Do we get a free giveaway on the first of every month? :wink:

It would be really interesting to know how you go about designing all those backrounds and shadows, and how you know when it's finished.

@hotNipi So, I have been trying to figure out what you use for a point of reference in the positioning of ticks and g-sectors (for the colours)

So far I have stretched my understanding this far...

image

This gives me the three quadrants of colours... I figured out the start point (and apparently it traverses 90deg counterclockwise from there) but not what the skew refers to...

<div class="g-sector g-sector-low" style="transform: rotate(135deg) skew(0deg, 0deg);"></div>
<div class="g-sector g-sector-normal" style="transform: rotate(225deg) skew(0deg, 0deg);"></div>
<div class="g-sector g-sector-high" style="transform: rotate(315deg) skew(0deg, 0deg);"></div>

And this is what I managed to brute force out for the ticks...

    transform: rotate(calc(38deg * var(--ga-tick) - 81deg));

But the tick coordinates don't make logical sense to me... at least based on what I understand as standard compass/protractor alignment. But then, math and me don't always compute :confounded:

image


I also tried to reverse engineer the background image code for possible future colour tweaking, but again I am at a bit of a loss...

Based on this...

background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPSc1JyBoZWlnaHQ9JzUnPgogIDxyZWN0IHdpZHRoPSc1JyBoZWlnaHQ9JzUnIGZpbGw9J3doaXRlJy8+CiAgPHBhdGggZD0nTTAgNUw1IDBaTTYgNEw0IDZaTS0xIDFMMSAtMVonIHN0cm9rZT0nIzg4OCcgc3Ryb2tlLXdpZHRoPScxJy8+Cjwvc3ZnPg=="); 

I pulled out the "buffer?" code (PHN2ZyB4bWxu......vc3ZnPg==) and ran it through some BASE64 to Image conversions, but nothing worked out.

The best I got was a wee little tiny mark (enlarged here)

image
• Resolution: 5×5
• MIME type: image/svg+xml
• Extension: svg
• Size: 187 B

I am not (yet) asking for the image... but the process used :stuck_out_tongue:

EDIT Hmm, OK, I think I figured out that there is NO full .jpg/etc. background of the bezel, rather a composite of that little image fit into and overlaid by other style constraints.

Fascinating stuff... but my head hurts, so time to take a break :timer_clock:

1 Like

Yup... and no need to change the composite image to change the colour of the bezel.

Not quite brass...

image

1 Like

Also available in CSS not quite woodgrain https://codepen.io/vushe/pen/OWeNXL Untitled 3

4 Likes

Oh no :smiley:

This can be done. Create class with gradient background similar to original what the plate using , but with brighter colors. And then watch the input msg with some parameter and add that class to the plate element. Or create button inside widget to toggle that class.

That's a good question.
The art in HTML/CSS is many many steps behind from what digital artists do. Thus I do watch tutorials about Illustrator and Photoshop and similar. There is may things what can't be translated to HTML/CSS but mostly the things are achievable. And then it takes to know or learn some CSS tricks.

I'm not good at the art at all but I can do replicas. So I take some good looking things and try my best to achieve something similar.

I don't know when it's finished. That would take years of learning art, which I'll probably miss. Too late for that for me.

Can you share your other gauges?

I'll rip that part out and you'll lose whole fun :slight_smile: It can be done in the way that you'll have no need to understand how it works.

But still I'll try to explain the math behind it.
Full circle = 360 deg
We have gap between beginning and end 90 deg (no ticks area)
Area to cover with ticks = 360 - 90 = 270 deg

Element to rotate is rectangle (height is small, and wide as the gauge plate), gradient fill is used to give color only for small part at the left end of the element

With 0 deg the element is at the center of gauge horizontally.

Now we need to know how many degrees it takes for one gap.
gap = 270 / (tick-count - 1)

Ticks start with 45deg rotated backwards so that needs to be subtracted

The each tick carry the iterator variable. (--ga-tick)

So for each tick:
rotation = gap * iterator - (gap + 45deg)

So the universal rotation rule is:
transform: rotate(calc(calc(270deg / var(--ga-tick-count)) * var(--ga-tick) - calc(calc(270deg / var(--ga-tick-count)) + 45deg)));

You'll need just bring in another variable where you define how many gaps between ticks you have.
(tick count - 1)
<div id="{{'gauge_'+$id}}" class="g-container" style="-g-angle:0; --container-size:6; --ga-tick-count:10">

That's all. :slight_smile:

Nutin' to it at all... :crazy_face: Hah! Sure

Well, thanks to your tutoring, I figured it out.. ish...

I am contemplating how to get proper sub-ticks instead of almost doubling up on the normal ones, but I think I have reached my coding limit today.

I think the "improved?" brass look would go better over a wood grained ui_card... something else to pursue.

image

[{"id":"2894c6d23426d14e","type":"ui_slider","z":"3cd636ebd5398d6e","name":"","label":"slider","tooltip":"","group":"2c0d82c5cbab11fd","order":6,"width":0,"height":0,"passthru":true,"outs":"all","topic":"topic","topicType":"msg","min":"-30","max":"40","step":1,"x":710,"y":340,"wires":[["eb080df2e58aef8a"]]},{"id":"eb080df2e58aef8a","type":"ui_template","z":"3cd636ebd5398d6e","group":"2c0d82c5cbab11fd","name":"gauge","order":4,"width":"6","height":"6","format":"<div id=\"{{'gauge_'+$id}}\" class=\"g-container\" style=\"-g-angle:0; --container-size:6\">\n    <div id=\"bgr\" class=\"g-body\">\n        <div class=\"g-ring\">\n            <div class=\"g-rivets\">\n                <div class=g-rivet></div>\n                <div class=g-rivet></div>\n                <div class=g-rivet></div>\n                <div class=g-rivet></div>\n            </div>\n            <div class=\"g-plate\">\n                <div class=\"g-sector g-sector-sub\" style=\"transform: rotate(133deg) skew(-28deg, 0deg);\"></div>\n                <div class=\"g-sector g-sector-low\" style=\"transform: rotate(251deg) skew(23deg, 0deg);\"></div>\n                <div class=\"g-sector g-sector-normal\" style=\"transform: rotate(318deg) skew(59deg, 0deg);\"></div>\n                <div class=\"g-sector g-sector-high\" style=\"transform: rotate(348deg) skew(31deg, 0deg);\"></div>\n                <div class=\"g-ticks\">\n                    <div class=\"g-tick\" style=\"--ga-tick:1;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:2;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:3;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:4;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:5;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:6;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:7;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:8;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:9;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:10;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:11;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:12;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:13;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:14;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:15;\"></div>\n                </div>\n                <div class=\"g-nums\">\n                    <div class=\"g-num\" style=\"left: 20%;top: 70%;\">-30</div>\n                    <div class=\"g-num\" style=\"left: 13%;top: 49%;\">-20</div>\n                    <div class=\"g-num\" style=\"left: 20%;top: 28%;\">-10</div>\n                    <div class=\"g-num\" style=\"left: 38%;top: 14%;\">0</div>\n                    <div class=\"g-num\" style=\"left: 57%;top: 14%;\">10</div>\n                    <div class=\"g-num\" style=\"left: 75%;top: 28%;\">20</div>\n                    <div class=\"g-num\" style=\"left: 78%;top: 49%;\">30</div>\n                    <div class=\"g-num\" style=\"left: 70%;top: 70%;\">40</div>\n                </div>\n                <div class=\"g-label\">Temp °C</div>\n                <div class=\"g-needle\"></div>\n                <div class=\"g-needle-ring\"></div>\n                <div id=\"{{'gauge_val_'+$id}}\" class=\"g-val\"></div>\n            </div>\n        </div>\n    </div>\n</div>\n<script>\n(function(scope) {\n    let min = -30;\n    let max = 40;\n    scope.$watch('msg', function(msg) {\n        if (msg) {\n            const v = Math.floor(((msg.payload - min) / (max - min)) * 100);\n            document.getElementById('gauge_'+scope.$id).style.setProperty('--g-angle', v);\n            document.getElementById('gauge_val_'+scope.$id).innerText = msg.payload;\n        }   \n  });\n})(scope);\n</script>\n","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":710,"y":300,"wires":[[]]},{"id":"c351447745138c19","type":"ui_template","z":"3cd636ebd5398d6e","group":"3ca910b5.3d50a","name":"gauge-style","order":4,"width":0,"height":0,"format":"<style id=\"hotNipi-gauge\">\n:root{\n    --needle-color:#dbe4eb;\n    --sec-high-color:#ff00004f;\n    --sec-normal-color:#00ff004f;\n    --sec-low-color:#0000ff4f;\n    --sec-sub-color:#0000ff8f;\n}\n.g-container {\n    padding-top: 3px;\n    padding-bottom: 3px;\n    width: 100%;\n    height: 100%;\n    position: relative;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    user-select:none;\n}\n    \n.g-body{\n    width:98%;\n    height:98%;\n    border-radius:15%;\n    position:relative;\n    display: flex;\n    align-content: center;\n    align-items: center;\n    justify-content: center;\n    box-shadow: 0px 5px 8px #00000045;\n    background:linear-gradient(0deg, rgba(81,74,29,1) 0%, rgba(163,149,59,1) 99%, rgba(181,166,66,1) 100%);\n}\n\n.g-body::before {    \n    content: \"\";\n    background-image: url(\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNSIgaGVpZ2h0PSI1IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogPGc+CiAgPHRpdGxlPkxheWVyIDE8L3RpdGxlPgogIDxyZWN0IHdpZHRoPSI1IiBoZWlnaHQ9IjUiIGZpbGw9IiM2MjYxMkMiIGlkPSJzdmdfMSIgc3Ryb2tlPSIjOTc5NDRCIi8+CiAgPHBhdGggZD0ibTAsNWw1LC01bC01LDV6bTYsLTFsLTIsMmwyLC0yem0tNywtM2wyLC0ybC0yLDJ6IiBpZD0ic3ZnXzIiIGZpbGw9IndoaXRlIiBzdHJva2U9IiM4ODgiLz4KIDwvZz4KCjwvc3ZnPg==\"); \n    background-repeat: repeat;\n    position: absolute;\n    top: 0px;\n    right: 0px;\n    bottom: 0px;\n    left: 0px;\n    opacity: 0.1;\n    border-radius:15%;\n}\n\n.g-ring{\n    width:90%;\n    height:90%;\n    border-radius:50%;\n    position:relative;\n    display: flex;\n    align-content: center;\n    align-items: center;\n    justify-content: center;\n   \n    background:linear-gradient(180deg, rgba(81,74,29,1) 0%, rgba(163,149,59,1) 99%, rgba(181,166,66,1) 100%);\n}\n.g-plate {\n    overflow:hidden;\n    width: 90%;\n    height: 90%;\n    border-radius: 50%;\n    position: relative;\n    box-shadow: inset 0 0 15px black;\n    background: radial-gradient(circle, #dd8400 3%, rgb(196, 205, 209) 1%, rgb(177, 183, 186) 40%, rgb(108, 114, 120) 100%);\n}\n.g-sector{\n    width: 100%;\n    height: 100%;\n    position: absolute;\n    top: 50%;\n    left: 50%;\n   \n    transform-origin: 0 0;\n}\n.g-sector-high {\n    background: var(--sec-high-color);\n    transform: rotate(329deg) skew(12deg, 23deg);\n}\n.g-sector-normal {\n    background:var(--sec-normal-color);\n    transform: rotate(329deg) skew(12deg, 23deg);\n}\n.g-sector-low {\n    background:var(--sec-low-color);\n    transform: rotate(329deg) skew(12deg, 23deg);\n}\n.g-sector-sub {\n    background:var(--sec-sub-color);\n    transform: rotate(329deg) skew(12deg, 23deg);\n}\n.g-ticks {\n    position: absolute;\n    top:0;\n    left:0;\n    width: 100%;\n    height: 100%;\n    filter: drop-shadow(2px 4px 6px black);\n}\n.g-tick {\n    transform: rotate(calc(19.3deg * var(--ga-tick) - 64.3deg));\n    background: #000;\n    position: relative;\n    left: 0;\n    top: 50%;\n    width: 100%;\n    height: 1%;\n    margin-bottom: -1%;\n    background: linear-gradient(90deg,rgba(0,0,0,0) 0,rgba(0,0,0,0) 2%,rgb(0 0 0 / 60%) 2%,rgb(0 0 0 / 60%) 10%,rgba(0,0,0,0) 10%);\n}\n.g-num {\n    position: absolute;\n}\n.g-nums {\n    position: absolute;\n    top:0;\n    width: 100%;\n    height: 100%;\n    color: #000000a1;\n    font-size: calc(var(--container-size) * 16%);\n    font-weight: 500;\n    filter: drop-shadow(2px 4px 6px black);\n}\n.g-needle {\n    transform: rotate(calc(270deg * calc(var(--g-angle, 0deg) / 99) - 45deg));\n    transition: transform 1s;\n    background: #000;\n    position: absolute;\n    left: 0;\n    top: 49%;\n    width: 100%;\n    height: 2%;\n    filter:drop-shadow(0px 1px 3px #00000080);\n    background: linear-gradient(90deg,rgba(2,0,36,0) 0,rgba(0,0,0,0) 15%,var(--needle-color) 15%,var(--needle-color) 50%,rgba(0,0,0,0) 50%);\n}\n.g-needle-ring {\n    position: absolute;\n    width: calc(var(--container-size) * 1.5%);\n    height: calc(var(--container-size) * 1.5%);\n    top: 50%;\n    left: 50%;\n    background: var(--needle-color);\n    border-radius: 50%;\n    transform: translate(-50%, -50%);\n    box-shadow: 0 1px 4px #0000009c;\n}\n.g-val{\n    position: absolute;\n    text-align: center;\n    left: 50%;\n    bottom: 8%;\n    width: 80px;\n    transform: translateX(-50%);\n    font-family: monospace;\n    font-size:  calc(var(--container-size) * 50%);\n    color: #000000a1;\n    filter: drop-shadow(2px 3px 2px #00000080);\n}\n.g-label{\n    position: absolute;\n    text-align: center;\n    left: 50%;\n    top: 65%;\n    width: 100%;\n    transform: translateX(-50%);\n    font-family: monospace;\n    font-size:  calc(var(--container-size) * 20%);\n    color: #000000a1;\n    filter: drop-shadow(2px 3px 2px #00000080);\n}\n.g-rivets{\n    position: absolute;\n    left:0;\n    top:0;\n    width: 100%;\n    height: 100%;\n}\n\n.g-rivet {\n    position: absolute;\n    width: calc(var(--container-size) * 2px);\n    height: calc(var(--container-size) * 2px);\n    border-radius: 50px;\n    background: linear-gradient(135deg, #adadad 0%,#d3d3d3 51%,#d1d1d1 68%,#8c8c8c 100%);\n    box-shadow: 0px 2px 4px #000, -1px -1px 5px rgba(0,0,0,0.2);\n    border: 1px solid rgba(255,255,255,0.1);\n}\n.g-rivet:nth-child(1){\n    top:calc(var(--container-size) * 1.5px);\n    left:calc(var(--container-size) * 1.5px);\n}\n.g-rivet:nth-child(2){\n    top:calc(var(--container-size) * 1.5px);\n    right:calc(var(--container-size) * 1.5px);\n}\n.g-rivet:nth-child(3){\n    bottom:calc(var(--container-size) * 1.5px);\n    left:calc(var(--container-size) * 1.5px);\n}\n.g-rivet:nth-child(4){\n    bottom:calc(var(--container-size) * 1.5px);\n    right:calc(var(--container-size) * 1.5px);\n}\n\n.g-rivet::before {\n    content: '';\n    position: absolute;\n    left: 50%;\n    top: 50%;\n    width: calc(var(--container-size) * 10%);\n    height: calc(var(--container-size) * 10%);\n    box-shadow: inset 0px 1px 2px #222;\n    transform: translate(-50%, -50%);\n    border-radius: 50%;\n    border-bottom: 1px solid rgba(255,255,255,0.3);\n}\n</style>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"global","x":730,"y":120,"wires":[[]]},{"id":"2c0d82c5cbab11fd","type":"ui_group","name":"Group 3","tab":"20bb081.66afff8","order":3,"disp":false,"width":"6","collapse":false},{"id":"3ca910b5.3d50a","type":"ui_group","name":"Group 1","tab":"20bb081.66afff8","order":1,"disp":false,"width":"6","collapse":false},{"id":"20bb081.66afff8","type":"ui_tab","name":"Ohh","icon":"dashboard","order":1,"disabled":false,"hidden":false}]

They are actually from various Canvas gauge libraries, as discussed in the topic linked below.

My flow by itself may not accomplish anything (mostly just a bunch of blank spots) as it is pulling from 2 or 3 (can't remember) different library's installed in custom locations, but some may work as their library is incorporated in a template.

[{"id":"15f672db96ac9474","type":"ui_template","z":"8c7dfd6121113522","group":"171f22a4261dd1c6","name":"Linear Vertical","order":1,"width":5,"height":12,"format":"<div style=\"margin:auto\">\n    \n<script src=\"/Canvas-Gauges/gauge.min.js\"></script>\n\n<canvas data-type=\"linear-gauge\"\n        data-width=\"180\"\n        data-height=\"620\"\n        data-min-value=\"0\"\n        data-max-value=\"100\"\n        data-border-radius=\"20\"\n        data-borders=\"0\"\n        data-bar-stroke-width=\"5\"\n        data-minor-ticks=\"10\"\n        data-major-ticks=\"0,10,20,30,40,50,60,70,80,90,100\"\n        data-value={{msg.payload}}\n        data-units=\"°C\"\n        data-color-Bar-Progress=\"rgba(255,0,0,.25)\"\n        data-color-value-box-shadow=\"false\"\n></canvas>\n\n</div>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":680,"y":80,"wires":[[]]},{"id":"01183e3a5d78bff9","type":"random","z":"8c7dfd6121113522","name":"","low":1,"high":"100","inte":"true","property":"payload","x":340,"y":80,"wires":[["15f672db96ac9474"]]},{"id":"2fd33d1202e5eb98","type":"ui_template","z":"8c7dfd6121113522","group":"365a732e0ed6d35d","name":"Full Round","order":1,"width":8,"height":7,"format":"<div style=\"margin:auto\">\n    \n<script src=\"/Canvas-Gauges/gauge.min.js\"></script>\n\n<canvas data-type=\"radial-gauge\"\n        data-width=\"350\"\n        data-height=\"350\"\n        data-units=\"Km/h\"\n        data-title=\"false\"\n        data-value={{msg.payload}}\n        data-min-value=\"0\"\n        data-max-value=\"100\"\n        data-major-ticks=\"0,20,40,60,80,100\"\n        data-minor-ticks=\"6\"\n        data-stroke-ticks=\"false\"\n        data-highlights='[\n            { \"from\": 0, \"to\": 60, \"color\": \"rgba(0,255,0)\" },\n            { \"from\": 60, \"to\": 80, \"color\": \"rgba(255,255,0)\" },\n            { \"from\": 80, \"to\": 100, \"color\": \"rgba(255,0,0)\" }\n        ]'\n        data-color-plate=\"#808080\"\n        data-color-major-ticks=\"#000000\"\n        data-color-minor-ticks=\"#808080\"\n        data-color-title=\"#fff\"\n        data-color-units=\"#ccc\"\n        data-color-numbers=\"#eee\"\n        data-color-needle-start=\"rgba(240, 128, 128, 5)\"\n        data-color-needle-end=\"rgba(255, 160, 122, 1)\"\n        data-animation-rule=\"elastic\"\n        data-animation-duration=\"500\"\n        data-value-box=\"true\"\n        data-font-value=\"Led\"\n        data-animated-value=\"true\"\n></canvas>\n\n</div>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":670,"y":160,"wires":[[]]},{"id":"3309ec3494dbae53","type":"random","z":"8c7dfd6121113522","name":"","low":1,"high":"100","inte":"true","property":"payload","x":340,"y":160,"wires":[["2fd33d1202e5eb98"]]},{"id":"6614d5b174cacc9b","type":"ui_template","z":"8c7dfd6121113522","group":"ad3ddda6cb6b3c19","name":"Half Round","order":1,"width":8,"height":7,"format":"<div style=\"margin:auto\">\n    \n<script src=\"/Canvas-Gauges/gauge.min.js\"></script>\n\n<canvas \n        data-type=\"radial-gauge\"\n        data-width=\"350\"\n        data-height=\"350\"\n        data-start-angle=\"90\"\n        data-ticks-angle=\"180\"\n        data-units=\"°C\"\n        data-title=\"false\"\n        data-value={{msg.payload}}\n        data-min-value=\"0\"\n        data-max-value=\"40\"\n        data-major-ticks=\"0,5,10,15,20,25,30,35,40\"\n        data-minor-ticks=\"5\"\n        data-stroke-ticks=\"false\"\n        data-borders=\"false\"\n        data-highlights='[\n            { \"from\": 0, \"to\": 10, \"color\": \"rgba(0,0,128)\" },\n            { \"from\": 10, \"to\": 15, \"color\": \"rgba(0,0,255)\" },\n            { \"from\": 15, \"to\": 20, \"color\": \"rgba(0,128,0)\" },\n            { \"from\": 20, \"to\": 25, \"color\": \"rgba(0,255,0)\" },\n            { \"from\": 25, \"to\": 30, \"color\": \"rgba(255,255,0)\" },\n            { \"from\": 30, \"to\": 40, \"color\": \"rgba(255,0,0)\" }\n        ]'\n        data-color-plate=\"#333333\"\n        data-border-shadow-width=\"0\"\n        data-color-major-ticks=\"#000000\"\n        data-color-minor-ticks=\"#808080\"\n        data-color-units=\"#ccc\"\n        data-color-numbers=\"#eee\"\n        data-color-needle-start=\"rgba(240, 128, 128, 5)\"\n        data-color-needle-end=\"rgba(255, 160, 122, 1)\"\n        data-needle-circle-inner=\"false\"\n        data-needle-circle-outer=\"true\"\n        data-animation-rule=\"elastic\"\n        data-animation-duration=\"500\"\n        data-value-box=\"false\"\n></canvas>\n\n</div>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":670,"y":200,"wires":[[]]},{"id":"5d6c7e51cc1523bf","type":"random","z":"8c7dfd6121113522","name":"","low":"0","high":"40","inte":"true","property":"payload","x":340,"y":200,"wires":[["6614d5b174cacc9b"]]},{"id":"64f819caa152f1b9","type":"ui_template","z":"8c7dfd6121113522","group":"5eab586c78e8cf53","name":"Linear Horizontal","order":1,"width":17,"height":3,"format":"<div style=\"margin:auto\">\n    \n<script src=\"/Canvas-Gauges/gauge.min.js\"></script>\n\n<canvas data-type=\"linear-gauge\"\n    data-value={{msg.payload}}\n    data-width=\"790\"\n    data-height=\"100\"\n    data-min-value=\"0\"\n    data-max-value=\"100\"\n    data-major-ticks=\"0,10,20,30,40,50,60,70,80,90,100\"\n    data-minor-ticks=\"10\"\n    data-stroke-ticks=\"true\"\n    data-color-plate=\"#fff\"\n    data-border-shadow-width=\"0\"\n    data-borders=\"false\"\n    data-bar-begin-circle=\"false\"\n    data-tick-side=\"left\"\n    data-number-side=\"left\"\n    data-needle-side=\"left\"\n    data-needle-type=\"line\"\n    data-needle-width=\"3\"\n    data-color-needle=\"#00FF00\"\n    data-color-needle-end=\"#00FF00\"\n    data-color-Bar-Progress=\"rgba(0,255,0,.5)\"\n    data-animation-duration=\"1500\"\n    data-animation-rule=\"linear\"\n    data-animation-target=\"plate\"\n    data-bar-width=\"10\"\n    data-ticks-width=\"50\"\n    data-ticks-width-minor=\"15\"\n></canvas>\n\n</div>\n","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":690,"y":120,"wires":[[]]},{"id":"0c8a61b04dc5fd5a","type":"random","z":"8c7dfd6121113522","name":"","low":1,"high":"100","inte":"true","property":"payload","x":340,"y":120,"wires":[["64f819caa152f1b9"]]},{"id":"0b5e3e8518add64e","type":"comment","z":"8c7dfd6121113522","name":"Gauges Galore","info":"","x":140,"y":20,"wires":[]},{"id":"6ace5c135d52db44","type":"ui_template","z":"8c7dfd6121113522","group":"0225baf06413ee39","name":"Canvas-Gauges","order":1,"width":7,"height":6,"format":"<div style=\"margin:auto\">\n\n<script src=\"/Canvas-Gauges/gauge.min.js\"></script>\n\n<canvas data-type=\"radial-gauge\"\n    data-width=\"300\"\n    data-height=\"300\"\n    data-units=\"°C\"\n    data-min-value=\"0\"\n    data-max-value=\"100\"\n    data-major-ticks=\"0,10,20,30,40,50,60,70,80,90,100\"\n    data-minor-ticks=\"10\"\n    data-stroke-ticks=\"true\"\n    data-highlights='[\n        {\"from\": 50, \"to\": 70, \"color\": \"rgba(255, 136, 0, .75)\"},    \n        {\"from\": 70, \"to\": 100, \"color\": \"rgba(200, 50, 50, .75)\"}\n    ]'\n    data-color-plate=\"#fff\"\n    data-border-shadow-width=\"0\"\n    data-borders=\"false\"\n    data-needle-type=\"arrow\"\n    data-needle-width=\"2\"\n    data-needle-circle-size=\"7\"\n    data-needle-circle-outer=\"true\"\n    data-needle-circle-inner=\"false\"\n    data-animation-duration=\"1500\"\n    data-animation-rule=\"linear\"\n    data-title = {{msg.title}}\n    data-value-Box = \"true\"\n    data-value-Int=\"2\"\n    data-value-Dec=\"2\"    \n    data-value={{msg.payload}}\n></canvas>\n\n</div>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":680,"y":280,"wires":[[]]},{"id":"5c83c1e35c72d6e6","type":"inject","z":"8c7dfd6121113522","name":"","props":[{"p":"payload"}],"repeat":"3","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":110,"y":320,"wires":[["01183e3a5d78bff9","0c8a61b04dc5fd5a","3309ec3494dbae53","5d6c7e51cc1523bf","ab02a775fe61480c","637cc3cb57087783","4d92bd212b2e6b74","9851b92096c23aec","a7cecd63f040a432","c09d075d66e41467"]]},{"id":"637cc3cb57087783","type":"random","z":"8c7dfd6121113522","name":"","low":1,"high":"100","inte":"false","property":"payload","x":340,"y":280,"wires":[["0cd9dfe26e83183c"]]},{"id":"b63cd624dbae0df5","type":"ui_template","z":"8c7dfd6121113522","group":"0225baf06413ee39","name":"Canvas-Gauges","order":2,"width":6,"height":6,"format":"<div style=\"margin:auto\">\n\n<script src=\"/Canvas-Gauges/gauge.min.js\"></script>\n\n<canvas data-type=\"radial-gauge\"\n    data-width=\"250\"\n    data-height=\"250\"\n    data-units=\"°C\"\n    data-min-value=\"0\"\n    data-max-value=\"100\"\n    data-major-ticks=\"0,10,20,30,40,50,60,70,80,90,100\"\n    data-minor-ticks=\"10\"\n    data-stroke-ticks=\"true\"\n    data-highlights='[\n        {\"from\": 50, \"to\": 70, \"color\": \"rgba(255, 136, 0, .75)\"},    \n        {\"from\": 70, \"to\": 100, \"color\": \"rgba(200, 50, 50, .75)\"}\n    ]'\n    data-color-plate=\"#fff\"\n    data-border-shadow-width=\"0\"\n    data-borders=\"false\"\n    data-needle-type=\"arrow\"\n    data-needle-width=\"2\"\n    data-needle-circle-size=\"7\"\n    data-needle-circle-outer=\"true\"\n    data-needle-circle-inner=\"false\"\n    data-animation-duration=\"1500\"\n    data-animation-rule=\"linear\"\n    data-title = {{msg.title}}\n    data-value-Box = \"true\"\n    data-value-Int=\"2\"\n    data-value-Dec=\"2\"    \n    data-value={{msg.payload}}\n></canvas>\n\n</div>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":680,"y":320,"wires":[[]]},{"id":"0cd9dfe26e83183c","type":"function","z":"8c7dfd6121113522","name":"","func":"let counter = context.get(\"counter\");\ncounter = counter + 1;\ncontext.set(\"counter\", counter);\nnode.status({text:counter});\n//----------\n\ndelete msg.topic;\nmsg.title = \"Time of Last Reading: \" + timeString_hms();\nreturn msg;\n\n//-----------\n\nfunction timeString_hms(){\n    let t = Date.now();\n    let date = new Date(t);    \n    let hours = (\"0\" + date.getHours()).slice(-2);\n    let minutes = (\"0\" + date.getMinutes()).slice(-2);\n    let seconds = (\"0\" + date.getSeconds()).slice(-2);    \n    let timestring = hours + ':' + minutes + ':' + seconds;\n    return timestring;\n}","outputs":1,"noerr":0,"initialize":"// Code added here will be run once\n// whenever the node is started.\nif (context.get(\"counter\") === undefined) {\n    context.set(\"counter\", 0);\n}","finalize":"","libs":[],"x":500,"y":280,"wires":[["6ace5c135d52db44"]]},{"id":"0842a23a0e327e9f","type":"function","z":"8c7dfd6121113522","name":"","func":"let counter = context.get(\"counter\");\ncounter = counter + 1;\ncontext.set(\"counter\", counter);\nnode.status({text:counter});\n\n//----------\n\ndelete msg.topic;\nmsg.title = \"Time of Last Reading: \" + timeString_hms();\nreturn msg;\n\n//-----------\n\nfunction timeString_hms(){\n    let t = Date.now();\n    let date = new Date(t);    \n    let hours = (\"0\" + date.getHours()).slice(-2);\n    let minutes = (\"0\" + date.getMinutes()).slice(-2);\n    let seconds = (\"0\" + date.getSeconds()).slice(-2);    \n    let timestring = hours + ':' + minutes + ':' + seconds;\n    return timestring;\n}\n","outputs":1,"noerr":0,"initialize":"// Code added here will be run once\n// whenever the node is started.\nif (context.get(\"counter\") === undefined) {\n    context.set(\"counter\", 0);\n}","finalize":"","libs":[],"x":500,"y":320,"wires":[["b63cd624dbae0df5"]]},{"id":"304666516656220f","type":"ui_template","z":"8c7dfd6121113522","group":"0225baf06413ee39","name":"Canvas-Gauges","order":3,"width":5,"height":6,"format":"<div style=\"margin:auto\">\n    \n<script src=\"/Canvas-Gauges/gauge.min.js\"></script>\n\n<canvas data-type=\"radial-gauge\"\n    data-width=\"200\"\n    data-height=\"200\"\n    data-units=\"°C\"\n    data-min-value=\"0\"\n    data-max-value=\"100\"\n    data-major-ticks=\"0,10,20,30,40,50,60,70,80,90,100\"\n    data-minor-ticks=\"10\"\n    data-stroke-ticks=\"true\"\n    data-highlights='[\n        {\"from\": 50, \"to\": 70, \"color\": \"rgba(255, 136, 0, .75)\"},    \n        {\"from\": 70, \"to\": 100, \"color\": \"rgba(200, 50, 50, .75)\"}\n    ]'\n    data-color-plate=\"#fff\"\n    data-border-shadow-width=\"0\"\n    data-borders=\"false\"\n    data-needle-type=\"arrow\"\n    data-needle-width=\"2\"\n    data-needle-circle-size=\"7\"\n    data-needle-circle-outer=\"true\"\n    data-needle-circle-inner=\"false\"\n    data-animation-duration=\"1500\"\n    data-animation-rule=\"linear\"\n    data-title = \"false\"\n    data-value-Box = \"true\"\n    data-value-Int=\"2\"\n    data-value-Dec=\"0\"    \n    data-value={{msg.payload}}\n></canvas>\n\n</div>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":680,"y":360,"wires":[[]]},{"id":"4d92bd212b2e6b74","type":"random","z":"8c7dfd6121113522","name":"","low":1,"high":"100","inte":"false","property":"payload","x":340,"y":320,"wires":[["0842a23a0e327e9f"]]},{"id":"9851b92096c23aec","type":"random","z":"8c7dfd6121113522","name":"","low":1,"high":"100","inte":"true","property":"payload","x":340,"y":360,"wires":[["d79514156f41f20c"]]},{"id":"d79514156f41f20c","type":"function","z":"8c7dfd6121113522","name":"","func":"let counter = context.get(\"counter\");\ncounter = counter + 1;\ncontext.set(\"counter\", counter);\nnode.status({text:counter});\n//----------\n\ndelete msg.topic;\nmsg.title = \"Time of Last Reading: \" + timeString_hms();\nreturn msg;\n\n//-----------\n\nfunction timeString_hms(){\n    let t = Date.now();\n    let date = new Date(t);    \n    let hours = (\"0\" + date.getHours()).slice(-2);\n    let minutes = (\"0\" + date.getMinutes()).slice(-2);\n    let seconds = (\"0\" + date.getSeconds()).slice(-2);    \n    let timestring = hours + ':' + minutes + ':' + seconds;\n    return timestring;\n}","outputs":1,"noerr":0,"initialize":"// Code added here will be run once\n// whenever the node is started.\nif (context.get(\"counter\") === undefined) {\n    context.set(\"counter\", 0);\n}","finalize":"","libs":[],"x":500,"y":360,"wires":[["304666516656220f"]]},{"id":"de2b2fa45759c4a9","type":"ui_template","z":"8c7dfd6121113522","group":"912b14d740dbf00d","name":"RGraph Dual","order":1,"width":8,"height":8,"format":"<canvas id=\"RGg\" width=\"400\" height=\"400\">[No canvas support]</canvas>\n\n<div style=\"margin:auto\"></div>\n\n<script language=\"javascript\" type=\"text/javascript\">\n\n           (function(scope){ \n                scope.$watch('msg', function(msg) {\n                   RGGaugeDual.value=[msg.temperature,msg.humidity];\n                   RGGaugeDual.grow();\n                });\n            })(scope);\n            \n            var RGGaugeDual = new RGraph.Gauge({\n                id: 'RGg',\n                min: 0,\n                max: 100,\n                value: [23,60],\n                options: {\n                    titleTop: 'Temperature',\n                    titleTopSize: '16',\n                    titleTopFont: 'Impact',\n                    titleTopColor: '#ff8888',\n                    titleTopPos: 0.25,\n                    titleBottom: 'Humidity',\n                    titleBottomSize: '14',\n                    titleBottomFont: 'Impact',\n                    titleBottomColor: '#8888ff',\n                    titleBottomPos: 0.3,\n                    backgroundColor: 'black',\n                    backgroundGradient: true,\n                    centerpinColor: '#666',\n                    needleSize: [null, 50],\n                    needleColors: ['Gradient(transparent:yellow:orange:#ff8888:#ff8888)', \n                                    'Gradient(transparent:cyan:green:blue:blue)'],\n                    textColor: 'white',\n                    tickmarks: 6,\n                    tickmarksBigColor: 'white',\n                    tickmarksMediumColor: 'white',\n                    tickmarksSmallColor: 'white',\n                    borderWidth: 1,\n                    borderOuter: '#666',\n                    borderInner: '#3333',\n                    colorsRanges: [\n                                    [0,10,'rgba(0,0,255,0.6)'], \n                                    [10,20,'rgba(0,128,255,0.6)'], \n                                    [20,30,'rgba(0,255,255,0.6)'], \n                                    [30,40,'rgba(0,255,128,0.6)'], \n                                    [40,50,'rgba(0,255,0,0.6)'], \n                                    [50,60,'rgba(128,255,0,0.6)'], \n                                    [60,70,'rgba(255,255,0,0.6)'], \n                                    [70,80,'rgba(255,128,0,0.6)'],                                                                                                                                                 \n                                    [80,90,'rgba(255,64,0,0.6)'],   \n                                    [90,100,'rgba(255,0,0,1']\n                                  ],\n                    textAccessible: true\n                }\n            });\n            RGGaugeDual.grow();\n</script>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":670,"y":780,"wires":[[]]},{"id":"ab02a775fe61480c","type":"random","z":"8c7dfd6121113522","name":"","low":"0","high":"40","inte":"true","property":"temperature","x":340,"y":760,"wires":[["759fbb7f30ba6ac2"]]},{"id":"759fbb7f30ba6ac2","type":"random","z":"8c7dfd6121113522","name":"","low":"0","high":"40","inte":"true","property":"humidity","x":340,"y":800,"wires":[["de2b2fa45759c4a9"]]},{"id":"13c39b07b625b67c","type":"ui_template","z":"8c7dfd6121113522","group":"6d2e01e4ea2d03f8","name":"RGraph Horseshoe - self triggered/timed","order":1,"width":6,"height":8,"format":"<canvas id=\"cvshs\" width=\"300\" height=\"300\">[No canvas support]</canvas>\n\n<script>\n    horseshoe = new RGraph.Horseshoe({\n        id: 'cvshs',\n        min: 0,\n        max: 100,\n        value: 65,\n        options: {\n            labelUnitsPost: '%'\n        }\n    }).grow();\n    \n    update = function ()\n    {\n        horseshoe.value = horseshoe.value + RGraph.random(-20,20);\n        horseshoe.grow();\n        setTimeout(update, 2000);\n    };\n\n    setTimeout(update, 2000);\n</script>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":960,"y":780,"wires":[[]]},{"id":"a2669babbbb6a58d","type":"ui_template","z":"8c7dfd6121113522","group":"912b14d740dbf00d","name":"RGraph Libraries","order":2,"width":0,"height":0,"format":"<script src=\"/RGraph/libraries/RGraph.common.core.js\"></script>\n<script src=\"/RGraph/libraries/RGraph.common.dynamic.js\"></script>\n<script src=\"/RGraph/libraries/RGraph.gauge.js\"></script>\n<script src=\"/RGraph/libraries/RGraph.horseshoe.js\"></script>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"global","x":890,"y":680,"wires":[[]]},{"id":"dc58109e99327d1e","type":"ui_template","z":"8c7dfd6121113522","group":"926072151b8e3190","name":"RGraph 1","order":1,"width":8,"height":3,"format":"<canvas id=\"rg1\" width=\"400\" height=\"140\"></canvas>\n\n<div style=\"margin:auto\"></div>\n\n<script language=\"javascript\" type=\"text/javascript\">\n    (function(scope){ \n        scope.$watch('msg', function(msg) {\n            gauge1.value = msg.payload;\n            gauge1.grow();\n        });\n    })(scope);\n            \n    let gauge1 = new RGraph.Gauge({\n        id: 'rg1',\n        min: 0,\n        max: 40,\n        value: 10,\n        options: {\n            centery: 120,\n            radius: 110,\n            anglesStart: RGraph.PI,\n            anglesEnd: RGraph.TWOPI,\n            numbersMargin: .1,\n            backgroundColor: 'black',\n            textColor: 'white',\n            needleSize: 65,\n            borderWidth: 15,\n            shadow: true,\n            needleType: 'line',\n            colorsRanges: [[0,8,'blue'], [8,16,'lightblue'], [16,24,'green'], [24,32,'orange'], [32,40,'red']],\n            borderInner: 'rgba(0,0,0,0)',\n            borderOuter: 'rgba(0,0,0,0)',\n            borderOutline: 'rgba(0,0,0,0)',\n            centerpinColor: 'rgba(0,0,0,0)',\n            centerpinRadius: 0\n        }\n    });\n    gauge1.grow();\n</script>\n","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":660,"y":680,"wires":[[]]},{"id":"a7cecd63f040a432","type":"random","z":"8c7dfd6121113522","name":"","low":"0","high":"40","inte":"true","property":"payload","x":340,"y":700,"wires":[["dc58109e99327d1e","5fa6155ba619c31e"]]},{"id":"5fa6155ba619c31e","type":"ui_text","z":"8c7dfd6121113522","group":"926072151b8e3190","order":2,"width":8,"height":1,"name":"Temperature 1","label":" ","format":"{{msg.payload}} &deg C","layout":"row-center","x":680,"y":720,"wires":[]},{"id":"c09d075d66e41467","type":"random","z":"8c7dfd6121113522","name":"","low":"0","high":"360","inte":"true","property":"payload","x":340,"y":460,"wires":[["9dac9baa9ffe467e","0e36bebef61b9bec","d21356027fdc21f8"]]},{"id":"9dac9baa9ffe467e","type":"ui_template","z":"8c7dfd6121113522","group":"a86601a0d85e8a94","name":"Compass","order":1,"width":10,"height":8,"format":"<div style=\"margin:auto\">\n    \n<script src=\"/Canvas-Gauges/gauge.min.js\"></script>\n\n<canvas data-type=\"radial-gauge\"\n    data-width=\"350\"\n    data-height=\"350\"\n    data-min-value=\"0\"\n    data-max-value=\"360\"\n    data-major-ticks=\"N,NE,E,SE,S,SW,W,NW,N\"\n    data-minor-ticks=\"22\"\n    data-ticks-angle=\"360\"\n    data-start-angle=\"180\"\n    data-stroke-ticks=\"false\"\n    data-highlights=\"false\"\n    data-color-plate=\"#222\"\n    data-color-major-ticks=\"#f5f5f5\"\n    data-color-minor-ticks=\"#ddd\"\n    data-color-numbers=\"#ccc\"\n    data-color-needle=\"rgba(240, 128, 128, 1)\"\n    data-color-needle-end=\"rgba(255, 160, 122, .9)\"\n    data-value-box=\"false\"\n    data-value-Dec=\"0\" \n    data-value-text-shadow=\"false\"\n    data-color-circle-inner=\"#fff\"\n    data-color-needle-circle-outer=\"#ccc\"\n    data-needle-circle-size=\"15\"\n    data-needle-circle-outer=\"false\"\n    data-animation-rule=\"linear\"\n    data-needle-type=\"line\"\n    data-needle-start=\"70\"\n    data-needle-end=\"99\"\n    data-needle-width=\"3\"\n    data-borders=\"true\"\n    data-border-inner-width=\"0\"\n    data-border-middle-width=\"0\"\n    data-border-outer-width=\"10\"\n    data-color-border-outer=\"#ccc\"\n    data-color-border-outer-end=\"#ccc\"\n    data-color-needle-shadow-down=\"#222\"\n    data-border-shadow-width=\"0\"\n    data-animation-duration=\"1000\"\n    data-value={{msg.payload}}\n></canvas>\n</div>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":660,"y":440,"wires":[[]]},{"id":"0e36bebef61b9bec","type":"ui_text","z":"8c7dfd6121113522","group":"a86601a0d85e8a94","order":2,"width":0,"height":0,"name":"","label":"Degrees","format":"{{msg.payload}}","layout":"col-center","x":660,"y":480,"wires":[]},{"id":"d21356027fdc21f8","type":"ui_template","z":"8c7dfd6121113522","group":"a86601a0d85e8a94","name":"Small Compass","order":3,"width":10,"height":3,"format":"<div style=\"margin:auto\">\n    \n<script src=\"/Canvas-Gauges/gauge.min.js\"></script>\n\n<canvas data-type=\"radial-gauge\"\n    data-width=\"140\"\n    data-height=\"140\"\n    data-min-value=\"0\"\n    data-max-value=\"360\"\n    data-major-ticks=\"N,NE,E,SE,S,SW,W,NW,N\"\n    data-font-Numbers-Size=\"28\"\n    data-minor-ticks=\"4\"\n    data-ticks-angle=\"360\"\n    data-start-angle=\"180\"\n    data-stroke-ticks=\"false\"\n    data-highlights=\"false\"\n    data-color-plate=\"#333333\"\n    data-color-major-ticks=\"lightblue\"\n    data-color-minor-ticks=\"lightgrey\"\n    data-color-numbers=\"cyan\"\n    data-color-needle=\"rgba(240, 128, 128, 1)\"\n    data-color-needle-end=\"rgba(255, 160, 122, .9)\"\n    data-value-box=\"false\"\n    data-value-Dec=\"0\" \n    data-value-text-shadow=\"false\"\n    data-color-circle-inner=\"#fff\"\n    data-color-needle-circle-outer=\"#ccc\"\n    data-needle-circle-size=\"5\"\n    data-needle-circle-outer=\"false\"\n    data-animation-rule=\"linear\"\n    data-needle-type=\"line\"\n    data-needle-start=\"70\"\n    data-needle-end=\"99\"\n    data-needle-width=\"3\"\n    data-borders=\"true\"\n    data-border-inner-width=\"0\"\n    data-border-middle-width=\"0\"\n    data-border-outer-width=\"2\"\n    data-color-border-outer=\"#ccc\"\n    data-color-border-outer-end=\"#ccc\"\n    data-color-needle-shadow-down=\"#222\"\n    data-border-shadow-width=\"0\"\n    data-animation-duration=\"1000\"\n    data-value={{msg.payload}}\n></canvas>\n</div>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":680,"y":540,"wires":[[]]},{"id":"171f22a4261dd1c6","type":"ui_group","name":"Canvas Linear Vertical","tab":"2deac665c2e9da53","order":1,"disp":true,"width":"5","collapse":false},{"id":"365a732e0ed6d35d","type":"ui_group","name":"Canvas Full Round","tab":"2deac665c2e9da53","order":2,"disp":true,"width":"8","collapse":false},{"id":"ad3ddda6cb6b3c19","type":"ui_group","name":"Canvas Half Round","tab":"2deac665c2e9da53","order":3,"disp":true,"width":"8","collapse":false},{"id":"5eab586c78e8cf53","type":"ui_group","name":"Canvas  Linear Horizontal","tab":"2deac665c2e9da53","order":4,"disp":true,"width":"17","collapse":false},{"id":"0225baf06413ee39","type":"ui_group","name":"Canvas - Tri-Size","tab":"2deac665c2e9da53","order":6,"disp":true,"width":"18","collapse":false},{"id":"912b14d740dbf00d","type":"ui_group","name":"RGraphDualPointer","tab":"2deac665c2e9da53","order":8,"disp":true,"width":"8","collapse":false},{"id":"6d2e01e4ea2d03f8","type":"ui_group","name":"RGraph Horseshoe","tab":"2deac665c2e9da53","order":9,"disp":true,"width":6,"collapse":false},{"id":"926072151b8e3190","type":"ui_group","name":"RGraph","tab":"2deac665c2e9da53","order":7,"disp":true,"width":"8","collapse":false},{"id":"a86601a0d85e8a94","type":"ui_group","name":"Compass","tab":"2deac665c2e9da53","order":9,"disp":true,"width":10,"collapse":false},{"id":"2deac665c2e9da53","type":"ui_tab","name":"Gauges Galore","icon":"data_usage","order":8,"disabled":false,"hidden":false}]

[{"id":"b21d274b8315c0f7","type":"inject","z":"3cd636ebd5398d6e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"7","crontab":"","once":false,"onceDelay":0.1,"topic":"","payloadType":"date","x":370,"y":300,"wires":[["dcd7d89bb2be17bf"]]},{"id":"c351447745138c19","type":"ui_template","z":"3cd636ebd5398d6e","group":"2c0d82c5cbab11fd","name":"gauge-style","order":1,"width":0,"height":0,"format":"<style id=\"hotNipi-gauge\">\n:root{\n    --needle-color:#dbe4eb;\n    --sec-high-color:#ff00004f;\n    --sec-normal-color:#00ff004f;\n    --sec-low-color:#0000ff4f;\n    --sec-sub-color:#0000ff8f;\n}\n.g-container {\n    padding-top: 3px;\n    padding-bottom: 3px;\n    width: 100%;\n    height: 100%;\n    position: relative;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    user-select:none;\n}\n    \n.g-body{\n    width:98%;\n    height:98%;\n    border-radius:15%;\n    position:relative;\n    display: flex;\n    align-content: center;\n    align-items: center;\n    justify-content: center;\n    box-shadow: 0px 5px 8px #00000045;\n    background:linear-gradient(0deg, rgba(81,74,29,1) 0%, rgba(163,149,59,1) 99%, rgba(181,166,66,1) 100%);\n}\n\n.g-body::before {    \n    content: \"\";\n    background-image: url(\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNSIgaGVpZ2h0PSI1IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogPGc+CiAgPHRpdGxlPkxheWVyIDE8L3RpdGxlPgogIDxyZWN0IHdpZHRoPSI1IiBoZWlnaHQ9IjUiIGZpbGw9IiM2MjYxMkMiIGlkPSJzdmdfMSIgc3Ryb2tlPSIjOTc5NDRCIi8+CiAgPHBhdGggZD0ibTAsNWw1LC01bC01LDV6bTYsLTFsLTIsMmwyLC0yem0tNywtM2wyLC0ybC0yLDJ6IiBpZD0ic3ZnXzIiIGZpbGw9IndoaXRlIiBzdHJva2U9IiM4ODgiLz4KIDwvZz4KCjwvc3ZnPg==\"); \n    background-repeat: repeat;\n    position: absolute;\n    top: 0px;\n    right: 0px;\n    bottom: 0px;\n    left: 0px;\n    opacity: 0.1;\n    border-radius:15%;\n}\n\n.g-ring{\n    width:90%;\n    height:90%;\n    border-radius:50%;\n    position:relative;\n    display: flex;\n    align-content: center;\n    align-items: center;\n    justify-content: center;\n   \n    background:linear-gradient(180deg, rgba(81,74,29,1) 0%, rgba(163,149,59,1) 99%, rgba(181,166,66,1) 100%);\n}\n.g-plate {\n    overflow:hidden;\n    width: 90%;\n    height: 90%;\n    border-radius: 50%;\n    position: relative;\n    box-shadow: inset 0 0 15px black;\n    background: radial-gradient(circle, #dd8400 3%, rgb(196, 205, 209) 1%, rgb(177, 183, 186) 40%, rgb(108, 114, 120) 100%);\n}\n.g-plate-bright {\n    overflow:hidden;\n    width: 90%;\n    height: 90%;\n    border-radius: 50%;\n    position: relative;\n    box-shadow: inset 0 0 10px yellow;\n    background: radial-gradient(circle, #ed9400 3%, rgb(255, 255, 255) 1%, rgb(255, 255, 158) 40%, rgb(148, 154, 160) 100%);\n}\n.g-sector{\n    width: 100%;\n    height: 100%;\n    position: absolute;\n    top: 50%;\n    left: 50%;\n   \n    transform-origin: 0 0;\n}\n.g-sector-high {\n    background: var(--sec-high-color);\n    transform: rotate(329deg) skew(12deg, 23deg);\n}\n.g-sector-normal {\n    background:var(--sec-normal-color);\n    transform: rotate(329deg) skew(12deg, 23deg);\n}\n.g-sector-low {\n    background:var(--sec-low-color);\n    transform: rotate(329deg) skew(12deg, 23deg);\n}\n.g-sector-sub {\n    background:var(--sec-sub-color);\n    transform: rotate(329deg) skew(12deg, 23deg);\n}\n.g-ticks {\n    position: absolute;\n    top:0;\n    left:0;\n    width: 100%;\n    height: 100%;\n    filter: drop-shadow(2px 4px 6px black);\n}\n.g-tick {\n    transform: rotate(calc(19.3deg * var(--ga-tick) - 64.3deg));\n    background: #000;\n    position: relative;\n    left: 0;\n    top: 50%;\n    width: 100%;\n    height: 1%;\n    margin-bottom: -1%;\n    background: linear-gradient(90deg,rgba(0,0,0,0) 0,rgba(0,0,0,0) 2%,rgb(0 0 0 / 60%) 2%,rgb(0 0 0 / 60%) 10%,rgba(0,0,0,0) 10%);\n}\n.g-num {\n    position: absolute;\n}\n.g-nums {\n    position: absolute;\n    top:0;\n    width: 100%;\n    height: 100%;\n    color: #000000a1;\n    font-size: calc(var(--container-size) * 16%);\n    font-weight: 500;\n    filter: drop-shadow(2px 4px 6px black);\n}\n.g-needle {\n    transform: rotate(calc(270deg * calc(var(--g-angle, 0deg) / 99) - 45deg));\n    transition: transform 1s;\n    background: #000;\n    position: absolute;\n    left: 0;\n    top: 49%;\n    width: 100%;\n    height: 2%;\n    filter:drop-shadow(0px 1px 3px #00000080);\n    background: linear-gradient(90deg,rgba(2,0,36,0) 0,rgba(0,0,0,0) 15%,var(--needle-color) 15%,var(--needle-color) 50%,rgba(0,0,0,0) 50%);\n}\n.g-needle-ring {\n    position: absolute;\n    width: calc(var(--container-size) * 1.5%);\n    height: calc(var(--container-size) * 1.5%);\n    top: 50%;\n    left: 50%;\n    background: var(--needle-color);\n    border-radius: 50%;\n    transform: translate(-50%, -50%);\n    box-shadow: 0 1px 4px #0000009c;\n}\n.g-val{\n    position: absolute;\n    text-align: center;\n    left: 50%;\n    bottom: 8%;\n    width: 80px;\n    transform: translateX(-50%);\n    font-family: monospace;\n    font-size:  calc(var(--container-size) * 50%);\n    color: #000000a1;\n    filter: drop-shadow(2px 3px 2px #00000080);\n}\n.g-label{\n    position: absolute;\n    text-align: center;\n    left: 50%;\n    top: 65%;\n    width: 100%;\n    transform: translateX(-50%);\n    font-family: monospace;\n    font-size:  calc(var(--container-size) * 20%);\n    color: #000000a1;\n    filter: drop-shadow(2px 3px 2px #00000080);\n}\n.g-rivets{\n    position: absolute;\n    left:0;\n    top:0;\n    width: 100%;\n    height: 100%;\n}\n\n.g-rivet {\n    position: absolute;\n    width: calc(var(--container-size) * 2px);\n    height: calc(var(--container-size) * 2px);\n    border-radius: 50px;\n    background: linear-gradient(135deg, #adadad 0%,#d3d3d3 51%,#d1d1d1 68%,#8c8c8c 100%);\n    box-shadow: 0px 2px 4px #000, -1px -1px 5px rgba(0,0,0,0.2);\n    border: 1px solid rgba(255,255,255,0.1);\n}\n.g-rivet:nth-child(1){\n    top:calc(var(--container-size) * 1.5px);\n    left:calc(var(--container-size) * 1.5px);\n}\n.g-rivet:nth-child(2){\n    top:calc(var(--container-size) * 1.5px);\n    right:calc(var(--container-size) * 1.5px);\n}\n.g-rivet:nth-child(3){\n    bottom:calc(var(--container-size) * 1.5px);\n    left:calc(var(--container-size) * 1.5px);\n}\n.g-rivet:nth-child(4){\n    bottom:calc(var(--container-size) * 1.5px);\n    right:calc(var(--container-size) * 1.5px);\n}\n\n.g-rivet::before {\n    content: '';\n    position: absolute;\n    left: 50%;\n    top: 50%;\n    width: calc(var(--container-size) * 10%);\n    height: calc(var(--container-size) * 10%);\n    box-shadow: inset 0px 1px 2px #222;\n    transform: translate(-50%, -50%);\n    border-radius: 50%;\n    border-bottom: 1px solid rgba(255,255,255,0.3);\n}\n</style>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"global","x":530,"y":240,"wires":[[]]},{"id":"eb080df2e58aef8a","type":"ui_template","z":"3cd636ebd5398d6e","group":"2c0d82c5cbab11fd","name":"gauge","order":3,"width":6,"height":6,"format":"<div id=\"{{'gauge_'+$id}}\" class=\"g-container\" style=\"-g-angle:0; --container-size:6\">\n    <div id=\"bgr\" class=\"g-body\">\n        <div class=\"g-ring\">\n            <div class=\"g-rivets\">\n                <div class=g-rivet></div>\n                <div class=g-rivet></div>\n                <div class=g-rivet></div>\n                <div class=g-rivet></div>\n            </div>\n            <div class=\"g-plate\">\n                <div class=\"g-sector g-sector-sub\" style=\"transform: rotate(133deg) skew(-28deg, 0deg);\"></div>\n                <div class=\"g-sector g-sector-low\" style=\"transform: rotate(251deg) skew(23deg, 0deg);\"></div>\n                <div class=\"g-sector g-sector-normal\" style=\"transform: rotate(318deg) skew(59deg, 0deg);\"></div>\n                <div class=\"g-sector g-sector-high\" style=\"transform: rotate(348deg) skew(31deg, 0deg);\"></div>\n                <div class=\"g-ticks\">\n                    <div class=\"g-tick\" style=\"--ga-tick:1;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:2;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:3;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:4;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:5;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:6;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:7;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:8;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:9;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:10;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:11;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:12;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:13;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:14;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:15;\"></div>\n                </div>\n                <div class=\"g-nums\">\n                    <div class=\"g-num\" style=\"left: 20%;top: 70%;\">-30</div>\n                    <div class=\"g-num\" style=\"left: 13%;top: 49%;\">-20</div>\n                    <div class=\"g-num\" style=\"left: 20%;top: 28%;\">-10</div>\n                    <div class=\"g-num\" style=\"left: 38%;top: 14%;\">0</div>\n                    <div class=\"g-num\" style=\"left: 57%;top: 14%;\">10</div>\n                    <div class=\"g-num\" style=\"left: 75%;top: 28%;\">20</div>\n                    <div class=\"g-num\" style=\"left: 78%;top: 49%;\">30</div>\n                    <div class=\"g-num\" style=\"left: 70%;top: 70%;\">40</div>\n                </div>\n                <div class=\"g-label\">Temp °C</div>\n                <div class=\"g-needle\"></div>\n                <div class=\"g-needle-ring\"></div>\n                <div id=\"{{'gauge_val_'+$id}}\" class=\"g-val\"></div>\n            </div>\n        </div>\n    </div>\n</div>\n<script>\n(function(scope) {\n    let min = -30;\n    let max = 40;\n    scope.$watch('msg', function(msg) {\n        if (msg) {\n            const v = Math.floor(((msg.payload - min) / (max - min)) * 100);\n            document.getElementById('gauge_'+scope.$id).style.setProperty('--g-angle', v);\n            document.getElementById('gauge_val_'+scope.$id).innerText = msg.payload;\n        }   \n  });\n})(scope);\n</script>\n","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":450,"y":360,"wires":[["4fd74e18b22679fe"]]},{"id":"dcd7d89bb2be17bf","type":"random","z":"3cd636ebd5398d6e","name":"","low":"-30","high":"40","inte":"true","property":"payload","x":540,"y":300,"wires":[["2894c6d23426d14e"]]},{"id":"2894c6d23426d14e","type":"ui_slider","z":"3cd636ebd5398d6e","name":"","label":"slider","tooltip":"","group":"2c0d82c5cbab11fd","order":5,"width":0,"height":0,"passthru":true,"outs":"all","topic":"topic","topicType":"msg","min":"-30","max":"40","step":1,"x":690,"y":300,"wires":[["eb080df2e58aef8a"]]},{"id":"4fd74e18b22679fe","type":"ui_template","z":"3cd636ebd5398d6e","group":"2c0d82c5cbab11fd","name":"backlit gauge","order":4,"width":6,"height":6,"format":"<div id=\"{{'gauge_'+$id}}\" class=\"g-container\" style=\"-g-angle:0; --container-size:6\">\n    <div id=\"bgr\" class=\"g-body\">\n        <div class=\"g-ring\">\n            <div class=\"g-rivets\">\n                <div class=g-rivet></div>\n                <div class=g-rivet></div>\n                <div class=g-rivet></div>\n                <div class=g-rivet></div>\n            </div>\n            <div class=\"g-plate-bright\">\n                <div class=\"g-sector g-sector-sub\" style=\"transform: rotate(133deg) skew(-28deg, 0deg);\"></div>\n                <div class=\"g-sector g-sector-low\" style=\"transform: rotate(251deg) skew(23deg, 0deg);\"></div>\n                <div class=\"g-sector g-sector-normal\" style=\"transform: rotate(318deg) skew(59deg, 0deg);\"></div>\n                <div class=\"g-sector g-sector-high\" style=\"transform: rotate(348deg) skew(31deg, 0deg);\"></div>\n                <div class=\"g-ticks\">\n                    <div class=\"g-tick\" style=\"--ga-tick:1;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:2;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:3;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:4;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:5;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:6;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:7;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:8;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:9;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:10;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:11;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:12;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:13;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:14;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:15;\"></div>\n                </div>\n                <div class=\"g-nums\">\n                    <div class=\"g-num\" style=\"left: 20%;top: 70%;\">-30</div>\n                    <div class=\"g-num\" style=\"left: 13%;top: 49%;\">-20</div>\n                    <div class=\"g-num\" style=\"left: 20%;top: 28%;\">-10</div>\n                    <div class=\"g-num\" style=\"left: 38%;top: 14%;\">0</div>\n                    <div class=\"g-num\" style=\"left: 57%;top: 14%;\">10</div>\n                    <div class=\"g-num\" style=\"left: 75%;top: 28%;\">20</div>\n                    <div class=\"g-num\" style=\"left: 78%;top: 49%;\">30</div>\n                    <div class=\"g-num\" style=\"left: 70%;top: 70%;\">40</div>\n                </div>\n                <div class=\"g-label\">Temp °C</div>\n                <div class=\"g-needle\"></div>\n                <div class=\"g-needle-ring\"></div>\n                <div id=\"{{'gauge_val_'+$id}}\" class=\"g-val\"></div>\n            </div>\n        </div>\n    </div>\n</div>\n<script>\n(function(scope) {\n    let min = -30;\n    let max = 40;\n    scope.$watch('msg', function(msg) {\n        if (msg) {\n            const v = Math.floor(((msg.payload - min) / (max - min)) * 100);\n            document.getElementById('gauge_'+scope.$id).style.setProperty('--g-angle', v);\n            document.getElementById('gauge_val_'+scope.$id).innerText = msg.payload;\n        }   \n  });\n})(scope);\n</script>\n","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":610,"y":360,"wires":[[]]},{"id":"2c0d82c5cbab11fd","type":"ui_group","name":"Group 3","tab":"20bb081.66afff8","order":3,"disp":false,"width":12,"collapse":false},{"id":"20bb081.66afff8","type":"ui_tab","name":"Ohh","icon":"dashboard","order":1,"disabled":false,"hidden":false}]

Sub-ticks are just as easy as regular ticks, just there is a lot more of them. :smiley:

image

[{"id":"6744cc2.7fb5234","type":"ui_template","z":"be2ac8b1.31fce8","group":"3ca910b5.3d50a","name":"gauge-style","order":4,"width":0,"height":0,"format":"<style id=\"hotNipi-gauge\">\n:root{\n    --needle-color:#001100;\n}\n.g-container {\n    padding-top: 3px;\n    padding-bottom: 3px;\n    width: 100%;\n    height: 100%;\n    position: relative;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    user-select:none;\n}\n    \n.g-body{\n    width:90%;\n    height:90%;\n    border-radius:15%;\n    position:relative;\n    display: flex;\n    align-content: center;\n    align-items: center;\n    justify-content: center;\n    box-shadow: 0px 5px 8px #00000045;\n    background:linear-gradient(0deg, rgba(78,78,78,1) 0%, rgba(215,215,215,1) 99%, rgba(236,236,236,1) 100%);\n}\n\n.g-body::before {    \n    content: \"\";\n    background-image: url(\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPSc1JyBoZWlnaHQ9JzUnPgogIDxyZWN0IHdpZHRoPSc1JyBoZWlnaHQ9JzUnIGZpbGw9J3doaXRlJy8+CiAgPHBhdGggZD0nTTAgNUw1IDBaTTYgNEw0IDZaTS0xIDFMMSAtMVonIHN0cm9rZT0nIzg4OCcgc3Ryb2tlLXdpZHRoPScxJy8+Cjwvc3ZnPg==\"); \n    background-repeat: repeat;\n    position: absolute;\n    top: 0px;\n    right: 0px;\n    bottom: 0px;\n    left: 0px;\n    opacity: 0.1;\n    border-radius:15%;\n}\n\n.g-ring{\n    width:90%;\n    height:90%;\n    border-radius:50%;\n    position:relative;\n    display: flex;\n    align-content: center;\n    align-items: center;\n    justify-content: center;\n   \n    background:linear-gradient(180deg, rgba(78,78,78,1) 0%, rgba(215,215,215,1) 99%, rgba(236,236,236,1) 100%);;\n}\n.g-plate {\n    overflow:hidden;\n    width: 90%;\n    height: 90%;\n    border-radius: 50%;\n    position: relative;\n    box-shadow: inset 0 0 15px black;\n    background: radial-gradient(circle, #dd8400 3%, rgb(196 205 209) 1%, rgb(177 183 186) 40%, rgb(108 114 120) 100%);\n}\n.g-sector-high {\n    width: 100%;\n    height: 100%;\n    position: absolute;\n    top: 50%;\n    left: 50%;\n    background: #ff00004f;\n    transform-origin: 0 0;\n    transform: rotate(329deg) skew(12deg, 23deg);\n}\n.g-ticks {\n    position: absolute;\n    top:0;\n    left:0;\n    width: 100%;\n    height: 100%;\n    filter: drop-shadow(2px 4px 6px black);\n}\n.g-tick {\n    transform: rotate(calc(calc(270deg / var(--ga-tick-count)) * var(--ga-tick) - calc(calc(270deg / var(--ga-tick-count)) + 45deg)));\n    background: #000;\n    position: relative;\n    left: 0;\n    top: 50%;\n    width: 100%;\n    height: 1%;\n    margin-bottom: -1%;\n    background: linear-gradient(90deg,rgba(0,0,0,0) 0,rgba(0,0,0,0) 2%,rgb(0 0 0 / 60%) 2%,rgb(0 0 0 / 60%) 10%,rgba(0,0,0,0) 10%);\n}\n.g-subtick {\n    transform: rotate(calc(calc(270deg / var(--ga-subtick-count)) * var(--ga-tick) - calc(calc(270deg / var(--ga-subtick-count)) + 45deg)));\n    background: #000;\n    position: relative;\n    left: 0;\n    top: 50%;\n    width: 100%;\n    height: 1%;\n    margin-bottom: -1%;\n    background: linear-gradient(90deg,rgba(0,0,0,0) 0,rgba(0,0,0,0) 2%,rgb(0 0 0 / 30%) 2%,rgb(0 0 0 / 30%) 6%,rgba(0,0,0,0) 6%);\n}\n.g-num {\n    position: absolute;\n}\n.g-nums {\n    position: absolute;\n    top:0;\n    width: 100%;\n    height: 100%;\n    color: #000000a1;\n    font-size: calc(var(--container-size) * 16%);\n    font-weight: 500;\n    filter: drop-shadow(2px 4px 6px black);\n}\n.g-needle {\n    transform: rotate(calc(270deg * calc(var(--gauge-value, 0deg) / 100) - 45deg));\n    transition: transform 1s;\n    background: #000;\n    position: absolute;\n    left: 0;\n    top: 49%;\n    width: 100%;\n    height: 2%;\n    filter:drop-shadow(0px 1px 3px #00000080);\n    background: linear-gradient(90deg,rgba(2,0,36,0) 0,rgba(0,0,0,0) 15%,var(--needle-color) 15%,var(--needle-color) 50%,rgba(0,0,0,0) 50%);\n}\n.g-needle-ring {\n    position: absolute;\n    width: calc(var(--container-size) * 1.5%);\n    height: calc(var(--container-size) * 1.5%);\n    top: 50%;\n    left: 50%;\n    background: var(--needle-color);\n    border-radius: 50%;\n    transform: translate(-50%, -50%);\n    box-shadow: 0 1px 4px #0000009c;\n}\n.g-val{\n    position: absolute;\n    text-align: center;\n    left: 50%;\n    bottom: 8%;\n    width: 80px;\n    transform: translateX(-50%);\n    font-family: monospace;\n    font-size:  calc(var(--container-size) * 40%);\n    color: #000000a1;\n    filter: drop-shadow(2px 3px 2px #00000080);\n}\n.g-label{\n    position: absolute;\n    text-align: center;\n    left: 50%;\n    top: 55%;\n    width: 100%;\n    transform: translateX(-50%);\n    font-family: monospace;\n    font-size:  calc(var(--container-size) * 18%);\n    color: #000000a1;\n    filter: drop-shadow(2px 3px 2px #00000080);\n}\n.g-rivets{\n    position: absolute;\n    left:0;\n    top:0;\n    width: 100%;\n    height: 100%;\n}\n\n.g-rivet {\n    position: absolute;\n    width: calc(var(--container-size) * 2px);\n    height: calc(var(--container-size) * 2px);\n    border-radius: 50px;\n    background: linear-gradient(135deg, #adadad 0%,#d3d3d3 51%,#d1d1d1 68%,#8c8c8c 100%);\n    box-shadow: 0px 2px 4px #000, -1px -1px 5px rgba(0,0,0,0.2);\n    border: 1px solid rgba(255,255,255,0.1);\n}\n.g-rivet:nth-child(1){\n    top:calc(var(--container-size) * 1.5px);\n    left:calc(var(--container-size) * 1.5px);\n}\n.g-rivet:nth-child(2){\n    top:calc(var(--container-size) * 1.5px);\n    right:calc(var(--container-size) * 1.5px);\n}\n.g-rivet:nth-child(3){\n    bottom:calc(var(--container-size) * 1.5px);\n    left:calc(var(--container-size) * 1.5px);\n}\n.g-rivet:nth-child(4){\n    bottom:calc(var(--container-size) * 1.5px);\n    right:calc(var(--container-size) * 1.5px);\n}\n\n.g-rivet::before {\n    content: '';\n    position: absolute;\n    left: 50%;\n    top: 50%;\n    width: calc(var(--container-size) * 10%);\n    height: calc(var(--container-size) * 10%);\n    box-shadow: inset 0px 1px 2px #222;\n    transform: translate(-50%, -50%);\n    border-radius: 50%;\n    border-bottom: 1px solid rgba(255,255,255,0.3);\n}\n</style>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"global","x":510,"y":720,"wires":[[]]},{"id":"838d07e8.155da8","type":"ui_template","z":"be2ac8b1.31fce8","group":"3ca910b5.3d50a","name":"gauge","order":4,"width":"6","height":"6","format":"<div id=\"{{'gauge_'+$id}}\" class=\"g-container\" style=\"--gauge-value:0; --container-size:6; --ga-tick-count:10; --ga-subtick-count:100\">\n    <div id=\"bgr\" class=\"g-body\">\n        <div class=\"g-ring\">\n            <div class=\"g-rivets\">\n                <div class=g-rivet></div>\n                <div class=g-rivet></div>\n                <div class=g-rivet></div>\n                <div class=g-rivet></div>\n            </div>\n            <div class=\"g-plate\">\n                <div class=\"g-sector-high\"></div>\n                <div class=\"g-ticks\">\n                    <div class=\"g-tick\" style=\"--ga-tick:1;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:2;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:3;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:4;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:5;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:6;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:7;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:8;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:9;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:10;\"></div>\n                    <div class=\"g-tick\" style=\"--ga-tick:11;\"></div>\n                </div>\n                <div class=\"g-ticks\">\n                    <div class=\"g-subtick\" style=\"--ga-tick:2;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:3;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:4;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:5;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:6;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:7;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:8;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:9;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:10;\"></div>\n                    \n                    <div class=\"g-subtick\" style=\"--ga-tick:12;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:13;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:14;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:15;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:16;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:17;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:18;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:19;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:20;\"></div>\n                    \n                    <div class=\"g-subtick\" style=\"--ga-tick:22;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:23;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:24;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:25;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:26;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:27;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:28;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:29;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:30;\"></div>\n                    \n                    <div class=\"g-subtick\" style=\"--ga-tick:32;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:33;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:34;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:35;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:36;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:37;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:38;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:39;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:40;\"></div>\n                    \n                    <div class=\"g-subtick\" style=\"--ga-tick:42;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:43;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:44;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:45;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:46;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:47;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:48;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:49;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:50;\"></div>\n                    \n                    <div class=\"g-subtick\" style=\"--ga-tick:52;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:53;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:54;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:55;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:56;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:57;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:58;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:59;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:60;\"></div>\n                    \n                    <div class=\"g-subtick\" style=\"--ga-tick:62;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:63;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:64;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:65;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:66;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:67;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:68;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:69;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:70;\"></div>\n                    \n                    <div class=\"g-subtick\" style=\"--ga-tick:72;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:73;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:74;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:75;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:76;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:77;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:78;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:79;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:80;\"></div>\n                    \n                    <div class=\"g-subtick\" style=\"--ga-tick:82;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:83;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:84;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:85;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:86;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:87;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:88;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:89;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:90;\"></div>\n                    \n                    <div class=\"g-subtick\" style=\"--ga-tick:92;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:93;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:94;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:95;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:96;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:97;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:98;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:99;\"></div>\n                    <div class=\"g-subtick\" style=\"--ga-tick:100;\"></div>\n                </div>\n                <div class=\"g-nums\">\n                    <div class=\"g-num\" style=\"left: 23%;top: 71%;\">0</div>\n                    <div class=\"g-num\" style=\"left: 13%;top: 56%;\">10</div>\n                    <div class=\"g-num\" style=\"left: 13%;top: 39%;\">20</div>\n                    <div class=\"g-num\" style=\"left: 19%;top: 24%;\">30</div>\n                    <div class=\"g-num\" style=\"left: 31%;top: 14%;\">40</div>\n                    <div class=\"g-num\" style=\"left: 47%;top: 10%;\">50</div>\n                    <div class=\"g-num\" style=\"left: 63%;top: 14%;\">60</div>\n                    <div class=\"g-num\" style=\"left: 74%;top: 25%;\">70</div>\n                    <div class=\"g-num\" style=\"left: 79%;top: 40%;\">80</div>\n                    <div class=\"g-num\" style=\"left: 78%;top: 56%;\">90</div>\n                    <div class=\"g-num\" style=\"left:65%; top:71%;\">100</div>\n                </div>\n                <div class=\"g-label\">Temperature</div>\n                <div class=\"g-needle\"></div>\n                <div class=\"g-needle-ring\"></div>\n                <div id=\"{{'gauge_val_'+$id}}\" class=\"g-val\"></div>\n            </div>\n        </div>\n    </div>\n</div>\n<script>\n(function(scope) {\n    let min = 0;\n    let max = 100;\n  scope.$watch('msg', function(msg) {\n    if (msg) {\n      // Do something when msg arrives\n        const v = Math.floor(((msg.payload - min) / (max - min)) * 100);\n        document.getElementById('gauge_'+scope.$id).style.setProperty('--gauge-value', v);\n        document.getElementById('gauge_val_'+scope.$id).innerText = v;\n    }\n   \n  });\n})(scope);\n</script>\n","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":510,"y":680,"wires":[[]]},{"id":"ee5b7fef.e2ddc","type":"ui_slider","z":"be2ac8b1.31fce8","name":"","label":"slider","tooltip":"","group":"3ca910b5.3d50a","order":6,"width":0,"height":0,"passthru":true,"outs":"all","topic":"topic","topicType":"msg","min":0,"max":"100","step":1,"x":350,"y":680,"wires":[["838d07e8.155da8"]]},{"id":"3ca910b5.3d50a","type":"ui_group","name":"Group 1","tab":"20bb081.66afff8","order":1,"disp":true,"width":6},{"id":"20bb081.66afff8","type":"ui_tab","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]

It misses every first so they don't overlap with main ticks

2 Likes

Yes indeed... I see I was on the right track :slight_smile: Just didn't want to tackle the math :sweat_smile:

Gaining ideas ...
image

You guys have too much free time? :wink: I was playing with snap.svg for a project some years back.

Doing this with HTML/CSS only is quite impressive, I must say. What's you're hourly rate? :smiley:

Too low as it usually is ... :smiley:

2 Likes

After consulting with "art guy" the advises applied to improve readability and to have cleaner look (bigger numbers, less shadows, brighter colors, sharper ticks ...)

I actually starting to like it ... :smiley:

Always consult professionals

7 Likes