Extract bar graph partial

pull/1/head
Alex Basson 4 years ago
parent 71ad999dd0
commit 643ee8d3a7

@ -1,5 +1,8 @@
@import "bootstrap";
@import "fonts";
@import "colors";
@import "flex";
@import "scaffolds";
@import "recipients";
@import "school_categories";
@import "questions";
@import "dashboard";

@ -1,3 +0,0 @@
// Place all the styles related to the Categories controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

@ -0,0 +1,14 @@
$red: #C92F47;
$beige: #EFEBE1;
.red {
color: $red;
}
.beige-bg {
background-color: $beige;
}
.white-bg {
background-color: white;
}

@ -0,0 +1,6 @@
@import 'fonts';
.graph-header {
@extend .font-bitter;
@extend .weight-700;
}

@ -1,3 +0,0 @@
// Place all the styles related to the Districts controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

@ -0,0 +1,25 @@
.fdr {
display: flex;
flex-direction: row;
}
.fdc {
display: flex;
flex-direction: column;
}
.fjc {
justify-content: center;
}
.fjb {
justify-content: space-between;
}
.fjl {
justify-content: left;
}
.fac {
align-items: center;
}

@ -0,0 +1,33 @@
.font-bitter {
font-family: 'Bitter', serif;
}
.font-cabin {
font-family: 'Cabin', sans-serif;
}
.weight-700 {
font-weight: 700;
}
.weight-600 {
font-weight: 600;
}
.weight-400 {
font-weight: 400;
}
.h1 {
@extend .font-bitter;
@extend .weight-600;
font-size: 40px;
}
.p {
@extend .font-cabin;
@extend .weight-400;
font-size: 17px;
}

@ -1,3 +0,0 @@
// Place all the styles related to the QuestionLists controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

@ -1,3 +0,0 @@
// Place all the styles related to the recipient_lists controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

@ -1,3 +0,0 @@
// Place all the styles related to the Recipients controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

@ -1,3 +0,0 @@
// Place all the styles related to the schedules controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

@ -1,3 +0,0 @@
// Place all the styles related to the Schools controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

@ -16,7 +16,11 @@ class DashboardController < ApplicationController
end
def district
@district ||= school.district
@district ||= District.find_by_slug district_slug
end
def district_slug
params[:district_id]
end
def school_slug

@ -1,9 +1,4 @@
module ConstructGraphParameters
TOTAL_GRAPH_WIDTH = 1152
GRAPH_WIDTH = 0.75 * TOTAL_GRAPH_WIDTH
CONSTRUCT_ROW_HEIGHT = 40
CONSTRUCT_ROW_BAR_HEIGHT = 20
module ZoneColor
WARNING = "#FF73C0"
WATCH = "#F096AD"
@ -11,26 +6,4 @@ module ConstructGraphParameters
APPROVAL = "#D0DD86"
IDEAL = "#C0FF73"
end
class ZoneParams
attr_reader :left_edge
attr_reader :width
def initialize(left_edge:, width:)
@left_edge = left_edge
@width = width
end
def right_edge
left_edge + width
end
end
WARNING_ZONE = ZoneParams.new left_edge: 0, width: (GRAPH_WIDTH / 2) / 3
WATCH_ZONE = ZoneParams.new left_edge: WARNING_ZONE.right_edge, width: (GRAPH_WIDTH / 2) / 3
GROWTH_ZONE = ZoneParams.new left_edge: WATCH_ZONE.right_edge, width: (GRAPH_WIDTH / 2) / 3
APPROVAL_ZONE = ZoneParams.new left_edge: GROWTH_ZONE.right_edge, width: (GRAPH_WIDTH / 2) / 2
IDEAL_ZONE = ZoneParams.new left_edge: APPROVAL_ZONE.right_edge, width: (GRAPH_WIDTH / 2) / 2
KEY_BENCHMARK_WIDTH = 2
end

