diff --git a/tracks/app/controllers/stats_controller.rb b/tracks/app/controllers/stats_controller.rb new file mode 100755 index 00000000..ce68554c --- /dev/null +++ b/tracks/app/controllers/stats_controller.rb @@ -0,0 +1,516 @@ +class StatsController < ApplicationController + + def index + @page_title = 'TRACKS::Statistics' + @projects = @user.projects + @contexts = @user.contexts + @actions = @user.todos + @tags = @user.tags + @unique_tags = @tags.find(:all, {:group=>"tag_id"}) + @hidden_contexts = @contexts.select{ |c| c.hide? } + @first_action = @actions.find(:first, :order => "created_at asc") + + # default chart dimensions + @chart_width=450 + @chart_height=250 + @pie_width=@chart_width + @pie_height=325 + + get_stats_actions + get_stats_contexts + get_stats_projects + get_stats_tags + + render :layout => 'standard' + end + + def actions_done_last12months_data + @actions = @user.todos + + @actions_done_last12months = @actions.count( + :all, { + :group => "period_diff(extract(year_month from now()), extract(year_month from completed_at))", + :conditions => "period_diff(extract(year_month from now()), extract(year_month from completed_at)) <= 12 and not completed_at is null" + }) + @actions_created_last12months = @actions.count(:all, { + :group => "period_diff(extract(year_month from now()), extract(year_month from created_at))", + :conditions => "period_diff(extract(year_month from now()), extract(year_month from created_at)) <= 12" + }) + + # find max count for graph + @max=0 + + # convert to hash to be able to fill in non-existing days in @actions_done_last12months + @sum_actions_done_last12months=0 + @actions_done_last12months_hash = Hash.new(0) + @actions_done_last12months.each do |month, count| + @actions_done_last12months_hash[month] = count + @sum_actions_done_last12months+= count.to_i + if count.to_i > @max + @max = count.to_i + end + end + + @sum_actions_created_last12months=0 + @actions_created_last12months_hash = Hash.new(0) + @actions_created_last12months.each do |month, count| + @actions_created_last12months_hash[month] = count + @sum_actions_created_last12months+= count.to_i + if count.to_i > @max + @max = count.to_i + end + end + + render :layout => false + end + + def actions_done_last30days_data + @actions = @user.todos + + # get count of actions done in the past 30 days. Results in a array of arrays + @actions_done_last30days = @actions.count(:all, { + :group => "datediff(now(), completed_at)", + :conditions => "datediff(now(), completed_at) <= 30 and not completed_at is null" + }) + @actions_created_last30days = @actions.count(:all, { + :group => "datediff(now(), created_at)", + :conditions => "datediff(now(), created_at) <= 30" + }) + + @max=0 + + # convert to hash to be albe to fill in non-existing days in @actions_done_last30days + @sum_actions_done_last30days=0 + + @actions_done_last30days_hash = Hash.new(0) + @actions_done_last30days.each do |day, count| + @actions_done_last30days_hash[day] = count + @sum_actions_done_last30days+= count.to_i + if count.to_i > @max + @max = count.to_i + end + end + + @sum_actions_created_last30days=0 + # convert to hash to be albe to fill in non-existing days in @actions_done_last30days + @actions_created_last30days_hash = Hash.new(0) + @actions_created_last30days.each do |day, count| + @actions_created_last30days_hash[day] = count + @sum_actions_created_last30days+= count.to_i + if count.to_i > @max + @max = count.to_i + end + end + + render :layout => false + end + + def actions_completion_time_data + @actions = @user.todos + + @actions_completion_time = @actions.count(:all, { + :group => "datediff(completed_at, created_at)", + :conditions => "not completed_at is null", :order => "datediff(completed_at, created_at) ASC" + }) + + # convert to hash to be able to fill in non-existing days in @actions_completion_time + # also convert days to weeks (/7) + + @max_days=0 + @max_actions=0 + @actions_completion_time_hash = Hash.new(0) + @actions_completion_time.each do |days, total| + # RAILS_DEFAULT_LOGGER.error("\n" + total.to_s + " - " + days + "\n") + @actions_completion_time_hash[days.to_i/7] = @actions_completion_time_hash[days.to_i/7] + total + if days.to_i > @max_days + @max_days=days.to_i + end + if @actions_completion_time_hash[days.to_i/7] > @max_actions + @max_actions = @actions_completion_time_hash[days.to_i/7] + end + end + + @cut_off = 10 + + render :layout => false + end + + def actions_running_time_data + @actions = @user.todos + + @actions_running_time = @actions.count(:all, { + :group => "datediff(now(), created_at)", + :conditions => "completed_at is null", :order => "datediff(now(), created_at) ASC" + }) + + # convert to hash to be able to fill in non-existing days in @actions_running_time + # also convert days to weeks (/7) + + @max_days=0 + @max_actions=0 + @actions_running_time_hash = Hash.new(0) + @actions_running_time.each do |days, total| + # RAILS_DEFAULT_LOGGER.error("\n" + total.to_s + " - " + days + "\n") + @actions_running_time_hash[days.to_i/7] = @actions_running_time_hash[days.to_i/7] + total + if days.to_i > @max_days + @max_days=days.to_i + end + if @actions_running_time_hash[days.to_i/7] > @max_actions + @max_actions = @actions_running_time_hash[days.to_i/7] + end + end + + # cut off chart at 52 weeks = one year + @cut_off=52 + + render :layout => false + end + + def actions_visible_running_time_data + @actions = @user.todos + + @actions_running_time = @actions.count(:all, { + :group => "datediff(now(), created_at)", + :conditions => "completed_at is null", :order => "datediff(now(), created_at) ASC" + }) + + @actions_running_time = @actions.find_by_sql( + "SELECT datediff(now(), t.created_at) as days, count(*) as total "+ + "FROM todos t LEFT OUTER JOIN projects p ON t.project_id = p.id LEFT OUTER JOIN contexts c ON t.context_id = c.id "+ + "WHERE t.user_id="+@user.id.to_s+" "+ + "AND t.completed_at is null " + + "AND NOT (p.state='hidden' OR c.hide=1) " + + "GROUP BY days ORDER BY days DESC" + ) + + # convert to hash to be able to fill in non-existing days in @actions_running_time + # also convert days to weeks (/7) + + @max_days=0 + @max_actions=0 + @actions_running_time_hash = Hash.new(0) + @actions_running_time.each do |a| + # RAILS_DEFAULT_LOGGER.error("\n" + total.to_s + " - " + days + "\n") + @actions_running_time_hash[a.days.to_i/7] += a.total.to_i + if a.days.to_i > @max_days + @max_days=a.days.to_i + end + if @actions_running_time_hash[a.days.to_i/7] > @max_actions + @max_actions = @actions_running_time_hash[a.days.to_i/7] + end + end + + # cut off chart at 52 weeks = one year + @cut_off=52 + + render :layout => false + end + + + def context_total_actions_data + @contexts = @user.contexts + + # SELECT c.name, c.hide, count(*) as totaal + # FROM contexts c, todos t + # where t.context_id=c.id group by c.id order by totaal desc; + + # get total action count per context + @actions_per_context = @contexts.find_by_sql( + "SELECT c.name as name, count(*) as total "+ + "FROM contexts c, todos t "+ + "WHERE t.context_id=c.id "+ + "AND t.user_id="+@user.id.to_s+" "+ + "GROUP BY c.id ORDER BY total DESC" + ) + + @sum=0 + 0.upto @actions_per_context.size()-1 do |i| + @sum += @actions_per_context[i]['total'].to_i + end + + render :layout => false + end + + def context_running_actions_data + @contexts = @user.contexts + + # SELECT c.name, c.hide, count(*) as totaal + # FROM contexts c, todos t + # where t.context_id=c.id group by c.id order by totaal desc; + + # get uncompleted action count per visible context + @actions_per_context = @contexts.find_by_sql( + "SELECT c.name as name, count(*) as total "+ + "FROM contexts c, todos t "+ + "WHERE t.context_id=c.id AND t.completed_at IS NULL AND NOT c.hide "+ + "AND t.user_id="+@user.id.to_s+" "+ + "GROUP BY c.id ORDER BY total DESC" + ) + + @sum=0 + 0.upto @actions_per_context.size()-1 do |i| + @sum += @actions_per_context[i]['total'].to_i + end + + render :layout => false + end + + def actions_day_of_week_all_data + @actions = @user.todos + + @actions_creation_day = @actions.count(:all, {:group => "dayofweek(created_at)" }) + @actions_completion_day = @actions.count(:all, {:group => "dayofweek(completed_at)", :conditions => "not completed_at is null" }) + + # convert to hash to be able to fill in non-existing days + @max=0 + @actions_creation_day_array = Array.new(7) { |i| 0} + @actions_creation_day.each do |dayofweek, total| + # dayofweek: sunday=1..saterday=7 + @max = total.to_i > @max ? total.to_i : @max + @actions_creation_day_array[dayofweek.to_i-1]=total.to_i + end + + # convert to hash to be able to fill in non-existing days + @actions_completion_day_array = Array.new(7) { |i| 0} + @actions_completion_day.each do |dayofweek, total| + # dayofweek: sunday=1..saterday=7 + @max = total.to_i > @max ? total.to_i : @max + @actions_completion_day_array[dayofweek.to_i-1]=total.to_i + end + + render :layout => false + end + + def actions_day_of_week_30days_data + @actions = @user.todos + + @actions_creation_day = @actions.count( + :all, { + :group => "dayofweek(created_at)", + :conditions => "datediff(now(), created_at) <= 30" + }) + + @actions_completion_day = @actions.count( + :all, {:group => "dayofweek(completed_at)", + :conditions => "not completed_at is null and datediff(now(), created_at) <= 30" + }) + + # convert to hash to be able to fill in non-existing days + @max=0 + @actions_creation_day_array = Array.new(7) { |i| 0} + @actions_creation_day.each do |dayofweek, total| + # dayofweek: sunday=1..saterday=7 + @max = total.to_i > @max ? total.to_i : @max + @actions_creation_day_array[dayofweek.to_i-1]=total.to_i + end + + # convert to hash to be able to fill in non-existing days + @actions_completion_day_array = Array.new(7) { |i| 0} + @actions_completion_day.each do |dayofweek, total| + # dayofweek: sunday=1..saterday=7 + @max = total.to_i > @max ? total.to_i : @max + @actions_completion_day_array[dayofweek.to_i-1]=total.to_i + end + + render :layout => false + end + + def actions_time_of_day_all_data + @actions = @user.todos + + @actions_creation_hour = @actions.count(:all, {:group => "hour(convert_tz(created_at, @@session.time_zone, '+2:00'))" }) + @actions_completion_hour = @actions.count(:all, {:group => "hour(convert_tz(created_at, @@session.time_zone, '+2:00'))", :conditions => "not completed_at is null" }) + + # convert to hash to be able to fill in non-existing days + @max=0 + @actions_creation_hour_array = Array.new(24) { |i| 0} + @actions_creation_hour.each do |hour, total| + @max = total.to_i > @max ? total.to_i : @max + @actions_creation_hour_array[hour.to_i]=total.to_i + end + + # convert to hash to be able to fill in non-existing days + @actions_completion_hour_array = Array.new(24) { |i| 0} + @actions_completion_hour.each do |hour, total| + @max = total.to_i > @max ? total.to_i : @max + @actions_completion_hour_array[hour.to_i]=total.to_i + end + + render :layout => false + end + + def actions_time_of_day_30days_data + @actions = @user.todos + + # TODO: find out how to find current timezone + @actions_creation_hour = @actions.count( + :all, { + :group => "hour(convert_tz(created_at, @@session.time_zone, '+2:00'))", + :conditions => "datediff(now(), created_at) <= 30" + }) + + # TODO: find out how to find current timezone + @actions_completion_hour = @actions.count( + :all, {:group => "hour(convert_tz(completed_at, @@session.time_zone, '+2:00'))", + :conditions => "not completed_at is null and datediff(now(), completed_at) <= 30" + }) + + # convert to hash to be able to fill in non-existing days + @max=0 + @actions_creation_hour_array = Array.new(24) { |i| 0} + @actions_creation_hour.each do |hour, total| + @max = total.to_i > @max ? total.to_i : @max + @actions_creation_hour_array[hour.to_i]=total.to_i + end + + # convert to hash to be able to fill in non-existing days + @actions_completion_hour_array = Array.new(24) { |i| 0} + @actions_completion_hour.each do |hour, total| + @max = total.to_i > @max ? total.to_i : @max + @actions_completion_hour_array[hour.to_i]=total.to_i + end + + render :layout => false + end + + private + + def get_stats_actions + # time to complete + @actions_avg_ttc = @actions.average("datediff(completed_at, created_at)", {:conditions => "not completed_at is null"} ) + @actions_max_ttc = @actions.maximum("datediff(completed_at, created_at)", {:conditions => "not completed_at is null"} ) + @actions_min_ttc = @actions.minimum("datediff(completed_at, created_at)", {:conditions => "not completed_at is null"} ) + @actions_min_ttc_sec = @actions.minimum("timediff(completed_at, created_at)", {:conditions => "not completed_at is null"} ) + + # get count of actions created and actions done in the past 30 days. Results in a array of arrays + @actions_done_last30days = @actions.count(:all, { + :group => "datediff(now(), completed_at)", + :conditions => "datediff(now(), completed_at) <= 30" + }) + @actions_created_last30days = @actions.count(:all, { + :group => "datediff(now(), created_at)", + :conditions => "datediff(now(), created_at) <= 30" + }) + + @sum_actions_done_last30days=0 + # convert to hash to be albe to fill in non-existing days in @actions_done_last30days + @actions_done_last30days_hash = Hash.new(0) + @actions_done_last30days.each do |day, count| + @actions_done_last30days_hash[day] = count + @sum_actions_done_last30days+= count.to_i + end + @sum_actions_created_last30days=0 + # convert to hash to be albe to fill in non-existing days in @actions_done_last30days + @actions_created_last30days_hash = Hash.new(0) + @actions_created_last30days.each do |day, count| + @actions_created_last30days_hash[day] = count + @sum_actions_created_last30days+= count.to_i + end + + # get count of actions done in the past 12 months. Results in a array of arrays + @actions_done_last12months = @actions.count(:all, { + :group => "period_diff(extract(year_month from now()), extract(year_month from completed_at))", + :conditions => "period_diff(extract(year_month from now()), extract(year_month from completed_at)) <= 12 and not completed_at is null" + }) + @actions_created_last12months = @actions.count(:all, { + :group => "period_diff(extract(year_month from now()), extract(year_month from created_at))", + :conditions => "period_diff(extract(year_month from now()), extract(year_month from created_at)) <= 12" + }) + + # convert to hash to be albe to fill in non-existing days in @actions_done_last12months + @sum_actions_done_last12months=0 + @actions_done_last12months_hash = Hash.new(0) + @actions_done_last12months.each do |month, count| + @actions_done_last12months_hash[month] = count + @sum_actions_done_last12months+= count.to_i + end + @sum_actions_created_last12months=0 + @actions_created_last12months_hash = Hash.new(0) + @actions_created_last12months.each do |month, count| + @actions_created_last12months_hash[month] = count + @sum_actions_created_last12months+= count.to_i + end + + end + + def get_stats_contexts + # get action count per context for TOP 5 + @actions_per_context = @contexts.find_by_sql( + "SELECT c.name as name, count(*) as total "+ + "FROM contexts c, todos t "+ + "WHERE t.context_id=c.id "+ + "AND t.user_id="+@user.id.to_s+" "+ + "GROUP BY c.id ORDER BY total DESC " + + "LIMIT 5" + ) + + # get uncompleted action count per visible context for TOP 5 + @running_actions_per_context = @contexts.find_by_sql( + "SELECT c.name as name, count(*) as total "+ + "FROM contexts c, todos t "+ + "WHERE t.context_id=c.id AND t.completed_at IS NULL AND NOT c.hide "+ + "AND t.user_id="+@user.id.to_s+" "+ + "GROUP BY c.id ORDER BY total DESC " + + "LIMIT 5" + ) + end + + def get_stats_projects + # get the first 10 projects and their action count (all actions) + @projects_and_actions = @projects.find_by_sql( + "SELECT p.name, count(*) as count "+ + "FROM projects p, todos t "+ + "WHERE p.id = t.project_id "+ + "AND p.user_id="+@user.id.to_s+" "+ + "GROUP BY p.id "+ + "ORDER BY count DESC " + + "LIMIT 10" + ) + + # get the first 10 projects with their actions count of actions that + # have been created or completed the past 30 days + @projects_and_actions_last30days = @projects.find_by_sql( + "SELECT p.name, count(*) AS count "+ + "FROM todos t, projects p "+ + "WHERE t.project_id = p.id AND "+ + " (datediff(now(), t.created_at) < 30 OR "+ + " datediff(now(), t.completed_at) < 30) "+ + "AND p.user_id="+@user.id.to_s+" "+ + "GROUP BY p.id "+ + "ORDER BY count DESC" + ) + + # get the first 10 projects and their running time (creation date versus now()) + @projects_and_runtime = @projects.find_by_sql( + "SELECT name, datediff(now(),created_at) AS days "+ + "FROM projects p "+ + "WHERE state='active' "+ + "AND p.user_id="+@user.id.to_s+" "+ + "ORDER BY days DESC "+ + "LIMIT 10" + ) + + end + + def get_stats_tags + # todo: parameterize limit + query = "select tags.id, name, count(*) as count" + query << " from taggings, tags" + query << " where tags.id = tag_id" + query << " AND taggings.user_id="+@user.id.to_s+" " + query << " group by tag_id" + query << " order by count DESC, name" + query << " limit 100" + @tags_for_cloud = Tag.find_by_sql(query).sort_by { |tag| tag.name.downcase } + + max, @tags_min = 0, 0 + @tags_for_cloud.each { |t| + max = t.count.to_i if t.count.to_i > max + @tags_min = t.count.to_i if t.count.to_i < @tags_min + } + + # 10 = number of levels + @tags_divisor = ((max - @tags_min) / 10) + 1 + + end +end diff --git a/tracks/app/helpers/stats_helper.rb b/tracks/app/helpers/stats_helper.rb new file mode 100755 index 00000000..65e2f8bb --- /dev/null +++ b/tracks/app/helpers/stats_helper.rb @@ -0,0 +1,2 @@ +module StatsHelper +end diff --git a/tracks/app/views/layouts/standard.rhtml b/tracks/app/views/layouts/standard.rhtml index 6a65dc24..e467511e 100644 --- a/tracks/app/views/layouts/standard.rhtml +++ b/tracks/app/views/layouts/standard.rhtml @@ -55,6 +55,7 @@ window.onload=function(){
Of all your completed actions, the average time to complete is <%= @actions_avg_ttc %> days. +The Max-/minimum days to complete is <%= @actions_max_ttc%>/<%= @actions_min_ttc %>. +The minimum time to complete is <%= @actions_min_ttc_sec %>
+ +In the last 30 days you created on average <%=@sum_actions_created_last30days/30%> actions +and completed on average <%=@sum_actions_done_last30days/30%> actions per day. +In the last 12 months you created on average <%=@sum_actions_created_last12months/12 %> actions +and completed on average <%=@sum_actions_done_last12months/12%> actions per month. +
+<%= render :partial => 'chart', :locals => {:width => @chart_width, :height => @chart_height, :data => '/stats/actions_done_last30days_data'} -%>
+
+<%= render :partial => 'chart', :locals => {:width => @chart_width, :height => @chart_height, :data => '/stats/actions_done_last12months_data'} -%>
+
+
+<%= render :partial => 'chart', :locals => {:width => @chart_width, :height => @chart_height, :data => '/stats/actions_completion_time_data'} -%>
+
+<%= render :partial => 'chart', :locals => {:width => @chart_width, :height => @chart_height, :data => '/stats/actions_visible_running_time_data'} -%>
+
+<%= render :partial => 'chart', :locals => {:width => @chart_width, :height => @chart_height, :data => '/stats/actions_running_time_data'} -%>
+
+
+<%= render :partial => 'chart', :locals => {:width => @chart_width, :height => @chart_height, :data => '/stats/actions_day_of_week_all_data'} -%>
+
+<%= render :partial => 'chart', :locals => {:width => @chart_width, :height => @chart_height, :data => '/stats/actions_day_of_week_30days_data'} -%>
+
+
+<%= render :partial => 'chart', :locals => {:width => @chart_width, :height => @chart_height, :data => '/stats/actions_time_of_day_all_data'} -%>
+
+<%= render :partial => 'chart', :locals => {:width => @chart_width, :height => @chart_height, :data => '/stats/actions_time_of_day_30days_data'} -%>
\ No newline at end of file
diff --git a/tracks/app/views/stats/_chart.rhtml b/tracks/app/views/stats/_chart.rhtml
new file mode 100755
index 00000000..8167023b
--- /dev/null
+++ b/tracks/app/views/stats/_chart.rhtml
@@ -0,0 +1,5 @@
+
diff --git a/tracks/app/views/stats/_contexts.rhtml b/tracks/app/views/stats/_contexts.rhtml
new file mode 100755
index 00000000..ee165c73
--- /dev/null
+++ b/tracks/app/views/stats/_contexts.rhtml
@@ -0,0 +1,30 @@
+
+<%= render :partial => 'chart', :locals => {:width => @pie_width, :height => @pie_height, :data => '/stats/context_total_actions_data'} -%>
+
+<%= render :partial => 'chart', :locals => {:width => @pie_width, :height => @pie_height, :data => '/stats/context_running_actions_data'} -%>
+
+
Top 5 Contexts
+<%
+ 1.upto 5 do |i|
+ %><%=i-%> -
+ <%= i <= @actions_per_context.size ? @actions_per_context[i-1]['name'] : "n/a"%>
+ (
+ <%= i <= @actions_per_context.size ? @actions_per_context[i-1]['total'] : "n/a"%>
+ )
+
<%
+ end
+-%>
+
Top 5 Visible Contexts with uncomplete actions
+<%
+ 1.upto 5 do |i|
+ %><%=i-%> -
+ <%= i <= @running_actions_per_context.size ? @running_actions_per_context[i-1]['name'] : "n/a"-%>
+ (
+ <%= i <= @running_actions_per_context.size ? @running_actions_per_context[i-1]['total'] : "n/a"-%>
+ )
+
<%
+ end
+-%>
+
Top 10 projects
+<% i=0
+ @projects_and_actions.each do |p|
+ i+=1 -%>
+ <%= i -%> - <%= p.name %> (<%=p.count %> actions)
+<% end
+ if i < 10
+ i.upto 10 do |j| %>
+ <%= i -%> - n/a (n/a)
+ <% end
+ end
+%>
+
+
+
Top 10 project in past 30 days
+<% i=0
+ @projects_and_actions_last30days.each do |p|
+ i+=1 -%>
+ <%= i -%> - <%= p.name %> (<%=p.count %> actions)
+<% end
+ if i < 10
+ i.upto 10 do |j| %>
+ <%= i -%> - n/a (n/a)
+ <% end
+ end
+%>
+
+
+
Top 10 longest running projects
+<% i=0
+ @projects_and_runtime.each do |p|
+ i+=1 -%>
+ <%= i -%> - <%= p.name %> (<%=p.days %> days)
+<% end
+ if i < 10
+ i.upto 10 do |j| %>
+ <%= i -%> - n/a (n/a)
+ <% end
+ end
+%>
+
\ No newline at end of file
diff --git a/tracks/app/views/stats/_tags.rhtml b/tracks/app/views/stats/_tags.rhtml
new file mode 100755
index 00000000..26b9e989
--- /dev/null
+++ b/tracks/app/views/stats/_tags.rhtml
@@ -0,0 +1,15 @@
+
+
Tag Cloud
++ <% if @tags_for_cloud.size < 1 + %> no tags available <% + else + @tags_for_cloud.each do |t| %> + <%= link_to t.name, + {:controller => "todos", :action => "tag", :id => t.name}, + {:style => "font-size: " + (9 + 2*(t.count.to_i-@tags_min)/@tags_divisor).to_s + "pt", + :title => t.count+" actions"} + -%> <% + end + end-%> +
\ No newline at end of file diff --git a/tracks/app/views/stats/_totals.rhtml b/tracks/app/views/stats/_totals.rhtml new file mode 100755 index 00000000..5fc50382 --- /dev/null +++ b/tracks/app/views/stats/_totals.rhtml @@ -0,0 +1,13 @@ +You have <%= @projects.count%> projects. +Of those <%= @projects.count(:conditions => "state = 'active'")%> are active projects, +<%= @projects.count(:conditions => "state = 'hidden'")%> hidden projects and +<%= @projects.count(:conditions => "state = 'completed'")%> completed projects
+ +You have <%= @contexts.count%> contexts. +Of those <%= @contexts.count(:conditions => "hide = 'false'")%> are visible contexts and +<%= @contexts.count(:conditions => "hide = 'true'") %> are hidden contexts + +
You have <%= @actions.reject{ |t| t.completed? }.length %> uncompleted actions of which +<%= @actions.select{ |t| t.deferred? }.length %> are deferred actions. +
Since your first action on <%= format_date(@first_action.created_at) %> you have a total of <%= @actions.count %> actions. <%= @actions.select { |t| t.completed? }.length %> of these are completed. +
You have <%= @tags.count-%> tags placed on actions. Of those tags, <%= @unique_tags.size -%> are unique. \ No newline at end of file diff --git a/tracks/app/views/stats/actions_completion_time_data.rhtml b/tracks/app/views/stats/actions_completion_time_data.rhtml new file mode 100755 index 00000000..2065c6f0 --- /dev/null +++ b/tracks/app/views/stats/actions_completion_time_data.rhtml @@ -0,0 +1,26 @@ +&title=Completion time (all completed actions),{font-size:16},& +&y_legend=Actions,12,0x736AFF& +&x_legend=Running time of an action (weeks),12,0x736AFF& +&y_ticks=5,10,5& +&filled_bar=50,0x9933CC,0x8010A0& +&values= +<% @count = @max_days > @cut_off*7 ? @cut_off : @max_days/7 + 0.upto @count-1 do |i| -%> +<%= @actions_completion_time_hash[i] -%>, +<% end -%> +<% + @sum=0 + @count.upto @max_days/7 do |i| + @sum += @actions_completion_time_hash[i] + end -%> +<%=@sum%>& +&x_labels=within 1, +<% 1.upto @count-1 do |i| -%> +<%= i %>-<%= i+1 %>, +<% end -%> +> <%= @count %>& +&y_min=0& +<% # add one to @max for people who have no actions completed yet. + # OpenFlashChart cannot handle y_max=0 -%> +&y_max=<%=1+@max_actions+@max_actions/10-%>& +&x_label_style=9,,2,1& \ No newline at end of file diff --git a/tracks/app/views/stats/actions_day_of_week_30days_data.rhtml b/tracks/app/views/stats/actions_day_of_week_30days_data.rhtml new file mode 100755 index 00000000..9505652e --- /dev/null +++ b/tracks/app/views/stats/actions_day_of_week_30days_data.rhtml @@ -0,0 +1,23 @@ +&title=Day of week (past 30 days),{font-size:16},& +&y_legend=Number of actions,12,0x736AFF& +&x_legend=Day of week,12,0x736AFF& +&y_ticks=5,10,5& +&filled_bar=50,0x9933CC,0x8010A0,Created,8& +&filled_bar_2=50,0x0066CC,0x0066CC,Completed,8& +&values=<% +0.upto 5 do |i| -%> + <%=@actions_creation_day_array[i] -%>, +<% end -%><%=@actions_creation_day_array[6]%>& +&values_2=<% +0.upto 5 do |i| -%> + <%=@actions_completion_day_array[i] -%>, +<% end -%><%=@actions_completion_day_array[6]%>& +&x_labels= <% +0.upto 5 do |i| -%> + <%=Date::DAYNAMES[i] -%>, +<% end -%><%=Date::DAYNAMES[6]%>& +&y_min=0& +<% # add one to @max for people who have no actions completed yet. + # OpenFlashChart cannot handle y_max=0 -%> +&y_max=<%=@max+1 -%>& +&x_label_style=9,,2,1& \ No newline at end of file diff --git a/tracks/app/views/stats/actions_day_of_week_all_data.rhtml b/tracks/app/views/stats/actions_day_of_week_all_data.rhtml new file mode 100755 index 00000000..fee11d73 --- /dev/null +++ b/tracks/app/views/stats/actions_day_of_week_all_data.rhtml @@ -0,0 +1,23 @@ +&title=Day of week (all actions),{font-size:16},& +&y_legend=Number of actions,12,0x736AFF& +&x_legend=Day of week,12,0x736AFF& +&y_ticks=5,10,5& +&filled_bar=50,0x9933CC,0x8010A0,Created,8& +&filled_bar_2=50,0x0066CC,0x0066CC,Completed,8& +&values=<% +0.upto 5 do |i| -%> + <%=@actions_creation_day_array[i] -%>, +<% end -%><%=@actions_creation_day_array[6]%>& +&values_2=<% +0.upto 5 do |i| -%> + <%=@actions_completion_day_array[i] -%>, +<% end -%><%=@actions_completion_day_array[6]%>& +&x_labels= <% +0.upto 5 do |i| -%> + <%=Date::DAYNAMES[i] -%>, +<% end -%><%=Date::DAYNAMES[6]%>& +&y_min=0& +<% # add one to @max for people who have no actions completed yet. + # OpenFlashChart cannot handle y_max=0 -%> +&y_max=<%=@max+1 -%>& +&x_label_style=9,,2,1& \ No newline at end of file diff --git a/tracks/app/views/stats/actions_done_last12months_data.rhtml b/tracks/app/views/stats/actions_done_last12months_data.rhtml new file mode 100755 index 00000000..e3520071 --- /dev/null +++ b/tracks/app/views/stats/actions_done_last12months_data.rhtml @@ -0,0 +1,27 @@ +&title=Actions in the last 12 months,{font-size:16},& +&y_legend=Number of actions,12,0x736AFF& +&x_legend=Months ago,12,0x736AFF& +&y_ticks=5,10,5& +&filled_bar=50,0x9933CC,0x8010A0,Completed,9& +&filled_bar_2=50,0x0066CC,0x0066CC,Created,9& +&line_3=3,0xFF0000, Avg completed, 9& +&line_4=3,0x00FF00, Avg created, 9& +&values= +<% 0.upto 11 do |i| -%> +<%= @actions_done_last12months_hash[i.to_s]%>, +<% end -%><%= @actions_done_last12months_hash["12"]%>& +&values_2= +<% 0.upto 11 do |i| -%> +<%= @actions_created_last12months_hash[i.to_s]%>, +<% end -%><%= @actions_created_last12months_hash["12"]%>& +&values_3=<%0.upto 11 do |i| -%><%=@sum_actions_done_last12months/12-%>,<%end-%><%=@sum_actions_done_last12months/12-%>& +&values_4=<%0.upto 11 do |i| -%><%=@sum_actions_created_last12months/12-%>,<%end-%><%=@sum_actions_created_last12months/12-%>& +&x_labels=<%0.upto 11 do |i| -%> +<%= Date::MONTHNAMES[ (Time.now.mon - i -1 ) % 12 + 1 ] -%>, +<% end -%> +<%= Date::MONTHNAMES[(Time.now.mon - 12 -1 ) % 12 + 1] -%>& +&y_min=0& +<% # add one to @max for people who have no actions completed yet. + # OpenFlashChart cannot handle y_max=0 -%> +&y_max=<%=@max+@max/10+1-%>& +&x_label_style=9,,2,& \ No newline at end of file diff --git a/tracks/app/views/stats/actions_done_last12monthsdata.rhtml b/tracks/app/views/stats/actions_done_last12monthsdata.rhtml new file mode 100755 index 00000000..75399b1e --- /dev/null +++ b/tracks/app/views/stats/actions_done_last12monthsdata.rhtml @@ -0,0 +1,18 @@ +&title=Actions completed in the last 12 months,16,& +&y_legend=Number of actions,12,0x736AFF& +&x_legend=Months ago,12,0x736AFF& +&y_ticks=5,10,5& +&filled_bar=50,0x9933CC,0x8010A0& +&line_2=3,0xFF0000& +&values= +<% 0.upto 11 do |i| -%> +<%= @actions_done_last12months_hash[i.to_s]%>, +<% end -%><%= @actions_done_last12months_hash["12"]%>& +&values_2=<%0.upto 11 do |i| -%><%=@sum_actions_done_last12months/12-%>,<%end-%><%=@sum_actions_done_last12months/12-%>& +&x_labels=<%0.upto 11 do |i| -%> +<%= Date::MONTHNAMES[ (Time.now.mon - i -1 ) % 12 + 1 ] -%>, +<% end -%> +<%= Date::MONTHNAMES[(Time.now.mon - 12 -1 ) % 12 + 1] -%>& +&y_min=0& +&y_max=<%=@max-%>& +&x_label_style=9,,2,& \ No newline at end of file diff --git a/tracks/app/views/stats/actions_done_last30days_data.rhtml b/tracks/app/views/stats/actions_done_last30days_data.rhtml new file mode 100755 index 00000000..c333da31 --- /dev/null +++ b/tracks/app/views/stats/actions_done_last30days_data.rhtml @@ -0,0 +1,42 @@ +&title=Actions in the last 30 days,{font-size:16},& +&y_legend=Number of actions,12,0x736AFF& +&x_legend=Number of days ago,12,0x736AFF& +&y_ticks=5,10,5& +&filled_bar=50,0x9933CC,0x8010A0,Completed,9& +&filled_bar_2=50,0x0066CC,0x0066CC,Created,9& +&line_3=3,0xFF0000, Avg completed, 9& +&line_4=3,0x00FF00, Avg created, 9& +&values= +<% 0.upto 29 do |i| -%> +<%= @actions_done_last30days_hash[i.to_s]%>, +<% end -%><%= @actions_done_last30days_hash["30"]%>& +&values_2= +<% 0.upto 29 do |i| -%> +<%= @actions_created_last30days_hash[i.to_s]%>, +<% end -%><%= @actions_created_last30days_hash["30"]%>& +&values_3= +<%0.upto 29 do |i| -%> +<%=@sum_actions_done_last30days/30-%>, +<%end-%> +<%=@sum_actions_done_last30days/30-%>& +&values_4= +<%0.upto 29 do |i| -%> +<%=@sum_actions_created_last30days/30-%>, +<%end-%> +<%=@sum_actions_created_last30days/30-%>& +&x_labels= +<%0.upto 29 do |i| + seconds = i * 24 * 60 * 60 + delta = Time.now-seconds +-%> +<%= delta.strftime("%a %d-%m") -%>, +<% end + seconds = 29*25*60*60 + delta = Time.now-seconds-%> +<%= delta.strftime("%a %d-%m") -%>& +&y_min=0& +<% # max + 10% for some extra space at the top + # add one to @max for people who have no actions completed yet. + # OpenFlashChart cannot handle y_max=0 -%> +&y_max=<%=@max+@max/10+1 -%>& +&x_label_style=9,,2,3& \ No newline at end of file diff --git a/tracks/app/views/stats/actions_done_last30daysdata.rhtml b/tracks/app/views/stats/actions_done_last30daysdata.rhtml new file mode 100755 index 00000000..4f2ff047 --- /dev/null +++ b/tracks/app/views/stats/actions_done_last30daysdata.rhtml @@ -0,0 +1,28 @@ +&title=Actions completed in the last 30 days,16,& +&y_legend=Number of actions,12,0x736AFF& +&x_legend=Number of days ago,12,0x736AFF& +&y_ticks=5,10,5& +&filled_bar=50,0x9933CC,0x8010A0& +&line_2=3,0xFF0000& +&values= +<% 0.upto 29 do |i| -%> +<%= @actions_done_last30days_hash[i.to_s]%>, +<% end -%><%= @actions_done_last30days_hash["30"]%>& +&values_2= +<%0.upto 29 do |i| -%> +<%=@sum_actions_done_last30days/30-%>, +<%end-%> +<%=@sum_actions_done_last30days/30-%>& +&x_labels= +<%0.upto 29 do |i| + seconds = i * 24 * 60 * 60 + delta = Time.now-seconds +-%> +<%= delta.strftime("%a %d-%m") -%>, +<% end + seconds = 29*25*60*60 + delta = Time.now-seconds-%> +<%= delta.strftime("%a %d-%m") -%>& +&y_min=0& +&y_max=<%=@max -%>& +&x_label_style=9,,2,3& \ No newline at end of file diff --git a/tracks/app/views/stats/actions_running_time_data.rhtml b/tracks/app/views/stats/actions_running_time_data.rhtml new file mode 100755 index 00000000..30f3c651 --- /dev/null +++ b/tracks/app/views/stats/actions_running_time_data.rhtml @@ -0,0 +1,27 @@ +&title=Current running time of all uncompleted actions,{font-size:16},& +&y_legend=Actions,12,0x736AFF& +&x_legend=Running time of an action (weeks),12,0x736AFF& +&y_ticks=5,10,5& +&filled_bar=50,0x9933CC,0x8010A0& +&values= +<% @count = @max_days > @cut_off*7 ? @cut_off : @max_days/7 + 0.upto @count-1 do |i| -%> +<%= @actions_running_time_hash[i] -%>, +<% end -%> +<% + @sum=0 + @count.upto @max_days/7 do |i| + @sum += @actions_running_time_hash[i] + end -%> +<%=@sum%>& +&x_labels=< 1, +<% 1.upto @count-1 do |i| -%> +<%= i %>-<%= i+1 %>, +<% end -%> +><%=@count-%>& +&y_min=0& +<% @max_actions = @sum > @max_actions ? @sum : @max_actions -%> +<% # add one to @max for people who have no actions completed yet. + # OpenFlashChart cannot handle y_max=0 -%> +&y_max=<%=1+@max_actions+@max_actions/10-%>& +&x_label_style=9,,2,2& diff --git a/tracks/app/views/stats/actions_time_of_day_30days_data.rhtml b/tracks/app/views/stats/actions_time_of_day_30days_data.rhtml new file mode 100755 index 00000000..12a459c2 --- /dev/null +++ b/tracks/app/views/stats/actions_time_of_day_30days_data.rhtml @@ -0,0 +1,23 @@ +&title=Time of day (last 30 days),{font-size:16},& +&y_legend=Number of actions,12,0x736AFF& +&x_legend=Time of Day,12,0x736AFF& +&y_ticks=5,10,5& +&filled_bar=50,0x9933CC,0x8010A0,Created,8& +&filled_bar_2=50,0x0066CC,0x0066CC,Completed,8& +&values=<% +0.upto 22 do |i| -%> + <%=@actions_creation_hour_array[i] -%>, +<% end -%><%=@actions_creation_hour_array[23]%>& +&values_2=<% +0.upto 22 do |i| -%> + <%=@actions_completion_hour_array[i] -%>, +<% end -%><%=@actions_completion_hour_array[23]%>& +&x_labels= <% +0.upto 22 do |i| -%> + <%=i-%>, +<% end -%>23& +&y_min=0& +<% # add one to @max for people who have no actions completed yet. + # OpenFlashChart cannot handle y_max=0 -%> +&y_max=<%=@max+1 -%>& +&x_label_style=9,,1,1& \ No newline at end of file diff --git a/tracks/app/views/stats/actions_time_of_day_all_data.rhtml b/tracks/app/views/stats/actions_time_of_day_all_data.rhtml new file mode 100755 index 00000000..c1b4ff3b --- /dev/null +++ b/tracks/app/views/stats/actions_time_of_day_all_data.rhtml @@ -0,0 +1,23 @@ +&title=Time of day (all actions),{font-size:16},& +&y_legend=Number of actions,12,0x736AFF& +&x_legend=Time of Day,12,0x736AFF& +&y_ticks=5,10,5& +&filled_bar=50,0x9933CC,0x8010A0,Created,8& +&filled_bar_2=50,0x0066CC,0x0066CC,Completed,8& +&values=<% +0.upto 22 do |i| -%> + <%=@actions_creation_hour_array[i] -%>, +<% end -%><%=@actions_creation_hour_array[23]%>& +&values_2=<% +0.upto 22 do |i| -%> + <%=@actions_completion_hour_array[i] -%>, +<% end -%><%=@actions_completion_hour_array[23]%>& +&x_labels= <% +0.upto 22 do |i| -%> + <%=i-%>, +<% end -%>23& +&y_min=0& +<% # add one to @max for people who have no actions completed yet. + # OpenFlashChart cannot handle y_max=0 -%> +&y_max=<%=@max+1 -%>& +&x_label_style=9,,1,1& \ No newline at end of file diff --git a/tracks/app/views/stats/actions_visible_running_time_data.rhtml b/tracks/app/views/stats/actions_visible_running_time_data.rhtml new file mode 100755 index 00000000..8aceae13 --- /dev/null +++ b/tracks/app/views/stats/actions_visible_running_time_data.rhtml @@ -0,0 +1,27 @@ +&title=Current running time of uncompleted visible actions,{font-size:16},& +&y_legend=Actions,12,0x736AFF& +&x_legend=Running time of an action (weeks),12,0x736AFF& +&y_ticks=5,10,5& +&filled_bar=50,0x9933CC,0x8010A0& +&values= +<% @count = @max_days > @cut_off*7 ? @cut_off : @max_days/7 + 0.upto @count-1 do |i| -%> +<%= @actions_running_time_hash[i] -%>, +<% end -%> +<% + @sum=0 + @count.upto @max_days/7 do |i| + @sum += @actions_running_time_hash[i] + end -%> +<%=@sum%>& +&x_labels=< 1, +<% 1.upto @count-1 do |i| -%> +<%= i %>-<%= i+1 %>, +<% end -%> +><%=@count-%>& +&y_min=0& +<% @max_actions = @sum > @max_actions ? @sum : @max_actions -%> +<% # add one to @max for people who have no actions completed yet. + # OpenFlashChart cannot handle y_max=0 -%> +&y_max=<%=1+@max_actions+@max_actions/10-%>& +&x_label_style=9,,2,2& diff --git a/tracks/app/views/stats/context_running_actions_data.rhtml b/tracks/app/views/stats/context_running_actions_data.rhtml new file mode 100755 index 00000000..a174be7e --- /dev/null +++ b/tracks/app/views/stats/context_running_actions_data.rhtml @@ -0,0 +1,16 @@ +&title=Spread of running actions for visible contexts,{font-size:16}& +&pie=60,#505050,#000000,true,1& +&x_axis_steps=1& &y_ticks=5,10,5& &line=3,#87421F& &y_min=0& &y_max=20& +&values=<% +0.upto @actions_per_context.size()-2 do | i | + %><%=@actions_per_context[i]['total'].to_i*100/@sum%>,<% +end +-%><%=@actions_per_context[@actions_per_context.size()-1]['total'].to_i*100/@sum%>& +&pie_labels=<% +0.upto @actions_per_context.size()-2 do | i | + %><%=@actions_per_context[i]['name']%>,<% +end +-%><%=@actions_per_context[@actions_per_context.size()-1]['name']%>& +&colours=#d01f3c,#356aa0,#C79810,#c61fd0,#1fc6d0,#1fd076,#72d01f,#c6d01f,#d0941f& +&tool_tip=#x_label#: #val#%25& +&x_label_style=9,,2,1& \ No newline at end of file diff --git a/tracks/app/views/stats/context_total_actions_data.rhtml b/tracks/app/views/stats/context_total_actions_data.rhtml new file mode 100755 index 00000000..4091fe5b --- /dev/null +++ b/tracks/app/views/stats/context_total_actions_data.rhtml @@ -0,0 +1,16 @@ +&title=Spread of actions for all context,{font-size:16}& +&pie=70,#505050,#000000,true,1& +&x_axis_steps=1& &y_ticks=5,10,5& &line=3,#87421F& &y_min=0& &y_max=20& +&values=<% +0.upto @actions_per_context.size()-2 do | i | + %><%=@actions_per_context[i]['total'].to_i*100/@sum%>,<% +end +-%><%=@actions_per_context[@actions_per_context.size()-1]['total'].to_i*100/@sum%>& +&pie_labels=<% +0.upto @actions_per_context.size()-2 do | i | + %><%=@actions_per_context[i]['name']%>,<% +end +-%><%=@actions_per_context[@actions_per_context.size()-1]['name']%>& +&colours=#d01f3c,#356aa0,#C79810,#c61fd0,#1fc6d0,#1fd076,#72d01f,#c6d01f,#d0941f& +&tool_tip=#x_label#: #val#%25& +&x_label_style=9,,2,1& \ No newline at end of file diff --git a/tracks/app/views/stats/index.rhtml b/tracks/app/views/stats/index.rhtml new file mode 100755 index 00000000..1ffc5357 --- /dev/null +++ b/tracks/app/views/stats/index.rhtml @@ -0,0 +1,23 @@ +