feat: add popover to analyze graphs that displays the n-size of the different columns. Make sure to only calculate a score for a race if there are more than 10 respondents to a question.

mciea-main
rebuilt 2 years ago
parent d00288fd71
commit 1265a164b9

@ -12,4 +12,4 @@ Style/Documentation:
Enabled: false Enabled: false
Style/StringLiterals: Style/StringLiterals:
EnforcedStyle: single_quotes EnforcedStyle: double_quotes

@ -5,11 +5,11 @@ module Analyze
class AllData class AllData
include Analyze::Graph::Column include Analyze::Graph::Column
def to_s def to_s
'All Data' "All Data"
end end
def slug def slug
'all-data' "all-data"
end end
def columns def columns

@ -5,11 +5,11 @@ module Analyze
module Column module Column
class AllAdmin < GroupedBarColumnPresenter class AllAdmin < GroupedBarColumnPresenter
def label def label
'All Admin' "All Admin"
end end
def basis def basis
'admin data' "admin data"
end end
def show_irrelevancy_message? def show_irrelevancy_message?
@ -23,12 +23,16 @@ module Analyze
end end
def insufficiency_message def insufficiency_message
['data not', 'available'] ["data not", "available"]
end end
def score(year_index) def score(year_index)
measure.admin_score(school:, academic_year: academic_years[year_index]) measure.admin_score(school:, academic_year: academic_years[year_index])
end end
def type
:admin
end
end end
end end
end end

@ -5,7 +5,7 @@ module Analyze
module Column module Column
class AllStudent < GroupedBarColumnPresenter class AllStudent < GroupedBarColumnPresenter
def label def label
'All Students' "All Students"
end end
def show_irrelevancy_message? def show_irrelevancy_message?
@ -23,6 +23,10 @@ module Analyze
def score(year_index) def score(year_index)
measure.student_score(school:, academic_year: academic_years[year_index]) measure.student_score(school:, academic_year: academic_years[year_index])
end end
def type
:student
end
end end
end end
end end

@ -5,7 +5,7 @@ module Analyze
module Column module Column
class AllSurveyData < GroupedBarColumnPresenter class AllSurveyData < GroupedBarColumnPresenter
def label def label
'Survey Data' "Survey Data"
end end
def show_irrelevancy_message? def show_irrelevancy_message?
@ -24,6 +24,10 @@ module Analyze
combined_score(school:, academic_year: academic_years[year_index]) combined_score(school:, academic_year: academic_years[year_index])
end end
def type
:all_survey_data
end
private private
def combined_score(school:, academic_year:) def combined_score(school:, academic_year:)

@ -5,11 +5,11 @@ module Analyze
module Column module Column
class AllTeacher < GroupedBarColumnPresenter class AllTeacher < GroupedBarColumnPresenter
def label def label
'All Teachers' "All Teachers"
end end
def basis def basis
'teacher surveys' "teacher surveys"
end end
def show_irrelevancy_message? def show_irrelevancy_message?
@ -27,6 +27,15 @@ module Analyze
def score(year_index) def score(year_index)
measure.teacher_score(school:, academic_year: academic_years[year_index]) measure.teacher_score(school:, academic_year: academic_years[year_index])
end end
def type
:teacher
end
def n_size(year_index)
SurveyItemResponse.where(survey_item: measure.teacher_survey_items, school:,
academic_year: academic_years[year_index]).count
end
end end
end end
end end

@ -6,12 +6,13 @@ module Analyze
module GenderColumn module GenderColumn
class Female < GroupedBarColumnPresenter class Female < GroupedBarColumnPresenter
include Analyze::Graph::Column::GenderColumn::ScoreForGender include Analyze::Graph::Column::GenderColumn::ScoreForGender
include Analyze::Graph::Column::GenderColumn::GenderCount
def label def label
'Female' "Female"
end end
def basis def basis
'student' "student"
end end
def show_irrelevancy_message? def show_irrelevancy_message?

@ -0,0 +1,18 @@
module Analyze
module Graph
module Column
module GenderColumn
module GenderCount
def type
:student
end
def n_size(year_index)
SurveyItemResponse.where(gender:, survey_item: measure.student_survey_items, school:, grade: grades(year_index),
academic_year: academic_years[year_index]).select(:response_id).distinct.count
end
end
end
end
end
end

