surveyor_gui 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (283) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +44 -0
  3. data/.travis.yml +17 -0
  4. data/Gemfile +7 -0
  5. data/LICENSE +21 -0
  6. data/MIT-LICENSE +20 -0
  7. data/README.md +159 -0
  8. data/Rakefile +66 -0
  9. data/app/controllers/answers_controller.rb +3 -0
  10. data/app/controllers/application_controller.rb +3 -0
  11. data/app/controllers/dependencys_controller.rb +286 -0
  12. data/app/controllers/question_groups_controller.rb +84 -0
  13. data/app/controllers/questions_controller.rb +187 -0
  14. data/app/controllers/survey_sections_controller.rb +80 -0
  15. data/app/controllers/surveyforms_controller.rb +4 -0
  16. data/app/controllers/surveyor_controller.rb +89 -0
  17. data/app/controllers/surveyor_gui/reports_controller.rb +339 -0
  18. data/app/controllers/surveyor_gui/responses_controller.rb +39 -0
  19. data/app/controllers/surveyor_gui/survey_controller.rb +16 -0
  20. data/app/facades/report_formatter.rb +44 -0
  21. data/app/facades/report_preview_wrapper.rb +11 -0
  22. data/app/facades/report_response_generator.rb +147 -0
  23. data/app/helpers/application_helper.rb +2 -0
  24. data/app/helpers/dependency_helper.rb +5 -0
  25. data/app/helpers/question_helper.rb +22 -0
  26. data/app/helpers/surveyform_helper.rb +179 -0
  27. data/app/helpers/surveyor_gui/report_helper.rb +19 -0
  28. data/app/helpers/surveyor_helper.rb +4 -0
  29. data/app/inputs/currency_input.rb +5 -0
  30. data/app/inputs/date_picker_input.rb +7 -0
  31. data/app/inputs/datetime_picker_input.rb +5 -0
  32. data/app/inputs/percent_input.rb +5 -0
  33. data/app/inputs/time_picker_input.rb +5 -0
  34. data/app/mailers/.gitkeep +0 -0
  35. data/app/models/.gitkeep +0 -0
  36. data/app/models/answer.rb +4 -0
  37. data/app/models/column.rb +3 -0
  38. data/app/models/dependency.rb +4 -0
  39. data/app/models/dependency_condition.rb +4 -0
  40. data/app/models/permitted_params_decorator.rb +80 -0
  41. data/app/models/question.rb +4 -0
  42. data/app/models/question_group.rb +4 -0
  43. data/app/models/question_type.rb +7 -0
  44. data/app/models/response.rb +4 -0
  45. data/app/models/response_set.rb +4 -0
  46. data/app/models/row.rb +3 -0
  47. data/app/models/survey.rb +4 -0
  48. data/app/models/survey_section.rb +4 -0
  49. data/app/models/surveyform.rb +103 -0
  50. data/app/uploaders/blob_uploader.rb +48 -0
  51. data/app/views/dependencys/_column.html.erb +1 -0
  52. data/app/views/dependencys/_dependency.html.erb +22 -0
  53. data/app/views/dependencys/_dependency_condition_fields.html.erb +48 -0
  54. data/app/views/dependencys/_form.html.erb +20 -0
  55. data/app/views/dependencys/blank.html.erb +0 -0
  56. data/app/views/dependencys/edit.html.erb +1 -0
  57. data/app/views/dependencys/new.html.erb +1 -0
  58. data/app/views/layouts/application.html.erb +14 -0
  59. data/app/views/layouts/surveyor_gui_blank.html.erb +12 -0
  60. data/app/views/layouts/surveyor_gui_default.html.erb +16 -0
  61. data/app/views/layouts/surveyor_modified.html.erb +14 -0
  62. data/app/views/partials/_answer.html.haml +33 -0
  63. data/app/views/partials/_question.html.haml +33 -0
  64. data/app/views/partials/_question_group.html.haml +73 -0
  65. data/app/views/partials/_section.html.haml +13 -0
  66. data/app/views/question_groups/_form.html.erb +56 -0
  67. data/app/views/question_groups/_group_inline_field.html.erb +21 -0
  68. data/app/views/question_groups/_group_inline_fields.html.erb +25 -0
  69. data/app/views/question_groups/blank.html.erb +0 -0
  70. data/app/views/question_groups/edit.html.erb +1 -0
  71. data/app/views/question_groups/new.html.erb +1 -0
  72. data/app/views/questions/_answer_fields.html.erb +23 -0
  73. data/app/views/questions/_answer_options.html.erb +28 -0
  74. data/app/views/questions/_form.html.erb +65 -0
  75. data/app/views/questions/_grid_dropdown_columns.html.erb +10 -0
  76. data/app/views/questions/_grid_dropdown_fields.html.erb +42 -0
  77. data/app/views/questions/_grid_fields.html.erb +9 -0
  78. data/app/views/questions/_no_picks.html.erb +29 -0
  79. data/app/views/questions/_pick.html +21 -0
  80. data/app/views/questions/_picks.html.erb +12 -0
  81. data/app/views/questions/blank.html.erb +0 -0
  82. data/app/views/questions/edit.html.erb +1 -0
  83. data/app/views/questions/new.html.erb +1 -0
  84. data/app/views/survey_sections/_form.html.erb +13 -0
  85. data/app/views/survey_sections/blank.html.erb +0 -0
  86. data/app/views/survey_sections/edit.html.erb +1 -0
  87. data/app/views/survey_sections/new.html.erb +1 -0
  88. data/app/views/surveyforms/_form.html.erb +50 -0
  89. data/app/views/surveyforms/_question_field.html.erb +148 -0
  90. data/app/views/surveyforms/_question_group.html.erb +116 -0
  91. data/app/views/surveyforms/_question_group_fields.html.erb +3 -0
  92. data/app/views/surveyforms/_question_name_and_number.html.erb +6 -0
  93. data/app/views/surveyforms/_question_section.html.erb +15 -0
  94. data/app/views/surveyforms/_question_wrapper.html.erb +109 -0
  95. data/app/views/surveyforms/_survey_section_fields.html.erb +138 -0
  96. data/app/views/surveyforms/clone_survey.html.erb +13 -0
  97. data/app/views/surveyforms/edit.html.erb +5 -0
  98. data/app/views/surveyforms/index.html.erb +40 -0
  99. data/app/views/surveyforms/new.html.erb +1 -0
  100. data/app/views/surveyforms/show.html.erb +5 -0
  101. data/app/views/surveyor_gui/reports/_graphs.html.haml +21 -0
  102. data/app/views/surveyor_gui/reports/_grid.html.haml +42 -0
  103. data/app/views/surveyor_gui/reports/_grid_dropdown.html.haml +56 -0
  104. data/app/views/surveyor_gui/reports/_repeater.html.haml +28 -0
  105. data/app/views/surveyor_gui/reports/_show_report.html.haml +33 -0
  106. data/app/views/surveyor_gui/reports/_single_question.html.haml +70 -0
  107. data/app/views/surveyor_gui/reports/show.html.erb +14 -0
  108. data/app/views/surveyor_gui/responses/_grid.html.haml +20 -0
  109. data/app/views/surveyor_gui/responses/_grid_dropdown.html.haml +20 -0
  110. data/app/views/surveyor_gui/responses/_repeater.html.haml +22 -0
  111. data/app/views/surveyor_gui/responses/_survey_results.html.haml +40 -0
  112. data/app/views/surveyor_gui/responses/index.html.haml +24 -0
  113. data/app/views/surveyor_gui/responses/show.html.haml +42 -0
  114. data/app/views/surveyor_gui/shared/_grid_comments.html.haml +10 -0
  115. data/app/views/surveyor_gui/shared/_new_line.html.haml +2 -0
  116. data/app/views/surveyor_gui/shared/_pick_comments.html.haml +15 -0
  117. data/app/views/surveyor_gui/shared/_question_number.html.haml +9 -0
  118. data/app/views/surveyor_gui/shared/_report_data.html.haml +24 -0
  119. data/app/views/surveyor_gui/shared/_stars_report_data.html.haml +14 -0
  120. data/config.ru +4 -0
  121. data/config/environment.rb +0 -0
  122. data/config/routes.rb +71 -0
  123. data/db/migrate/20140307204049_add_template_to_surveys.rb +5 -0
  124. data/db/migrate/20140307235607_add_test_data_to_response_sets.rb +5 -0
  125. data/db/migrate/20140308171947_add_original_choice_to_answers.rb +5 -0
  126. data/db/migrate/20140308172118_add_blob_to_responses.rb +5 -0
  127. data/db/migrate/20140308172417_add_modifiable_to_survey_section.rb +5 -0
  128. data/db/migrate/20140308174532_add_modifiable_to_question.rb +5 -0
  129. data/db/migrate/20140308175305_add_dynamically_generate_to_questions.rb +5 -0
  130. data/db/migrate/20140311032923_add_dummy_blob_to_questions.rb +5 -0
  131. data/db/migrate/20140311160609_add_dynamic_source_to_questions.rb +5 -0
  132. data/db/migrate/20140311161714_add_report_code_to_questions.rb +5 -0
  133. data/db/migrate/20140530181134_add_is_comment_to_questions.rb +5 -0
  134. data/db/migrate/20140531012006_add_is_comment_to_answers.rb +5 -0
  135. data/db/migrate/20140531225529_create_rows.rb +9 -0
  136. data/db/migrate/20140601011151_create_columns.rb +11 -0
  137. data/db/migrate/20140602030330_add_column_id_to_answers.rb +5 -0
  138. data/db/migrate/20140603155606_add_column_id_to_responses.rb +5 -0
  139. data/db/migrate/20140606023527_add_column_id_to_dependency_conditions.rb +5 -0
  140. data/db/migrate/20140815165307_add_user_id_to_survey.rb +5 -0
  141. data/lib/assets/.gitkeep +0 -0
  142. data/lib/assets/images/addicon.png +0 -0
  143. data/lib/assets/images/datepicker.gif +0 -0
  144. data/lib/assets/images/delete.gif +0 -0
  145. data/lib/assets/images/delete.png +0 -0
  146. data/lib/assets/images/images/border.png +0 -0
  147. data/lib/assets/images/images/controls.png +0 -0
  148. data/lib/assets/images/images/loading.gif +0 -0
  149. data/lib/assets/images/images/loading_background.png +0 -0
  150. data/lib/assets/images/images/overlay.png +0 -0
  151. data/lib/assets/images/rails.png +0 -0
  152. data/lib/assets/images/star.gif +0 -0
  153. data/lib/assets/javascripts/.gitkeep +0 -0
  154. data/lib/assets/javascripts/surveyor_gui/jquery.MetaData.js +121 -0
  155. data/lib/assets/javascripts/surveyor_gui/jquery.blockUI.js +619 -0
  156. data/lib/assets/javascripts/surveyor_gui/jquery.rating.js +377 -0
  157. data/lib/assets/javascripts/surveyor_gui/jquery.validate.js +1188 -0
  158. data/lib/assets/javascripts/surveyor_gui/surveyor_add_ons.js +10 -0
  159. data/lib/assets/javascripts/surveyor_gui/surveyor_gui.js +1417 -0
  160. data/lib/assets/stylesheets/.gitkeep +0 -0
  161. data/lib/assets/stylesheets/surveyor_gui/jquery.rating.css +12 -0
  162. data/lib/assets/stylesheets/surveyor_gui/surveyor_add_ons.css +3 -0
  163. data/lib/assets/stylesheets/surveyor_gui/surveyor_gui.sass +650 -0
  164. data/lib/enumerable_extenders.rb +31 -0
  165. data/lib/generators/surveyor_gui/install_generator.rb +57 -0
  166. data/lib/generators/surveyor_gui/templates/app/assets/javascripts/surveyor_add_ons.js +2 -0
  167. data/lib/generators/surveyor_gui/templates/app/assets/javascripts/surveyor_gui_all.js +24 -0
  168. data/lib/generators/surveyor_gui/templates/app/assets/stylesheets/surveyor_add_ons.css.sass +1 -0
  169. data/lib/generators/surveyor_gui/templates/app/assets/stylesheets/surveyor_gui_all.css.sass +8 -0
  170. data/lib/generators/surveyor_gui/templates/app/helpers/surveyor_helper.rb +4 -0
  171. data/lib/generators/surveyor_gui/templates/app/models/response_set_user.rb +13 -0
  172. data/lib/generators/surveyor_gui/templates/app/views/layouts/surveyor_gui_default.html.erb +16 -0
  173. data/lib/generators/surveyor_gui/templates/config/initializers/simple_form.rb +140 -0
  174. data/lib/generators/surveyor_gui/templates/config/locales/en.yml +5 -0
  175. data/lib/surveyor_gui.rb +17 -0
  176. data/lib/surveyor_gui/engine.rb +30 -0
  177. data/lib/surveyor_gui/helpers/surveyor_helper_methods.rb +19 -0
  178. data/lib/surveyor_gui/models/answer_methods.rb +24 -0
  179. data/lib/surveyor_gui/models/column_methods.rb +43 -0
  180. data/lib/surveyor_gui/models/dependency_condition_methods.rb +53 -0
  181. data/lib/surveyor_gui/models/dependency_methods.rb +83 -0
  182. data/lib/surveyor_gui/models/question_and_group_shared_methods.rb +11 -0
  183. data/lib/surveyor_gui/models/question_group_methods.rb +55 -0
  184. data/lib/surveyor_gui/models/question_methods.rb +435 -0
  185. data/lib/surveyor_gui/models/question_type_methods.rb +493 -0
  186. data/lib/surveyor_gui/models/response_methods.rb +67 -0
  187. data/lib/surveyor_gui/models/response_set_methods.rb +54 -0
  188. data/lib/surveyor_gui/models/row_methods.rb +11 -0
  189. data/lib/surveyor_gui/models/survey_methods.rb +32 -0
  190. data/lib/surveyor_gui/models/survey_section_methods.rb +32 -0
  191. data/lib/surveyor_gui/surveyforms_controller_methods.rb +258 -0
  192. data/lib/surveyor_gui/version.rb +3 -0
  193. data/lib/tasks/.gitkeep +0 -0
  194. data/lib/tasks/surveyor_gui_tasks.rake +4 -0
  195. data/lib/templates/erb/scaffold/_form.html.erb +13 -0
  196. data/spec/controllers/surveyforms_controller_spec.rb +361 -0
  197. data/spec/controllers/surveyor_controller_spec.rb +303 -0
  198. data/spec/factories.rb +181 -0
  199. data/spec/features/create_survey_spec.rb +418 -0
  200. data/spec/features/dependencies_spec.rb +61 -0
  201. data/spec/features/rearrange_survey_spec.rb +118 -0
  202. data/spec/features/ui_spec.rb +469 -0
  203. data/spec/fixtures/REDCapDemoDatabase_DataDictionary.csv +127 -0
  204. data/spec/fixtures/chinese_survey.rb +14 -0
  205. data/spec/fixtures/everything.rb +215 -0
  206. data/spec/fixtures/favorites-ish.rb +22 -0
  207. data/spec/fixtures/favorites.rb +22 -0
  208. data/spec/fixtures/feelings.rb +38 -0
  209. data/spec/fixtures/lifestyle.rb +55 -0
  210. data/spec/fixtures/numbers.rb +21 -0
  211. data/spec/fixtures/redcap_new_headers.csv +1 -0
  212. data/spec/fixtures/redcap_siblings.csv +1 -0
  213. data/spec/fixtures/redcap_whitespace.csv +1 -0
  214. data/spec/helpers/formtastic_custom_input_spec.rb +15 -0
  215. data/spec/helpers/surveyor_helper_spec.rb +116 -0
  216. data/spec/lib/common_spec.rb +37 -0
  217. data/spec/lib/parser_spec.rb +393 -0
  218. data/spec/lib/rake_kitchen_sink.rb +42 -0
  219. data/spec/lib/redcap_parser_spec.rb +129 -0
  220. data/spec/lib/unparser_spec.rb +126 -0
  221. data/spec/models/answer_spec.rb +144 -0
  222. data/spec/models/dependency_condition_spec.rb +428 -0
  223. data/spec/models/dependency_spec.rb +90 -0
  224. data/spec/models/question_group_spec.rb +66 -0
  225. data/spec/models/question_spec.rb +176 -0
  226. data/spec/models/response_set_spec.rb +452 -0
  227. data/spec/models/response_spec.rb +208 -0
  228. data/spec/models/survey_section_spec.rb +58 -0
  229. data/spec/models/survey_spec.rb +155 -0
  230. data/spec/models/surveyor_gui/question_spec.rb +60 -0
  231. data/spec/models/surveyor_gui/question_type_spec.rb +268 -0
  232. data/spec/models/validation_condition_spec.rb +98 -0
  233. data/spec/models/validation_spec.rb +64 -0
  234. data/spec/spec.opts +4 -0
  235. data/spec/spec_helper.rb +119 -0
  236. data/spec/support/scenario_outline_helper.rb +39 -0
  237. data/spec/support/shared.rb +10 -0
  238. data/spec/support/surveyforms_creation_helpers.rb +312 -0
  239. data/spec/support/surveyforms_rearrangement_helpers.rb +170 -0
  240. data/spec/support/surveyor_api_helpers.rb +15 -0
  241. data/spec/support/surveyor_ui_helpers.rb +108 -0
  242. data/spec/support/wait_for_ajax.rb +11 -0
  243. data/spec/views/questions/edit.html.erb_spec.rb +73 -0
  244. data/spec/views/surveyforms/edit.html.erb_spec.rb +126 -0
  245. data/surveyor_gui.gemspec +52 -0
  246. data/test/dummy/README.rdoc +261 -0
  247. data/test/dummy/Rakefile +7 -0
  248. data/test/dummy/app/assets/javascripts/application.js +15 -0
  249. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  250. data/test/dummy/app/controllers/application_controller.rb +3 -0
  251. data/test/dummy/app/helpers/application_helper.rb +2 -0
  252. data/test/dummy/app/mailers/.gitkeep +0 -0
  253. data/test/dummy/app/models/.gitkeep +0 -0
  254. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  255. data/test/dummy/config.ru +4 -0
  256. data/test/dummy/config/application.rb +59 -0
  257. data/test/dummy/config/boot.rb +10 -0
  258. data/test/dummy/config/database.yml +25 -0
  259. data/test/dummy/config/environment.rb +5 -0
  260. data/test/dummy/config/environments/development.rb +37 -0
  261. data/test/dummy/config/environments/production.rb +67 -0
  262. data/test/dummy/config/environments/test.rb +37 -0
  263. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  264. data/test/dummy/config/initializers/inflections.rb +15 -0
  265. data/test/dummy/config/initializers/mime_types.rb +5 -0
  266. data/test/dummy/config/initializers/secret_token.rb +7 -0
  267. data/test/dummy/config/initializers/session_store.rb +8 -0
  268. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  269. data/test/dummy/config/locales/en.yml +5 -0
  270. data/test/dummy/config/routes.rb +58 -0
  271. data/test/dummy/lib/assets/.gitkeep +0 -0
  272. data/test/dummy/log/.gitkeep +0 -0
  273. data/test/dummy/public/404.html +26 -0
  274. data/test/dummy/public/422.html +26 -0
  275. data/test/dummy/public/500.html +25 -0
  276. data/test/dummy/public/favicon.ico +0 -0
  277. data/test/dummy/script/rails +6 -0
  278. data/test/surveyor-gui_test.rb +7 -0
  279. data/test/test_helper.rb +15 -0
  280. data/vendor/assets/stylesheets/.gitkeep +0 -0
  281. data/vendor/assets/stylesheets/custom.sass +5 -0
  282. data/vendor/plugins/.gitkeep +0 -0
  283. metadata +664 -0
