Tank level indication inside of ui-template(v2)

Or a bit more "tank like" level widget

image

Code is HERE
<script>
    export default{
        data(){
            return {
                min:0,
                max:6.5,
                label:"Second Tank",
                unit:"m³",
                showMax:true,
                maxLabel:"Max",
                value:0
            }
        }
    }
</script>
    
<template>
    <div class="wrapper">
        <div class="tank">
            <div class="fluid" :style="{'height':percentage}"></div>
            <div class="frame"></div>
            <p class="txt">{{formattedValue}}<span>{{unit}}</span></p>
            <p class="label">{{label}}</p>
            <p v-if="showMax" class="limit"><span>{{maxLabel}}</span>{{max}}{{unit}}</p>
        </div>
        <div>
</template>

<script>
    export default{        
        methods:{
            getElement: function(name,base){
                if(base){
                    return this.$refs[name]
                }
                return this.$refs[name][0]
            },
            validate: function(data){
                let ret
                if(typeof data !== "number"){
                    ret = parseFloat(data)
                    if(isNaN(ret)){
                        console.log("BAD DATA! gauge id:",this.id,"data:",data)
                        ret = null
                    }
                }
                else{
                    ret = data
                }
                return ret
            }
        },
        computed: {
            formattedValue: function () {
                return this.value.toFixed(2)
            },
            percentage: function(){
                return Math.floor(((this.value - this.min) / (this.max - this.min)) * 100)+"%";
            }
        },
        watch: {
            msg: function(){            
                const v = this.validate(this.msg.payload)           
                this.value = v                         
            }
        }    
    }    
</script>
<style>
    .wrapper{
        position:relative;
        --border:3px;
        --corner:30px;
        --fluidColor:#00a8ff;
    }
    .tank {
        position: absolute;
        width: 100%;
        height: 100%;
        margin: auto;
        inset: 0;
        overflow: hidden;
        border-bottom-left-radius: var(--corner);
        border-bottom-right-radius: var(--corner);
    }
    .tank .txt {
        position: relative;
        width: 100%;
        top: 55%;
        text-align: center;
        font-size: x-large;
        font-weight: 700;
        user-select: none;
    }
    .tank .txt span {
        font-size: small;
        display: contents;
    }
    .tank .label {
        position: absolute;
        width: 100%;
        top: 20%;
        text-align: center;
        font-size: 1rem;        
        user-select: none;
    }
    .tank .limit {
        position: absolute;
        top: 1ch;
        right: 1ch;
        text-align: end;
        font-size: smaller;
        opacity:.7;
        user-select: none;
    }
    .tank .limit span {
        padding-right:0.5ch;
    }
    .tank .frame {
        position: absolute;
        width: calc(100% - var(--border));
        height:calc(100% - var(--border));
        margin: auto;
        inset: 0;
        outline: var(--border) solid;     
        border-bottom-left-radius: var(--corner);
        border-bottom-right-radius: var(--corner);
    }

    .tank .fluid {
        position: absolute;
        width: 100%;
        height:100%;
        bottom: 0;
        background: var(--fluidColor);
        border-bottom-left-radius: var(--corner);
        border-bottom-right-radius: var(--corner);
    }
</style>
3 Likes