@ -6,12 +6,13 @@ module Analyze
module GenderColumn module GenderColumn
class Male < GroupedBarColumnPresenter class Male < GroupedBarColumnPresenter
include Analyze::Graph::Column::GenderColumn::ScoreForGender include Analyze::Graph::Column::GenderColumn::ScoreForGender
include Analyze::Graph::Column::GenderColumn::GenderCount
def label def label
'Male' "Male"
end end
def basis def basis
'student' "student"
end end
def show_irrelevancy_message? def show_irrelevancy_message?

@ -6,12 +6,13 @@ module Analyze
module GenderColumn module GenderColumn
class NonBinary < GroupedBarColumnPresenter class NonBinary < GroupedBarColumnPresenter
include Analyze::Graph::Column::GenderColumn::ScoreForGender include Analyze::Graph::Column::GenderColumn::ScoreForGender
include Analyze::Graph::Column::GenderColumn::GenderCount
def label def label
'Non-Binary' "Non-Binary"
end end
def basis def basis
'student' "student"
end end
def show_irrelevancy_message? def show_irrelevancy_message?

@ -6,12 +6,13 @@ module Analyze
module GenderColumn module GenderColumn
class Unknown < GroupedBarColumnPresenter class Unknown < GroupedBarColumnPresenter
include Analyze::Graph::Column::GenderColumn::ScoreForGender include Analyze::Graph::Column::GenderColumn::ScoreForGender
include Analyze::Graph::Column::GenderColumn::GenderCount
def label def label
'Unknown' "Unknown"
end end
def basis def basis
'student' "student"
end end
def show_irrelevancy_message? def show_irrelevancy_message?

@ -6,12 +6,13 @@ module Analyze
module Grade module Grade
class Eight < GroupedBarColumnPresenter class Eight < GroupedBarColumnPresenter
include Analyze::Graph::Column::Grade::ScoreForGrade include Analyze::Graph::Column::Grade::ScoreForGrade
include Analyze::Graph::Column::Grade::GradeCount
def label def label
'Grade 8' "Grade 8"
end end
def basis def basis
'student' "student"
end end
def show_irrelevancy_message? def show_irrelevancy_message?
@ -30,4 +31,3 @@ module Analyze
end end
end end
end end

@ -6,12 +6,13 @@ module Analyze
module Grade module Grade
class Eleven < GroupedBarColumnPresenter class Eleven < GroupedBarColumnPresenter
include Analyze::Graph::Column::Grade::ScoreForGrade include Analyze::Graph::Column::Grade::ScoreForGrade
include Analyze::Graph::Column::Grade::GradeCount
def label def label
'Grade 11' "Grade 11"
end end
def basis def basis
'student' "student"
end end
def show_irrelevancy_message? def show_irrelevancy_message?
@ -30,4 +31,3 @@ module Analyze
end end
end end
end end

@ -6,12 +6,13 @@ module Analyze
module Grade module Grade
class Five < GroupedBarColumnPresenter class Five < GroupedBarColumnPresenter
include Analyze::Graph::Column::Grade::ScoreForGrade include Analyze::Graph::Column::Grade::ScoreForGrade
include Analyze::Graph::Column::Grade::GradeCount
def label def label
'Grade 5' "Grade 5"
end end
def basis def basis
'student' "student"
end end
def show_irrelevancy_message? def show_irrelevancy_message?

@ -6,12 +6,13 @@ module Analyze
module Grade module Grade
class Four < GroupedBarColumnPresenter class Four < GroupedBarColumnPresenter
include Analyze::Graph::Column::Grade::ScoreForGrade include Analyze::Graph::Column::Grade::ScoreForGrade
include Analyze::Graph::Column::Grade::GradeCount
def label def label
'Grade 4' "Grade 4"
end end
def basis def basis
'student' "student"
end end
def show_irrelevancy_message? def show_irrelevancy_message?