@ -24,32 +24,38 @@ class ConstructGraphRowPresenter
end
def bar_width
unrounded_bar_width.round
"#{(bar_width_percentage * 100).round(2)}%"
end
def x_offset
case zone.type
when :ideal, :approval
0
"50%"
else
-1 * bar_width
"#{((0.5 - bar_width_percentage) * 100).round(2)}%"
end
end
private
def unrounded_bar_width
IDEAL_ZONE_WIDTH_PERCENTAGE = 0.5 / 2
APPROVAL_ZONE_WIDTH_PERCENTAGE = 0.5 / 2
GROWTH_ZONE_WIDTH_PERCENTAGE = 0.5 / 3
WATCH_ZONE_WIDTH_PERCENTAGE = 0.5 / 3
WARNING_ZONE_WIDTH_PERCENTAGE = 0.5 / 3
def bar_width_percentage
case zone.type
when :ideal
percentage * ideal_zone_params.width + approval_zone_params.width
percentage * IDEAL_ZONE_WIDTH_PERCENTAGE + APPROVAL_ZONE_WIDTH_PERCENTAGE
when :approval
percentage * approval_zone_params.width
percentage * APPROVAL_ZONE_WIDTH_PERCENTAGE
when :growth
percentage * growth_zone_params.width
percentage * GROWTH_ZONE_WIDTH_PERCENTAGE
when :watch
percentage * watch_zone_params.width + growth_zone_params.width
percentage * WATCH_ZONE_WIDTH_PERCENTAGE + GROWTH_ZONE_WIDTH_PERCENTAGE
else
percentage * warning_zone_params.width + watch_zone_params.width + growth_zone_params.width
percentage * WARNING_ZONE_WIDTH_PERCENTAGE + WATCH_ZONE_WIDTH_PERCENTAGE + GROWTH_ZONE_WIDTH_PERCENTAGE
end
end
@ -60,24 +66,4 @@ class ConstructGraphRowPresenter
def zone
@construct.zone_for_score(@score)
end
def ideal_zone_params
ConstructGraphParameters::IDEAL_ZONE
end
def approval_zone_params
ConstructGraphParameters::APPROVAL_ZONE
end
def growth_zone_params
ConstructGraphParameters::GROWTH_ZONE
end
def watch_zone_params
ConstructGraphParameters::WATCH_ZONE
end
def warning_zone_params
ConstructGraphParameters::WARNING_ZONE
end
end

@ -0,0 +1,43 @@
<div class="white-bg" style="padding: 24px; border-radius: 8px;">
<% heading_gutter = 30 %>
<% construct_row_height = 40 %>
<% graph_height = construct_graph_row_presenters.length * construct_row_height + heading_gutter %>
<% construct_row_bar_height = 20 %>
<% label_padding_right = 24 %>
<svg width="100%" height=<%= graph_height %> xmlns="http://www.w3.org/2000/svg">
<svg id="graph-background" x="25%" y="0" width="75%">
<g id="scale-headings">
<text class="graph-header" x="8.335%" y=<%= heading_gutter / 2 %> text-anchor="middle" dominant-baseline="middle">Warning</text>
<text class="graph-header" x="25%" y=<%= heading_gutter / 2 %> text-anchor="middle" dominant-baseline="middle">Watch</text>
<text class="graph-header" x="41.665%" y=<%= heading_gutter / 2 %> text-anchor="middle" dominant-baseline="middle">Growth</text>
<text class="graph-header" x="62.5%" y=<%= heading_gutter / 2 %> text-anchor="middle" dominant-baseline="middle">Approval</text>
<text class="graph-header" x="87.5%" y=<%= heading_gutter / 2 %> text-anchor="middle" dominant-baseline="middle">Ideal</text>
</g>
<g id="scale-background" transform="translate(0, <%= heading_gutter %>)">
<rect id="warning-zone" x="0" y="0" width="16.67%" height="100%" fill=<%= ConstructGraphParameters::ZoneColor::WARNING %> fill-opacity="0.2" />
<rect id="watch-zone" x="16.67%" y="0" width="16.67%" height="100%" fill=<%= ConstructGraphParameters::ZoneColor::WATCH %> fill-opacity="0.2" />
<rect id="growth-zone" x="33.33%" y="0" width="16.67%" height="100%" fill=<%= ConstructGraphParameters::ZoneColor::GROWTH %> fill-opacity="0.2" />
<rect id="approval-zone" x="50%" y="0" width="25%" height="100%" fill=<%= ConstructGraphParameters::ZoneColor::APPROVAL %> fill-opacity="0.2" />
<rect id="ideal-zone" x="75%" y="0" width="25%" height="100%" fill=<%= ConstructGraphParameters::ZoneColor::IDEAL %> fill-opacity="0.2" />
<rect id="key-benchmark" x="50%" transform="translate(-1, 0)" y="0" width="2" height="100%" fill="black" />
</g>
</svg>
<g id="construct-rows">
<svg id="construct-row-labels" x="0" y=<%= heading_gutter %>>
<%= construct_graph_row_presenters.each_with_index do |presenter, index| %>
<text class="font-cabin weight-600" x="25%" dx=<%= -1 * label_padding_right %> y=<%= index * construct_row_height + construct_row_height / 2 %> text-anchor="end" dominant-baseline="middle"><%= presenter.construct_name %></text>
<% end %>
</svg>
<svg id="construct-row-bars" x="25%" y=<%= heading_gutter %> width="75%">
<%= construct_graph_row_presenters.each_with_index do |presenter, index| %>
<rect class="construct-row-bar" x="<%= presenter.x_offset %>" y=<%= index * construct_row_height + (construct_row_height - construct_row_bar_height) / 2 %> width="<%= presenter.bar_width %>" height=<%= construct_row_bar_height %> fill=<%= presenter.bar_color %> />
<% end %>
</svg>
</g>
</svg>
</div>

