diff --git a/app/controllers/analyze_controller.rb b/app/controllers/analyze_controller.rb index 9eaaec4e..e45c8748 100644 --- a/app/controllers/analyze_controller.rb +++ b/app/controllers/analyze_controller.rb @@ -3,7 +3,7 @@ class AnalyzeController < SqmApplicationController before_action :assign_categories, :assign_subcategories, :assign_measures, :assign_academic_years, :response_rate_timestamp, :races, :selected_races, :graph, :graphs, :background, :race_score_timestamp, - :sources, :group, :groups, :selected_grades, :grades, :slice, :genders, only: [:index] + :sources, :group, :groups, :selected_grades, :grades, :slice, :selected_genders, :genders, only: [:index] def index; end private @@ -76,7 +76,7 @@ class AnalyzeController < SqmApplicationController def graphs @graphs ||= [Analyze::Graph::StudentsAndTeachers.new, Analyze::Graph::StudentsByRace.new(races: selected_races), - Analyze::Graph::StudentsByGrade.new(grades: selected_grades)] + Analyze::Graph::StudentsByGrade.new(grades: selected_grades), Analyze::Graph::StudentsByGender.new(genders: selected_genders)] end def background @@ -148,6 +148,21 @@ class AnalyzeController < SqmApplicationController end.keys end + def selected_genders + @selected_genders ||= begin + gender_params = params[:genders] + return @selected_genders = genders unless gender_params + + gender_list = gender_params.split(',') if gender_params + if gender_list + gender_list = gender_list.map do |gender| + Gender.find_by_designation(gender) + end + end + gender_list + end + end + def genders @genders ||= Gender.all end diff --git a/app/javascript/controllers/analyze_controller.js b/app/javascript/controllers/analyze_controller.js index 9276a693..dad9712e 100644 --- a/app/javascript/controllers/analyze_controller.js +++ b/app/javascript/controllers/analyze_controller.js @@ -18,6 +18,8 @@ export default class extends Controller { this.selected_graph() + "&races=" + this.selected_races().join(",") + + "&genders=" + + this.selected_genders().join(",") + "&grades=" + this.selected_grades().join(","); @@ -79,10 +81,10 @@ export default class extends Controller { })[0]; if (selected_graph === 'students-and-teachers') { return selected_graph; - } - - if (this.selected_group() === 'race') { + } else if (this.selected_group() === 'race') { return 'students-by-race' + } else if (this.selected_group() === 'gender'){ + return 'students-by-gender' } else { return 'students-by-grade' } @@ -113,4 +115,17 @@ export default class extends Controller { return grades; } + + selected_genders() { + let gender_checkboxes = [...document.getElementsByName("gender-checkbox")] + let genders = gender_checkboxes + .filter((item) => { + return item.checked; + }) + .map((item) => { + return item.id.replace('gender-', ''); + }); + + return genders; + } } diff --git a/app/models/survey_item_response.rb b/app/models/survey_item_response.rb index 6c35f465..a11ee040 100644 --- a/app/models/survey_item_response.rb +++ b/app/models/survey_item_response.rb @@ -22,4 +22,8 @@ class SurveyItemResponse < ActiveRecord::Base academic_year: , grade:).group(:survey_item).average(:likert_score) } + scope :averages_for_gender, ->(survey_items, school, academic_year, gender) { + SurveyItemResponse.where(survey_item: survey_items, school:, + academic_year: , gender:).group(:survey_item).average(:likert_score) + } end diff --git a/app/presenters/analyze/graph/column/gender/female.rb b/app/presenters/analyze/graph/column/gender/female.rb new file mode 100644 index 00000000..fdcb0b25 --- /dev/null +++ b/app/presenters/analyze/graph/column/gender/female.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +module Analyze + module Graph + module Column + module Gender + class Female < GroupedBarColumnPresenter + include Analyze::Graph::Column::Gender::ScoreForGender + def label + 'Female' + end + + def basis + 'student' + end + + def show_irrelevancy_message? + false + end + + def show_insufficient_data_message? + false + end + + def gender + ::Gender.find_by_qualtrics_code 1 + end + end + end + end + end +end diff --git a/app/presenters/analyze/graph/column/gender/male.rb b/app/presenters/analyze/graph/column/gender/male.rb new file mode 100644 index 00000000..7a3eba06 --- /dev/null +++ b/app/presenters/analyze/graph/column/gender/male.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +module Analyze + module Graph + module Column + module Gender + class Male < GroupedBarColumnPresenter + include Analyze::Graph::Column::Gender::ScoreForGender + def label + 'Male' + end + + def basis + 'student' + end + + def show_irrelevancy_message? + false + end + + def show_insufficient_data_message? + false + end + + def gender + ::Gender.find_by_qualtrics_code 2 + end + end + end + end + end +end diff --git a/app/presenters/analyze/graph/column/gender/non_binary.rb b/app/presenters/analyze/graph/column/gender/non_binary.rb new file mode 100644 index 00000000..25caab34 --- /dev/null +++ b/app/presenters/analyze/graph/column/gender/non_binary.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +module Analyze + module Graph + module Column + module Gender + class NonBinary < GroupedBarColumnPresenter + include Analyze::Graph::Column::Gender::ScoreForGender + def label + 'Non-Binary' + end + + def basis + 'student' + end + + def show_irrelevancy_message? + false + end + + def show_insufficient_data_message? + false + end + + def gender + ::Gender.find_by_qualtrics_code 4 + end + end + end + end + end +end diff --git a/app/presenters/analyze/graph/column/gender/score_for_gender.rb b/app/presenters/analyze/graph/column/gender/score_for_gender.rb new file mode 100644 index 00000000..e904ce7c --- /dev/null +++ b/app/presenters/analyze/graph/column/gender/score_for_gender.rb @@ -0,0 +1,39 @@ +module Analyze + module Graph + module Column + module Gender + module ScoreForGender + def score(year_index) + academic_year = academic_years[year_index] + averages = SurveyItemResponse.averages_for_gender(measure.student_survey_items, school, academic_year, gender) + average = bubble_up_averages(averages:) + + scorify(average:, meets_student_threshold: sufficient_student_responses?(academic_year:)) + end + + def bubble_up_averages(averages:) + measure.student_scales.map do |scale| + scale.survey_items.map do |survey_item| + averages[survey_item] + end.remove_blanks.average + end.remove_blanks.average + end + + def scorify(average:, meets_student_threshold:) + return Score::NIL_SCORE unless meets_student_threshold + + Score.new(average:, + meets_teacher_threshold: false, + meets_student_threshold: true, + meets_admin_data_threshold: false) + end + + def sufficient_student_responses?(academic_year:) + yearly_counts = SurveyItemResponse.where(school: , academic_year: , gender:).group(:gender).select(:response_id).distinct(:response_id).count + yearly_counts.first[1] >= 10 + end + end + end + end + end +end diff --git a/app/presenters/analyze/graph/column/gender/unknown.rb b/app/presenters/analyze/graph/column/gender/unknown.rb new file mode 100644 index 00000000..b0adbf8c --- /dev/null +++ b/app/presenters/analyze/graph/column/gender/unknown.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +module Analyze + module Graph + module Column + module Gender + class Unknown < GroupedBarColumnPresenter + include Analyze::Graph::Column::Gender::ScoreForGender + def label + 'Unknown' + end + + def basis + 'student' + end + + def show_irrelevancy_message? + false + end + + def show_insufficient_data_message? + false + end + + def gender + ::Gender.find_by_qualtrics_code 99 + end + end + end + end + end +end diff --git a/app/presenters/analyze/graph/students_by_gender.rb b/app/presenters/analyze/graph/students_by_gender.rb new file mode 100644 index 00000000..aef0e794 --- /dev/null +++ b/app/presenters/analyze/graph/students_by_gender.rb @@ -0,0 +1,42 @@ +module Analyze + module Graph + class StudentsByGender + include Analyze::Graph::Column::Gender + attr_reader :genders + + def initialize(genders:) + @genders = genders + end + + def to_s + 'Students by Gender' + end + + def slug + 'students-by-gender' + end + + def columns + [].tap do |array| + genders.each do |gender| + array << column_for_gender_code(code: gender.qualtrics_code) + end + array << Analyze::Graph::Column::AllStudent + end + end + + private + + def column_for_gender_code(code:) + CFR[code] + end + + CFR = { + 1 => Analyze::Graph::Column::Gender::Female, + 2 => Analyze::Graph::Column::Gender::Male, + 4 => Analyze::Graph::Column::Gender::NonBinary, + 99 => Analyze::Graph::Column::Gender::Unknown + }.freeze + end + end +end diff --git a/app/services/survey_responses_data_loader.rb b/app/services/survey_responses_data_loader.rb index 678f1d05..6704d6db 100644 --- a/app/services/survey_responses_data_loader.rb +++ b/app/services/survey_responses_data_loader.rb @@ -114,6 +114,7 @@ class Values def gender gender_code = row['gender'] || row['Gender'] || 99 gender_code = gender_code.to_i + gender_code = 4 if gender_code == 3 gender_code = 99 if gender_code.zero? Gender.find_by_qualtrics_code gender_code end diff --git a/app/views/analyze/_data_filters.html.erb b/app/views/analyze/_data_filters.html.erb index fb20e909..f1510033 100644 --- a/app/views/analyze/_data_filters.html.erb +++ b/app/views/analyze/_data_filters.html.erb @@ -64,13 +64,13 @@ <% @genders.each do |gender| %>