IonDen / ion.rangeSlider

jQuery only range slider
http://ionden.com/a/plugins/ion.rangeSlider/en.html
MIT License
2.55k stars 508 forks source link

Misleading rounding of grid labels when a tick does not align with a step #572

Closed mactyr closed 4 years ago

mactyr commented 6 years ago

This image shows a single-valued slider (ion.rangeSlider v. 2.2.0) with min: 0, max: 10 and step: 1. It has the default grid_num of 4. It seems that the grid labels are rounded to the nearest step, even when the rounded value does not reflect the actual position of the tick mark. E.g., in this case the mark labeled "3" is actually at 2.5 units, and the mark labeled "8" is at 7.5 units. In fact, in this image, the slider's value ("from") is 3, but it appears that it is larger than 3 because the handle is to the right of the tick mark labeled "3".

image

I thought that I might work around this with a custom prettify function, but I discovered that the value was being rounded before being sent as input to the prettify, so there doesn't seem to be a simple way to change the rounding.

The problem can be solved, at least in some cases, by adjusting grid_num to a value that will cause tick marks to align with steps. I'll implement that workaround for now, but in my use case it's inconvenient because I'm generating a number of sliders dynamically based on data, so determining a good value for grid_num is non-trivial. It would be helpful if ion.rangeSlider allowed more decimal places for grid labels (perhaps up to a configurable limit) when ticks do not align with steps. I.e., for my purposes, it would be preferable for the "3" label to say "2.5", even though that is not a value that the user can actually select due to the step size.

IonDen commented 6 years ago

Hi, this is a common issue if value range is small. Can be easily fixed with grid_snap: true: http://jsfiddle.net/ras1h5f8/

mactyr commented 6 years ago

Thank you, I had missed grid_snap and it does look like it will prevent this problem.

I would still suggest that the default label rounding behavior is confusing, though, and it would be better not to round the label to the step (or at least have the option not to round) if the grid mark does not fall on a step. It makes sense to me to both round the label and snap the step (which grid_snap does) or to do neither, but doing one without the other seems just to be misleading, because the label is then incorrect for the position of the tick. It's hard to imagine a use case where that would be desirable, so it's surprising default behavior.

That said, thanks again for helping me solve the immediate problem!

mactyr commented 6 years ago

I've done some experimenting and it turns out that grid_snap isn't a slam dunk for all of the sliders I'm generating. For example, I also have one with a range of 0-60 and a step of 0.1, for which the grid_snap output is:

image

I can selectively apply grid_snap based on some criteria, of course, but if I'm going to do that I think I'll just stick with my original adaptive grid_num code. In case anyone else is wrestling with this situation, here's what I'm doing (range is an object I'm using to prepare the ion.rangeSlider configuration):

if (!range.gridNum) {
  range.gridNum = 1;
  let steps = (range.max - range.min) / range.step;
  for (let i = 7; i >= 2; i--) {
    if (steps % i == 0) {
      range.gridNum = i;
      break;
    }
  }
}

This will choose the largest number between 2 and 7 that evenly divides the number of steps in your range, and use that as the gridNum (which I then assign to grid_num). If no number between 2 and 7 evenly divides the number of steps, then the gridNum will stay at 1, which will effectively show a slider without a grid (because it's a "grid" with one unit, no subdivisions). Between 2 and 7 grid divisions looks best to my eye, but of course you can adjust the bounds to your taste.

IonDen commented 6 years ago

Hi, yes, grid snap is not a silver bullet to solve all the problem. You should play with grid_snap and grid_num to get the best looking and usable grid for each individual case you have.

mactyr commented 6 years ago

Thanks, IonDen. I guess the perspective I'm trying to communicate is that playing with each individual slider isn't always an option -- for example, in my case I'm dynamically generating sliders based on data that I can't fully know in advance. So it would be helpful if ion.rangeSlider had more sophisticated default behavior (e.g., if you could set grid_snap and it would prune down to a reasonable number of labels rather than displaying them all overlapping). That said, I understand that my use case may be edgy enough that it's not a priority, and the grid_num calculation I posted above does solve my immediate problem, so I'm happy to let you move on to other things. 😃 Thanks for your time.