@ -1,8 +1,9 @@
<h1><%= @school.name %></h1>
<div class="beige-bg" style="padding: 80px 120px;">
<div class="fdr fjb fac">
<h2 class="h1">Areas Of Interest</h2>
<div>
<h2>Areas Of Interest</h2>
<select name="academic-year">
<option value="<%= @academic_year %>" selected><%= format_academic_year(@academic_year) %></option>
</select>
@ -15,60 +16,13 @@
<option value="<%= @school.slug %>" selected><%= @school.name %></option>
</select>
</div>
</div>
<div>
<h2>Top & Bottom 5 Distance From Benchmark</h2>
<h2 class="h1 red">Distance from benchmark</h2>
<p class="p">This graph shows how much a score is above or below the benchmark of any given scale.</p>
</div>
<% heading_gutter = 30 %>
<% graph_height = @construct_graph_row_presenters.length * ConstructGraphParameters::CONSTRUCT_ROW_HEIGHT + heading_gutter %>
<svg viewbox="0 0 <%= ConstructGraphParameters::TOTAL_GRAPH_WIDTH %> <%= graph_height %>" width=<%= ConstructGraphParameters::TOTAL_GRAPH_WIDTH %> height=<%= graph_height %> xmlns="http://www.w3.org/2000/svg">
<% graph_center = ConstructGraphParameters::GRAPH_WIDTH / 2 %>
<% label_padding_right = 24 %>
<% warning_zone = ConstructGraphParameters::WARNING_ZONE %>
<% watch_zone = ConstructGraphParameters::WATCH_ZONE %>
<% growth_zone = ConstructGraphParameters::GROWTH_ZONE %>
<% approval_zone = ConstructGraphParameters::APPROVAL_ZONE %>
<% ideal_zone = ConstructGraphParameters::IDEAL_ZONE %>
<% key_benchmark_width = ConstructGraphParameters::KEY_BENCHMARK_WIDTH %>
<% key_benchmark_left_edge = graph_center - key_benchmark_width / 2 %>
<% construct_row_height = ConstructGraphParameters::CONSTRUCT_ROW_HEIGHT %>
<% construct_row_bar_height = ConstructGraphParameters::CONSTRUCT_ROW_BAR_HEIGHT %>
<%= render partial: "construct_bar_graph", locals: {construct_graph_row_presenters: @construct_graph_row_presenters}%>
<svg id="graph-background" x="25%" y="0" width="75%">
<g id="scale-headings">
<text x=<%= warning_zone.left_edge + warning_zone.width / 2 %> y=<%= heading_gutter / 2 %> text-anchor="middle" dominant-baseline="middle">Warning</text>
<text x=<%= watch_zone.left_edge + watch_zone.width / 2 %> y=<%= heading_gutter / 2 %> text-anchor="middle" dominant-baseline="middle">Watch</text>
<text x=<%= growth_zone.left_edge + growth_zone.width / 2 %> y=<%= heading_gutter / 2 %> text-anchor="middle" dominant-baseline="middle">Growth</text>
<text x=<%= approval_zone.left_edge + approval_zone.width / 2 %> y=<%= heading_gutter / 2 %> text-anchor="middle" dominant-baseline="middle">Approval</text>
<text x=<%= ideal_zone.left_edge + ideal_zone.width / 2 %> y=<%= heading_gutter / 2 %> text-anchor="middle" dominant-baseline="middle">Ideal</text>
</g>
<g id="scale-background" transform="translate(0, <%= heading_gutter %>)">
<rect id="warning-zone" x=<%= warning_zone.left_edge %> y="0" width=<%= warning_zone.width %> height="100%" fill=<%= ConstructGraphParameters::ZoneColor::WARNING %> fill-opacity="0.2" />
<rect id="watch-zone" x=<%= watch_zone.left_edge %> y="0" width=<%= watch_zone.width %> height="100%" fill=<%= ConstructGraphParameters::ZoneColor::WATCH %> fill-opacity="0.2" />
<rect id="growth-zone" x=<%= growth_zone.left_edge %> y="0" width=<%= growth_zone.width %> height="100%" fill=<%= ConstructGraphParameters::ZoneColor::GROWTH %> fill-opacity="0.2" />
<rect id="approval-zone" x=<%= approval_zone.left_edge %> y="0" width=<%= approval_zone.width %> height="100%" fill=<%= ConstructGraphParameters::ZoneColor::APPROVAL %> fill-opacity="0.2" />
<rect id="ideal-zone" x=<%= ideal_zone.left_edge %> y="0" width=<%= ideal_zone.width %> height="100%" fill=<%= ConstructGraphParameters::ZoneColor::IDEAL %> fill-opacity="0.2" />
<rect id="key-benchmark" x=<%= key_benchmark_left_edge %> y="0" width=<%= key_benchmark_width %> height="100%" fill="black" />
</g>
</svg>
<g id="construct-rows">
<svg id="construct-row-labels" x="0" y=<%= heading_gutter %>>
<%= @construct_graph_row_presenters.each_with_index do |presenter, index| %>
<text x="25%" dx=<%= -1 * label_padding_right %> y=<%= index * construct_row_height + construct_row_height / 2 %> text-anchor="end" dominant-baseline="middle"><%= presenter.construct_name %></text>
<% end %>
</svg>
<svg id="construct-row-bars" x="25%" y=<%= heading_gutter %>>
<%= @construct_graph_row_presenters.each_with_index do |presenter, index| %>
<rect class="construct-row-bar" x=<%= graph_center + presenter.x_offset %> y=<%= index * construct_row_height + (construct_row_height - construct_row_bar_height) / 2 %> width="<%= presenter.bar_width %>" height=<%= construct_row_bar_height %> fill=<%= presenter.bar_color %> />
<% end %>
</svg>
</g>
</svg>
</div>

