chore: show analyze page without errors

main
Nelson Jovel 2 years ago
parent e4e6a5c7fb
commit b47f8d2f61

@ -7,7 +7,6 @@ module Dashboard
def show
@categories = Category.sorted.map { |category| CategoryPresenter.new(category:) }
puts params
@category = CategoryPresenter.new(category: Category.find_by_slug(params[:id]))
end
end

@ -45,7 +45,7 @@ module Dashboard
@empty_dataset ||= Hash.new do |memo, (school, academic_year)|
memo[[school, academic_year]] = measures.none? do |measure|
response_rate = measure.subcategory.response_rate(school:, academic_year:)
response_rate.meets_student_threshold || response_rate.meets_teacher_threshold || measure.sufficient_admin_data?(school:, academic_year:)
response_rate.meets_student_threshold? || response_rate.meets_teacher_threshold? || measure.sufficient_admin_data?(school:, academic_year:)
end
end
@ -56,7 +56,7 @@ module Dashboard
@empty_survey_dataset ||= Hash.new do |memo, (school, academic_year)|
memo[[school, academic_year]] = measures.none? do |measure|
response_rate = measure.subcategory.response_rate(school:, academic_year:)
response_rate.meets_student_threshold || response_rate.meets_teacher_threshold
response_rate.meets_student_threshold? || response_rate.meets_teacher_threshold?
end
end
@empty_survey_dataset[[school, academic_year]]

@ -3,16 +3,16 @@
module Dashboard
module HeaderHelper
def link_to_overview(district:, school:, academic_year:)
"/districts/#{district.slug}/schools/#{school.slug}/overview?year=#{academic_year.range}"
district_school_overview_index_path(district, school, year: academic_year.range)
end
def link_to_browse(district:, school:, academic_year:)
"/districts/#{district.slug}/schools/#{school.slug}/browse/teachers-leadership?year=#{academic_year.range}"
district_school_category_path(district, school, { year: academic_year.range, id: "teachers-leadership" })
end
def link_to_analyze(district:, school:, academic_year:)
year = academic_year.range
"/districts/#{district.slug}/schools/#{school.slug}/analyze?year=#{year}&category=1&academic_years=#{year}"
district_school_analyze_index_path(district, school, { year:, category: 1, academic_years: year })
end
def district_url_for(district:, academic_year:)

@ -1,85 +1,87 @@
# frozen_string_literal: true
module Analyze
class BarPresenter
include AnalyzeHelper
attr_reader :score, :x_position, :academic_year, :measure_id, :measure, :color
MINIMUM_BAR_HEIGHT = 2
def initialize(measure:, academic_year:, score:, x_position:, color:)
@score = score
@x_position = x_position
@academic_year = academic_year
@measure = measure
@measure_id = measure.measure_id
@color = color
end
module Dashboard
module Analyze
class BarPresenter
include AnalyzeHelper
attr_reader :score, :x_position, :academic_year, :measure_id, :measure, :color
MINIMUM_BAR_HEIGHT = 2
def initialize(measure:, academic_year:, score:, x_position:, color:)
@score = score
@x_position = x_position
@academic_year = academic_year
@measure = measure
@measure_id = measure.measure_id
@color = color
end
def y_offset
benchmark_height = analyze_zone_height * 2
case zone.type
when :ideal, :approval
benchmark_height - bar_height_percentage
else
benchmark_height
def y_offset
benchmark_height = analyze_zone_height * 2
case zone.type
when :ideal, :approval
benchmark_height - bar_height_percentage
else
benchmark_height
end
end
end
def bar_color
"fill-#{zone.type}"
end
def bar_color
"fill-#{zone.type}"
end
def bar_height_percentage
bar_height = send("#{zone.type}_bar_height_percentage") || 0
enforce_minimum_height(bar_height:)
end
def bar_height_percentage
bar_height = send("#{zone.type}_bar_height_percentage") || 0
enforce_minimum_height(bar_height:)
end
def percentage
low_benchmark = zone.low_benchmark
(score.average - low_benchmark) / (zone.high_benchmark - low_benchmark)
end
def percentage
low_benchmark = zone.low_benchmark
(score.average - low_benchmark) / (zone.high_benchmark - low_benchmark)
end
def zone
zones = Zones.new(
watch_low_benchmark: measure.watch_low_benchmark,
growth_low_benchmark: measure.growth_low_benchmark,
approval_low_benchmark: measure.approval_low_benchmark,
ideal_low_benchmark: measure.ideal_low_benchmark
)
zones.zone_for_score(score.average)
end
def zone
zones = Zones.new(
watch_low_benchmark: measure.watch_low_benchmark,
growth_low_benchmark: measure.growth_low_benchmark,
approval_low_benchmark: measure.approval_low_benchmark,
ideal_low_benchmark: measure.ideal_low_benchmark
)
zones.zone_for_score(score.average)
end
def average
average = score.average || 0
def average
average = score.average || 0
average.round(6)
end
average.round(6)
end
private
private
def enforce_minimum_height(bar_height:)
bar_height < MINIMUM_BAR_HEIGHT ? MINIMUM_BAR_HEIGHT : bar_height
end
def enforce_minimum_height(bar_height:)
bar_height < MINIMUM_BAR_HEIGHT ? MINIMUM_BAR_HEIGHT : bar_height
end
def ideal_bar_height_percentage
(percentage * zone_height_percentage + zone_height_percentage) * 100
end
def ideal_bar_height_percentage
(percentage * zone_height_percentage + zone_height_percentage) * 100
end
def approval_bar_height_percentage
(percentage * zone_height_percentage) * 100
end
def approval_bar_height_percentage
(percentage * zone_height_percentage) * 100
end
def growth_bar_height_percentage
((1 - percentage) * zone_height_percentage) * 100
end
def growth_bar_height_percentage
((1 - percentage) * zone_height_percentage) * 100
end
def watch_bar_height_percentage
((1 - percentage) * zone_height_percentage + zone_height_percentage) * 100
end
def watch_bar_height_percentage
((1 - percentage) * zone_height_percentage + zone_height_percentage) * 100
end
def warning_bar_height_percentage
((1 - percentage) * zone_height_percentage + zone_height_percentage + zone_height_percentage) * 100
def warning_bar_height_percentage
((1 - percentage) * zone_height_percentage + zone_height_percentage + zone_height_percentage) * 100
end
end
end
end

@ -1,19 +1,21 @@
# frozen_string_literal: true
module Analyze
module Graph
class AllData
include Analyze::Graph::Column
def to_s
"All Data"
end
module Dashboard
module Analyze
module Graph
class AllData
include Analyze::Graph::Column
def to_s
"All Data"
end
def slug
"all-data"
end
def slug
"all-data"
end
def columns
[AllStudent, AllTeacher, AllAdmin, GroupedBarColumnPresenter]
def columns
[AllStudent, AllTeacher, AllAdmin, GroupedBarColumnPresenter]
end
end
end
end

@ -1,37 +1,39 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
class AllAdmin < GroupedBarColumnPresenter
def label
%w[All Admin]
end
module Dashboard
module Analyze
module Graph
module Column
class AllAdmin < GroupedBarColumnPresenter
def label
%w[All Admin]
end
def basis
"admin data"
end
def basis
"admin data"
end
def show_irrelevancy_message?
!measure.includes_admin_data_items?
end
def show_irrelevancy_message?
!measure.includes_admin_data_items?
end
def show_insufficient_data_message?
!academic_years.any? do |year|
measure.sufficient_admin_data?(school:, academic_year: year)
def show_insufficient_data_message?
!academic_years.any? do |year|
measure.sufficient_admin_data?(school:, academic_year: year)
end
end
end
def insufficiency_message
["data not", "available"]
end
def insufficiency_message
["data not", "available"]
end
def score(year_index)
measure.admin_score(school:, academic_year: academic_years[year_index])
end
def score(year_index)
measure.admin_score(school:, academic_year: academic_years[year_index])
end
def type
:admin
def type
:admin
end
end
end
end

@ -1,31 +1,33 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
class AllStudent < GroupedBarColumnPresenter
def label
%w[All Students]
end
def show_irrelevancy_message?
!measure.includes_student_survey_items?
end
module Dashboard
module Analyze
module Graph
module Column
class AllStudent < GroupedBarColumnPresenter
def label
%w[All Students]
end
def show_insufficient_data_message?
scores = academic_years.map do |year|
measure.score(school:, academic_year: year)
def show_irrelevancy_message?
!measure.includes_student_survey_items?
end
scores.all? { |score| !score.meets_student_threshold? }
end
def show_insufficient_data_message?
scores = academic_years.map do |year|
measure.score(school:, academic_year: year)
end
def score(year_index)
measure.student_score(school:, academic_year: academic_years[year_index])
end
scores.all? { |score| !score.meets_student_threshold? }
end
def type
:student
def score(year_index)
measure.student_score(school:, academic_year: academic_years[year_index])
end
def type
:student
end
end
end
end

@ -1,45 +1,47 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
class AllSurveyData < GroupedBarColumnPresenter
def label
%w[Survey Data]
end
def show_irrelevancy_message?
false
end
module Dashboard
module Analyze
module Graph
module Column
class AllSurveyData < GroupedBarColumnPresenter
def label
%w[Survey Data]
end
def show_insufficient_data_message?
scores = academic_years.map do |year|
combined_score(school:, academic_year: year)
def show_irrelevancy_message?
false
end
scores.all? { |score| !score.meets_student_threshold? && !score.meets_teacher_threshold? }
end
def show_insufficient_data_message?
scores = academic_years.map do |year|
combined_score(school:, academic_year: year)
end
def score(year_index)
combined_score(school:, academic_year: academic_years[year_index])
end
scores.all? { |score| !score.meets_student_threshold? && !score.meets_teacher_threshold? }
end
def type
:all_survey_data
end
def score(year_index)
combined_score(school:, academic_year: academic_years[year_index])
end
private
def type
:all_survey_data
end
private
def combined_score(school:, academic_year:)
teacher_score = measure.teacher_score(school:, academic_year:)
student_score = measure.student_score(school:, academic_year:)
def combined_score(school:, academic_year:)
teacher_score = measure.teacher_score(school:, academic_year:)
student_score = measure.student_score(school:, academic_year:)
averages = []
averages << student_score.average unless student_score.average.nil?
averages << teacher_score.average unless teacher_score.average.nil?
average = averages.average if averages.length > 0
combined_score = Score.new(average:, meets_student_threshold: student_score.meets_student_threshold,
meets_teacher_threshold: teacher_score.meets_teacher_threshold)
averages = []
averages << student_score.average unless student_score.average.nil?
averages << teacher_score.average unless teacher_score.average.nil?
average = averages.average if averages.length > 0
combined_score = Score.new(average:, meets_student_threshold: student_score.meets_student_threshold,
meets_teacher_threshold: teacher_score.meets_teacher_threshold)
end
end
end
end

@ -1,40 +1,42 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
class AllTeacher < GroupedBarColumnPresenter
def label
%w[All Teachers]
end
def basis
"teacher surveys"
end
module Dashboard
module Analyze
module Graph
module Column
class AllTeacher < GroupedBarColumnPresenter
def label
%w[All Teachers]
end
def show_irrelevancy_message?
!measure.includes_teacher_survey_items?
end
def basis
"teacher surveys"
end
def show_insufficient_data_message?
scores = academic_years.map do |year|
measure.score(school:, academic_year: year)
def show_irrelevancy_message?
!measure.includes_teacher_survey_items?
end
scores.all? { |score| !score.meets_teacher_threshold? }
end
def show_insufficient_data_message?
scores = academic_years.map do |year|
measure.score(school:, academic_year: year)
end
def score(year_index)
measure.teacher_score(school:, academic_year: academic_years[year_index])
end
scores.all? { |score| !score.meets_teacher_threshold? }
end
def type
:teacher
end
def score(year_index)
measure.teacher_score(school:, academic_year: academic_years[year_index])
end
def n_size(year_index)
SurveyItemResponse.where(survey_item: measure.teacher_survey_items, school:,
academic_year: academic_years[year_index]).select(:response_id).distinct.count
def type
:teacher
end
def n_size(year_index)
SurveyItemResponse.where(survey_item: measure.teacher_survey_items, school:,
academic_year: academic_years[year_index]).select(:response_id).distinct.count
end
end
end
end

