Ask A Question

Notifications

You’re not receiving notifications from this thread.

Group records by month to display in a chart

Francisco Quinones asked in General

Hi Chris Im using HighChart and I have some data that want to display in group by month.

Reply

You may have to adjust the hashes for HighCharts, but the groupdate gem is pretty good for this. It was designed for the Chartkick gem. https://github.com/ankane/groupdate

Reply

more details of my problem. Im looking for a way to make the code more dry, has I need to display all the Task, and Task by status. So your getting a bar chart with Task complete, Task Pending and Task cancel. With this code I can display alll task. so now how can I use this code but to display each status on the chart. without duplicating the code.

Controller

@months = Array.new
@total_tasks = Array.new
@tasks = Task.group_by { |t| t.start_date.strftime("%B/%Y")} 
@tasks.reverse_each do |key, value|
    @months << key
    @total_tasks << value.size
end

With this line I get the same output

   Task.group_by_month(:date, format: "%b %Y").count

VIEW

<div id="chart_tasks" style="min-width: 210px; max-width: auto; height: 400px; margin: 0 auto"></div>
<%= javascript_tag do %>
   window.months = JSON.parse('<%= raw @months%>')
   window.total_tasks = JSON.parse('<%= raw @total_tasks%>')
<% end %>

$(function () {
    $('#chart_tasks').highcharts({

        xAxis: {
            categories: months
        }, 

        series: [{
                name: ' Task Total',
                type: 'column', 
                data: total_tasks,
                dataLabels: {
                        enabled: true,
                        color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'black'
                    }
            }
    });
});
Reply

I think you'll need to filter the array of tasks for each status, create variables for each of those, and then pass those in as different series to your chart.

Reply
    @finish , @unfinish = [], []
@tasks.each do |t|
    @finish << t if t.status == 'Complete'
    @unfinish << t if t.status == 'Cancel'
end
Reply

You can make that a bit easier if you do select too:

@tasks      = Task.group_by { |t| t.start_date.strftime("%B/%Y")} 
@finished   = @task.select{ |task| task.status == 'Complete' }
@unfinished = @task.select{ |task| task.status == 'Cancel' }
Reply

Nice more clean love it what I was looking. Chris Thank you for all the help for the pass few months. my app looks great with all the help.

Reply

You're welcome man! :)

Reply

Chris can I use any of this scope for that??

scope :cancel, lambda {where(:status => "Cancelada")}
scope :unfinish, lambda {where(:status => "Expirada")}
scope :pending, lambda {where(:status => "Pendiente")}
scope :finish, lambda {where(:status => "Completada")}
scope :transfer, lambda {where(:move_task => true)}
Reply

Yup! I would recommend doing scopes for this for sure.

Reply

Chris if I do.
@tasks = Task.group_by { |t| t.start_date.strftime("%B/%Y")}
@finished = @tasks.select{ |task| task.status == 'Complete' }

I get a error

   NoMethodError: undefined method `status' for "November/2015":String
from (irb):136:in `block in irb_binding'
from (irb):136:in `select'

I think that @tasks its using a K,V and when im reading the .select{ |task| task.status} its doing this

 k = "November/2015"
 k.status
Reply

Ah yeah, your group_by is going to give you a hash. You probably want to do group_bys on those after filtering the queries to make it cleaner.

Reply

Chris How can I filter the queries with out duplicating the code so much as Im breaking my head. I like to keep it all dry up and few querys
can you giving me a example of your approach. thankyou.

Reply

I would do something like this (using the group_by_month method from groupdate so it's a bit cleaner).

@tasks    = Task.all.group_by_month(:date, format: "%b %Y").count
@finished = Task.finish.group_by_month(:date, format: "%b %Y").count
@unfinish = Task.unfinish.group_by_month(:date, format: "%b %Y").count
Reply

thankyou thats the best solution.

Reply
Join the discussion
Create an account Log in

Want to stay up-to-date with Ruby on Rails?

Join 86,946+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.