Dashboard 2.0 is now Generally Available

Some building blocks to play with:

Template:

<template>
    <div class="level">
        <div v-for="(color, index) in colors" :key="index" class="led" :ref="'dot-' + index +'-'+this.id"></div>
    </div>
</template>

<script>
export default {
    data(){
        return {
            //define me here                   
            min:0,
            max:100,
            dark:0.4,            
            colors:["#4ed34e",
                    "#4ed34e",
                    "#4ed34e",
                    "#4ed34e",
                    "#4ed34e",
                    "#4ed34e",
                    "#4ed34e",
                    "#4ed34e",
                    "#4ed34e",
                    "#4ed34e",
                    "#ffcf00",
                    "#ffcf00",
                    "#ffcf00",
                    "#ffcf00",
                    "red",
                    "red",
                    "red"],

            //no need to change those
            value:0,
            inited:false
        }
    },

   
    methods: {        
        getElement: function(name){
            return this.$refs[name][0]
        },

        full: function(){
            return Math.floor(this.colors.length*this.percentage/100)
        },
        half: function (){
            let p = this.colors.length*this.percentage/100;
            p -= this.full()
            p *= .5
            p += this.dark;
            return p;
        },

        lit: function(){
            if(this.inited == false){
                return
            }
            this.colors.forEach((e,i) => {
                let dot = this.getElement("dot-"+i+"-"+this.id);
                if(!dot){
                    console.log("no dots found")
                    return
                }                
                if(i<this.full()){
                    dot.style.filter= "brightness(1.1)";
                }
                else if(i==this.full()){                   
                    dot.style.filter = "brightness("+this.half()+")";
                }
                else{
                    dot.style.filter= "brightness("+this.dark+")";
                }
            })
        }
    },
    watch: {
        msg: function(){    
            if(this.msg.payload != undefined){           
                this.value = this.msg.payload                
                this.lit()
            }
        }
    },
    computed: {
        formattedValue: function () {
            return this.value.toFixed(2)
        },
        percentage: function(){
            return Math.floor(((this.value - this.min) / (this.max - this.min)) * 100);
        }
    },
    mounted(){
        this.colors.forEach((c,i) => {
                let dot = this.getElement("dot-"+i+"-"+this.id);
                if(!dot){
                    console.log("no dots found")
                    return
                }
                dot.style.backgroundColor = c
            }
        )       
        this.inited = true;
    },
        
}
</script>

CSS:

.level{
    display: flex;
    gap:2px;
}    
.led {
    background: #ffffff;
    width: 100%;
    height: 100%;
    border-radius: 4px;
    box-shadow: inset 0px 0px 20px 0px #00000099, 0px 0px 3px 0px #00000099;
    filter: brightness(0.4);
}

6 Likes