@ -1,30 +1,32 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module EllColumn
class Ell < GroupedBarColumnPresenter
include Analyze::Graph::Column::EllColumn::ScoreForEll
include Analyze::Graph::Column::EllColumn::EllCount
def label
%w[ELL]
end
module Dashboard
module Analyze
module Graph
module Column
module EllColumn
class Ell < GroupedBarColumnPresenter
include Analyze::Graph::Column::EllColumn::ScoreForEll
include Analyze::Graph::Column::EllColumn::EllCount
def label
%w[ELL]
end
def basis
"student"
end
def basis
"student"
end
def show_irrelevancy_message?
false
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def show_insufficient_data_message?
false
end
def ell
::Ell.find_by_slug "ell"
def ell
::Ell.find_by_slug "ell"
end
end
end
end

@ -1,15 +1,19 @@
module Analyze
module Graph
module Column
module EllColumn
module EllCount
def type
:student
end
# frozen_string_literal: true
module Dashboard
module Analyze
module Graph
module Column
module EllColumn
module EllCount
def type
:student
end
def n_size(year_index)
SurveyItemResponse.where(ell:, survey_item: measure.student_survey_items, school:, grade: grades(year_index),
academic_year: academic_years[year_index]).select(:response_id).distinct.count
def n_size(year_index)
SurveyItemResponse.where(ell:, 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

@ -1,30 +1,32 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module EllColumn
class NotEll < GroupedBarColumnPresenter
include Analyze::Graph::Column::EllColumn::ScoreForEll
include Analyze::Graph::Column::EllColumn::EllCount
def label
["Not ELL"]
end
module Dashboard
module Analyze
module Graph
module Column
module EllColumn
class NotEll < GroupedBarColumnPresenter
include Analyze::Graph::Column::EllColumn::ScoreForEll
include Analyze::Graph::Column::EllColumn::EllCount
def label
["Not ELL"]
end
def basis
"student"
end
def basis
"student"
end
def show_irrelevancy_message?
false
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def show_insufficient_data_message?
false
end
def ell
::Ell.find_by_slug "not-ell"
def ell
Ell.find_by_slug "not-ell"
end
end
end
end

@ -1,38 +1,42 @@
module Analyze
module Graph
module Column
module EllColumn
module ScoreForEll
def score(year_index)
academic_year = academic_years[year_index]
meets_student_threshold = sufficient_student_responses?(academic_year:)
return Score::NIL_SCORE unless meets_student_threshold
# frozen_string_literal: true
averages = SurveyItemResponse.averages_for_ell(measure.student_survey_items, school, academic_year,
ell)
average = bubble_up_averages(averages:).round(2)
module Dashboard
module Analyze
module Graph
module Column
module EllColumn
module ScoreForEll
def score(year_index)
academic_year = academic_years[year_index]
meets_student_threshold = sufficient_student_responses?(academic_year:)
return Score::NIL_SCORE unless meets_student_threshold
Score.new(average:,
meets_teacher_threshold: false,
meets_student_threshold:,
meets_admin_data_threshold: false)
end
averages = SurveyItemResponse.averages_for_ell(measure.student_survey_items, school, academic_year,
ell)
average = bubble_up_averages(averages:).round(2)
Score.new(average:,
meets_teacher_threshold: false,
meets_student_threshold:,
meets_admin_data_threshold: false)
end
def bubble_up_averages(averages:)
measure.student_scales.map do |scale|
scale.survey_items.map do |survey_item|
averages[survey_item]
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.remove_blanks.average
end
end
def sufficient_student_responses?(academic_year:)
return false unless measure.subcategory.response_rate(school:, academic_year:).meets_student_threshold?
def sufficient_student_responses?(academic_year:)
return false unless measure.subcategory.response_rate(school:, academic_year:).meets_student_threshold?
yearly_counts = SurveyItemResponse.where(school:, academic_year:,
ell:, survey_item: measure.student_survey_items).group(:ell).select(:response_id).distinct(:response_id).count
yearly_counts.any? do |count|
count[1] >= 10
yearly_counts = SurveyItemResponse.where(school:, academic_year:,
ell:, survey_item: measure.student_survey_items).group(:ell).select(:response_id).distinct(:response_id).count
yearly_counts.any? do |count|
count[1] >= 10
end
end
end
end

@ -1,30 +1,32 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module EllColumn
class Unknown < GroupedBarColumnPresenter
include Analyze::Graph::Column::EllColumn::ScoreForEll
include Analyze::Graph::Column::EllColumn::EllCount
def label
%w[Unknown]
end
module Dashboard
module Analyze
module Graph
module Column
module EllColumn
class Unknown < GroupedBarColumnPresenter
include Analyze::Graph::Column::EllColumn::ScoreForEll
include Analyze::Graph::Column::EllColumn::EllCount
def label
%w[Unknown]
end
def basis
"student"
end
def basis
"student"
end
def show_irrelevancy_message?
false
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def show_insufficient_data_message?
false
end
def ell
::Ell.find_by_slug "unknown"
def ell
Ell.find_by_slug "unknown"
end
end
end
end

@ -1,30 +1,32 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module GenderColumn
class Female < GroupedBarColumnPresenter
include Analyze::Graph::Column::GenderColumn::ScoreForGender
include Analyze::Graph::Column::GenderColumn::GenderCount
def label
%w[Female]
end
module Dashboard
module Analyze
module Graph
module Column
module GenderColumn
class Female < GroupedBarColumnPresenter
include Analyze::Graph::Column::GenderColumn::ScoreForGender
include Analyze::Graph::Column::GenderColumn::GenderCount
def label
%w[Female]
end
def basis
"student"
end
def basis
"student"
end
def show_irrelevancy_message?
false
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def show_insufficient_data_message?
false
end
def gender
::Gender.find_by_qualtrics_code 1
def gender
::Gender.find_by_qualtrics_code 1
end
end
end
end

@ -1,15 +1,19 @@
module Analyze
module Graph
module Column
module GenderColumn
module GenderCount
def type
:student
end
# frozen_string_literal: true
module Dashboard
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
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

@ -1,30 +1,32 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module GenderColumn
class Male < GroupedBarColumnPresenter
include Analyze::Graph::Column::GenderColumn::ScoreForGender
include Analyze::Graph::Column::GenderColumn::GenderCount
def label
%w[Male]
end
module Dashboard
module Analyze
module Graph
module Column
module GenderColumn
class Male < GroupedBarColumnPresenter
include Analyze::Graph::Column::GenderColumn::ScoreForGender
include Analyze::Graph::Column::GenderColumn::GenderCount
def label
%w[Male]
end
def basis
"student"
end
def basis
"student"
end
def show_irrelevancy_message?
false
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def show_insufficient_data_message?
false
end
def gender
::Gender.find_by_qualtrics_code 2
def gender
::Gender.find_by_qualtrics_code 2
end
end
end
end

@ -1,30 +1,32 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module GenderColumn
class NonBinary < GroupedBarColumnPresenter
include Analyze::Graph::Column::GenderColumn::ScoreForGender
include Analyze::Graph::Column::GenderColumn::GenderCount
def label
%w[Non-Binary]
end
module Dashboard
module Analyze
module Graph
module Column
module GenderColumn
class NonBinary < GroupedBarColumnPresenter
include Analyze::Graph::Column::GenderColumn::ScoreForGender
include Analyze::Graph::Column::GenderColumn::GenderCount
def label
%w[Non-Binary]
end
def basis
"student"
end
def basis
"student"
end
def show_irrelevancy_message?
false
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def show_insufficient_data_message?
false
end
def gender
::Gender.find_by_qualtrics_code 4
def gender
::Gender.find_by_qualtrics_code 4
end
end
end
end

@ -1,38 +1,42 @@
module Analyze
module Graph
module Column
module GenderColumn
module ScoreForGender
def score(year_index)
academic_year = academic_years[year_index]
meets_student_threshold = sufficient_student_responses?(academic_year:)
return Score::NIL_SCORE unless meets_student_threshold
# frozen_string_literal: true
averages = SurveyItemResponse.averages_for_gender(measure.student_survey_items, school, academic_year,
gender)
average = bubble_up_averages(averages:).round(2)
module Dashboard
module Analyze
module Graph
module Column
module GenderColumn
module ScoreForGender
def score(year_index)
academic_year = academic_years[year_index]
meets_student_threshold = sufficient_student_responses?(academic_year:)
return Score::NIL_SCORE unless meets_student_threshold
Score.new(average:,
meets_teacher_threshold: false,
meets_student_threshold:,
meets_admin_data_threshold: false)
end
averages = SurveyItemResponse.averages_for_gender(measure.student_survey_items, school, academic_year,
gender)
average = bubble_up_averages(averages:).round(2)
Score.new(average:,
meets_teacher_threshold: false,
meets_student_threshold:,
meets_admin_data_threshold: false)
end
def bubble_up_averages(averages:)
measure.student_scales.map do |scale|
scale.survey_items.map do |survey_item|
averages[survey_item]
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.remove_blanks.average
end
end
def sufficient_student_responses?(academic_year:)
return false unless measure.subcategory.response_rate(school:, academic_year:).meets_student_threshold?
def sufficient_student_responses?(academic_year:)
return false unless measure.subcategory.response_rate(school:, academic_year:).meets_student_threshold?
yearly_counts = SurveyItemResponse.where(school:, academic_year:,
gender:, survey_item: measure.student_survey_items).group(:gender).select(:response_id).distinct(:response_id).count
yearly_counts.any? do |count|
count[1] >= 10
yearly_counts = SurveyItemResponse.where(school:, academic_year:,
gender:, survey_item: measure.student_survey_items).group(:gender).select(:response_id).distinct(:response_id).count
yearly_counts.any? do |count|
count[1] >= 10
end
end
end
end

@ -1,30 +1,32 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module GenderColumn
class Unknown < GroupedBarColumnPresenter
include Analyze::Graph::Column::GenderColumn::ScoreForGender
include Analyze::Graph::Column::GenderColumn::GenderCount
def label
%w[Unknown]
end
module Dashboard
module Analyze
module Graph
module Column
module GenderColumn
class Unknown < GroupedBarColumnPresenter
include Analyze::Graph::Column::GenderColumn::ScoreForGender
include Analyze::Graph::Column::GenderColumn::GenderCount
def label
%w[Unknown]
end
def basis
"student"
end
def basis
"student"
end
def show_irrelevancy_message?
false
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def show_insufficient_data_message?
false
end
def gender
::Gender.find_by_qualtrics_code 99
def gender
::Gender.find_by_qualtrics_code 99
end
end
end
end

@ -1,30 +1,32 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module Grade
class Eight < GroupedBarColumnPresenter
include Analyze::Graph::Column::Grade::ScoreForGrade
include Analyze::Graph::Column::Grade::GradeCount
def label
%w[Grade 8]
end
module Dashboard
module Analyze
module Graph
module Column
module Grade
class Eight < GroupedBarColumnPresenter
include Analyze::Graph::Column::Grade::ScoreForGrade
include Analyze::Graph::Column::Grade::GradeCount
def label
%w[Grade 8]
end
def basis
"student"
end
def basis
"student"
end
def show_irrelevancy_message?
false
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def show_insufficient_data_message?
false
end
def grade
8
def grade
8
end
end
end
end

@ -1,30 +1,32 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module Grade
class Eleven < GroupedBarColumnPresenter
include Analyze::Graph::Column::Grade::ScoreForGrade
include Analyze::Graph::Column::Grade::GradeCount
def label
%w[Grade 11]
end
module Dashboard
module Analyze
module Graph
module Column
module Grade
class Eleven < GroupedBarColumnPresenter
include Analyze::Graph::Column::Grade::ScoreForGrade
include Analyze::Graph::Column::Grade::GradeCount
def label
%w[Grade 11]
end
def basis
"student"
end
def basis
"student"
end
def show_irrelevancy_message?
false
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def show_insufficient_data_message?
false
end
def grade
11
def grade
11
end
end
end
end

@ -1,30 +1,32 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module Grade
class Five < GroupedBarColumnPresenter
include Analyze::Graph::Column::Grade::ScoreForGrade
include Analyze::Graph::Column::Grade::GradeCount
def label
%w[Grade 5]
end
module Dashboard
module Analyze
module Graph
module Column
module Grade
class Five < GroupedBarColumnPresenter
include Analyze::Graph::Column::Grade::ScoreForGrade
include Analyze::Graph::Column::Grade::GradeCount
def label
%w[Grade 5]
end
def basis
"student"
end
def basis
"student"
end
def show_irrelevancy_message?
false
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def show_insufficient_data_message?
false
end
def grade
5
def grade
5
end
end
end
end

@ -1,30 +1,32 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module Grade
class Four < GroupedBarColumnPresenter
include Analyze::Graph::Column::Grade::ScoreForGrade
include Analyze::Graph::Column::Grade::GradeCount
def label
%w[Grade 4]
end
module Dashboard
module Analyze
module Graph
module Column
module Grade
class Four < GroupedBarColumnPresenter
include Analyze::Graph::Column::Grade::ScoreForGrade
include Analyze::Graph::Column::Grade::GradeCount
def label
%w[Grade 4]
end
def basis
"student"
end
def basis
"student"
end
def show_irrelevancy_message?
false
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def show_insufficient_data_message?
false
end
def grade
4
def grade
4
end
end
end
end

@ -1,15 +1,19 @@
module Analyze
module Graph
module Column
module Grade
module GradeCount
def type
:student
end
# frozen_string_literal: true
module Dashboard
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
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

@ -1,30 +1,32 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module Grade
class Nine < GroupedBarColumnPresenter
include Analyze::Graph::Column::Grade::ScoreForGrade
include Analyze::Graph::Column::Grade::GradeCount
def label
%w[Grade 9]
end
module Dashboard
module Analyze
module Graph
module Column
module Grade
class Nine < GroupedBarColumnPresenter
include Analyze::Graph::Column::Grade::ScoreForGrade
include Analyze::Graph::Column::Grade::GradeCount
def label
%w[Grade 9]
end
def basis
"student"
end
def basis
"student"
end
def show_irrelevancy_message?
false
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def show_insufficient_data_message?
false
end
def grade
9
def grade
9
end
end
end
end

@ -1,30 +1,32 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module Grade
class One < GroupedBarColumnPresenter
include Analyze::Graph::Column::Grade::ScoreForGrade
include Analyze::Graph::Column::Grade::GradeCount
def label
%w[Grade 1]
end
module Dashboard
module Analyze
module Graph
module Column
module Grade
class One < GroupedBarColumnPresenter
include Analyze::Graph::Column::Grade::ScoreForGrade
include Analyze::Graph::Column::Grade::GradeCount
def label
%w[Grade 1]
end
def basis
"student"
end
def basis
"student"
end
def show_irrelevancy_message?
false
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def show_insufficient_data_message?
false
end
def grade
1
def grade
1
end
end
end
end

@ -1,38 +1,42 @@
module Analyze
module Graph
module Column
module Grade
module ScoreForGrade
def score(year_index)
academic_year = academic_years[year_index]
meets_student_threshold = sufficient_student_responses?(academic_year:)
return Score::NIL_SCORE unless meets_student_threshold
# frozen_string_literal: true
averages = SurveyItemResponse.averages_for_grade(measure.student_survey_items, school,
academic_year, grade)
average = bubble_up_averages(averages:).round(2)
module Dashboard
module Analyze
module Graph
module Column
module Grade
module ScoreForGrade
def score(year_index)
academic_year = academic_years[year_index]
meets_student_threshold = sufficient_student_responses?(academic_year:)
return Score::NIL_SCORE unless meets_student_threshold
Score.new(average:,
meets_teacher_threshold: false,
meets_student_threshold:,
meets_admin_data_threshold: false)
end
averages = SurveyItemResponse.averages_for_grade(measure.student_survey_items, school,
academic_year, grade)
average = bubble_up_averages(averages:).round(2)
Score.new(average:,
meets_teacher_threshold: false,
meets_student_threshold:,
meets_admin_data_threshold: false)
end
def bubble_up_averages(averages:)
measure.student_scales.map do |scale|
scale.survey_items.map do |survey_item|
averages[survey_item]
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.remove_blanks.average
end
end
def sufficient_student_responses?(academic_year:)
return false unless measure.subcategory.response_rate(school:, academic_year:).meets_student_threshold?
def sufficient_student_responses?(academic_year:)
return false unless measure.subcategory.response_rate(school:, academic_year:).meets_student_threshold?
yearly_counts = SurveyItemResponse.where(school:, academic_year:,
survey_item: measure.student_survey_items).group(:grade).select(:response_id).distinct(:response_id).count
yearly_counts.any? do |count|
count[1] >= 10
yearly_counts = SurveyItemResponse.where(school:, academic_year:,
survey_item: measure.student_survey_items).group(:grade).select(:response_id).distinct(:response_id).count
yearly_counts.any? do |count|
count[1] >= 10
end
end
end
end

@ -1,30 +1,32 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module Grade
class Seven < GroupedBarColumnPresenter
include Analyze::Graph::Column::Grade::ScoreForGrade
include Analyze::Graph::Column::Grade::GradeCount
def label
%w[Grade 7]
end
module Dashboard
module Analyze
module Graph
module Column
module Grade
class Seven < GroupedBarColumnPresenter
include Analyze::Graph::Column::Grade::ScoreForGrade
include Analyze::Graph::Column::Grade::GradeCount
def label
%w[Grade 7]
end
def basis
"student"
end
def basis
"student"
end
def show_irrelevancy_message?
false
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def show_insufficient_data_message?
false
end
def grade
7
def grade
7
end
end
end
end

@ -1,30 +1,32 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module Grade
class Six < GroupedBarColumnPresenter
include Analyze::Graph::Column::Grade::ScoreForGrade
include Analyze::Graph::Column::Grade::GradeCount
def label
%w[Grade 6]
end
module Dashboard
module Analyze
module Graph
module Column
module Grade
class Six < GroupedBarColumnPresenter
include Analyze::Graph::Column::Grade::ScoreForGrade
include Analyze::Graph::Column::Grade::GradeCount
def label
%w[Grade 6]
end
def basis
"student"
end
def basis
"student"
end
def show_irrelevancy_message?
false
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def show_insufficient_data_message?
false
end
def grade
6
def grade
6
end
end
end
end

@ -1,30 +1,32 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module Grade
class Ten < GroupedBarColumnPresenter
include Analyze::Graph::Column::Grade::ScoreForGrade
include Analyze::Graph::Column::Grade::GradeCount
def label
%w[Grade 10]
end
module Dashboard
module Analyze
module Graph
module Column
module Grade
class Ten < GroupedBarColumnPresenter
include Analyze::Graph::Column::Grade::ScoreForGrade
include Analyze::Graph::Column::Grade::GradeCount
def label
%w[Grade 10]
end
def basis
"student"
end
def basis
"student"
end
def show_irrelevancy_message?
false
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def show_insufficient_data_message?
false
end
def grade
10
def grade
10
end
end
end
end

@ -1,30 +1,32 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module Grade
class Three < GroupedBarColumnPresenter
include Analyze::Graph::Column::Grade::ScoreForGrade
include Analyze::Graph::Column::Grade::GradeCount
def label
%w[Grade 3]
end
module Dashboard
module Analyze
module Graph
module Column
module Grade
class Three < GroupedBarColumnPresenter
include Analyze::Graph::Column::Grade::ScoreForGrade
include Analyze::Graph::Column::Grade::GradeCount
def label
%w[Grade 3]
end
def basis
"student"
end
def basis
"student"
end
def show_irrelevancy_message?
false
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def show_insufficient_data_message?
false
end
def grade
3
def grade
3
end
end
end
end

@ -1,30 +1,32 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module Grade
class Twelve < GroupedBarColumnPresenter
include Analyze::Graph::Column::Grade::ScoreForGrade
include Analyze::Graph::Column::Grade::GradeCount
def label
%w[Grade 12]
end
module Dashboard
module Analyze
module Graph
module Column
module Grade
class Twelve < GroupedBarColumnPresenter
include Analyze::Graph::Column::Grade::ScoreForGrade
include Analyze::Graph::Column::Grade::GradeCount
def label
%w[Grade 12]
end
def basis
"student"
end
def basis
"student"
end
def show_irrelevancy_message?
false
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def show_insufficient_data_message?
false
end
def grade
12
def grade
12
end
end
end
end

@ -1,30 +1,32 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module Grade
class Two < GroupedBarColumnPresenter
include Analyze::Graph::Column::Grade::ScoreForGrade
include Analyze::Graph::Column::Grade::GradeCount
def label
%w[Grade 2]
end
module Dashboard
module Analyze
module Graph
module Column
module Grade
class Two < GroupedBarColumnPresenter
include Analyze::Graph::Column::Grade::ScoreForGrade
include Analyze::Graph::Column::Grade::GradeCount
def label
%w[Grade 2]
end
def basis
"student"
end
def basis
"student"
end
def show_irrelevancy_message?
false
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def show_insufficient_data_message?
false
end
def grade
2
def grade
2
end
end
end
end

@ -1,30 +1,32 @@
# 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
%w[Kindergarten]
end
module Dashboard
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
%w[Kindergarten]
end
def basis
"student"
end
def basis
"student"
end
def show_irrelevancy_message?
false
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def show_insufficient_data_message?
false
end
def grade
0
def grade
0
end
end
end
end

@ -1,170 +1,172 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
class GroupedBarColumnPresenter
include AnalyzeHelper
attr_reader :measure_name, :measure_id, :category, :position, :measure, :school, :academic_years,
:number_of_columns
def initialize(measure:, school:, academic_years:, position:, number_of_columns:)
@measure = measure
@measure_name = @measure.name
@measure_id = @measure.measure_id
@category = @measure.subcategory.category
@school = school
@academic_years = academic_years
@position = position
@number_of_columns = number_of_columns
end
def academic_year_for_year_index(year_index)
academic_years[year_index]
end
def score(year_index)
measure.score(school:, academic_year: academic_years[year_index]) || 0
end
module Dashboard
module Analyze
module Graph
module Column
class GroupedBarColumnPresenter
include AnalyzeHelper
attr_reader :measure_name, :measure_id, :category, :position, :measure, :school, :academic_years,
:number_of_columns
def initialize(measure:, school:, academic_years:, position:, number_of_columns:)
@measure = measure
@measure_name = @measure.name
@measure_id = @measure.measure_id
@category = @measure.subcategory.category
@school = school
@academic_years = academic_years
@position = position
@number_of_columns = number_of_columns
end
def bars
@bars ||= yearly_scores.map.each_with_index do |yearly_score, index|
year = yearly_score.year
Analyze::BarPresenter.new(measure:, academic_year: year,
score: yearly_score.score,
x_position: bar_x(index),
color: bar_color(year))
def academic_year_for_year_index(year_index)
academic_years[year_index]
end
end
def label
%w[All Data]
end
def score(year_index)
measure.score(school:, academic_year: academic_years[year_index]) || 0
end
def show_irrelevancy_message?
false
end
def bars
@bars ||= yearly_scores.map.each_with_index do |yearly_score, index|
year = yearly_score.year
Analyze::BarPresenter.new(measure:, academic_year: year,
score: yearly_score.score,
x_position: bar_x(index),
color: bar_color(year))
end
end
def show_insufficient_data_message?
scores = academic_years.map do |year|
measure.score(school:, academic_year: year)
def label
%w[All Data]
end
scores.all? do |score|
!score.meets_teacher_threshold? && !score.meets_student_threshold? && !score.meets_admin_data_threshold?
def show_irrelevancy_message?
false
end
end
def column_midpoint
zone_label_width + (grouped_chart_column_width * (position + 1)) - (grouped_chart_column_width / 2)
end
def show_insufficient_data_message?
scores = academic_years.map do |year|
measure.score(school:, academic_year: year)
end
def bar_width
min_bar_width(10.5 / data_sources)
end
scores.all? do |score|
!score.meets_teacher_threshold? && !score.meets_student_threshold? && !score.meets_admin_data_threshold?
end
end
def min_bar_width(number)
min_width = 2
number < min_width ? min_width : number
end
def column_midpoint
zone_label_width + (grouped_chart_column_width * (position + 1)) - (grouped_chart_column_width / 2)
end
def message_x
column_midpoint - message_width / 2
end
def bar_width
min_bar_width(10.5 / data_sources)
end
def message_y
17
end
def min_bar_width(number)
min_width = 2
number < min_width ? min_width : number
end
def message_width
20
end
def message_x
column_midpoint - message_width / 2
end
def message_height
34
end
def message_y
17
end
def column_end_x
zone_label_width + (grouped_chart_column_width * (position + 1))
end
def message_width
20
end
def column_start_x
zone_label_width + (grouped_chart_column_width * position)
end
def message_height
34
end
def grouped_chart_column_width
graph_width / data_sources
end
def column_end_x
zone_label_width + (grouped_chart_column_width * (position + 1))
end
def bar_label_height
(100 - ((100 - analyze_graph_height) / 2))
end
def column_start_x
zone_label_width + (grouped_chart_column_width * position)
end
def data_sources
number_of_columns
end
def grouped_chart_column_width
graph_width / data_sources
end
def basis
"student surveys"
end
def bar_label_height
(100 - ((100 - analyze_graph_height) / 2))
end
def type
:all_data
end
def data_sources
number_of_columns
end
def show_popover?
%i[student teacher].include? type
end
def basis
"student surveys"
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 type
:all_data
end
def popover_content(year_index)
"#{n_size(year_index)} #{type.to_s.capitalize}s"
end
def show_popover?
%i[student teacher].include? type
end
def insufficiency_message
["survey response", "rate below 25%"]
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 sufficient_data?(year_index)
case basis
when "student"
score(year_index).meets_student_threshold
when "teacher"
score(year_index).meets_teacher_threshold
else
true
def popover_content(year_index)
"#{n_size(year_index)} #{type.to_s.capitalize}s"
end
end
def grades(year_index)
Respondent.by_school_and_year(school:, academic_year: academic_years[year_index]).enrollment_by_grade.keys
end
def insufficiency_message
["survey response", "rate below 25%"]
end
private
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
YearlyScore = Struct.new(:year, :score)
def yearly_scores
yearly_scores = academic_years.each_with_index.map do |year, index|
YearlyScore.new(year, score(index))
def grades(year_index)
Respondent.by_school_and_year(school:, academic_year: academic_years[year_index]).enrollment_by_grade.keys
end
yearly_scores.reject do |yearly_score|
yearly_score.score.blank?
private
YearlyScore = Struct.new(:year, :score)
def yearly_scores
yearly_scores = academic_years.each_with_index.map do |year, index|
YearlyScore.new(year, score(index))
end
yearly_scores.reject do |yearly_score|
yearly_score.score.blank?
end
end
end
def bar_color(year)
@available_academic_years ||= AcademicYear.order(:range).all
colors[@available_academic_years.find_index(year)]
end
def bar_color(year)
@available_academic_years ||= AcademicYear.order(:range).all
colors[@available_academic_years.find_index(year)]
end
def bar_x(index)
column_start_x + (index * bar_width * 1.2) +
((column_end_x - column_start_x) - (yearly_scores.size * bar_width * 1.2)) / 2
def bar_x(index)
column_start_x + (index * bar_width * 1.2) +
((column_end_x - column_start_x) - (yearly_scores.size * bar_width * 1.2)) / 2
end
end
end
end

@ -1,26 +1,28 @@
# 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
%w[Economically Disadvantaged]
end
module Dashboard
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
%w[Economically Disadvantaged]
end
def show_irrelevancy_message?
false
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def show_insufficient_data_message?
false
end
def income
Income.find_by_designation "Economically Disadvantaged - Y"
def income
Income.find_by_designation "Economically Disadvantaged - Y"
end
end
end
end

@ -1,15 +1,19 @@
module Analyze
module Graph
module Column
module IncomeColumn
module IncomeCount
def type
:student
end
# frozen_string_literal: true
module Dashboard
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
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

@ -1,26 +1,28 @@
# 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 Economically", "Disadvantaged"]
end
module Dashboard
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 Economically", "Disadvantaged"]
end
def show_irrelevancy_message?
false
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def show_insufficient_data_message?
false
end
def income
Income.find_by_designation "Economically Disadvantaged - N"
def income
Income.find_by_designation "Economically Disadvantaged - N"
end
end
end
end

@ -1,38 +1,42 @@
module Analyze
module Graph
module Column
module IncomeColumn
module ScoreForIncome
def score(year_index)
academic_year = academic_years[year_index]
meets_student_threshold = sufficient_student_responses?(academic_year:)
return Score::NIL_SCORE unless meets_student_threshold
# frozen_string_literal: true
averages = SurveyItemResponse.averages_for_income(measure.student_survey_items, school, academic_year,
income)
average = bubble_up_averages(averages:).round(2)
module Dashboard
module Analyze
module Graph
module Column
module IncomeColumn
module ScoreForIncome
def score(year_index)
academic_year = academic_years[year_index]
meets_student_threshold = sufficient_student_responses?(academic_year:)
return Score::NIL_SCORE unless meets_student_threshold
Score.new(average:,
meets_teacher_threshold: false,
meets_student_threshold:,
meets_admin_data_threshold: false)
end
averages = SurveyItemResponse.averages_for_income(measure.student_survey_items, school, academic_year,
income)
average = bubble_up_averages(averages:).round(2)
Score.new(average:,
meets_teacher_threshold: false,
meets_student_threshold:,
meets_admin_data_threshold: false)
end
def bubble_up_averages(averages:)
measure.student_scales.map do |scale|
scale.survey_items.map do |survey_item|
averages[survey_item]
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.remove_blanks.average
end
end
def sufficient_student_responses?(academic_year:)
return false unless measure.subcategory.response_rate(school:, academic_year:).meets_student_threshold?
def sufficient_student_responses?(academic_year:)
return false unless measure.subcategory.response_rate(school:, academic_year:).meets_student_threshold?
yearly_counts = SurveyItemResponse.where(school:, academic_year:,
income:, survey_item: measure.student_survey_items).group(:income).select(:response_id).distinct(:response_id).count
yearly_counts.any? do |count|
count[1] >= 10
yearly_counts = SurveyItemResponse.where(school:, academic_year:,
income:, survey_item: measure.student_survey_items).group(:income).select(:response_id).distinct(:response_id).count
yearly_counts.any? do |count|
count[1] >= 10
end
end
end
end

@ -1,26 +1,28 @@
# 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
module Dashboard
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_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def show_insufficient_data_message?
false
end
def income
Income.find_by_designation "Unknown"
def income
Income.find_by_designation "Unknown"
end
end
end
end

@ -1,26 +1,28 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module RaceColumn
class AmericanIndian < GroupedBarColumnPresenter
include Analyze::Graph::Column::ScoreForRace
include Analyze::Graph::Column::RaceColumn::RaceCount
def label
%w[American Indian]
end
module Dashboard
module Analyze
module Graph
module Column
module RaceColumn
class AmericanIndian < GroupedBarColumnPresenter
include Analyze::Graph::Column::ScoreForRace
include Analyze::Graph::Column::RaceColumn::RaceCount
def label
%w[American Indian]
end
def show_irrelevancy_message?
false
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def show_insufficient_data_message?
false
end
def race
Race.find_by_qualtrics_code 1
def race
Race.find_by_qualtrics_code 1
end
end
end
end

@ -1,26 +1,28 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module RaceColumn
class Asian < GroupedBarColumnPresenter
include Analyze::Graph::Column::ScoreForRace
include Analyze::Graph::Column::RaceColumn::RaceCount
def label
%w[Asian]
end
module Dashboard
module Analyze
module Graph
module Column
module RaceColumn
class Asian < GroupedBarColumnPresenter
include Analyze::Graph::Column::ScoreForRace
include Analyze::Graph::Column::RaceColumn::RaceCount
def label
%w[Asian]
end
def show_irrelevancy_message?
false
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def show_insufficient_data_message?
false
end
def race
Race.find_by_qualtrics_code 2
def race
Race.find_by_qualtrics_code 2
end
end
end
end

@ -1,26 +1,28 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module RaceColumn
class Black < GroupedBarColumnPresenter
include Analyze::Graph::Column::ScoreForRace
include Analyze::Graph::Column::RaceColumn::RaceCount
def label
%w[Black]
end
module Dashboard
module Analyze
module Graph
module Column
module RaceColumn
class Black < GroupedBarColumnPresenter
include Analyze::Graph::Column::ScoreForRace
include Analyze::Graph::Column::RaceColumn::RaceCount
def label
%w[Black]
end
def show_irrelevancy_message?
false
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def show_insufficient_data_message?
false
end
def race
Race.find_by_qualtrics_code 3
def race
Race.find_by_qualtrics_code 3
end
end
end
end

@ -1,26 +1,28 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module RaceColumn
class Hispanic < GroupedBarColumnPresenter
include Analyze::Graph::Column::ScoreForRace
include Analyze::Graph::Column::RaceColumn::RaceCount
def label
%w[Hispanic]
end
module Dashboard
module Analyze
module Graph
module Column
module RaceColumn
class Hispanic < GroupedBarColumnPresenter
include Analyze::Graph::Column::ScoreForRace
include Analyze::Graph::Column::RaceColumn::RaceCount
def label
%w[Hispanic]
end
def show_irrelevancy_message?
false
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def show_insufficient_data_message?
false
end
def race
Race.find_by_qualtrics_code 4
def race
Race.find_by_qualtrics_code 4
end
end
end
end

@ -1,27 +1,29 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module RaceColumn
class MiddleEastern < GroupedBarColumnPresenter
include Analyze::Graph::Column::ScoreForRace
include Analyze::Graph::Column::RaceColumn::RaceCount
module Dashboard
module Analyze
module Graph
module Column
module RaceColumn
class MiddleEastern < GroupedBarColumnPresenter
include Analyze::Graph::Column::ScoreForRace
include Analyze::Graph::Column::RaceColumn::RaceCount
def label
%w[Middle Eastern]
end
def label
%w[Middle Eastern]
end
def show_irrelevancy_message?
false
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def show_insufficient_data_message?
false
end
def race
Race.find_by_qualtrics_code 8
def race
Race.find_by_qualtrics_code 8
end
end
end
end

@ -1,26 +1,28 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module RaceColumn
class Multiracial < GroupedBarColumnPresenter
include Analyze::Graph::Column::ScoreForRace
include Analyze::Graph::Column::RaceColumn::RaceCount
def label
%w[Multiracial]
end
module Dashboard
module Analyze
module Graph
module Column
module RaceColumn
class Multiracial < GroupedBarColumnPresenter
include Analyze::Graph::Column::ScoreForRace
include Analyze::Graph::Column::RaceColumn::RaceCount
def label
%w[Multiracial]
end
def show_irrelevancy_message?
false
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def show_insufficient_data_message?
false
end
def race
Race.find_by_qualtrics_code 100
def race
Race.find_by_qualtrics_code 100
end
end
end
end

@ -1,17 +1,21 @@
module Analyze
module Graph
module Column
module RaceColumn
module RaceCount
def type
:student
end
# frozen_string_literal: true
module Dashboard
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
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

@ -1,26 +1,28 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module RaceColumn
class Unknown < GroupedBarColumnPresenter
include Analyze::Graph::Column::ScoreForRace
include Analyze::Graph::Column::RaceColumn::RaceCount
def label
%w[Not Listed]
end
module Dashboard
module Analyze
module Graph
module Column
module RaceColumn
class Unknown < GroupedBarColumnPresenter
include Analyze::Graph::Column::ScoreForRace
include Analyze::Graph::Column::RaceColumn::RaceCount
def label
%w[Not Listed]
end
def show_irrelevancy_message?
false
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def show_insufficient_data_message?
false
end
def race
Race.find_by_qualtrics_code 99
def race
Race.find_by_qualtrics_code 99
end
end
end
end

@ -1,26 +1,28 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module RaceColumn
class White < GroupedBarColumnPresenter
include Analyze::Graph::Column::ScoreForRace
include Analyze::Graph::Column::RaceColumn::RaceCount
def label
%w[White]
end
module Dashboard
module Analyze
module Graph
module Column
module RaceColumn
class White < GroupedBarColumnPresenter
include Analyze::Graph::Column::ScoreForRace
include Analyze::Graph::Column::RaceColumn::RaceCount
def label
%w[White]
end
def show_irrelevancy_message?
false
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def show_insufficient_data_message?
false
end
def race
Race.find_by_qualtrics_code 5
def race
Race.find_by_qualtrics_code 5
end
end
end
end

@ -1,38 +1,42 @@
module Analyze
module Graph
module Column
module ScoreForRace
def score(year_index)
academic_year = academic_years[year_index]
meets_student_threshold = sufficient_student_responses?(academic_year:)
return Score::NIL_SCORE unless meets_student_threshold
# frozen_string_literal: true
survey_items = measure.student_survey_items
module Dashboard
module Analyze
module Graph
module Column
module ScoreForRace
def score(year_index)
academic_year = academic_years[year_index]
meets_student_threshold = sufficient_student_responses?(academic_year:)
return Score::NIL_SCORE unless meets_student_threshold
averages = SurveyItemResponse.averages_for_race(school, academic_year, race)
average = bubble_up_averages(averages:).round(2)
survey_items = measure.student_survey_items
Score.new(average:,
meets_teacher_threshold: false,
meets_student_threshold:,
meets_admin_data_threshold: false)
end
averages = SurveyItemResponse.averages_for_race(school, academic_year, race)
average = bubble_up_averages(averages:).round(2)
Score.new(average:,
meets_teacher_threshold: false,
meets_student_threshold:,
meets_admin_data_threshold: false)
end
def bubble_up_averages(averages:)
measure.student_scales.map do |scale|
scale.survey_items.map do |survey_item|
averages[survey_item.id]
def bubble_up_averages(averages:)
measure.student_scales.map do |scale|
scale.survey_items.map do |survey_item|
averages[survey_item.id]
end.remove_blanks.average
end.remove_blanks.average
end.remove_blanks.average
end
end
def sufficient_student_responses?(academic_year:)
return false unless measure.subcategory.response_rate(school:, academic_year:).meets_student_threshold?
def sufficient_student_responses?(academic_year:)
return false unless measure.subcategory.response_rate(school:, academic_year:).meets_student_threshold?
number_of_students_for_a_racial_group = SurveyItemResponse.joins("JOIN student_races on dashboard_survey_item_responses.student_id = student_races.student_id JOIN students on students.id = student_races.student_id").where(
school:, academic_year:
).where("student_races.race_id": race.id).distinct.pluck(:student_id).count
number_of_students_for_a_racial_group >= 10
number_of_students_for_a_racial_group = SurveyItemResponse.joins("JOIN student_races on dashboard_survey_item_responses.student_id = student_races.student_id JOIN students on students.id = student_races.student_id").where(
school:, academic_year:
).where("student_races.race_id": race.id).distinct.pluck(:student_id).count
number_of_students_for_a_racial_group >= 10
end
end
end
end

@ -1,31 +1,33 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module SpedColumn
class NotSped < GroupedBarColumnPresenter
include Analyze::Graph::Column::SpedColumn::ScoreForSped
include Analyze::Graph::Column::SpedColumn::SpedCount
module Dashboard
module Analyze
module Graph
module Column
module SpedColumn
class NotSped < GroupedBarColumnPresenter
include Analyze::Graph::Column::SpedColumn::ScoreForSped
include Analyze::Graph::Column::SpedColumn::SpedCount
def label
["Not Special", "Education"]
end
def label
["Not Special", "Education"]
end
def basis
"student"
end
def basis
"student"
end
def show_irrelevancy_message?
false
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def show_insufficient_data_message?
false
end
def sped
::Sped.find_by_slug "not-special-education"
def sped
::Sped.find_by_slug "not-special-education"
end
end
end
end

@ -1,38 +1,42 @@
module Analyze
module Graph
module Column
module SpedColumn
module ScoreForSped
def score(year_index)
academic_year = academic_years[year_index]
meets_student_threshold = sufficient_student_responses?(academic_year:)
return Score::NIL_SCORE unless meets_student_threshold
# frozen_string_literal: true
averages = SurveyItemResponse.averages_for_sped(measure.student_survey_items, school, academic_year,
sped)
average = bubble_up_averages(averages:).round(2)
module Dashboard
module Analyze
module Graph
module Column
module SpedColumn
module ScoreForSped
def score(year_index)
academic_year = academic_years[year_index]
meets_student_threshold = sufficient_student_responses?(academic_year:)
return Score::NIL_SCORE unless meets_student_threshold
Score.new(average:,
meets_teacher_threshold: false,
meets_student_threshold:,
meets_admin_data_threshold: false)
end
averages = SurveyItemResponse.averages_for_sped(measure.student_survey_items, school, academic_year,
sped)
average = bubble_up_averages(averages:).round(2)
Score.new(average:,
meets_teacher_threshold: false,
meets_student_threshold:,
meets_admin_data_threshold: false)
end
def bubble_up_averages(averages:)
measure.student_scales.map do |scale|
scale.survey_items.map do |survey_item|
averages[survey_item]
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.remove_blanks.average
end
end
def sufficient_student_responses?(academic_year:)
return false unless measure.subcategory.response_rate(school:, academic_year:).meets_student_threshold?
def sufficient_student_responses?(academic_year:)
return false unless measure.subcategory.response_rate(school:, academic_year:).meets_student_threshold?
yearly_counts = SurveyItemResponse.where(school:, academic_year:,
sped:, survey_item: measure.student_survey_items).group(:sped).select(:response_id).distinct(:response_id).count
yearly_counts.any? do |count|
count[1] >= 10
yearly_counts = SurveyItemResponse.where(school:, academic_year:,
sped:, survey_item: measure.student_survey_items).group(:sped).select(:response_id).distinct(:response_id).count
yearly_counts.any? do |count|
count[1] >= 10
end
end
end
end

@ -1,31 +1,33 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module SpedColumn
class Sped < GroupedBarColumnPresenter
include Analyze::Graph::Column::SpedColumn::ScoreForSped
include Analyze::Graph::Column::SpedColumn::SpedCount
module Dashboard
module Analyze
module Graph
module Column
module SpedColumn
class Sped < GroupedBarColumnPresenter
include Analyze::Graph::Column::SpedColumn::ScoreForSped
include Analyze::Graph::Column::SpedColumn::SpedCount
def label
%w[Special Education]
end
def label
%w[Special Education]
end
def basis
"student"
end
def basis
"student"
end
def show_irrelevancy_message?
false
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def show_insufficient_data_message?
false
end
def sped
::Sped.find_by_slug "special-education"
def sped
::Sped.find_by_slug "special-education"
end
end
end
end

@ -1,15 +1,19 @@
module Analyze
module Graph
module Column
module SpedColumn
module SpedCount
def type
:student
end
# frozen_string_literal: true
module Dashboard
module Analyze
module Graph
module Column
module SpedColumn
module SpedCount
def type
:student
end
def n_size(year_index)
SurveyItemResponse.where(sped:, survey_item: measure.student_survey_items, school:, grade: grades(year_index),
academic_year: academic_years[year_index]).select(:response_id).distinct.count
def n_size(year_index)
SurveyItemResponse.where(sped:, 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

@ -1,31 +1,33 @@
# frozen_string_literal: true
module Analyze
module Graph
module Column
module SpedColumn
class Unknown < GroupedBarColumnPresenter
include Analyze::Graph::Column::SpedColumn::ScoreForSped
include Analyze::Graph::Column::SpedColumn::SpedCount
module Dashboard
module Analyze
module Graph
module Column
module SpedColumn
class Unknown < GroupedBarColumnPresenter
include Analyze::Graph::Column::SpedColumn::ScoreForSped
include Analyze::Graph::Column::SpedColumn::SpedCount
def label
%w[Unknown]
end
def label
%w[Unknown]
end
def basis
"student"
end
def basis
"student"
end
def show_irrelevancy_message?
false
end
def show_irrelevancy_message?
false
end
def show_insufficient_data_message?
false
end
def show_insufficient_data_message?
false
end
def sped
::Sped.find_by_slug "unknown"
def sped
::Sped.find_by_slug "unknown"
end
end
end
end

@ -1,19 +1,21 @@
# frozen_string_literal: true
module Analyze
module Graph
class StudentsAndTeachers
include Analyze::Graph::Column
def to_s
'Students & Teachers'
end
module Dashboard
module Analyze
module Graph
class StudentsAndTeachers
include Analyze::Graph::Column
def to_s
"Students & Teachers"
end
def slug
'students-and-teachers'
end
def slug
"students-and-teachers"
end
def columns
[AllStudent, AllTeacher, AllSurveyData]
def columns
[AllStudent, AllTeacher, AllSurveyData]
end
end
end
end

@ -1,44 +1,46 @@
# frozen_string_literal: true
module Analyze
module Graph
class StudentsByEll
include Analyze::Graph::Column::EllColumn
attr_reader :ells
def initialize(ells:)
@ells = ells
end
module Dashboard
module Analyze
module Graph
class StudentsByEll
include Analyze::Graph::Column::EllColumn
attr_reader :ells
def initialize(ells:)
@ells = ells
end
def to_s
"Students by Ell"
end
def to_s
"Students by Ell"
end
def slug
"students-by-ell"
end
def slug
"students-by-ell"
end
def columns
[].tap do |array|
ells.each do |ell|
array << column_for_ell_code(code: ell.slug)
def columns
[].tap do |array|
ells.each do |ell|
array << column_for_ell_code(code: ell.slug)
end
array.sort_by!(&:to_s)
array << Analyze::Graph::Column::AllStudent
end
array.sort_by!(&:to_s)
array << Analyze::Graph::Column::AllStudent
end
end
private
private
def column_for_ell_code(code:)
CFR[code]
end
def column_for_ell_code(code:)
CFR[code]
end
CFR = {
"ell" => Analyze::Graph::Column::EllColumn::Ell,
"not-ell" => Analyze::Graph::Column::EllColumn::NotEll,
"unknown" => Analyze::Graph::Column::EllColumn::Unknown
}.freeze
CFR = {
"ell" => Analyze::Graph::Column::EllColumn::Ell,
"not-ell" => Analyze::Graph::Column::EllColumn::NotEll,
"unknown" => Analyze::Graph::Column::EllColumn::Unknown
}.freeze
end
end
end
end

@ -1,45 +1,47 @@
# frozen_string_literal: true
module Analyze
module Graph
class StudentsByGender
include Analyze::Graph::Column::GenderColumn
attr_reader :genders
def initialize(genders:)
@genders = genders
end
module Dashboard
module Analyze
module Graph
class StudentsByGender
include Analyze::Graph::Column::GenderColumn
attr_reader :genders
def initialize(genders:)
@genders = genders
end
def to_s
"Students by Gender"
end
def to_s
"Students by Gender"
end
def slug
"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)
def columns
[].tap do |array|
genders.each do |gender|
array << column_for_gender_code(code: gender.qualtrics_code)
end
array.sort_by!(&:to_s)
array << Analyze::Graph::Column::AllStudent
end
array.sort_by!(&:to_s)
array << Analyze::Graph::Column::AllStudent
end
end
private
private
def column_for_gender_code(code:)
CFR[code]
end
def column_for_gender_code(code:)
CFR[code]
end
CFR = {
1 => Analyze::Graph::Column::GenderColumn::Female,
2 => Analyze::Graph::Column::GenderColumn::Male,
4 => Analyze::Graph::Column::GenderColumn::NonBinary,
99 => Analyze::Graph::Column::GenderColumn::Unknown
}.freeze
CFR = {
1 => Analyze::Graph::Column::GenderColumn::Female,
2 => Analyze::Graph::Column::GenderColumn::Male,
4 => Analyze::Graph::Column::GenderColumn::NonBinary,
99 => Analyze::Graph::Column::GenderColumn::Unknown
}.freeze
end
end
end
end

@ -1,53 +1,55 @@
# frozen_string_literal: true
module Analyze
module Graph
class StudentsByGrade
include Analyze::Graph::Column::Grade
attr_reader :grades
def initialize(grades:)
@grades = grades
end
module Dashboard
module Analyze
module Graph
class StudentsByGrade
include Analyze::Graph::Column::Grade
attr_reader :grades
def initialize(grades:)
@grades = grades
end
def to_s
"Students by Grade"
end
def to_s
"Students by Grade"
end
def slug
"students-by-grade"
end
def slug
"students-by-grade"
end
def columns
[].tap do |array|
grades.each do |grade|
array << column_for_grade_code(code: grade)
def columns
[].tap do |array|
grades.each do |grade|
array << column_for_grade_code(code: grade)
end
array << Analyze::Graph::Column::AllStudent
end
array << Analyze::Graph::Column::AllStudent
end
end
private
private
def column_for_grade_code(code:)
CFR[code]
end
def column_for_grade_code(code:)
CFR[code]
end
CFR = {
0 => Zero,
1 => One,
2 => Two,
3 => Three,
4 => Four,
5 => Five,
6 => Six,
7 => Seven,
8 => Eight,
9 => Nine,
10 => Ten,
11 => Eleven,
12 => Twelve
}.freeze
CFR = {
0 => Zero,
1 => One,
2 => Two,
3 => Three,
4 => Four,
5 => Five,
6 => Six,
7 => Seven,
8 => Eight,
9 => Nine,
10 => Ten,
11 => Eleven,
12 => Twelve
}.freeze
end
end
end
end

@ -1,42 +1,44 @@
# frozen_string_literal: true
module Analyze
module Graph
class StudentsByIncome
attr_reader :incomes
def initialize(incomes:)
@incomes = incomes
end
module Dashboard
module Analyze
module Graph
class StudentsByIncome
attr_reader :incomes
def initialize(incomes:)
@incomes = incomes
end
def to_s
"Students by income"
end
def to_s
"Students by income"
end
def slug
"students-by-income"
end
def slug
"students-by-income"
end
def columns
[].tap do |array|
incomes.each do |income|
array << column_for_income_code(code: income.slug)
def columns
[].tap do |array|
incomes.each do |income|
array << column_for_income_code(code: income.slug)
end
array << Analyze::Graph::Column::AllStudent
end
array << Analyze::Graph::Column::AllStudent
end
end
private
private
def column_for_income_code(code:)
CFR[code.to_s]
end
def column_for_income_code(code:)
CFR[code.to_s]
end
CFR = {
"economically-disadvantaged-y" => Analyze::Graph::Column::IncomeColumn::Disadvantaged,
"economically-disadvantaged-n" => Analyze::Graph::Column::IncomeColumn::NotDisadvantaged,
"unknown" => Analyze::Graph::Column::IncomeColumn::Unknown
}.freeze
CFR = {
"economically-disadvantaged-y" => Analyze::Graph::Column::IncomeColumn::Disadvantaged,
"economically-disadvantaged-n" => Analyze::Graph::Column::IncomeColumn::NotDisadvantaged,
"unknown" => Analyze::Graph::Column::IncomeColumn::Unknown
}.freeze
end
end
end
end

@ -1,47 +1,49 @@
# frozen_string_literal: true
module Analyze
module Graph
class StudentsByRace
attr_reader :races
def initialize(races:)
@races = races
end
module Dashboard
module Analyze
module Graph
class StudentsByRace
attr_reader :races
def initialize(races:)
@races = races
end
def to_s
"Students by Race"
end
def to_s
"Students by Race"
end
def slug
"students-by-race"
end
def slug
"students-by-race"
end
def columns
[].tap do |array|
races.each do |race|
array << column_for_race_code(code: race.qualtrics_code)
def columns
[].tap do |array|
races.each do |race|
array << column_for_race_code(code: race.qualtrics_code)
end
array << Analyze::Graph::Column::AllStudent
end
array << Analyze::Graph::Column::AllStudent
end
end
private
private
def column_for_race_code(code:)
CFR[code.to_s]
end
def column_for_race_code(code:)
CFR[code.to_s]
end
CFR = {
"1" => Analyze::Graph::Column::RaceColumn::AmericanIndian,
"2" => Analyze::Graph::Column::RaceColumn::Asian,
"3" => Analyze::Graph::Column::RaceColumn::Black,
"4" => Analyze::Graph::Column::RaceColumn::Hispanic,
"5" => Analyze::Graph::Column::RaceColumn::White,
"8" => Analyze::Graph::Column::RaceColumn::MiddleEastern,
"99" => Analyze::Graph::Column::RaceColumn::Unknown,
"100" => Analyze::Graph::Column::RaceColumn::Multiracial
}.freeze
CFR = {
"1" => Analyze::Graph::Column::RaceColumn::AmericanIndian,
"2" => Analyze::Graph::Column::RaceColumn::Asian,
"3" => Analyze::Graph::Column::RaceColumn::Black,
"4" => Analyze::Graph::Column::RaceColumn::Hispanic,
"5" => Analyze::Graph::Column::RaceColumn::White,
"8" => Analyze::Graph::Column::RaceColumn::MiddleEastern,
"99" => Analyze::Graph::Column::RaceColumn::Unknown,
"100" => Analyze::Graph::Column::RaceColumn::Multiracial
}.freeze
end
end
end
end

@ -1,43 +1,45 @@
# frozen_string_literal: true
module Analyze
module Graph
class StudentsBySped
include Analyze::Graph::Column::SpedColumn
attr_reader :speds
def initialize(speds:)
@speds = speds
end
module Dashboard
module Analyze
module Graph
class StudentsBySped
include Analyze::Graph::Column::SpedColumn
attr_reader :speds
def initialize(speds:)
@speds = speds
end
def to_s
"Students by SpEd"
end
def to_s
"Students by SpEd"
end
def slug
"students-by-sped"
end
def slug
"students-by-sped"
end
def columns
[].tap do |array|
speds.each do |sped|
array << column_for_sped_code(code: sped.slug)
def columns
[].tap do |array|
speds.each do |sped|
array << column_for_sped_code(code: sped.slug)
end
array << Analyze::Graph::Column::AllStudent
end
array << Analyze::Graph::Column::AllStudent
end
end
private
private
def column_for_sped_code(code:)
CFR[code]
end
def column_for_sped_code(code:)
CFR[code]
end
CFR = {
"special-education" => Analyze::Graph::Column::SpedColumn::Sped,
"not-special-education" => Analyze::Graph::Column::SpedColumn::NotSped,
"unknown" => Analyze::Graph::Column::SpedColumn::Unknown
}.freeze
CFR = {
"special-education" => Analyze::Graph::Column::SpedColumn::Sped,
"not-special-education" => Analyze::Graph::Column::SpedColumn::NotSped,
"unknown" => Analyze::Graph::Column::SpedColumn::Unknown
}.freeze
end
end
end
end

@ -1,12 +1,16 @@
module Analyze
module Group
class Ell
def name
"ELL"
end
# frozen_string_literal: true
module Dashboard
module Analyze
module Group
class Ell
def name
"ELL"
end
def slug
"ell"
def slug
"ell"
end
end
end
end

@ -1,12 +1,16 @@
module Analyze
module Group
class Gender
def name
'Gender'
end
# frozen_string_literal: true
module Dashboard
module Analyze
module Group
class Gender
def name
"Gender"
end
def slug
'gender'
def slug
"gender"
end
end
end
end

@ -1,12 +1,16 @@
module Analyze
module Group
class Grade
def name
'Grade'
end
# frozen_string_literal: true
module Dashboard
module Analyze
module Group
class Grade
def name
"Grade"
end
def slug
'grade'
def slug
"grade"
end
end
end
end

@ -1,12 +1,16 @@
module Analyze
module Group
class Income
def name
'Income'
end
# frozen_string_literal: true
module Dashboard
module Analyze
module Group
class Income
def name
"Income"
end
def slug
'income'
def slug
"income"
end
end
end
end

@ -1,12 +1,16 @@
module Analyze
module Group
class Race
def name
'Race'
end
# frozen_string_literal: true
module Dashboard
module Analyze
module Group
class Race
def name
"Race"
end
def slug
'race'
def slug
"race"
end
end
end
end

@ -1,12 +1,16 @@
module Analyze
module Group
class Sped
def name
"Special Education"
end
# frozen_string_literal: true
module Dashboard
module Analyze
module Group
class Sped
def name
"Special Education"
end
def slug
"sped"
def slug
"sped"
end
end
end
end

@ -1,200 +1,206 @@
module Analyze
class Presenter
attr_reader :params, :school, :academic_year
def initialize(params:, school:, academic_year:)
@params = params
@school = school
@academic_year = academic_year
end
module Dashboard
module Analyze
class Presenter
attr_reader :params, :school, :academic_year
def initialize(params:, school:, academic_year:)
@params = params
@school = school
@academic_year = academic_year
end
def category
@category ||= Category.find_by_category_id(params[:category]) || Category.order(:category_id).first
end
def category
@category ||= Category.find_by_category_id(params[:category]) || Category.order(:category_id).first
end
def categories
@categories = Category.all.order(:category_id)
end
def categories
@categories = Category.all.order(:category_id)
end
def subcategory
@subcategory ||= Subcategory.find_by_subcategory_id(params[:subcategory]) || subcategories.first
end
def subcategory
@subcategory ||= Subcategory.find_by_subcategory_id(params[:subcategory]) || subcategories.first
end
def subcategories
@subcategories = category.subcategories.order(:subcategory_id)
end
def subcategories
@subcategories = category.subcategories.order(:subcategory_id)
end
def measures
@measures = subcategory.measures.order(:measure_id).includes(%i[admin_data_items subcategory])
end
def measures
@measures = subcategory.measures.order(:measure_id).includes(%i[admin_data_items subcategory])
end
def academic_years
@academic_years = AcademicYear.order(:range).all
end
def academic_years
@academic_years = AcademicYear.order(:range).all
end
def selected_academic_years
@selected_academic_years ||= begin
year_params = params[:academic_years]
return [] unless year_params
def selected_academic_years
@selected_academic_years ||= begin
year_params = params[:academic_years]
return [] unless year_params
year_params.split(",").map { |year| AcademicYear.find_by_range(year) }.compact
year_params.split(",").map { |year| AcademicYear.find_by_range(year) }.compact
end
end
end
def races
@races ||= Race.all.order(designation: :ASC)
end
def races
@races ||= Race.all.order(designation: :ASC)
end
def selected_races
@selected_races ||= begin
race_params = params[:races]
return races unless race_params
def selected_races
@selected_races ||= begin
race_params = params[:races]
return races unless race_params
race_params.split(",").map { |race| Race.find_by_slug race }.compact
race_params.split(",").map { |race| Race.find_by_slug race }.compact
end
end
end
def ells
@ells ||= Ell.all.order(slug: :ASC)
end
def ells
@ells ||= Ell.all.order(slug: :ASC)
end
def selected_ells
@selected_ells ||= begin
ell_params = params[:ells]
return ells unless ell_params
def selected_ells
@selected_ells ||= begin
ell_params = params[:ells]
return ells unless ell_params
ell_params.split(",").map { |ell| Ell.find_by_slug ell }.compact
ell_params.split(",").map { |ell| Ell.find_by_slug ell }.compact
end
end
end
def speds
@speds ||= Sped.all.order(id: :ASC)
end
def speds
@speds ||= Sped.all.order(id: :ASC)
end
def selected_speds
@selected_speds ||= begin
sped_params = params[:speds]
return speds unless sped_params
def selected_speds
@selected_speds ||= begin
sped_params = params[:speds]
return speds unless sped_params
sped_params.split(",").map { |sped| Sped.find_by_slug sped }.compact
sped_params.split(",").map { |sped| Sped.find_by_slug sped }.compact
end
end
end
def graphs
@graphs ||= [Analyze::Graph::AllData.new,
Analyze::Graph::StudentsAndTeachers.new,
Analyze::Graph::StudentsByRace.new(races: selected_races),
Analyze::Graph::StudentsByGrade.new(grades: selected_grades),
Analyze::Graph::StudentsByGender.new(genders: selected_genders),
Analyze::Graph::StudentsByIncome.new(incomes: selected_incomes),
Analyze::Graph::StudentsByEll.new(ells: selected_ells),
Analyze::Graph::StudentsBySped.new(speds: selected_speds)]
end
def graphs
@graphs ||= [Analyze::Graph::AllData.new,
Analyze::Graph::StudentsAndTeachers.new,
Analyze::Graph::StudentsByRace.new(races: selected_races),
Analyze::Graph::StudentsByGrade.new(grades: selected_grades),
Analyze::Graph::StudentsByGender.new(genders: selected_genders),
Analyze::Graph::StudentsByIncome.new(incomes: selected_incomes),
Analyze::Graph::StudentsByEll.new(ells: selected_ells),
Analyze::Graph::StudentsBySped.new(speds: selected_speds)]
end
def graph
@graph ||= graphs.reduce(graphs.first) do |acc, graph|
graph.slug == params[:graph] ? graph : acc
def graph
@graph ||= graphs.reduce(graphs.first) do |acc, graph|
graph.slug == params[:graph] ? graph : acc
end
end
end
def selected_grades
@selected_grades ||= begin
grade_params = params[:grades]
return grades unless grade_params
def selected_grades
@selected_grades ||= begin
grade_params = params[:grades]
return grades unless grade_params
grade_params.split(",").map(&:to_i)
grade_params.split(",").map(&:to_i)
end
end
end
def selected_genders
@selected_genders ||= begin
gender_params = params[:genders]
return genders unless gender_params
def selected_genders
@selected_genders ||= begin
gender_params = params[:genders]
return genders unless gender_params
gender_params.split(",").sort.map { |gender| Gender.find_by_designation(gender) }.compact
gender_params.split(",").sort.map { |gender| Gender.find_by_designation(gender) }.compact
end
end
end
def genders
@genders ||= Gender.all.order(designation: :ASC)
end
def genders
@genders ||= Gender.all.order(designation: :ASC)
end
def groups
@groups = [Analyze::Group::Ell.new, Analyze::Group::Gender.new, Analyze::Group::Grade.new, Analyze::Group::Income.new,
Analyze::Group::Race.new, Analyze::Group::Sped.new]
end
def groups
@groups = [Analyze::Group::Ell.new,
Analyze::Group::Gender.new,
Analyze::Group::Grade.new,
Analyze::Group::Income.new,
Analyze::Group::Race.new,
Analyze::Group::Sped.new]
end
def group
@group ||= groups.reduce(groups.first) do |acc, group|
group.slug == params[:group] ? group : acc
def group
@group ||= groups.reduce(groups.first) do |acc, group|
group.slug == params[:group] ? group : acc
end
end
end
def slice
@slice ||= slices.reduce(slices.first) do |acc, slice|
slice.slug == params[:slice] ? slice : acc
def slice
@slice ||= slices.reduce(slices.first) do |acc, slice|
slice.slug == params[:slice] ? slice : acc
end
end
end
def slices
source.slices
end
def slices
source.slices
end
def source
@source ||= sources.reduce(sources.first) do |acc, source|
source.slug == params[:source] ? source : acc
def source
@source ||= sources.reduce(sources.first) do |acc, source|
source.slug == params[:source] ? source : acc
end
end
end
def sources
all_data_slices = [Analyze::Slice::AllData.new]
all_data_source = Analyze::Source::AllData.new(slices: all_data_slices)
def sources
all_data_slices = [Analyze::Slice::AllData.new]
all_data_source = Analyze::Source::AllData.new(slices: all_data_slices)
students_and_teachers = Analyze::Slice::StudentsAndTeachers.new
students_by_group = Analyze::Slice::StudentsByGroup.new(races:, grades:)
survey_data_slices = [students_and_teachers, students_by_group]
survey_data_source = Analyze::Source::SurveyData.new(slices: survey_data_slices)
students_and_teachers = Analyze::Slice::StudentsAndTeachers.new
students_by_group = Analyze::Slice::StudentsByGroup.new(races:, grades:)
survey_data_slices = [students_and_teachers, students_by_group]
survey_data_source = Analyze::Source::SurveyData.new(slices: survey_data_slices)
@sources = [all_data_source, survey_data_source]
end
@sources = [all_data_source, survey_data_source]
end
def grades
@grades ||= SurveyItemResponse.where(school:, academic_year:)
.where.not(grade: nil)
.group(:grade)
.select(:response_id)
.distinct(:response_id)
.count.reject do |_key, value|
value < 10
end.keys
end
def grades
@grades ||= SurveyItemResponse.where(school:, academic_year:)
.where.not(grade: nil)
.group(:grade)
.select(:response_id)
.distinct(:response_id)
.count.reject do |_key, value|
value < 10
end.keys
end
def incomes
@incomes ||= Income.all
end
def incomes
@incomes ||= Income.all
end
def selected_incomes
@selected_incomes ||= begin
income_params = params[:incomes]
return incomes unless income_params
def selected_incomes
@selected_incomes ||= begin
income_params = params[:incomes]
return incomes unless income_params
income_params.split(",").map { |income| Income.find_by_slug(income) }.compact
income_params.split(",").map { |income| Income.find_by_slug(income) }.compact
end
end
end
def cache_objects
[subcategory,
selected_academic_years,
graph,
selected_races,
selected_grades,
grades,
selected_genders,
genders,
selected_ells,
ells,
selected_speds,
speds]
def cache_objects
[subcategory,
selected_academic_years,
graph,
selected_races,
selected_grades,
grades,
selected_genders,
genders,
selected_ells,
ells,
selected_speds,
speds]
end
end
end
end

@ -1,16 +1,20 @@
module Analyze
module Slice
class AllData
def to_s
'All Data'
end
# frozen_string_literal: true
def slug
'all-data'
end
module Dashboard
module Analyze
module Slice
class AllData
def to_s
"All Data"
end
def slug
"all-data"
end
def graphs
[Analyze::Graph::AllData.new]
def graphs
[Analyze::Graph::AllData.new]
end
end
end
end

@ -1,16 +1,20 @@
module Analyze
module Slice
class StudentsAndTeachers
def to_s
'Students & Teachers'
end
# frozen_string_literal: true
def slug
'students-and-teachers'
end
module Dashboard
module Analyze
module Slice
class StudentsAndTeachers
def to_s
"Students & Teachers"
end
def slug
"students-and-teachers"
end
def graphs
[Analyze::Graph::StudentsAndTeachers.new]
def graphs
[Analyze::Graph::StudentsAndTeachers.new]
end
end
end
end

@ -1,23 +1,28 @@
module Analyze
module Slice
class StudentsByGroup
attr_reader :races, :grades
# frozen_string_literal: true
def initialize(races:, grades:)
@races = races
@grades = grades
end
module Dashboard
module Analyze
module Slice
class StudentsByGroup
attr_reader :races, :grades
def to_s
'Students by Group'
end
def initialize(races:, grades:)
@races = races
@grades = grades
end
def slug
'students-by-group'
end
def to_s
"Students by Group"
end
def slug
"students-by-group"
end
def graphs
[Analyze::Graph::StudentsByRace.new(races:), Analyze::Graph::StudentsByGrade.new(grades:)]
def graphs
[Analyze::Graph::StudentsByRace.new(races:),
Analyze::Graph::StudentsByGrade.new(grades:)]
end
end
end
end

@ -1,20 +1,24 @@
module Analyze
module Source
class AllData
attr_reader :slices
# frozen_string_literal: true
include Analyze::Slice
module Dashboard
module Analyze
module Source
class AllData
attr_reader :slices
def initialize(slices:)
@slices = slices
end
include Analyze::Slice
def to_s
'All Data'
end
def initialize(slices:)
@slices = slices
end
def to_s
"All Data"
end
def slug
'all-data'
def slug
"all-data"
end
end
end
end

@ -1,20 +1,24 @@
module Analyze
module Source
class SurveyData
attr_reader :slices
# frozen_string_literal: true
include Analyze::Slice
module Dashboard
module Analyze
module Source
class SurveyData
attr_reader :slices
def initialize(slices:)
@slices = slices
end
include Analyze::Slice
def to_s
'Survey Data Only'
end
def initialize(slices:)
@slices = slices
end
def to_s
"Survey Data Only"
end
def slug
'survey-data-only'
def slug
"survey-data-only"
end
end
end
end

@ -0,0 +1,17 @@
<div class="d-flex align-items-center mx-5">
<input
id="<%= id %>"
class="m-3 <%= name %>-checkbox form-check-input"
type="checkbox"
name="<%= name %>-checkbox"
value="<%= base_url %>"
data-action="click->analyze#refresh"
<%= selected_items.include?(item) ? "checked" : "" %>
<%= @presenter.graph.slug == 'students-and-teachers' || @presenter.source.slug == 'all-data' ? "disabled" : "" %>
<%= @presenter.group.slug == name ? "" : "hidden" %>>
<label for="<%= id %>"
<%= @presenter.group.slug == name ? "" : "hidden" %>>
<%= label_text %>
</label>
</div>

@ -0,0 +1,41 @@
<h3 class="sub-header-4 mt-5">Data Filters</h3>
<div class="bg-gray p-3" data-controller="analyze">
<% @presenter.sources.each do |source| %>
<input type="radio"
id="<%= source.slug %>"
class="form-check-input"
name="source"
value="<%= base_url %>"
data-action="click->analyze#refresh"
<%= source.slug == @presenter.source.slug ? "checked" : "" %>>
<label for="<%= source.slug %>"><%= source.to_s %></label>
<% source.slices.each do | slice | %>
<div class="mx-3">
<input type="radio"
id="<%= slice.slug %>"
class="form-check-input"
name="slice"
value="<%= base_url %>"
data-action="click->analyze#refresh"
<%= slice.slug == @presenter.slice.slug ? "checked" : "" %>
<%= slice.slug == "all-data" ? "hidden" : "" %>>
<label for="<%= slice.slug %>"
<%= slice.slug == "all-data" ? "hidden" : "" %>>
<%= slice.to_s %></label>
</div>
<% end %>
<% end %>
<%= render partial: "group_selectors" %>
</div>
<script>
window.source = "<%= @presenter.source.slug %>";
window.slice = "<%= @presenter.slice.slug %>";
window.group = "<%= @presenter.group.slug %>";
window.graph = "<%= @presenter.graph.slug %>";
</script>

@ -0,0 +1,14 @@
<h3 class="sub-header-4">Focus Area</h3>
<p>Select a category & subcategory to analyze measure-level results</p>
<select id="select-category" class="mx-3 form-select" data-id="category-dropdown" data-action="analyze#refresh">
<% categories.each do |category| %>
<option value="<%= analyze_category_link(district: district, school: school, academic_year: academic_year, category: category) %>" <%= category.id == @presenter.category.id ? "selected": "" %>><%= "#{category.category_id}: #{category.name}" %></option>
<% end %>
</select>
<select id="select-subcategory" class="mx-3 form-select mt-3" data-id="subcategory-dropdown" data-action="analyze#refresh">
<% subcategories.each do |subcategory| %>
<option value="<%= analyze_subcategory_link(district: district, school: school, academic_year: academic_year, category: category, subcategory: subcategory) %>" <%= subcategory.subcategory_id == @presenter.subcategory.subcategory_id ? "selected": "" %>>
<%= "#{subcategory.subcategory_id}: #{subcategory.name}" %>
</option>
<% end %>
</select>

@ -0,0 +1,30 @@
<g id="graph-background">
<rect x="0" y="0" width="100%" height="<%= background.analyze_zone_height * 2 %>%" fill="#edecf0" />
<rect x="0" y="<%= background.analyze_zone_height * 2 %>%" width="100%" height="<%= background.analyze_zone_height * 3 %>%" fill="#fffaee" />
<rect x="0" y="0" width="100%" height="<%= background.analyze_graph_height %>%" fill="none" stroke="grey" />
<rect x="0" y="<%= background.benchmark_y %>%" width="100%" height="<%= background.benchmark_height %>%" fill="black" />
<g id="zone-dividers" stroke-width="1">
<line x1="0" y1="17%" x2="100%" y2="17%" stroke="white" />
<line x1="0" y1="51%" x2="100%" y2="51%" stroke="#edecf0" />
<line x1="0" y1="68%" x2="100%" y2="68%" stroke="#edecf0" />
</g>
<g id="zone-labels">
<text class="zone-header" x="<%= background.zone_label_x %>%" y="<%= background.zone_label_y(1) %>%" text-anchor="start" dominant-baseline="middle">
Ideal
</text>
<text class="zone-header" x="<%= background.zone_label_x %>%" y="<%= background.zone_label_y(2) %>%" text-anchor="start" dominant-baseline="middle">
Approval
</text>
<text class="zone-header" x="<%= background.zone_label_x %>%" y="<%= background.zone_label_y(3) %>%" text-anchor="start" dominant-baseline="middle">
Growth
</text>
<text class="zone-header" x="<%= background.zone_label_x %>%" y="<%= background.zone_label_y(4) %>%" text-anchor="start" dominant-baseline="middle">
Watch
</text>
<text class="zone-header" x="<%= background.zone_label_x %>%" y="<%= background.zone_label_y(5) %>%" text-anchor="start" dominant-baseline="middle">
Warning
</text>
</g>
</g>

@ -0,0 +1,31 @@
<select id="select-group" name="group" class="mx-4 form-select" data-id="group-dropdown" data-action="analyze#refresh">
<% @presenter.groups.each do |group| %>
<option id="<%= group.slug %>" name="group-option" value="<%= base_url %>" <%= group.slug == @presenter.group.slug ? "Selected": "" %>><%= group.name %> </option>
<% end %>
</select>
<p class="sub-header-5 mx-4 mt-3 font-size-14"> Select a group </p>
<% @presenter.races.each do |race| %>
<%= render(partial: "checkboxes", locals: {id: "race-#{race.slug}", item: race, selected_items: @presenter.selected_races, name: "race", label_text: race.designation}) %>
<% end %>
<% @presenter.grades.each do |grade| %>
<%= render(partial: "checkboxes", locals: {id: "grade-#{grade}", item: grade, selected_items: @presenter.selected_grades, name: "grade", label_text: grade}) %>
<% end %>
<% @presenter.genders.each do |gender| %>
<%= render(partial: "checkboxes", locals: {id: "gender-#{gender.designation}", item: gender, selected_items: @presenter.selected_genders, name: "gender", label_text: gender.designation}) %>
<% end %>
<% @presenter.incomes.each do |income| %>
<%= render(partial: "checkboxes", locals: {id: "income-#{income.slug}", item: income, selected_items: @presenter.selected_incomes, name: "income", label_text: income.label}) %>
<% end %>
<% @presenter.ells.each do |ell| %>
<%= render(partial: "checkboxes", locals: {id: "ell-#{ell.slug}", item: ell, selected_items: @presenter.selected_ells, name: "ell", label_text: ell.designation}) %>
<% end %>
<% @presenter.speds.each do |sped| %>
<%= render(partial: "checkboxes", locals: {id: "sped-#{sped.slug}", item: sped, selected_items: @presenter.selected_speds, name: "sped", label_text: sped.designation}) %>
<% end %>

@ -0,0 +1,10 @@
<svg width="100%" height="<%= svg_height %>">
<%= render partial: "graph_background", locals: {background: @background} %>
<% number_of_columns = @presenter.graph.columns.length %>
<% @presenter.graph.columns.each_with_index do |column, index| %>
<% p = column.new(measure: measure, school: @school, academic_years: @presenter.selected_academic_years, position: index , number_of_columns:) %>
<%= render partial: "grouped_bar_column", locals: {column: p} %>
<% end %>
</svg>

After

Width:  |  Height:  |  Size: 493 B

@ -0,0 +1,53 @@
<g class="grouped-bar-column" data-for-measure-id="<%= column.measure.measure_id %>">
<% score_label_y = [5, 10, 15, 5, 10, 15 ] %>
<% column.bars.each_with_index do |bar, index| %>
<% 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 %>
<% end %>
<% end %>
<line x1="<%= column.column_start_x %>%" y1="0" x2="<%= column.column_start_x %>%" y2="85%" stroke="grey" stroke-width="1" stroke-dasharray="5,2" />
<% words = column.label %>
<% words.each_with_index do | line, index | %>
<text class="graph-footer" x="<%= column.column_midpoint %>%" y="<%= column.bar_label_height + (index * 5) %>%" text-anchor="middle" dominant-baseline="middle" data-grouped-bar-label="<%= column.label %>">
<%= line %>
</text>
<% end %>
<% if column.show_irrelevancy_message? %>
<rect x="<%= column.message_x %>%" y="<%= column.message_y %>%" rx="15" ry="15" width="<%= column.message_width %>%" height="<%= column.message_height %>%" fill="white" stroke="gray" />
<text x="<%= column.column_midpoint %>%" y="<%= 20 %>%" text-anchor="middle">
<tspan x="<%= column.column_midpoint %>%" y="29%">measure not</tspan>
<tspan x="<%= column.column_midpoint %>%" y="34%">based on</tspan>
<tspan x="<%= column.column_midpoint %>%" y="39%"><%= column.basis %></tspan>
</text>
<% elsif column.show_insufficient_data_message? %>
<rect x="<%= column.message_x %>%" y="<%= column.message_y %>%" rx="15" ry="15" width="<%= column.message_width %>%" height="<%= column.message_height %>%" fill="white" stroke="gray" />
<text x="<%= column.column_midpoint %>%" y="<%= 20 %>%" text-anchor="middle">
<% column.insufficiency_message.each_with_index do |line, index| %>
<% offset = 29 + index * 5 %>
<tspan x='<%= column.column_midpoint %>%' y='<%= offset %>%'><%= line %></tspan>
<% end %>
</text>
<% end %>
</g>

@ -0,0 +1,34 @@
<h3 class="sub-header-4 mt-5">School Years</h3>
<% available_academic_years.each_with_index do | year, index | %>
<div class="d-flex justify-content-start align-items-center mt-1" data-controller="analyze">
<input type="checkbox"
class="form-check-input"
id="<%= year.range %>"
name="year-checkbox"
value="<%= analyze_subcategory_link(district: district, school: school, academic_year: academic_year, category: category, subcategory: subcategory) %>"
<%= selected_academic_years.include?(year) ? "checked" : "" %>
data-action="click->analyze#refresh"
<% empty_dataset = empty_dataset?(measures: measures, school: school, academic_year: year) %>
<% empty_survey_dataset = empty_survey_dataset?(measures: measures, school: school, academic_year: year) %>
<% if graph.slug == 'all-data' %>
<%= empty_dataset ? "disabled" : "" %>
<% else %>
<%= empty_survey_dataset ? "disabled" : "" %>
<% end %>
>
<label class="px-3" for="<%= year.range %>"><%= year.range %></label><br>
<div class="bg-color-blue px-3" style="width:20px;height:20px;background-color:<%= colors[index] %>;"></div>
<% if graph.slug == 'all-data' && empty_dataset %>
<i class="fa-solid fa-circle-exclamation px-3"
data-bs-toggle="popover" data-bs-placement="right"
data-bs-content="No admin data OR teacher and student survey response rates below <%= Dashboard::ResponseRate::TEACHER_RATE_THRESHOLD %>%">
</i>
<% end %>
<% if graph.slug != 'all-data' && empty_survey_dataset %>
<i class="fa-solid fa-circle-exclamation px-3"
data-bs-toggle="popover" data-bs-placement="right"
data-bs-content="Teacher and student survey response rates below <%= Dashboard::ResponseRate::TEACHER_RATE_THRESHOLD %>%">
</i>
<% end %>
</div>
<% end %>

@ -0,0 +1,27 @@
<% content_for :title do %>
<h1 class="sub-header-2 color-white m-0"> Analysis of <%= @school.name %> </h1>
<% end %>
<div class="graph-content">
<div class="breadcrumbs sub-header-4">
<%= @presenter.category.category_id %>:<%= @presenter.category.name %> > <%= @presenter.subcategory.subcategory_id %>:<%= @presenter.subcategory.name %>
</div>
<hr>
</div>
<div class="d-flex flex-row pt-5 row">
<div class="d-flex flex-column flex-grow-6 bg-color-white col-3 px-5" data-controller="analyze">
<%= render partial: "focus_area", locals: {categories: @presenter.categories, district: @district, school: @school, academic_year: @academic_year, category: @presenter.category, subcategories: @presenter.subcategories} %>
<%= render partial: "school_years", locals: {available_academic_years: @presenter.academic_years, selected_academic_years: @presenter.selected_academic_years, district: @district, school: @school, academic_year: @academic_year, category: @presenter.category, subcategory: @presenter.subcategory, measures: @presenter.measures, graph: @presenter.graph} %>
<%= render partial: "data_filters", locals: {district: @district, school: @school, academic_year: @academic_year, category: @presenter.category, subcategory: @presenter.subcategory} %>
</div>
<% cache [@school, @presenter.cache_objects] do %>
<div class="bg-color-white flex-grow-1 col-9">
<% @presenter.measures.each do |measure| %>
<section class="mb-6">
<p class="construct-id">Measure <%= measure.measure_id %></p>
<h2> <%= measure.name %> </h2>
<%= render partial: "grouped_bar_chart" , locals: { measure: measure} %>
</section>
<% end %>
</div>
<% end %>
</div>
Loading…
Cancel
Save