@ -0,0 +1,18 @@
module Analyze
module Graph
module Column
module Grade
module GradeCount
def type
:student
end
def n_size(year_index)
SurveyItemResponse.where(grade:, survey_item: measure.student_survey_items, school:,
academic_year: academic_years[year_index]).select(:response_id).distinct.count
end
end
end
end
end
end

@ -6,12 +6,13 @@ module Analyze
module Grade module Grade
class Nine < GroupedBarColumnPresenter class Nine < GroupedBarColumnPresenter
include Analyze::Graph::Column::Grade::ScoreForGrade include Analyze::Graph::Column::Grade::ScoreForGrade
include Analyze::Graph::Column::Grade::GradeCount
def label def label
'Grade 9' "Grade 9"
end end
def basis def basis
'student' "student"
end end
def show_irrelevancy_message? def show_irrelevancy_message?
@ -30,5 +31,3 @@ module Analyze
end end
end end
end end

@ -6,12 +6,13 @@ module Analyze
module Grade module Grade
class One < GroupedBarColumnPresenter class One < GroupedBarColumnPresenter
include Analyze::Graph::Column::Grade::ScoreForGrade include Analyze::Graph::Column::Grade::ScoreForGrade
include Analyze::Graph::Column::Grade::GradeCount
def label def label
'Grade 1' "Grade 1"
end end
def basis def basis
'student' "student"
end end
def show_irrelevancy_message? def show_irrelevancy_message?

@ -6,12 +6,13 @@ module Analyze
module Grade module Grade
class Seven < GroupedBarColumnPresenter class Seven < GroupedBarColumnPresenter
include Analyze::Graph::Column::Grade::ScoreForGrade include Analyze::Graph::Column::Grade::ScoreForGrade
include Analyze::Graph::Column::Grade::GradeCount
def label def label
'Grade 7' "Grade 7"
end end
def basis def basis
'student' "student"
end end
def show_irrelevancy_message? def show_irrelevancy_message?

@ -6,12 +6,13 @@ module Analyze
module Grade module Grade
class Six < GroupedBarColumnPresenter class Six < GroupedBarColumnPresenter
include Analyze::Graph::Column::Grade::ScoreForGrade include Analyze::Graph::Column::Grade::ScoreForGrade
include Analyze::Graph::Column::Grade::GradeCount
def label def label
'Grade 6' "Grade 6"
end end
def basis def basis
'student' "student"
end end
def show_irrelevancy_message? def show_irrelevancy_message?

@ -6,12 +6,13 @@ module Analyze
module Grade module Grade
class Ten < GroupedBarColumnPresenter class Ten < GroupedBarColumnPresenter
include Analyze::Graph::Column::Grade::ScoreForGrade include Analyze::Graph::Column::Grade::ScoreForGrade
include Analyze::Graph::Column::Grade::GradeCount
def label def label
'Grade 10' "Grade 10"
end end
def basis def basis
'student' "student"
end end
def show_irrelevancy_message? def show_irrelevancy_message?
@ -30,5 +31,3 @@ module Analyze
end end
end end
end end

@ -6,12 +6,13 @@ module Analyze
module Grade module Grade
class Three < GroupedBarColumnPresenter class Three < GroupedBarColumnPresenter
include Analyze::Graph::Column::Grade::ScoreForGrade include Analyze::Graph::Column::Grade::ScoreForGrade
include Analyze::Graph::Column::Grade::GradeCount
def label def label
'Grade 3' "Grade 3"
end end
def basis def basis
'student' "student"
end end
def show_irrelevancy_message? def show_irrelevancy_message?

@ -6,12 +6,13 @@ module Analyze
module Grade module Grade
class Twelve < GroupedBarColumnPresenter class Twelve < GroupedBarColumnPresenter
include Analyze::Graph::Column::Grade::ScoreForGrade include Analyze::Graph::Column::Grade::ScoreForGrade
include Analyze::Graph::Column::Grade::GradeCount
def label def label
'Grade 12' "Grade 12"
end end
def basis def basis
'student' "student"
end end
def show_irrelevancy_message? def show_irrelevancy_message?
@ -30,5 +31,3 @@ module Analyze
end end
end end
end end

