Group records by month to display in a chart
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
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'
}
}
});
});
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.
@finish , @unfinish = [], []
@tasks.each do |t|
@finish << t if t.status == 'Complete'
@unfinish << t if t.status == 'Cancel'
end
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' }
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.
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)}
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
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.
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.
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