What about this one? Responsive and stuff...
Yes, you'll need to have dark background for it. Long way to be a widget ...
CODE
<template>
<div class="fg-body">
<div class="fg-display">
<div class="fg-backplate">
<div ref="display" class="fg-numbers" >
<div v-for="(n, index) in numbers" :key="index" class="fg-num">{{n}}
</div>
</div>
<div class="fg-needle"></div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
min:0,
max:100,
value:0
}
},
computed: {
numbers:function(){
var t = (this.max - this.min) / 10;
let i = this.min;
let r = []
for (let e = 0; e < 11; ++e){
r.push(i),
i = parseFloat((i + t).toFixed(2));
}
return r
}
},
methods: {
range :function (n, p, a, r) {
if (a == "clamp") {
if (n < p.minin) {
n=p.minin;
}
if (n> p.maxin) {
n = p.maxin;
}
}
if (a == "roll") {
let d = p.maxin - p.minin;
n = ((n - p.minin) % d + d) % d + p.minin;
}
let v = ((n - p.minin) / (p.maxin - p.minin) * (p.maxout - p.minout)) + p.minout;
if (r) {
v = Math.round(v);
}
return v
},
percentage: function(){
let p = 100 - ((this.value - this.min) / (this.max - this.min)) * 100
let params = {minin:0, maxin:100, minout:2.5, maxout:97.5};
return this.range(p,params)
},
getElement: function(name,base){
if(base){
return this.$refs[name]
}
return this.$refs[name][0]
},
validate(data){
let ret
if(typeof data !== "number"){
ret = parseFloat(data)
if(isNaN(ret)){
console.log("BAD DATA! gauge type:",this.type, "id:",this.id,"data:",data)
return null
}
}
else{
ret = data
}
return ret
},
move(){
const display = this.$refs.display;
if(!display){
return
}
display.style.left = this.percentage()+"%"
}
},
watch: {
msg: function(){
if(this.msg.payload !== undefined){
const v = this.validate(this.msg.payload)
if(v === null){
return
}
this.value = v
this.move()
}
}
},
mounted() {
},
unmounted() {
}
}
</script>
<style>
.fg-body {
position: relative;
width: 100%;
height: 100%;
display: flex;
align-content: center;
flex-wrap: wrap;
}
.fg-numbers {
position:relative;
display: flex;
flex-direction: row;
justify-content: space-between;
height: 100%;
font-size: 1.25rem;
word-wrap: normal;
align-content: center;
flex-wrap: wrap;
transform: translateX(-50%);
transition: left 1s ease-in-out;
}
.fg-backplate {
width: 600px;
flex-shrink: 0;
position: relative;
}
.fg-numbers:before {
content: "";
position: absolute;
right: 0%;
width: 100%;
top: 0px;
height: 25%;
background: linear-gradient(to right,
#00000050,
#00000050 50%,
transparent 50%,
transparent);
background-size: 0.6% 100%;
}
.fg-numbers:after {
content: "Gauges by hotNipi ®";
position: absolute;
font-size: 9px;
left: -90px;
top: 9px;
color: #00000080;
}
.fg-display {
width: 100%;
height: 100%;
display:flex;
justify-content: center;
position: relative;
box-sizing: border-box;
overflow: hidden;
border: 3px solid black;
background-color: #cfcfcf;
outline: 1px solid #4d4d4d;
outline-offset: -2px;
border-radius: 6px;
box-shadow: inset 0 0 9px 1px black;
}
.fg-display:before,
.fg-display:after {
content: "";
position: absolute;
inset: 0;
}
.fg-display:before {
background: linear-gradient(270deg, #000000b0, transparent 20%);
}
.fg-display:after {
background: linear-gradient(90deg, #000000b0, transparent 20%);
}
.fg-num {
position: relative;
text-align: center;
top: 3px;
width: 30px;
color: black;
}
.fg-needle {
position: absolute;
left: calc(50% - 1px);
top: 1px;
width: 2px;
height: 21px;
background-color: #eb1e1e;
box-shadow: 0px 0px 7px 2px #0000008c;
}
</style>