@ -8,12 +8,13 @@ module Analyze
attr_reader :sufficient_responses attr_reader :sufficient_responses
include Analyze::Graph::Column::Grade::ScoreForGrade include Analyze::Graph::Column::Grade::ScoreForGrade
include Analyze::Graph::Column::Grade::GradeCount
def label def label
'Grade 2' "Grade 2"
end end
def basis def basis
'student' "student"
end end
def show_irrelevancy_message? def show_irrelevancy_message?

@ -0,0 +1,33 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module Grade
class Zero < GroupedBarColumnPresenter
include Analyze::Graph::Column::Grade::ScoreForGrade
include Analyze::Graph::Column::Grade::GradeCount
def label
"Kindergarten"
end
def basis
"student"
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def grade
0
end
end
end
end
end
end

@ -35,11 +35,11 @@ module Analyze
end end
def label def label
'All Data' "All Data"
end end
def basis def basis
'' ""
end end
def show_irrelevancy_message? def show_irrelevancy_message?
@ -106,11 +106,43 @@ module Analyze
end end
def basis def basis
'student surveys' "student surveys"
end
def type
:all_data
end
def show_popover?
%i[student teacher].include? type
end
def n_size(year_index)
SurveyItemResponse.where(survey_item: measure.student_survey_items, school:, grade: grades(year_index),
academic_year: academic_years[year_index]).select(:response_id).distinct.count
end
def popover_content(year_index)
"#{n_size(year_index)} #{type.to_s.capitalize}s"
end end
def insufficiency_message def insufficiency_message
['survey response', 'rate below 25%'] ["survey response", "rate below 25%"]
end
def sufficient_data?(year_index)
case basis
when "student"
score(year_index).meets_student_threshold
when "teacher"
score(year_index).meets_teacher_threshold
else
true
end
end
def grades(year_index)
Respondent.find_by(school:, academic_year: academic_years[year_index]).counts_by_grade.keys
end end
private private

@ -0,0 +1,29 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module IncomeColumn
class Disadvantaged < GroupedBarColumnPresenter
include Analyze::Graph::Column::IncomeColumn::ScoreForIncome
include Analyze::Graph::Column::IncomeColumn::IncomeCount
def label
"Economically Disadvantaged"
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def income
Income.find_by_designation "Economically Disadvantaged - Y"
end
end
end
end
end
end

@ -0,0 +1,18 @@
module Analyze
module Graph
module Column
module IncomeColumn
module IncomeCount
def type
:student
end
def n_size(year_index)
SurveyItemResponse.where(income:, survey_item: measure.student_survey_items, school:, grade: grades(year_index),
academic_year: academic_years[year_index]).select(:response_id).distinct.count
end
end
end
end
end
end

@ -0,0 +1,29 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module IncomeColumn
class NotDisadvantaged < GroupedBarColumnPresenter
include Analyze::Graph::Column::IncomeColumn::ScoreForIncome
include Analyze::Graph::Column::IncomeColumn::IncomeCount
def label
"Not Disadvantaged"
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def income
Income.find_by_designation "Economically Disadvantaged - N"
end
end
end
end
end
end

@ -0,0 +1,29 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module IncomeColumn
class Unknown < GroupedBarColumnPresenter
include Analyze::Graph::Column::IncomeColumn::ScoreForIncome
include Analyze::Graph::Column::IncomeColumn::IncomeCount
def label
"Unknown"
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def income
Income.find_by_designation "Unknown"
end
end
end
end
end
end

@ -6,8 +6,9 @@ module Analyze
module RaceColumn module RaceColumn
class AmericanIndian < GroupedBarColumnPresenter class AmericanIndian < GroupedBarColumnPresenter
include Analyze::Graph::Column::ScoreForRace include Analyze::Graph::Column::ScoreForRace
include Analyze::Graph::Column::RaceColumn::RaceCount
def label def label
'American Indian' "American Indian"
end end
def show_irrelevancy_message? def show_irrelevancy_message?