@ -4,6 +4,8 @@
%meta{:content => "text/html; charset=UTF-8", "http-equiv" => "Content-Type"}/
%meta{:charset => "utf-8"}/
%meta{:content => "width=device-width, initial-scale=1, shrink-to-fit=no", :name => "viewport"}/
%link{href: "https://fonts.googleapis.com/css?family=Bitter:400,600,700", rel: "stylesheet", type: "text/css"}/
%link{href: "https://fonts.googleapis.com/css?family=Cabin:400,600,700", rel: "stylesheet", type: "text/css"}/
%title MCIEA
= csrf_meta_tags
= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload'

@ -37,11 +37,11 @@ RSpec.describe "construct graph row presenter" do
end
it('returns a bar width equal to the approval zone width plus the proportionate ideal zone width') do
expect(presenter.bar_width).to eq 324
expect(presenter.bar_width).to eq "37.5%"
end
it('returns an x-offset of 0') do
expect(presenter.x_offset).to eq 0
expect(presenter.x_offset).to eq "50%"
end
end
@ -55,11 +55,11 @@ RSpec.describe "construct graph row presenter" do
end
it('returns a bar width equal to the proportionate approval zone width') do
expect(presenter.bar_width).to eq 108
expect(presenter.bar_width).to eq "12.5%"
end
it('returns an x-offset of 0') do
expect(presenter.x_offset).to eq 0
expect(presenter.x_offset).to eq "50%"
end
end
@ -73,11 +73,11 @@ RSpec.describe "construct graph row presenter" do
end
it('returns a bar width equal to the proportionate growth zone width') do
expect(presenter.bar_width).to eq 29
expect(presenter.bar_width).to eq "3.33%"
end
it('returns an x-offset equal to the bar width') do
expect(presenter.x_offset).to eq -29
expect(presenter.x_offset).to eq "46.67%"
end
end
@ -91,11 +91,11 @@ RSpec.describe "construct graph row presenter" do
end
it('returns a bar width equal to the proportionate watch zone width plus the growth zone width') do
expect(presenter.bar_width).to eq 216
expect(presenter.bar_width).to eq "25.01%"
end
it('returns an x-offset equal to the bar width') do
expect(presenter.x_offset).to eq -216
expect(presenter.x_offset).to eq "25.0%"
end
end
@ -109,11 +109,11 @@ RSpec.describe "construct graph row presenter" do
end
it('returns a bar width equal to the proportionate warning zone width plus the watch & growth zone widths') do
expect(presenter.bar_width).to eq 424
expect(presenter.bar_width).to eq "49.13%"
end
it('returns an x-offset equal to the bar width') do
expect(presenter.x_offset).to eq -424
expect(presenter.x_offset).to eq "0.87%"
end
end
end

Loading…
Cancel
Save