diff --git a/tracks/app/controllers/stats_controller.rb b/tracks/app/controllers/stats_controller.rb
index 97762d26..402214f1 100755
--- a/tracks/app/controllers/stats_controller.rb
+++ b/tracks/app/controllers/stats_controller.rb
@@ -1,5 +1,7 @@
class StatsController < ApplicationController
+ helper :todos
+
append_before_filter :init, :exclude => []
def index
@@ -9,12 +11,6 @@ class StatsController < ApplicationController
@hidden_contexts = @contexts.find(:all, {:conditions => ["hide = ? ", true]})
@first_action = @actions.find(:first, :order => "created_at ASC")
- # default chart dimensions
- @chart_width=460
- @chart_height=250
- @pie_width=@chart_width
- @pie_height=325
-
get_stats_actions
get_stats_contexts
get_stats_projects
@@ -27,7 +23,7 @@ class StatsController < ApplicationController
@actions = @user.todos
# get actions created and completed in the past 12+3 months. +3 for running
- # average
+ # average
@actions_done_last12months = @actions.find(:all, {
:select => "completed_at",
:conditions => ["completed_at > ? AND completed_at IS NOT NULL", @cut_off_year_plus3]
@@ -38,8 +34,8 @@ class StatsController < ApplicationController
})
# convert to hash to be able to fill in non-existing days in
- # @actions_done_last12months and count the total actions done in the past 12
- # months to be able to calculate percentage
+ # @actions_done_last12months and count the total actions done in the past
+ # 12 months to be able to calculate percentage
# use 0 to initialise action count to zero
@actions_done_last12months_hash = Hash.new(0)
@@ -50,8 +46,8 @@ class StatsController < ApplicationController
end
# convert to hash to be able to fill in non-existing days in
- # @actions_created_last12months and count the total actions done in the past
- # 12 months to be able to calculate percentage
+ # @actions_created_last12months and count the total actions done in the
+ # past 12 months to be able to calculate percentage
# use 0 to initialise action count to zero
@actions_created_last12months_hash = Hash.new(0)
@@ -76,7 +72,8 @@ class StatsController < ApplicationController
end
# find running avg for month i by calculating avg of month i and the two
- # after them. Ignore current month because you do not have full data for it
+ # after them. Ignore current month because you do not have full data for
+ # it
@actions_done_avg_last12months_hash = Hash.new("null")
1.upto(12) { |i|
@actions_done_avg_last12months_hash[i] = (@actions_done_last12months_hash[i] +
@@ -85,7 +82,8 @@ class StatsController < ApplicationController
}
# find running avg for month i by calculating avg of month i and the two
- # after them. Ignore current month because you do not have full data for it
+ # after them. Ignore current month because you do not have full data for
+ # it
@actions_created_avg_last12months_hash = Hash.new("null")
1.upto(12) { |i|
@actions_created_avg_last12months_hash[i] = (@actions_created_last12months_hash[i] +
@@ -120,8 +118,8 @@ class StatsController < ApplicationController
})
# convert to hash to be able to fill in non-existing days in
- # @actions_done_last30days and count the total actions done in the past 30
- # days to be able to calculate percentage
+ # @actions_done_last30days and count the total actions done in the past 30
+ # days to be able to calculate percentage
@sum_actions_done_last30days=0
# use 0 to initialise action count to zero
@@ -136,8 +134,8 @@ class StatsController < ApplicationController
end
# convert to hash to be able to fill in non-existing days in
- # @actions_done_last30days and count the total actions done in the past 30
- # days to be able to calculate percentage
+ # @actions_done_last30days and count the total actions done in the past 30
+ # days to be able to calculate percentage
@sum_actions_created_last30days=0
# use 0 to initialise action count to zero
@@ -166,7 +164,7 @@ class StatsController < ApplicationController
})
# convert to hash to be able to fill in non-existing days in
- # @actions_completion_time also convert days to weeks (/7)
+ # @actions_completion_time also convert days to weeks (/7)
@max_days, @max_actions, @sum_actions=0,0,0
@actions_completion_time_hash = Hash.new(0)
@@ -193,7 +191,7 @@ class StatsController < ApplicationController
})
# convert to hash to be able to fill in non-existing days in
- # @actions_running_time also convert days to weeks (/7)
+ # @actions_running_time also convert days to weeks (/7)
@max_days, @max_actions, @sum_actions=0,0,0
@actions_running_time_hash = Hash.new(0)
@@ -215,11 +213,18 @@ class StatsController < ApplicationController
end
def actions_visible_running_time_data
+ # running means
+ # - not completed (completed_at must be null) visible means
+ # - actions not part of a hidden project
+ # - actions not part of a hidden context
+ # - actions not deferred (show_from must be null)
+
@actions_running_time = @actions.find_by_sql([
"SELECT t.created_at "+
"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=? "+
- "AND t.completed_at is null " +
+ "AND t.completed_at IS NULL " +
+ "AND t.show_from IS NULL " +
"AND NOT (p.state='hidden' OR c.hide=?) " +
"ORDER BY t.created_at ASC", @user.id, true]
)
@@ -248,9 +253,9 @@ class StatsController < ApplicationController
def context_total_actions_data
- # get total action count per context
- # Went from GROUP BY c.id to c.name for compatibility with postgresql. Since
- # the name is forced to be unique, this should work.
+ # get total action count per context Went from GROUP BY c.id to c.name for
+ # compatibility with postgresql. Since the name is forced to be unique, this
+ # should work.
@all_actions_per_context = @contexts.find_by_sql(
"SELECT c.name AS name, c.id as id, count(*) AS total "+
"FROM contexts c, todos t "+
@@ -456,6 +461,79 @@ class StatsController < ApplicationController
render :layout => false
end
+
+ def show_selected_actions_from_chart
+ @page_title = "TRACKS::Action selection"
+ @count = 99
+
+ @source_view = 'stats'
+
+ case params['id']
+ when 'avrt', 'avrt_end' # actions_visible_running_time
+
+ # HACK: because open flash chart uses & to denote the end of a parameter,
+ # we cannot use URLs with multiple parameters (that would use &). So we
+ # revert to using two id's for the same selection. avtr_end means that the
+ # last bar of the chart is selected. avtr is used for all other bars
+
+ week_from = params['index'].to_i
+ week_to = week_from+1
+
+ @chart_name = "actions_visible_running_time_data"
+ @page_title = "Actions selected from week "
+ if params['id'] == 'avrt_end'
+ @page_title += week_from.to_s + " and further"
+ else
+ @page_title += week_from.to_s + " - " + week_to.to_s + ""
+ end
+
+ # get all running actions that are visible
+ @actions_running_time = @actions.find_by_sql([
+ "SELECT t.id, t.created_at "+
+ "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=? "+
+ "AND t.completed_at IS NULL " +
+ "AND t.show_from IS NULL " +
+ "AND NOT (p.state='hidden' OR c.hide=?) " +
+ "ORDER BY t.created_at ASC", @user.id, true]
+ )
+
+ @selected_todo_ids = ""
+
+ @count=0
+ @actions_running_time.each do |r|
+ days = (@today - r.created_at) / @seconds_per_day
+ weeks = (days/7).to_i
+ if params['id'] == 'avrt_end'
+ if weeks >= week_from
+ @selected_todo_ids += r.id.to_s+","
+ @count+=1
+ end
+ else
+ if weeks.between?(week_from, week_to-1)
+ @selected_todo_ids += r.id.to_s+","
+ @count+=1
+ end
+ end
+ end
+
+ # strip trailing comma
+ @selected_todo_ids = @selected_todo_ids[0..@selected_todo_ids.length-2]
+
+ @actions = @user.todos
+
+ # get actions created and completed in the past 12+3 months. +3 for
+ # running average
+ @selected_actions = @actions.find(:all, {
+ :conditions => "id in (" + @selected_todo_ids + ")"
+ })
+
+ render :action => "show_selection_from_chart"
+ else
+ # render error
+ render_failure "404 NOT FOUND. Unknown query selected"
+ end
+ end
private
@@ -464,6 +542,12 @@ class StatsController < ApplicationController
@projects = @user.projects
@contexts = @user.contexts
@tags = @user.tags
+
+ # default chart dimensions
+ @chart_width=460
+ @chart_height=250
+ @pie_width=@chart_width
+ @pie_height=325
# get the current date wih time set to 0:0
now = Time.new
@@ -535,8 +619,8 @@ class StatsController < ApplicationController
def get_stats_contexts
# get action count per context for TOP 5
#
- # Went from GROUP BY c.id to c.id, c.name for compatibility with postgresql. Since
- # the name is forced to be unique, this should work.
+ # Went from GROUP BY c.id to c.id, c.name for compatibility with postgresql.
+ # Since the name is forced to be unique, this should work.
@actions_per_context = @contexts.find_by_sql(
"SELECT c.id AS id, c.name AS name, count(*) AS total "+
"FROM contexts c, todos t "+
@@ -548,8 +632,8 @@ class StatsController < ApplicationController
# get uncompleted action count per visible context for TOP 5
#
- # Went from GROUP BY c.id to c.id, c.name for compatibility with postgresql. Since
- # the name is forced to be unique, this should work.
+ # Went from GROUP BY c.id to c.id, c.name for compatibility with postgresql.
+ # Since the name is forced to be unique, this should work.
@running_actions_per_context = @contexts.find_by_sql(
"SELECT c.id AS id, c.name AS name, count(*) AS total "+
"FROM contexts c, todos t "+
diff --git a/tracks/app/helpers/todos_helper.rb b/tracks/app/helpers/todos_helper.rb
index 1cadbb36..44da0bba 100644
--- a/tracks/app/helpers/todos_helper.rb
+++ b/tracks/app/helpers/todos_helper.rb
@@ -103,10 +103,10 @@ module TodosHelper
str += @todo.project.name unless should_suppress_project
str = "(#{str})" unless str.blank?
else
- if (['project', 'tag'].include?(parent_container_type))
+ if (['project', 'tag', 'stats'].include?(parent_container_type))
str << item_link_to_context( @todo )
end
- if (['context', 'tickler', 'tag'].include?(parent_container_type)) && @todo.project_id
+ if (['context', 'tickler', 'tag', 'stats'].include?(parent_container_type)) && @todo.project_id
str << item_link_to_project( @todo )
end
end
@@ -191,6 +191,7 @@ module TodosHelper
def parent_container_type
return 'tickler' if source_view_is :deferred
return 'project' if source_view_is :project
+ return 'stats' if source_view_is :stats
return 'context'
end
diff --git a/tracks/app/views/stats/actions_visible_running_time_data.rhtml b/tracks/app/views/stats/actions_visible_running_time_data.rhtml
index 709d96e2..007344cd 100755
--- a/tracks/app/views/stats/actions_visible_running_time_data.rhtml
+++ b/tracks/app/views/stats/actions_visible_running_time_data.rhtml
@@ -11,6 +11,9 @@
@sum=0
@count.upto((@max_days/7).to_i) { |i| @sum += @actions_running_time_hash[i] } -%>
<%=@sum%>&
+&links=<%
+0.upto(@count-1) { |i| %><%= url_for :controller => 'stats', :action => 'show_selected_actions_from_chart', :index => i, :id=> "avrt" %>, <% }
+%><%= url_for :controller => 'stats', :action => 'show_selected_actions_from_chart', :index => @count, :id=> "avrt_end" %>&
&line_2=2,0xFF0000&
&values_2=
<% total=0
diff --git a/tracks/app/views/stats/show_selection_from_chart.rhtml b/tracks/app/views/stats/show_selection_from_chart.rhtml
new file mode 100644
index 00000000..2ef5f4ec
--- /dev/null
+++ b/tracks/app/views/stats/show_selection_from_chart.rhtml
@@ -0,0 +1,18 @@
+<%= render :partial => 'chart', :locals => {:width => @chart_width, :height => @chart_height, :data => url_for(:action => @chart_name)} -%>
+
+
Click on a bar in the chart to update the actions below. Click <%=link_to "here", {:controller => "stats", :action => "index"} %> to return to the statistics page
+