@ -6,8 +6,9 @@ module Analyze
module RaceColumn module RaceColumn
class Asian < GroupedBarColumnPresenter class Asian < GroupedBarColumnPresenter
include Analyze::Graph::Column::ScoreForRace include Analyze::Graph::Column::ScoreForRace
include Analyze::Graph::Column::RaceColumn::RaceCount
def label def label
'Asian' "Asian"
end end
def show_irrelevancy_message? def show_irrelevancy_message?

@ -6,8 +6,9 @@ module Analyze
module RaceColumn module RaceColumn
class Black < GroupedBarColumnPresenter class Black < GroupedBarColumnPresenter
include Analyze::Graph::Column::ScoreForRace include Analyze::Graph::Column::ScoreForRace
include Analyze::Graph::Column::RaceColumn::RaceCount
def label def label
'Black' "Black"
end end
def show_irrelevancy_message? def show_irrelevancy_message?

@ -6,8 +6,9 @@ module Analyze
module RaceColumn module RaceColumn
class Hispanic < GroupedBarColumnPresenter class Hispanic < GroupedBarColumnPresenter
include Analyze::Graph::Column::ScoreForRace include Analyze::Graph::Column::ScoreForRace
include Analyze::Graph::Column::RaceColumn::RaceCount
def label def label
'Hispanic' "Hispanic"
end end
def show_irrelevancy_message? def show_irrelevancy_message?

@ -6,9 +6,10 @@ module Analyze
module RaceColumn module RaceColumn
class MiddleEastern < GroupedBarColumnPresenter class MiddleEastern < GroupedBarColumnPresenter
include Analyze::Graph::Column::ScoreForRace include Analyze::Graph::Column::ScoreForRace
include Analyze::Graph::Column::RaceColumn::RaceCount
def label def label
'Middle Eastern' "Middle Eastern"
end end
def show_irrelevancy_message? def show_irrelevancy_message?

@ -6,8 +6,9 @@ module Analyze
module RaceColumn module RaceColumn
class Multiracial < GroupedBarColumnPresenter class Multiracial < GroupedBarColumnPresenter
include Analyze::Graph::Column::ScoreForRace include Analyze::Graph::Column::ScoreForRace
include Analyze::Graph::Column::RaceColumn::RaceCount
def label def label
'Multiracial' "Multiracial"
end end
def show_irrelevancy_message? def show_irrelevancy_message?

@ -0,0 +1,20 @@
module Analyze
module Graph
module Column
module RaceColumn
module RaceCount
def type
:student
end
def n_size(year_index)
SurveyItemResponse.joins("JOIN student_races on survey_item_responses.student_id = student_races.student_id JOIN students on students.id = student_races.student_id").where(
school:, academic_year: academic_years[year_index],
survey_item: measure.student_survey_items
).where("student_races.race_id": race.id).select(:response_id).distinct.count
end
end
end
end
end
end

@ -6,8 +6,9 @@ module Analyze
module RaceColumn module RaceColumn
class Unknown < GroupedBarColumnPresenter class Unknown < GroupedBarColumnPresenter
include Analyze::Graph::Column::ScoreForRace include Analyze::Graph::Column::ScoreForRace
include Analyze::Graph::Column::RaceColumn::RaceCount
def label def label
'Not Listed' "Not Listed"
end end
def show_irrelevancy_message? def show_irrelevancy_message?

@ -6,8 +6,9 @@ module Analyze
module RaceColumn module RaceColumn
class White < GroupedBarColumnPresenter class White < GroupedBarColumnPresenter
include Analyze::Graph::Column::ScoreForRace include Analyze::Graph::Column::ScoreForRace
include Analyze::Graph::Column::RaceColumn::RaceCount
def label def label
'White' "White"
end end
def show_irrelevancy_message? def show_irrelevancy_message?

