Highchart datepicker

I am trying to get jquery-ui datepicker to work with highcharts so that a user can select a date an example being

A user selects 10th October to 25th October

Once the user has selected the dates the highchart should redraw and show the hours for the projects that have done along with the tasks. My chart looks like the following:

Chart

From the photo currently the highchart shows the hours a user has done for a task against the project “Asda”.

At the moment I have the chart simply displays the hours for the current week. What I am trying to do is use the jquery datepicker so that it can display past hours that the user has entered. If the user selects “from 10th October” “to “25th October” the chart should redraw and show the hours and projects for the selected date range.

My code follows:

Index.html.erb

<%= javascript_include_tag 'highcharts', 'exporting' %>

<%= render 'projectselect' %>

<div class = 'right'>
<label for="from">From</label>
<input type="text" id="from" name="from" size="15"/>
<label for="to">to</label>
<input type="text" id="to" name="to" size="15"/>
</div>

<button id="button">Redraw</button>


<div id="container" style="height: 400px"></div>

<script>
$(document).ready(function() {var chart = new Highcharts.Chart(options);});
onchange: $(function() {
        var dates = $( "#from, #to" ).datepicker({
            defaultDate: "+1w",
            changeMonth: true,
            numberOfMonths: 1,
            onSelect: function( selectedDate ) {
                var option = this.id == "from" ? "minDate" : "maxDate",
                    instance = $( this ).data( "datepicker" ),
                    date = $.datepicker.parseDate(
                        instance.settings.dateFormat ||
                        $.datepicker._defaults.dateFormat,
                        selectedDate, instance.settings );
                dates.not( this ).datepicker( "option", option, date );
            }
        });
    });

$('#button').click(function() {
    chart.redraw();
});

var options = {
    chart: {
         renderTo: 'container',
         defaultSeriesType: 'column'
      },
      title: {
          text: '<%= current_user.username %>',
      },
      subtitle: {
         text: 'Project Hours'
      },
      xAxis: {
         categories: [
            'Pre-Sales',
            'Project',
            'Fault Fixing',
            'Support',
            'Out Of Hours',
            'Sick',
            'Toil',
            'Leave'  
         ]
      },
      yAxis: {
         min: 0,
         title: {
            text: 'Hours'
         }
      },
        plotOptions: {
         series: {
            stacking: 'normal'

         }
      },ip: {
         formatter: function() {
            return ''+
               this.x +': '+ this.y +' Hours';
         }
      },

      credits: {
         text: '',
         href: ''
      },

      exporting: {
         enabled: true,
         filename: 'Project-Hours'
      },

      plotOptions: {
         column: {
            pointPadding: 0.3,
            borderWidth: 0
         }
      },

      series: [
      <% @users_projects.each do |users_project| %>
                <% if !users_project.user.nil? && current_user.full_name == users_project.user.full_name %>
                  <% @data.each do |data| %>
            <% if data[ :values ] == [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] %>
            <% else %>
              <% if data[ :name ] == users_project.project.project_name %>
              {
                name: '<%= data[ :name ] %>',
                data: [
                <% data[ :values ].each do |value| %>
                 <%= value %>,
                <% end %>
                ]
              },
              <% end %>
          <% end %>
                <% end %>
      <% else %>
      <% end %>
            <% end %>
      ]
};
</script>

What would be the best way to approach this?

Answers:

Answer

In onSelect callback of datepickers, you should validate, if both #from and #to are selected (or provide sensible defaults if not) and at the end fire and xhr request to server to get new series of data.

onSelect: function( selectedDate ) {
  var option = this.id == "from" ? "minDate" : "maxDate",
  instance = $( this ).data( "datepicker" ),
    date = $.datepicker.parseDate(
      instance.settings.dateFormat || $.datepicker._defaults.dateFormat,
      selectedDate,
      instance.settings
    );
    dates.not( this ).datepicker( "option", option, date );

    // validate if we have both dates and get new series from server
    if ($(dates[0]).datepicker("getDate") &&
        $(dates[1]).datepicker("getDate")) {
      $.ajax({
        type: 'POST',
        url: '<%= user_projects_path(params[:user_id]) %>',
        data: {"from": $(dates[0]).datepicker("getDate"), "to" : $(dates[1]).datepicker("getDate") },
        success: function(data) {
          // now we have new series of data to display in graph
          // we remove the old one, add the new and redraw the chart
          for(var i=0; i<chart.series.length; i++) {
            chart.get(chart.series[i].options.id).remove();
          }

          // fiddle with json data from xhr response to form valid series
          var series = data; 
          chart.addSeries(series, true); // second param says we want to redraw chart
        }
      });
    }
}

Controller method under user_projects_path url needs to exists and return JSON formatted series data for given user_id of course. You can filter your series data before returning with params sent by jquery xhr request (from and to).

Quick and dirty solution but I hope you got the point...

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.