Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UI-Slider : Non-Linear slider #1416

Open
xX-Nexus-Xx opened this issue Oct 22, 2024 · 5 comments
Open

UI-Slider : Non-Linear slider #1416

xX-Nexus-Xx opened this issue Oct 22, 2024 · 5 comments
Labels
feature-request New feature or request that needs to be turned into Epic/Story details needs-triage Needs looking at to decide what to do

Comments

@xX-Nexus-Xx
Copy link

Description

Would it be possible to add the option of having a non-linear slider.

Example:

  • Slider-min: 0
  • Slider-Max: 90
  • Number of segments: 3
  • Segment[1] : 1
  • Segment[1].steps : 0.2
  • Segment[2]: 10
  • Segment[2].steps: 1
  • Segment[3]: 90
  • Segment[3],steps: 10

this would result in a slider for 0-90 days

0| 0.2| 0.4 | 0.6 | 0.8 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 20 | 30 | 40| 50 | 60 | 70 | 80 | 90

thanks for considering

Have you provided an initial effort estimate for this issue?

I have provided an initial effort estimate

@xX-Nexus-Xx xX-Nexus-Xx added feature-request New feature or request that needs to be turned into Epic/Story details needs-triage Needs looking at to decide what to do labels Oct 22, 2024
@colinl
Copy link
Contributor

colinl commented Oct 22, 2024

Would it be simpler to specify that you want a log scale?

@xX-Nexus-Xx
Copy link
Author

Yeah, I was considering LOG scale as well, but it will be difficult to setup for valid scale values.

In below example I can determine exactly the values which are of interest for me:
0| 0.2| 0.4 | 0.6 | 0.8 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 20 | 30 | 40| 50 | 60 | 70 | 80 | 90
with a setup exactly for 60-days,70-days or 80-days ... or whatever I want.

Don't get me wrong a LOG scale might be useful for a lot of use-cases (and maybe another feature request) but in my case a "customized scale" would be more flexible

@colinl
Copy link
Contributor

colinl commented Oct 23, 2024

There are two issues here.

  1. The ability to specify a non-linear scale
  2. The ability to specify the annotation values

The second might be useful even with a linear scale, and the two together might do what you want. So in your case specifying a log scale and the values that you want (but letting the slider work out exactly where those are on the scale) might be the way to go.

However, if 0 is actually a valid value that you need sent then you can't use a log scale.

a setup exactly for 60-days,70-days or 80-days ... or whatever I want.
In practice, are you looking for only specific values to be sent? If that is the case then I think a slider is not what you want as it will produce intermediate values, such as 75.

@hotNipi
Copy link
Contributor

hotNipi commented Oct 23, 2024

No support for uneven steps. vuetifyjs/vuetify#5930
So the only thing you can do is still have slider 0 - 100 but the output (and thumb maybe) to have computed value.

There are many ways to achieve multiple regions with different grow rate of course.
Here's a quick one to test with ui_template

<template>
    <div>
        <v-slider
                v-model="value"
                :label="name"
                direction="horizontal"
                step="1"                
                thumb-label="true"                                                
                @end="onChange()"
            >
            <template v-slot:thumb-label="item">
                {{thumbvalue}}
            </template>
        </v-slider>

    </div>
</template>

<script>
    export default {
        data() {
         
            return {
                name:"slider",
                value:0,
                min:0,
                max:100000,
                valuelist:[]
            }
        },
        watch: {
           
        },
        computed: {
            thumbvalue : function(){
                const ranged = this.range(this.value,{minIn:0, minOut:0, maxIn:100, maxOut:this.valuelist.length - 1})
                return this.valuelist[ranged]
            }
        },
        methods: {
            onChange:function(c) {                       
                this.send({payload:this.thumbvalue})
            },
            range:function (n, p, round = true) {
                if (n < p.minIn) { n=p.minIn; } if (n> p.maxIn) {
                    n = p.maxIn;
                }
                if(round){
                    return Math.round(((n - p.minIn) / (p.maxIn - p.minIn) * (p.maxOut - p.minOut)) + p.minOut);
                }
                return ((n - p.minIn) / (p.maxIn - p.minIn) * (p.maxOut - p.minOut)) + p.minOut;
            },
            generateSliderValues: function(){
                let maxValue = this.max
                let minValue = this.min
                
                const prepareValueList = function() {
                    let first = minValue > maxValue ? maxValue : minValue
                    let result = [ first ]
                    result = result.concat(create(1, 1, 10, minValue, maxValue))
                    result = result.concat(create(10, 5, 50, minValue, maxValue))
                    result = result.concat(create(50, 10, 100, minValue, maxValue))
                    result = result.concat(create(100, 100, 1000, minValue, maxValue))
                    result = result.concat(create(1000, 1000, 10000, minValue, maxValue))
                    result = result.concat(create(10000, 5000, 100000, minValue, maxValue))
                    result = result.concat(create(100000, 100000, 1000000, minValue, maxValue))
                    result = result.concat(create(1000000, 10000000, 1000000000, minValue, maxValue))
                    result = result.concat(create(10000000000, 1000000000, 100000000000, minValue, maxValue))
                    
                    if (result.indexOf(maxValue) === -1) {
                        result.push(maxValue)
                    }
                    return result
                }
                const create = function(from, incr, to, min, max) {
                    if (min > max) {
                        return []
                    }
                    if (from >= to || from > max) {
                        return []
                    }
                    if (from + incr > to) {
                        return []
                    }
                    var ret = []
                    var val = from
                    while (val < to) {
                        if (val < min) { 
                            val +=incr
                            continue
                        }
                        else {
                            if (val>= max) {
                                val = max
                                ret.push(val)
                                break
                            }
                            if (ret.indexOf(val) === -1 && val > min) {
                                ret.push(val)
                            }
                            val += incr
                        }
                    }
                    return ret
                }
                this.valuelist = prepareValueList()
            }
            
        },
        mounted() {
            this.generateSliderValues()
        },
        unmounted() {
          
        }
    }
</script>
<style>
  
</style>

@xX-Nexus-Xx
Copy link
Author

Hey @hotNipi , yes this does work well .. I still need to understand how ... but it works and I can adjust to my needs already

thx a lot

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request New feature or request that needs to be turned into Epic/Story details needs-triage Needs looking at to decide what to do
Projects
Status: Backlog
Development

No branches or pull requests

3 participants