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

Yet another spectacular gauge iteration!
Your CSS seems to be very clear and self explanatory, which makes it much easier to tweek.
Thanks for this project.

A question if I may? All of your json files in this topic place the CSS in the page header. As I understand it, that applies the CSS to every Dashboard tab which may not be what's required.
If I put the CSS into "Widget in group" then it is applied to all groups on that tab.
So is there a particular reason for it being in the page header?

Are you planning to release this as a UI node? What changes do you think are necessay for that?
I'm trying to get the gauge width flexible with a single parameter.

There's plenty of inspiration in classic car dashboards - Lancia delta integrale:

3 Likes

Thank you for kind words :slight_smile:

Oh it is not. It is just as it comes out when prototyping and can be written much more cleaner.

If the CSS applies commonly for all targeted elements - the correct place for it is in site head. So it affects over all tabs. That also forces to write the CSS in the way it can be used commonly and this is usually way to write less but smarter CSS. Finally it is easier to maintain and makes it easier to override at tabs or even widget level if you need to.

Well, maybe. At first - it takes way more time as to prototype it. Thing I can't steal too easily.
Also I haven't figured out where to draw the line according to what it should provide and then, if something is not provided how make it easily tweak-able. And many more unanswered questions ...

Maybe I need some partners to make me started and keep me going... Like a good project manager and technical writer...

Yeah. Car gauges are special in the way. They are beautiful and may be fancy target to try to replicate but in many cases pretty hard to make usable for common/environmental measuring. Most probably it takes then whole set to make. Quite of work. :slight_smile:

The quarter gauge is a nice addition, I guess the obvious options would be to mirror it on both axis, then a group of 4 could make a circle :wink:

2 Likes

@Gunner if you wouldn't mind sharing a flow with the 3 needle gauge. Been playing with the code and every time I try something it's a cobbled mess.
Thanks

The quarter gauges are just.... so beautiful - thanks to @hotNipi for all your hard work.

1 Like

Thank you David :slight_smile:

To be in style tried also tweak some custom elements for my dashboard, wrapped a little chart line to display-like container (most basic line, made with d3.js representing electricity price curve for today)

Seems like this little gauge is not the limit. The sky may be... :smiley:

image

5 Likes

It's October tomorrow.... just saying :wink:

2 Likes

Known that you have power to close the thread ... :upside_down_face: I'd also like to do so but with some royal fireworks - unfortunately I haven't had any time to prepare anything ... :smiley:

2 Likes

No prob... But it is a bit of a hack, what with my looping value feedback.