@@ -0,0 +1,84 @@
1
+ class QuestionGroupsController < ApplicationController
2
+
3
+ def new
4
+ @title = "Add Question"
5
+ @survey_section_id = params[:survey_section_id]
6
+ @question_group = QuestionGroup.new(
7
+ text: params[:text],
8
+ question_type_id: params[:question_type_id])
9
+ original_question = Question.find(params[:question_id]) if !params[:question_id].blank?
10
+ if original_question
11
+ @question_group.questions.build(
12
+ display_order: params[:display_order],
13
+ id: params[:question_id],
14
+ question_type_id: original_question.question_type_id,
15
+ pick: original_question.pick,
16
+ display_type: original_question.display_type)
17
+ else
18
+ @question_group.questions.build(
19
+ display_order: params[:display_order])
20
+ end
21
+ end
22
+
23
+
24
+ def edit
25
+ @title = "Edit Question Group"
26
+ @question_group = QuestionGroup.includes(:questions).find(params[:id])
27
+ @question_group.question_type_id = params[:question_type_id]
28
+ @survey_section_id = @question_group.questions.first.survey_section_id
29
+ end
30
+
31
+ def create
32
+ @question_group = QuestionGroup.new(question_group_params)
33
+ if @question_group.save
34
+ #@question_group.questions.update_attributes(survey_section_id: question_group_params[])
35
+ original_question = Question.find(question_group_params[:question_id]) if !question_group_params[:question_id].blank?
36
+ original_question.destroy if original_question
37
+ render :inline => '<div id="cboxQuestionId">'+@question_group.questions.first.id.to_s+'</div>', :layout => 'surveyor_gui_blank'
38
+ else
39
+ @title = "Add Question"
40
+ survey_section_id = question_group_params[:survey_section_id]
41
+ redirect_to :action => 'new', :controller => 'questions', :layout => 'surveyor_gui_blank', :survey_section_id => survey_section_id
42
+ end
43
+ end
44
+
45
+ def update
46
+ @title = "Update Question"
47
+ @question_group = QuestionGroup.includes(:questions).find(params[:id])
48
+ if @question_group.update_attributes(question_group_params)
49
+ render :blank, :layout => 'surveyor_gui_blank'
50
+ #If a nested question is destroyed, the Question model performs a cascade delete
51
+ #on the parent QuestionGroup (stuck with this behaviour as it is a Surveyor default).
52
+ #Need to check for this and restore question group.
53
+ begin
54
+ QuestionGroup.find(params[:id])
55
+ rescue
56
+ scrubbed_params = question_group_params.to_hash
57
+ scrubbed_params.delete("questions_attributes")
58
+ QuestionGroup.create!(scrubbed_params)
59
+ end
60
+ else
61
+ render :action => 'edit', :layout => 'surveyor_gui_blank'
62
+ end
63
+ end
64
+
65
+ def render_group_inline_partial
66
+ if params[:id].blank?
67
+ @question_group = QuestionGroup.new
68
+ else
69
+ @question_group = QuestionGroup.find(params[:id])
70
+ end
71
+ if params[:add_row]
72
+
73
+ @question_group = QuestionGroup.new
74
+ @question_group.questions.build(display_order: params[:display_order])
75
+ render :partial => 'group_inline_field'
76
+ else
77
+ render :partial => 'group_inline_fields'
78
+ end
79
+ end
80
+ private
81
+ def question_group_params
82
+ ::PermittedParams.new(params[:question_group]).question_group
83
+ end
84
+ end
@@ -0,0 +1,187 @@
1
+ class QuestionsController < ApplicationController
2
+ layout 'surveyor_gui_blank'
3
+
4
+ def new
5
+ @title = "Add Question"
6
+ survey_section = SurveySection.find(params[:survey_section_id])
7
+ survey = Survey.find(survey_section.survey_id)
8
+ @question_group = QuestionGroup.new
9
+ if params[:prev_question_id]
10
+ prev_question_display_order = _get_prev_display_order(params[:prev_question_id])
11
+ @question = Question.new(:survey_section_id => params[:survey_section_id],
12
+ :text => params[:text],
13
+ :display_type => "default",
14
+ :display_order => prev_question_display_order)
15
+ else
16
+ @question = Question.new(:survey_section_id => params[:survey_section_id],
17
+ :text => params[:text],
18
+ :display_type => "default",
19
+ :display_order => params[:display_order] || 0)
20
+ end
21
+ @question.question_type_id = params[:question_type_id] if !params[:question_type_id].blank?
22
+ @question.answers.build(:text => '', :response_class=>"string")
23
+ end
24
+
25
+ def edit
26
+ @title = "Edit Question"
27
+ @question = Question.includes(:answers).find(params[:id])
28
+ @question.question_type_id = params[:question_type_id] if !params[:question_type_id].blank?
29
+ end
30
+
31
+ def adjusted_text
32
+ if @question.part_of_group?
33
+ @question.question_group.text
34
+ else
35
+ @question.text
36
+ end
37
+ end
38
+
39
+ helper_method :adjusted_text
40
+
41
+ def create
42
+ Question.where(:survey_section_id => params[:question][:survey_section_id])
43
+ .where("display_order >= ?", params[:question][:display_order])
44
+ .update_all("display_order = display_order+1")
45
+ if !params[:question][:answers_attributes].blank? && !params[:question][:answers_attributes]['0'].blank?
46
+ params[:question][:answers_attributes]['0'][:original_choice] = params[:question][:answers_attributes]['0'][:text]
47
+ end
48
+ @question = Question.new(question_params)
49
+ if @question.save
50
+ @question.answers.each_with_index {|a, index| a.destroy if index > 0} if @question.pick == 'none'
51
+ #load any page - if it has no flash errors, the colorbox that contains it will be closed immediately after the page loads
52
+ render :inline => '<div id="cboxQuestionId">'+@question.id.to_s+'</div>', :layout => 'surveyor_gui_blank'
53
+ else
54
+ @title = "Add Question"
55
+ render :action => 'new', :layout => 'surveyor_gui_blank'
56
+ end
57
+ end
58
+
59
+ def update
60
+ @title = "Update Question"
61
+ @question = Question.includes(:answers).find(params[:id])
62
+ if @question.update_attributes(question_params)
63
+ @question.answers.each_with_index {|a, index| a.destroy if index > 0} if @question.pick == 'none'
64
+ #load any page - if it has no flash errors, the colorbox that contains it will be closed immediately after the page loads
65
+ render :blank, :layout => 'surveyor_gui_blank'
66
+ else
67
+ render :action => 'edit', :layout => 'surveyor_gui_blank'
68
+ end
69
+ end
70
+
71
+ def destroy
72
+ question = Question.find(params[:id])
73
+ if !question.survey_section.survey.template && question.survey_section.survey.response_sets.count > 0
74
+ flash[:error]="Reponses have already been collected for this survey, therefore it cannot be modified. Please create a new survey instead."
75
+ return false
76
+ end
77
+ if !question.dependency_conditions.blank?
78
+ render :text=>"The following questions have logic that depend on this question: \n\n"+question.dependency_conditions.map{|d| " - "+d.dependency.question.text}.join('\n')+"\n\nPlease delete logic before deleting this question.".html_safe
79
+ return
80
+ end
81
+ if question.part_of_group?
82
+ question.question_group.questions.each{|q| q.destroy}
83
+ render :text=>''
84
+ return
85
+ end
86
+ question.destroy
87
+ render :text=>''
88
+ end
89
+
90
+ def sort
91
+ survey = Surveyform.find(params[:survey_id])
92
+ survey.sort_as_per_array(params)
93
+ render :nothing => true
94
+ end
95
+
96
+ def cut_question
97
+ session[:cut_question]=params[:id]
98
+ if q=Question.find(params[:id])
99
+ q.update_attribute(:survey_section_id,nil)
100
+ end
101
+ redirect_to :back
102
+ end
103
+
104
+ def render_answer_fields_partial
105
+ if params[:id].blank?
106
+ @questions = Question.new
107
+ else
108
+ @questions = Question.find(params[:id])
109
+ end
110
+ if @questions.answers.empty?
111
+ @questions.answers.build(:text=>'')
112
+ else
113
+ if !@questions.answers.first.original_choice.blank?
114
+ @questions.answers.first.update_attribute(:text,@questions.answers.first.original_choice)
115
+ end
116
+ if params[:add_row]
117
+ display_order = @questions.answers.maximum(:display_order)
118
+ display_order = display_order ? display_order + 1 : 0
119
+ @questions = Question.new
120
+ @questions.answers.build(:text=>'', :display_order=>display_order)
121
+ end
122
+ end
123
+ render :partial => 'answer_fields'
124
+ end
125
+
126
+ def render_grid_partial
127
+ if params[:id].blank?
128
+ @questions = Question.new
129
+ else
130
+ @questions = Question.find(params[:id])
131
+ end
132
+ if @questions.answers.empty?
133
+ @questions.answers.build(text: "", response_class: "answer")
134
+ else
135
+ if !@questions.answers.first.original_choice.blank?
136
+ @questions.answers.first.update_attribute(:text,@questions.answers.first.original_choice)
137
+ end
138
+ end
139
+ if @questions.question_group
140
+ @question_group=@questions.question_group
141
+ else
142
+ @question_group=QuestionGroup.new
143
+ @question_group.columns.build
144
+ end
145
+ column_count = @question_group.columns.size
146
+ requested_columns = params[:index] == "NaN" ? column_count : params[:index].to_i
147
+ if requested_columns >= column_count
148
+ requested_columns = requested_columns - column_count
149
+ (requested_columns).times.each {@question_group.columns.build}
150
+ else
151
+ @question_group.trim_columns (column_count-requested_columns)
152
+ end
153
+ @questions.dropdown_column_count = requested_columns.to_i+1
154
+ if params[:question_type_id] == "grid_dropdown"
155
+ render :partial => 'grid_dropdown_fields'
156
+ else
157
+ render :partial => 'grid_fields'
158
+ end
159
+ end
160
+
161
+
162
+ def render_no_picks_partial
163
+ if params[:id].blank?
164
+ @questions = Question.new
165
+ else
166
+ @questions = Question.find(params[:id])
167
+ end
168
+ if @questions.answers.empty?
169
+ @questions.answers.build(:text=>'')
170
+ end
171
+ render :partial => 'no_picks'
172
+ end
173
+
174
+ private
175
+ def question_params
176
+ ::PermittedParams.new(params[:question]).question
177
+ end
178
+
179
+ def _get_prev_display_order(prev_question)
180
+ prev_question = Question.find(prev_question)
181
+ if prev_question.part_of_group?
182
+ prev_question.question_group.questions.last.display_order + 1
183
+ else
184
+ prev_question.display_order + 1
185
+ end
186
+ end
187
+ end
@@ -0,0 +1,80 @@
1
+ class SurveySectionsController < ApplicationController
2
+ layout 'surveyor_gui_blank'
3
+
4
+ def new
5
+ @title = "Add Survey Section"
6
+ survey = Survey.find(params[:survey_id])
7
+ prev_section = SurveySection.find(params[:prev_section_id])
8
+ @last_survey_section = survey.survey_sections.last
9
+ @survey_section = survey.survey_sections
10
+ .build(:title => 'New Section',
11
+ :display_order => prev_section.display_order + 1,
12
+ :modifiable => true)
13
+ end
14
+
15
+ def edit
16
+ @title = "Edit Survey Section"
17
+ @survey_section = SurveySection.find(params[:id])
18
+ end
19
+
20
+ def create
21
+ survey = Survey.find(params[:survey_section][:survey_id])
22
+ SurveySection.where(:survey_id => survey.id)
23
+ .where("display_order >= ?", params[:survey_section][:display_order])
24
+ .update_all("display_order = display_order+1")
25
+ @survey_section = survey.survey_sections.build(survey_section_params)
26
+ @survey_section.display_order = params[:survey_section][:display_order].to_i
27
+ #@survey_section.questions.build(:text=>'New question',:pick=>'none',:display_order=>0,:display_type=>'default').answers.build(:text=>'string', :response_class=>'string', :display_order=>1, :template=>true)
28
+ if @survey_section.save
29
+ redirect_to :back
30
+ else
31
+ render :action => 'new', :layout => 'surveyor_gui_blank'
32
+ end
33
+ end
34
+
35
+ def update
36
+ @title = "Update Survey Section"
37
+ @survey_section = SurveySection.find(params[:id])
38
+ if @survey_section.update_attributes(survey_section_params)
39
+ render :blank, :layout => 'surveyor_gui_blank'
40
+ else
41
+ render :action => 'edit', :layout => 'surveyor_gui_blank'
42
+ end
43
+ end
44
+
45
+ def destroy
46
+ @survey_section = SurveySection.find(params[:id])
47
+ if !@survey_section.survey.template && @survey_section.survey.response_sets.count > 0
48
+ render :text => "Reponses have already been collected for this survey, therefore it cannot be modified. Please create a new survey instead."
49
+ return false
50
+ end
51
+ if !@survey_section.modifiable
52
+ render :text => "This section cannot be removed."
53
+ return false
54
+ end
55
+ if !@survey_section.questions.map{|q| q.dependency_conditions}.flatten.blank?
56
+ render :text => "The following questions have logic that depend on questions in this section: \n\n"+@survey_section.questions.map{|q| q.dependency_conditions.map{|d| " - "+d.dependency.question.text}}.flatten.join('\n')+"\n\nPlease delete logic before deleting this section.".html_safe
57
+ return
58
+ end
59
+ @survey_section.destroy
60
+ render :text => ""
61
+ end
62
+
63
+ def sort
64
+ survey = Survey.find(params[:survey_id])
65
+ satts = { :id => params[:survey_id], :survey_sections_attributes=>{} }
66
+ sections = params[:survey_section]
67
+ sections.each_with_index do |sid, index|
68
+ satts[:survey_sections_attributes][index.to_s] = { :id => sid, :display_order => index }
69
+ end
70
+ puts satts
71
+ survey.update_attributes!(satts)
72
+ render :nothing => true
73
+ end
74
+
75
+ private
76
+ def survey_section_params
77
+ ::PermittedParams.new(params[:survey_section]).survey_section
78
+ end
79
+
80
+ end
@@ -0,0 +1,4 @@
1
+ class SurveyformsController < ApplicationController
2
+ include Surveyor::SurveyorControllerMethods
3
+ include SurveyorGui::SurveyformsControllerMethods
4
+ end
@@ -0,0 +1,89 @@
1
+ module SurveyorControllerCustomMethods
2
+ def self.included(base)
3
+ base.send :layout, 'surveyor_modified'
4
+ end
5
+
6
+ def edit
7
+ root = File.expand_path('../../', __FILE__)
8
+ #place the surveyor_gui views ahead of the default surveyor view in order of preference
9
+ #so we can load customized partials.
10
+ prepend_view_path(root+'/views')
11
+ super
12
+ end
13
+ def update
14
+ question_ids_for_dependencies = (params[:r] || []).map{|k,v| v["question_id"] }.compact.uniq
15
+ saved = load_and_update_response_set_with_retries
16
+
17
+ if saved && params[:finish] && !@response_set.mandatory_questions_complete?
18
+ #did not complete mandatory fields
19
+ ids, remove, question_ids, flashmsg = {}, {}, [], []
20
+ flashmsg << "You must complete all required fields before submitting the survey. Please fill in the following:"
21
+
22
+ triggered_mandatory_missing = @response_set.triggered_mandatory_missing
23
+
24
+ survey_section = ''
25
+ question_number = {}
26
+ last_question_of_previous_section = 0
27
+ last_question_number = 0
28
+ @response_set.survey.survey_sections.each do |ss|
29
+ index = 0
30
+ ss.questions.where('display_type!=?','label').each do |q|
31
+ if q.triggered?(@response_set)
32
+ question_number[q.id.to_s] = last_question_number = last_question_of_previous_section + index + 1
33
+ index = index + 1
34
+ end
35
+ end
36
+ last_question_of_previous_section = last_question_number
37
+ end
38
+
39
+ triggered_mandatory_missing.each do |m|
40
+ if m.survey_section_id != survey_section
41
+ survey_section = m.survey_section_id
42
+ flashmsg << ""
43
+ flashmsg << "&nbsp;&nbsp;" + m.survey_section.title
44
+ end
45
+
46
+ flashmsg << "&nbsp;&nbsp;&nbsp;&nbsp;question&nbsp;" + question_number[m.id.to_s].to_s + ') '+ m.text
47
+ end
48
+ respond_to do |format|
49
+ format.js do
50
+
51
+ render :json=>{"flashmsg"=>flashmsg}
52
+ end
53
+ format.html do
54
+ flash[:notice] = flashmsg.join('<br />')
55
+ redirect_to surveyor.edit_my_survey_path(:anchor => anchor_from(params[:section]), :section => section_id_from(params))
56
+ end
57
+ end
58
+ return
59
+ # elsif @response_set.survey.id.to_s == evaluation_institution.institution.vendor_value_analysis_questionnaire_id && saved && params[:finish]
60
+ elsif saved && params[:finish]
61
+ return redirect_with_message(surveyor_finish, :notice, t('surveyor.completed_survey'))
62
+ end
63
+
64
+
65
+ respond_to do |format|
66
+ format.html do
67
+ if @response_set.nil?
68
+ return redirect_with_message(surveyor.available_surveys_path, :notice, t('surveyor.unable_to_find_your_responses'))
69
+ else
70
+ flash[:notice] = t('surveyor.unable_to_update_survey') unless saved
71
+ redirect_to surveyor.edit_my_survey_path(:anchor => anchor_from(params[:section]), :section => section_id_from(params))
72
+ end
73
+ end
74
+ format.js do
75
+ if @response_set
76
+ render :json => @response_set.reload.all_dependencies(question_ids_for_dependencies)
77
+ else
78
+ render :text => "No response set #{params[:response_set_code]}",
79
+ :status => 404
80
+ end
81
+ end
82
+ end
83
+
84
+ end
85
+ end
86
+ class SurveyorController < ApplicationController
87
+ include Surveyor::SurveyorControllerMethods
88
+ include SurveyorControllerCustomMethods
89
+ end
@@ -0,0 +1,339 @@
1
+ require 'complex'
2
+ include Math
3
+
4
+ class SurveyorGui::ReportsController < ApplicationController
5
+ include ReportPreviewWrapper
6
+
7
+ # ReportPreviewWrapper wraps preview in a database transaction so test data is not permanently saved.
8
+ around_action :wrap_in_transaction, only: :preview
9
+ layout 'surveyor_gui_default'
10
+
11
+ def preview
12
+ response_qty = 5
13
+ @title = "Preview Report for "+response_qty.to_s+" randomized responses"
14
+ @survey = Survey.find(params[:survey_id])
15
+ user_id = defined?(current_user) && current_user ? current_user.id : nil
16
+ response_qty.times.each {
17
+ @response_set = ResponseSet.create(survey: @survey, user_id: user_id, test_data: true)
18
+ ReportResponseGenerator.new(@survey).generate_1_result_set(@response_set)
19
+ }
20
+ @response_sets = ResponseSet.where(survey_id: @survey.id, test_data: true, user_id: user_id)
21
+ @responses = Response.joins(:response_set, :answer).where('user_id = ? and survey_id = ? and test_data = ? and answers.is_comment = ?',user_id,params[:survey_id],true, false)
22
+ if (!@survey)
23
+ flash[:notice] = "Survey/Questionnnaire not found."
24
+ redirect_to :back
25
+ end
26
+ generate_report(params[:survey_id], true)
27
+ render :show
28
+ end
29
+
30
+ def show
31
+ @survey = Survey.find(params[:id])
32
+ @response_sets = ResponseSet.where(survey_id: @survey.id, test_data: false)
33
+ @responses = Response.joins(:response_set, :answer).where('survey_id = ? and test_data = ? and answers.is_comment=?',@survey.id,false, false)
34
+ @title = "Show report for #{@survey.title}"
35
+ if @responses.count > 0
36
+ generate_report(@survey.id, false)
37
+ else
38
+ flash[:error] = "No responses have been collected for this survey"
39
+ redirect_to surveyforms_path
40
+ end
41
+ end
42
+
43
+ def generate_report(survey_id, test)
44
+ questions = Question.joins(:survey_section).where('survey_sections.survey_id = ? and is_comment = ?', survey_id, false)
45
+ # multiple_choice_responses = Response.joins(:response_set, :answer).where('survey_id = ? and test_data = ?',survey_id,test).group('responses.question_id','answers.id','answers.text').select('responses.question_id, answers.id, answers.text as text, count(*) as answer_count').order('responses.question_id','answers.id')
46
+
47
+ # multiple_choice_responses = Answer.unscoped.joins(:question=>:survey_section).includes(:responses=>:response_set).where('survey_sections.survey_id=? and (response_sets.test_data=? or response_sets.test_data is null)',survey_id,test).group('answers.question_id','answers.id','answers.text').select('answers.question_id, answers.id, answers.text as text, count(*) as answer_count').order('answers.question_id','answers.id')
48
+
49
+ # multiple_choice_responses = Answer.unscoped.find(:all,
50
+ # :joins => "LEFT JOIN responses ON responses.answer_id = answers.id",
51
+ # :select => "answers.question_id, answers.id, answers.text as text, count(answers.*) as answer_count",
52
+ # :group => "answers.question_id, answers.id, answers.text",
53
+ # :order => "answers.question_id, answers.id")
54
+
55
+ multiple_choice_responses = Answer.unscoped.joins("LEFT OUTER JOIN responses ON responses.answer_id = answers.id
56
+ LEFT OUTER JOIN response_sets ON response_sets.id = responses.response_set_id").
57
+ joins(:question=>:survey_section).
58
+ where('survey_sections.survey_id=? and (response_sets.test_data=? or response_sets.test_data is null)',survey_id,test).
59
+ select("answers.question_id, answers.id, answers.text as text, answers.is_comment, count(responses.id) as answer_count").
60
+ group("answers.question_id, answers.id, answers.text, answers.is_comment").
61
+ order("answers.question_id, answers.id")
62
+
63
+ single_choice_responses = Response.joins(:response_set).where('survey_id = ? and test_data = ?',survey_id,test).select('responses.question_id, responses.answer_id,
64
+ responses.float_value,
65
+ responses.integer_value,
66
+ responses.datetime_value,
67
+ responses.string_value')
68
+ @chart = {}
69
+ colors = ['#4572A7', '#AA4643', '#89A54E', '#80699B', '#3D96AE', '#DB843D', '#92A8CD', '#A47D7C', '#B5CA92']
70
+ questions.each do |q|
71
+ if [:grid_one, :grid_any].include? q.question_type_id
72
+ generate_stacked_bar_chart(q, multiple_choice_responses, colors)
73
+ elsif q.question_type_id == :grid_dropdown
74
+ q.question_group.questions.where(is_comment: false).each do |question|
75
+ generate_grid_dropdown_bar_chart(question, multiple_choice_responses, colors)
76
+ end
77
+ elsif q.pick == 'one'
78
+ generate_pie_chart(q, multiple_choice_responses)
79
+ elsif q.pick == 'any'
80
+ generate_bar_chart(q, multiple_choice_responses, colors)
81
+ elsif [:number,:date,:datetime,:time].include? q.question_type_id
82
+ generate_histogram_chart(q, single_choice_responses)
83
+ end
84
+ end
85
+ end
86
+
87
+ private
88
+
89
+ def generate_pie_chart(q, responses)
90
+ piearray = []
91
+ responses.where(:question_id => q.id).each_with_index do |a, index|
92
+ piearray[index]= {:y=> a.answer_count.to_i, :name => a.text.to_s} if !a.is_comment?
93
+ end
94
+ @chart[q.id.to_s] = LazyHighCharts::HighChart.new('graph') do |f|
95
+ f.options[:chart][:plotBorderWidth] = nil
96
+ f.options[:chart][:plotBackgroundColor] = nil
97
+ f.options[:title][:text] = q.text
98
+ f.plot_options(:pie=>{
99
+ :allowPointSelect=>true,
100
+ :cursor=>"pointer" ,
101
+ :dataLabels=>{
102
+ :enabled=>true,
103
+ :color=>"#000000",
104
+ :connectorColor=>"#000000"
105
+ },
106
+ :enableMouseTracking => false,
107
+ :shadow => false,
108
+ :animation => false
109
+ })
110
+ f.series( :type => 'pie',
111
+ :name=> q.text,
112
+ :data => piearray
113
+ )
114
+ end
115
+ end
116
+
117
+ def generate_bar_chart(q, responses, colors)
118
+ bararray = []
119
+ responses.where(:question_id => q.id).each_with_index do |a, index|
120
+ bararray[index]= {:y=> a.answer_count.to_i, :color => colors[index].to_s} if !a.is_comment?
121
+ end
122
+ @chart[q.id.to_s] = LazyHighCharts::HighChart.new('graph') do |f|
123
+ f.options[:chart][:defaultSeriesType] = 'column'
124
+ f.options[:title][:text] = q.text
125
+ f.options[:xAxis][:categories] = q.answers.order('answers.id').map{|a| a.text}
126
+ f.options[:xAxis][:labels] = {:rotation=> -45, :align => 'right'}
127
+ f.options[:yAxis][:min] = 0
128
+ f.options[:yAxis][:title] = {:text => 'Count'}
129
+ f.plot_options(
130
+ :pointPadding=>true,
131
+ :borderWidth => 0,
132
+ :enableMouseTracking => false,
133
+ :shadow => false,
134
+ :animation => false,
135
+ :stickyTracking => false
136
+ )
137
+ f.series( :data => bararray,
138
+ :dataLabels => {
139
+ :enabled=>true
140
+ } )
141
+ end
142
+ end
143
+
144
+ def generate_stacked_bar_chart(q, responses, colors)
145
+ @chart[q.id.to_s] = LazyHighCharts::HighChart.new('graph') do |f|
146
+ f.options[:chart][:defaultSeriesType] = 'column'
147
+ f.options[:title][:text] = q.question_group.text
148
+ f.options[:xAxis][:categories] = q.answers.order('answers.id').map{|a| a.text}
149
+ f.options[:xAxis][:labels] = {:rotation=> -45, :align => 'right'}
150
+ f.options[:yAxis][:min] = 0
151
+ f.options[:yAxis][:title] = {:text => 'Count'}
152
+ f.plot_options(
153
+ :column => {
154
+ :stacking => 'normal',
155
+ dataLabels: {
156
+ enabled: true,
157
+ color: 'black',
158
+ style: {
159
+ fontWeight: 'bold',
160
+ fontSize: '12px'
161
+ }
162
+ }
163
+ },
164
+ :pointPadding=>true,
165
+ :borderWidth => 0,
166
+ :enableMouseTracking => false,
167
+ :shadow => false,
168
+ :animation => false,
169
+ :stickyTracking => false
170
+ )
171
+
172
+ q.question_group.questions.where(is_comment: false).each_with_index do |question, question_index|
173
+ bararray = []
174
+ responses.where(:question_id => question.id).each_with_index do |a, answer_index|
175
+ bararray[answer_index]= {:y=> a.answer_count.to_i}
176
+ end
177
+ f.series(
178
+ name: question.text,
179
+ data: bararray,
180
+ color: colors[question_index].to_s
181
+ )
182
+ end
183
+ end
184
+ end
185
+
186
+ def generate_grid_dropdown_bar_chart(q, responses, colors)
187
+ @chart[q.id.to_s] = LazyHighCharts::HighChart.new('graph') do |f|
188
+ f.options[:chart][:defaultSeriesType] = 'column'
189
+ f.options[:title][:text] = q.text
190
+ f.options[:xAxis][:categories] = q.question_group.columns.map{|c| c.text}
191
+ f.options[:xAxis][:labels] = {:rotation=> -45, :align => 'right'}
192
+ f.options[:yAxis][:min] = 0
193
+ f.options[:yAxis][:title] = {:text => 'Count'}
194
+ f.plot_options(
195
+ :column => {
196
+ :stacking => 'normal',
197
+ dataLabels: {
198
+ enabled: true,
199
+ color: 'black',
200
+ style: {
201
+ fontWeight: 'bold',
202
+ fontSize: '12px'
203
+ }
204
+ }
205
+ },
206
+ :pointPadding=>true,
207
+ :borderWidth => 0,
208
+ :enableMouseTracking => false,
209
+ :shadow => false,
210
+ :animation => false,
211
+ :stickyTracking => false
212
+ )
213
+
214
+ series = []
215
+ q.question_group.columns.each_with_index do |column, column_index|
216
+ q.answers.where(column_id: column.id).each_with_index do |answer, answer_index|
217
+ response_count = Response.where(question_id: q.id, answer_id: answer.id, column_id: column.id).count
218
+ series<<{column_id: column.id, answer_id: answer.id, name: answer.text, y: response_count.to_i}
219
+ end
220
+ end
221
+ series.map{|a| a[:name]}.uniq.each_with_index do |answer_name, answer_index|
222
+ bararray=[]
223
+ q.question_group.columns.each do |column|
224
+ match = series.select{|s| s[:name]==answer_name && s[:column_id]==column.id}.first
225
+ bararray << (match ? match[:y] : 0)
226
+ end
227
+ f.series(
228
+ name: answer_name,
229
+ data: bararray,
230
+ color: colors[answer_index].to_s
231
+ )
232
+ end
233
+ end
234
+ end
235
+
236
+ def generate_histogram_chart(q, responses)
237
+ suffix = q.suffix
238
+ histarray = HistogramArray.new(q, responses.where(:question_id => q.id), suffix).calculate
239
+ @chart[q.id.to_s] = LazyHighCharts::HighChart.new('graph') do |f|
240
+ f.options[:chart][:defaultSeriesType] = 'column'
241
+ f.options[:title][:text] = 'Histogram for "'+q.text+'"'
242
+ f.options[:legend][:enabled] = false
243
+ f.options[:xAxis][:categories] = histarray.map{|h| h[:x]}
244
+ f.options[:xAxis][:labels] = {:rotation=> -45, :align => 'right'}
245
+ f.options[:yAxis][:min] = 0
246
+ f.options[:yAxis][:title] = {:text => 'Occurrences'}
247
+ f.plot_options(
248
+ :pointPadding=>true,
249
+ :borderWidth => 0,
250
+ :enableMouseTracking => false,
251
+ :shadow => false,
252
+ :animation => false
253
+ )
254
+ f.series( :data=> histarray.map{|h| h[:y]},
255
+ :dataLabels => {
256
+ :enabled=>true
257
+ }
258
+ )
259
+ end
260
+ end
261
+
262
+ def report_params
263
+ @report_params ||= params.permit(:survey_id, :id)
264
+ end
265
+
266
+ end
267
+
268
+ class HistogramArray
269
+ def initialize(question, in_arr, label=nil)
270
+ @out_arr = []
271
+ p "in arr at init #{in_arr.map{|a| a}}"
272
+ @in_arr = in_arr.map{|a| a.response_value}
273
+ return if in_arr.empty?
274
+ @question = question
275
+ set_min
276
+ set_max
277
+ set_count
278
+ set_distribution
279
+ set_step
280
+ end
281
+
282
+ def calculate
283
+ if !@in_arr.empty?
284
+ @distribution.times do |index|
285
+ refresh_range
286
+ set_x_label
287
+ @out_arr[index]= {
288
+ :x => @x_label,
289
+ :y => @in_arr.select {|v| v.to_f >= @lower_bound && v.to_f < @upper_bound}.count
290
+ }
291
+ end
292
+ end
293
+ return @out_arr
294
+ end
295
+
296
+ private
297
+
298
+ def set_min
299
+ @min = @range = @in_arr.min.to_f
300
+ end
301
+
302
+ def set_max
303
+ @max = @in_arr.max.to_f
304
+ @max = @max + @max.abs*0.00000000001
305
+ end
306
+
307
+ def set_count
308
+ @count = @in_arr.count
309
+ end
310
+
311
+ def set_distribution
312
+ @distribution = sqrt(@count).round
313
+ end
314
+
315
+ def set_step
316
+ @step = ((@max-@min)/@distribution)
317
+ end
318
+
319
+ def refresh_range
320
+ @lower_bound = @range
321
+ @upper_bound = @range+@step
322
+ @range = @upper_bound
323
+ end
324
+
325
+ def trunc_range(num)
326
+ return (num*10000000000).to_i/10000000000
327
+ end
328
+
329
+ def set_x_label
330
+ if @question.question_type_id == :number
331
+ @x_label = trunc_range(@lower_bound).to_s+' to '+trunc_range(@upper_bound).to_s+' '+@label.to_s
332
+ else
333
+ response_formatter = ReportFormatter.new(@question, @in_arr)
334
+ lower_bound = response_formatter.format_stats(@lower_bound)
335
+ upper_bound = response_formatter.format_stats(@upper_bound)
336
+ @x_label = lower_bound+' to '+upper_bound+' '+@label.to_s
337
+ end
338
+ end
339
+ end