@ -60,9 +60,9 @@ class RaceScoreLoader
def self.grouped_responses(school:, academic_year:, survey_items:, race:) def self.grouped_responses(school:, academic_year:, survey_items:, race:)
@grouped_responses ||= Hash.new do |memo, (school, academic_year, survey_items, race)| @grouped_responses ||= Hash.new do |memo, (school, academic_year, survey_items, race)|
memo[[school, academic_year, survey_items, race]] = memo[[school, academic_year, survey_items, race]] =
SurveyItemResponse.joins('JOIN student_races on survey_item_responses.student_id = student_races.student_id JOIN students on students.id = student_races.student_id').where( SurveyItemResponse.joins("JOIN student_races on survey_item_responses.student_id = student_races.student_id JOIN students on students.id = student_races.student_id").where(
school:, academic_year: school:, academic_year:
).where("student_races.race_id": race.id).group(:survey_item_id).average(:likert_score) ).where("student_races.race_id": race.id).group(:survey_item_id).having("count(*) >= 10").average(:likert_score)
end end
@grouped_responses[[school, academic_year, survey_items, race]] @grouped_responses[[school, academic_year, survey_items, race]]
@ -88,7 +88,7 @@ class RaceScoreLoader
def self.sufficient_responses(school:, academic_year:, race:) def self.sufficient_responses(school:, academic_year:, race:)
@sufficient_responses ||= Hash.new do |memo, (school, academic_year, race)| @sufficient_responses ||= Hash.new do |memo, (school, academic_year, race)|
number_of_students_for_a_racial_group = SurveyItemResponse.joins('JOIN student_races on survey_item_responses.student_id = student_races.student_id JOIN students on students.id = student_races.student_id').where( number_of_students_for_a_racial_group = SurveyItemResponse.joins("JOIN student_races on survey_item_responses.student_id = student_races.student_id JOIN students on students.id = student_races.student_id").where(
school:, academic_year: school:, academic_year:
).where("student_races.race_id": race.id).distinct.pluck(:student_id).count ).where("student_races.race_id": race.id).distinct.pluck(:student_id).count
memo[[school, academic_year, race]] = number_of_students_for_a_racial_group >= 10 memo[[school, academic_year, race]] = number_of_students_for_a_racial_group >= 10

@ -1,12 +1,26 @@
<g class="grouped-bar-column" data-for-measure-id="<%= column.measure.measure_id %>"> <g class="grouped-bar-column" data-for-measure-id="<%= column.measure.measure_id %>">
<% score_label_y = [5, 10, 15, 5, 10, 15 ] %> <% score_label_y = [5, 10, 15, 5, 10, 15 ] %>
<% column.bars.each_with_index do |bar, index| %> <% column.bars.each_with_index do |bar, index| %>
<rect data-for-academic-year="<%= bar.academic_year.range %>" x="<%= bar.x_position %>%" y="<%= bar.y_offset %>%" width="<%= column.bar_width %>%" height="<%= bar.bar_height_percentage %>%" fill="<%= bar.color %>" /> <% if column.sufficient_data?(index) %>
<rect
<% if column.show_popover? %>
data-bs-toggle="popover"
data-bs-placement="right"
data-bs-content="<%= column.popover_content(index) %>"
<% end %>
data-for-academic-year="<%= bar.academic_year.range %>"
x="<%= bar.x_position %>%"
y="<%= bar.y_offset %>%"
width="<%= column.bar_width %>%"
height="<%= bar.bar_height_percentage %>%"
fill="<%= bar.color %>" />
<% if ENV["SCORES"].present? && ENV["SCORES"].upcase == "SHOW" %>
<text x="<%= bar.x_position + (column.bar_width * 0.5) %>%" y="<%= score_label_y[index] %>%" text-anchor="middle" dominant-baseline="middle">
<%= bar.average %>
</text>
<% end %>
<% if ENV["SCORES"].present? && ENV["SCORES"].upcase == "SHOW" %>
<text x="<%= bar.x_position + (column.bar_width * 0.5) %>%" y="<%= score_label_y[index] %>%" text-anchor="middle" dominant-baseline="middle">
<%= bar.average %>
</text>
<% end %> <% end %>
<% end %> <% end %>

@ -0,0 +1,15 @@
describe('navigates the analyze page', () => {
it('it displays counts of students and teacher in the hovers', () => {
login("/districts/lee-public-schools/schools/lee-elementary-school/analyze?year=2022-23&academic_years=2022-23", "bGVlOmxlZSE=")
})
})
function login(path, credentials) {
cy.visit(path, {
headers: {
authorization: `Basic ${credentials}`
},
failOnStatusCode: false
})
}
Loading…
Cancel
Save