[{"id":"f120bcfaddfcfa82","type":"ui_template","z":"3cd636ebd5398d6e","group":"d1ae1ccfedfa70c5","name":"FansnazzyGauge1","order":5,"width":8,"height":8,"format":"<style>\n\n\n    #{{'gauge_'+$id}} .g-tick:nth-child(n+6) {\n        background: linear-gradient(90deg, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 2%, rgb(31 148 0 / 80%) 2%, rgb(31 148 0 / 80%)\n        10%, rgba(0, 0, 0, 0) 10%);\n        height: 1.3px;\n        margin-bottom: -1.3px;\n    }\n    #{{'gauge_'+$id}} .g-tick:nth-child(n+9) {\n        background: linear-gradient(90deg, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 2%, rgb(255 0 0 / 60%) 2%, rgb(255 0 0 / 60%) 10%, rgba(0, 0, 0, 0) 10%);\n        height: 1.3px;\n        margin-bottom: -1.3px;\n    }\n    #{{'gauge_'+$id}} .g-subtick:nth-child(n+46) {\n        background: linear-gradient(90deg, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 2%, rgb(31 148 0 / 80%) 2%, rgb(31 148 0 / 80%), 6%, rgba(0, 0, 0, 0) 6%);\n        height: 1.3px;\n        margin-bottom: -1.3px;\n    }\n    #{{'gauge_'+$id}} .g-subtick:nth-child(n+73) {\n        background: linear-gradient(90deg, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 2%, rgb(255 0 0 / 40%) 2%, rgb(255 0 0 / 40%) 6%, rgba(0, 0, 0, 0) 6%);\n        height: 1.3px;\n        margin-bottom: -1.3px;\n    }\n    #{{'gauge_'+$id}} .g-num:nth-child(n+6) {\n        color: #089606ff;\n    }\n    #{{'gauge_'+$id}} .g-num:nth-child(n+9) {\n        color: #dc0808ee;\n    }\n</style>\n\n<div id=\"{{'gauge_'+$id}}\" class=\"g-container\" style=\"--gauge-value:0; --container-size:8; --gn-distance:15; --ga-tick-count:10; --ga-subtick-count:100; --g-unit:'Ā°C'\">\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\n            <div class={{msg.backlight}}>\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=\"--ga-tick:1;\" >-40</div>\n                    <div class=\"g-num\" style=\"--ga-tick:2;\">-30</div>\n                    <div class=\"g-num\" style=\"--ga-tick:3;\">-20</div>\n                    <div class=\"g-num\" style=\"--ga-tick:4;\">-10</div>\n                    <div class=\"g-num\" style=\"--ga-tick:5;\">0</div>\n                    <div class=\"g-num\" style=\"--ga-tick:6;\">10</div>\n                    <div class=\"g-num\" style=\"--ga-tick:7;\">20</div>\n                    <div class=\"g-num\" style=\"--ga-tick:8;\">30</div>\n                    <div class=\"g-num\" style=\"--ga-tick:9;\">40</div>\n                    <div class=\"g-num\" style=\"--ga-tick:10;\">50</div>\n                    <div class=\"g-num\" style=\"--ga-tick:11;\">60</div>\n                </div>\n                <div class=\"g-label\">Temperature</div>\n                <div class=\"g-needle-third\"></div>\n                <div class=\"g-needle-second\"></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 id=\"{{'gauge_val_second'+$id}}\" class=\"g-val-second\"></div>\n                <div id=\"{{'gauge_val_third'+$id}}\" class=\"g-val-third\"></div>\n            </div>\n        </div>\n    </div>\n</div>\n<script>\n(function(scope) {\n    let min = -40;\n    let max = 60;\n  scope.$watch('msg', function(msg) {\n     if (msg) {\n      // Do something when msg arrives\n\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 = msg.payload;\n        \n        if (msg.redMarker == true) {\n            const v = Math.floor(((msg.payload - min) / (max - min)) * 100);\n            document.getElementById('gauge_'+scope.$id).style.setProperty('--gauge-value-second', v);\n        }\n        \n        if (msg.blueMarker == true) {\n            const v = Math.floor(((msg.payload - min) / (max - min)) * 100);\n            document.getElementById('gauge_'+scope.$id).style.setProperty('--gauge-value-third', v);\n        }\n    }\n   \n  });\n})(scope);\n</script>\n","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":590,"y":240,"wires":[[]]},{"id":"1e4738339a392c7d","type":"ui_slider","z":"3cd636ebd5398d6e","name":"","label":"","tooltip":"","group":"d1ae1ccfedfa70c5","order":8,"width":5,"height":1,"passthru":true,"outs":"end","topic":"topic","topicType":"msg","min":"-40","max":"60","step":1,"x":390,"y":240,"wires":[["f120bcfaddfcfa82","44c2bbdb4caf59ad"]]},{"id":"d882807221ba900d","type":"change","z":"3cd636ebd5398d6e","name":"","rules":[{"t":"move","p":"payload","pt":"msg","to":"blueMarker","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":170,"y":180,"wires":[["1e4738339a392c7d"]]},{"id":"5a855c6dcb47d649","type":"inject","z":"3cd636ebd5398d6e","name":"","props":[{"p":"payload"},{"p":"backlight","v":"g-plate","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"0","payloadType":"num","x":150,"y":280,"wires":[["1e4738339a392c7d","67c5951214a3675d"]]},{"id":"838603a75a1b0a69","type":"change","z":"3cd636ebd5398d6e","name":"","rules":[{"t":"move","p":"payload","pt":"msg","to":"backlight","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":170,"y":440,"wires":[["1e4738339a392c7d"]]},{"id":"53b1f8687de24c79","type":"change","z":"3cd636ebd5398d6e","name":"","rules":[{"t":"move","p":"payload","pt":"msg","to":"redMarker","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":170,"y":20,"wires":[["1e4738339a392c7d"]]},{"id":"160431978ed3e63a","type":"inject","z":"3cd636ebd5398d6e","name":"","props":[{"p":"payload"},{"p":"backlight","v":"g-plate","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"0","payloadType":"num","x":150,"y":120,"wires":[["b0c6f282c4c0df11","1e4738339a392c7d"]]},{"id":"44c2bbdb4caf59ad","type":"ui_switch","z":"3cd636ebd5398d6e","name":"Backlight Switch","label":"","tooltip":"","group":"d1ae1ccfedfa70c5","order":9,"width":1,"height":1,"passthru":true,"decouple":"false","topic":"topic","topicType":"msg","style":"","onvalue":"true","onvalueType":"bool","onicon":"fa-toggle-on fa-2x","oncolor":"blue","offvalue":"false","offvalueType":"bool","officon":"fa-toggle-off fa-2x","offcolor":"lightblue","animate":false,"x":160,"y":340,"wires":[["272e16b6ca31ed8d"]]},{"id":"67c5951214a3675d","type":"ui_button","z":"3cd636ebd5398d6e","name":"Marker Button","group":"d1ae1ccfedfa70c5","order":6,"width":1,"height":1,"passthru":true,"label":"","tooltip":"","color":"blue","bgcolor":"grey","icon":"fa-check","payload":"true","payloadType":"bool","topic":"topic","topicType":"msg","x":160,"y":220,"wires":[["d882807221ba900d"]]},{"id":"272e16b6ca31ed8d","type":"function","z":"3cd636ebd5398d6e","name":"","func":"let setting;\nif (msg.payload == true) {\n    setting = \"g-plate-backlight\";\n    } else {\n    setting = \"g-plate\";\n    }\nmsg = {payload: setting};\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":140,"y":400,"wires":[["838603a75a1b0a69"]]},{"id":"b0c6f282c4c0df11","type":"ui_button","z":"3cd636ebd5398d6e","name":"Marker Button","group":"d1ae1ccfedfa70c5","order":7,"width":1,"height":1,"passthru":true,"label":"","tooltip":"","color":"red","bgcolor":"grey","icon":"fa-check","payload":"true","payloadType":"bool","topic":"topic","topicType":"msg","x":160,"y":60,"wires":[["53b1f8687de24c79"]]},{"id":"06e028443a7a21ad","type":"ui_template","z":"3cd636ebd5398d6e","d":true,"group":"d1ae1ccfedfa70c5","name":"Ring override","order":2,"width":0,"height":0,"format":"<style id=\"HotNipi-gaugeTweeks-Ring\">\n.g-body {\n    border-radius: 50%;\n}\n\n.g-body::before {    \n    border-radius: 50%;\n}\n\n.g-rivets {\n    display:none;\n}\n</style>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":550,"y":40,"wires":[[]]},{"id":"5997efbdd790ff46","type":"ui_template","z":"3cd636ebd5398d6e","group":"d1ae1ccfedfa70c5","name":"gauge-style","order":1,"width":0,"height":0,"format":"<style id=\"hotNipi-gauge\">\n:root{\n    --needle-color: black;\n    --needle-ring-color: silver;\n    --needle-second-color: red;\n    --needle-third-color: blue;\n    --red-ticks:9;\n}\n\n.md-button {\n    border-radius:0.8em;\n    color: var(--text-color);\n}\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(78,78,78,1) 0%, rgba(215,215,215,1) 99%, rgba(235,235,235,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: 94%;\n    height: 94%;\n    border-radius: 50%;\n    position: relative;\n    display: flex;\n    align-content: center;\n    align-items: center;\n    justify-content: center;\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: 93%;\n    height: 93%;\n    border-radius: 50%;\n    position: relative;\n    box-shadow: inset 0 0 15px #000000a3;\n    /*background: radial-gradient(circle, #dd8400 3%, rgb(196 205 209) 1%, rgb(177 183 186) 40%, rgb(191 193 194) 100%);*/\n    background: radial-gradient(circle, #dd8400 3%, rgb(176 185 189) 1%, rgb(157 163 166) 40%, rgb(171 173 174) 100%);\n}\n\n.g-plate-backlight {\n    overflow: hidden;\n    width: 93%;\n    height: 93%;\n    border-radius: 50%;\n    position: relative;\n    box-shadow: inset 0 0 10px lightblue;\n    background: radial-gradient(circle, #0033ff 3%, rgb(16, 164, 255) 1%, rgb(16, 128, 255) 40%, lightblue 100%);\n}\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(328deg) 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: 1px;\n    margin-bottom: -1px;\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\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: 1px;\n    margin-bottom: -1px;\n    background: linear-gradient(90deg,rgba(0,0,0,0) 0,rgba(0,0,0,0) 2%,rgb(0 0 0 / 40%) 2%,rgb(0 0 0 / 40%) 6%,rgba(0,0,0,0) 6%);\n}\n\n.g-num {\n    position: absolute;\n    top: 50%;\n    left: 50%;\n    text-align: center;\n    transform: translate(-50%, -50%) rotate(calc(calc(270deg / var(--ga-tick-count)) * var(--ga-tick) - calc(calc(270deg /\n    var(--ga-tick-count)) + 45deg))) translate(calc(-1px * var(--container-size) * var(--gn-distance))) rotate(calc(calc(270deg / var(--ga-tick-count)) * var(--ga-tick) *-1 -\n    calc(calc(270deg / var(--ga-tick-count))*-1 - 45deg)));\n}\n\n.g-nums {\n    position: absolute;\n    top: 0;\n    width: 100%;\n    height: 100%;\n    color: #000000dd;\n    font-size: calc(var(--container-size) * 20%);\n    font-weight: 500;\n    filter: drop-shadow(2px 4px 10px white);\n}\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\n.g-needle-second {\n    transform: rotate(calc(270deg * calc(var(--gauge-value-second, 0deg) / 100) - 45deg));\n    transition: transform .5s;\n    background: #000;\n    position: absolute;\n    left: 0;\n    top: 49%;\n    width: 100%;\n    height: 1%;\n    filter:drop-shadow(0px 1px 3px #ff000080);\n    background: linear-gradient(90deg,rgba(2,0,36,0) 0,rgba(0,0,0,0) 15%,var(--needle-second-color) 15%,var(--needle-second-color) 50%,rgba(0,0,0,0) 50%);\n}\n\n.g-needle-third {\n    transform: rotate(calc(270deg * calc(var(--gauge-value-third, 0deg) / 100) - 45deg));\n    transition: transform .5s;\n    background: #000;\n    position: absolute;\n    left: 0;\n    top: 49%;\n    width: 100%;\n    height: 1%;\n    filter:drop-shadow(0px 1px 3px #0000ff80);\n    background: linear-gradient(90deg,rgba(2,0,36,0) 0,rgba(0,0,0,0) 15%,var(--needle-third-color) 15%,var(--needle-third-color) 50%,rgba(0,0,0,0) 50%);\n}\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-ring-color);\n    border-radius: 50%;\n    transform: translate(-50%, -50%);\n    box-shadow: 0 1px 4px #0000009c;\n}\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: #000000c1;\n    filter: drop-shadow(2px 3px 2px #ffffff60);\n}\n\n.g-val-second{\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: #ff0000a1;\n    filter: drop-shadow(2px 3px 2px #ff000060);\n}\n\n.g-val-third{\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: #ff0000a1;\n    filter: drop-shadow(2px 3px 2px #0000ff60);\n}\n\n.g-label{\n    position: absolute;\n    text-align: center;\n    left: 50%;\n    top: 58%;\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 #ffffff80);\n}\n\n.g-label::after{\n    content: var(--g-unit);\n    font-size: clamp(1em,calc(var(--container-size) * 40%),1.5em);\n    position: absolute;\n    left: 0;\n    top: 100%;\n    width: 100%;\n    height: 100%;\n}\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\n.g-rivet:nth-child(1){\n    top:calc(var(--container-size) * 1.5px);\n    left:calc(var(--container-size) * 1.5px);\n}\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\n.g-rivet:nth-child(3){\n    bottom:calc(var(--container-size) * 1.5px);\n    left:calc(var(--container-size) * 1.5px);\n}\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":"local","x":550,"y":100,"wires":[[]]},{"id":"521c6749307adab0","type":"ui_template","z":"3cd636ebd5398d6e","group":"1218347fb0ba10c3","name":"Brass Ring override","order":4,"width":0,"height":0,"format":"<style id=\"HotNipi-gaugeTweeks-BrassRing\">\n\n:root {\n    --needle-ring-color:#b5a642;\n}\n\n.g-body {\n    border-radius: 50%;\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    border-radius: 50%;\n}\n\n.g-ring{\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\n.g-rivets {\n    display:none;\n}\n\n</style>\n\n","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":910,"y":40,"wires":[[]]},{"id":"d1ae1ccfedfa70c5","type":"ui_group","name":"Gauge1","tab":"20bb081.66afff8","order":1,"disp":false,"width":"8","collapse":false},{"id":"1218347fb0ba10c3","type":"ui_group","name":"Gauge2","tab":"20bb081.66afff8","order":2,"disp":false,"width":"8","collapse":false},{"id":"20bb081.66afff8","type":"ui_tab","name":"New Gauge","icon":"dashboard","order":1,"disabled":false,"hidden":false}]

Thanks muchly, having a play with it now

@gerry If you haven't seen this yet, the two needle setup is very well explained here Awesome gauges for Node-Red - YouTube, you'll need just adopt same strategy for third. Not much magic.

I had another look at pointy needles, also countersunk screws (must try and discipline myself to use percentages not pixel sizes). I'm learning a lot!

3 Likes

Nice needles!!

But you know that bezel finish will get all scratched up first time you try to use a flathead screwdriver and it slips off :laughing:

@jbudd ... your needles are fantastic and realistic. Can you post the code for those needles?

1 Like

wow! what a great look!

A work in progress
I had to make changes to the HTML as well as CSS for this.
Updated - now less of a dial and more of an alarm clock.

Untitled 4

(Couldn't find a "men at work" fa-icon)
It isn't telling the right time, sadly.

4 Likes

Nice. I specially like the red needle on top of the center piece.
Don't hesitate to share the code. Never known what will be next crazy idea ...

OK, Pointy needles:

hotNipi's needle is created by a div with

height: 2%
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%)

The unrotated position of the needle is pointing horizontally left.
I'm not sure if you changed this on the quarter circle style gauge?
Untitled 1

Since I found it hard to alter the needle appearance I changed the div to height 100% and used clip-path to define the visible area:

.g-needle {
  transform: rotate(calc(270deg * calc(var(--gauge-value, 0deg) / 100) - 45deg));
  transition: transform 1s;
  background: var(--needle-color);
  position: absolute;
  height: 100%;
  width: 100%;
  top: 0;
  left: 0;
  clip-path: polygon(7% 49.7%, 33% 48.5%, 60% 48.5%, 60% 51.5%, 33% 51.5%, 7% 50.3%);
}

Changing to 100% height (?) destroys the drop shadow effect.
Untitled 3

To get it back (absolutely no idea why this works) I wrapped the needle div in another

<div class="g-needle-shadow">
     <div class="g-needle"></div>
</div>

and apply the shadow to that div

.g-needle-shadow {
    height:100%;
    filter:drop-shadow(0px 1px 3px #00000080);
}

Untitled 5

My clock hands are defined like this - no doubt other folks can provide more elegant examples.
Hour hand clip-path: polygon(17% 50%, 21% 47%, 42% 48%, 46% 49%, 46% 51%, 42% 52%, 21% 53%);
Minute hand clip-path: polygon(4% 50.3%, 4% 49.7%, 42% 47%, 46% 49%, 46% 51%, 42% 53%);
Second hand clip-path: polygon(6% 50%, 7% 49.5%, 60% 49.3%, 60% 50.7%, 7% 50.5%);
(the phosphor glow is another div within the hour or minute with another clip path)

You can overlay the centre ring by the order of the divs.

I have no idea if clip-path is more / less efficient in browser resources but I wonder if it's appropriate to design the ticks like this too.

2 Likes

Clip-path is good by for IE, and that is what we all want to :slight_smile:

Quarter version is really tweaks on top regular and there is probably some mistakes left in, I haven't had too much time think about it properly.