Search code examples
highchartsuislider

Implement slider in highcharts


I am trying to tie a jquery slider to a highcharts scatter plot. The slider sits just below the chart and it is it's job is to draw a vertical line within the chart as a point of reference for the user. I have everything working except the slider does not end up aligning with the line that it creates (because it isn't really tied to the xAxis).

I can't seem to find a straightforward way to do this and it is complicated further if/when a user zooms in on the chart - then the slider values need to be re-calculated to match the now visible plot area (I would be willing to disable the zoom though, if needed).

So I thought maybe the thing to do would be instead of trying to tie a jQuery UI Slider to the chart - draw a slider in the chart using the Renderer. Though, there still, I don't really have a way of tying it to the xAxis so that my slider would line up with the line it created.

I would settle for use of the xAxis crosshairs except that they only display when you are hovering over a point. I would need it to display all the time - no matter where you were along the xAxis.

So - 1. Is there a way to tie a slider to a Highchart so that it lines up perfectly with the xAxis. 2. If not, is there a way to use the built-in xAxis crosshairs but show them all the time and not just when over a data point?

Here is an example of something close to what I am doing in my actual project:
http://jsfiddle.net/5hk0d6do/23/

       $('#container').highcharts({options}, function(chart){

        $slider = $('#slider');
        $slider.slider({
            min: chart.axes[0].min,
            max: chart.axes[0].max,
            slide : function(event, ui){
                var plotX = chart.xAxis[0].toPixels(ui.value, false);
                $('#slider_bar').remove();
                chart.renderer.path(['M', plotX, 75, 'V', plotX, 300]).attr({
                    'stroke-width': 1,
                    stroke: 'rgba(223, 83, 83, .5)',
                    id : 'slider_bar'
                })
                .add();  
            }
        }); 
        $slider.slider('option', 'slide').call($slider, null, { value: chart.axes[0].min });                                    
});

It is true that I could try and push the margins of the slider div in to match the chart but that seemed like a very frail solution and possibly very browser dependent for just how well it lined up.

Thanks!


Solution

  • With a little jQuery help, I don't see why you couldn't get the positioning correct. Do it dynamically though to improve cross-browser results:

    var $slider = $('#slider');
    var xaxis = chart.axes[0];
    var containerOff = $('#container').offset();
    
    $slider.slider({
      min: xaxis.min,
      max: xaxis.max,
      slide: function(event, ui) {
        var plotX = xaxis.toPixels(ui.value, false);
        $('#slider_bar').remove();
        chart.renderer.path(['M', plotX, 75, 'V', plotX, 300]).attr({
          'stroke-width': 1,
          stroke: 'rgba(223, 83, 83, .5)',
          id: 'slider_bar'
        })
          .add();
      }
    });
    
    // now that it is drawn, position it dynamically
    $slider.css({
      'width':xaxis.len,
      'position': 'absolute',
      'left': chart.plotLeft + containerOff.left
    });
    

    Here's an example.