gre / multi-slider

React component for multiple values slider (allocate values)
http://gre.github.io/multi-slider
49 stars 31 forks source link

Feature-Suggestions #5

Open tpinne opened 7 years ago

tpinne commented 7 years ago

Hi,

I really like your component. It's a really easy to use true multi slider.

I have some things on my mind which I think could take it up a notch:

1. Fixed stepping Setting a fixed stepping to only allow value changes restricted to that stepping. To switch between 0, 10, 20, ... and so on

2. Values above/below handle Add an option to display the current values above/below the corresponding handle. Don't know if this is possible with SVG.

3. Enable standard range slider behaviour It would be great to use this component as a standard range slider too. By "standard" I mean an optional mode where the slider is fixed to 2 handles and 2 values, highlighting only the area between them and returning the absolute value of their position.

Sadly I'm not that of an expert that I could provide much of a help for any of these suggestions.

Best regards tpinne

gre commented 7 years ago

Hi, thanks for suggestions,

1.: Is that on every handle or only on specific handles? if not, how would it differ to actually 'dividing' the number of units ? I mean, instead of allocating 100 units, you alloc just 10 and you have the 10-stepping (but you need to multiply x10 somewhere).

2.: Yes, this is possible, SVG have a <text> element. do you want it to display everytime or only on drag? I feel the library should exposes you some renderHandleLabel prop you can pass to address this. the result of the call of that function would be sandboxed in a x-translated <g>.

3.: I'm not sure to understand.

tpinne commented 7 years ago

1. Of course one could alloc just 10 and do the backwards math elsewhere. But you would have to do it every time you use the slider with other configurations. You doing slightly the same math over and over again when the component could give you a expectable outcome regarding the values you put into it. And regarding 2. you would need different renderHandleLabel methods ore a generic one which computes the output based on several input parameters. Which for basic rendering of just the current value the component could do the work. The logic would be in one place.

2. Best would be a configurable display. I can think of scenarios, where it is sufficient to just display on drag. In other cases it's useful to see the values directly.

3. Currently every handle defines the "length" from the current position to the left handle or beginning of whole track (0). You actually split the complete "length" in ($numberOfHandlers + 1) sections. Which is exactly the current use case for us, which I haven't seen in any other component so far. And I like the SVG so so much. So much, that I would like to use it as a typical range slider.

But you can't use it (out of the box without some mathematic magic) to define a range between the min and max values. Like for example a price range for product search, where the defined range between the lower and upper bound is visually distinguishable. Have a look at the 3rd example at http://ionden.com/a/plugins/ion.rangeSlider/demo.html. This demonstrates it the best. Or http://react-component.github.io/slider/examples/range.html. It was hard for me to put it into words. But in this mode one would expect an array with two values. With the values being the absolute values for the lower and upper bound for that range. And not an upper bound relative to the lower bound.

http://react-component.github.io/slider/ has everything one would need for a typical range slider. But not in SVG and not with the option to just "divide a number" into configurable parts.

Sure I could use different components for these purposes. But I like SVG and the simple, touch friendly, styling of yours.

I hope I could clarify this a little bit.

gre commented 7 years ago

ok so (1) is easy to add. i've created https://github.com/gre/multi-slider/issues/9

for (2). see https://github.com/gre/multi-slider/issues/8 ( I was wrong by saying renderHandleLabel, it's more renderTrackLabel, because a value is on the "track", not really on the handle). On the same principle, I think it would be great to override how a track is rendered, and also how a handle is rendered. (so i've created https://github.com/gre/multi-slider/issues/7 and https://github.com/gre/multi-slider/issues/6 )

please continue the discussion on related issue if needed.

for (3) , I think with the #7 and #6 solved, it will be possible to render a min-max range while this component staying somehow more generic.

basically you could simplify the logic by saying:

const MinMaxRange = ({ range, onChangeRange, max })  =>
  <MultiSlider
    value={range.concat([ max ])}
    onChange={([ _, from, to ]) => onChangeRange([ from, to ])}
    ...some other things to customize rendering...
/>

note that this lib currently assumes the value start at ZERO, so you would not be able to define a max... it's hackable, but maybe the lib could be improved to introduce a startValue, or something like that. (maybe it should be the first number in value..)

so that said, it's hackable, but not (yet?) built-in the lib. so maybe we could improve the lib to support that and handle what you said (a bit like the slider you showed).

I'm not sure when i'll have time to work on these subjects, PR are welcomed tho

realigork commented 6 years ago

Hey, this is great work! Probably the only range slider that implement this kind of behaviour. So thank you so much for great work! There are few things I would like to ask you:

  1. The option to set either slider horizontal or vertical by passing down orientation prop or smth.
  2. Issue with handles overlapping each other. If you move all of the handles to the far end, then you may not be able to pull them back anymore. Therefore, it would be best if handles don't overlap each other.

I would really appreciate if you could look at it at your earliest convenience. I can help with the orientation, but handle overlapping issue is bit more complicated...