Skip to content

Commit

Permalink
Build statistics block from new data format
Browse files Browse the repository at this point in the history
Previously we're expecting statistics data to be represented in three
columns, one of which would contain the variable name.

That is no longer the case. The variable name is coming from the Y-axis
header. Now the first column represents the x-axis and all of the
others represent the values on the y-axes.

The statistics block is still able to display multiple lines on a line
graph with the same x-axis.

The first header value is being ignored because that is the value for
the x-axis. The rows method is concerned with collating the values to
plot the data against the y-axis.

Also updates the tests to handle files where some data points are
missing, or provided as decimal values. And updates the landing page
factory to accept four attachments to test these different scenarios.

We no longer need to symbolize the keys in the CSV as we need to be able
to match against the header value which is a string, and pass the header
values for the y-axis to the chart component as a string.
  • Loading branch information
leenagupte committed Nov 6, 2024
1 parent eeba94a commit 86e75c0
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 53 deletions.
53 changes: 26 additions & 27 deletions app/models/landing_page/block/statistics.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,16 @@ def x_axis_keys
end

def rows
rows = []

csv_rows.each do |row|
variable_name = row.values.second
value = row.values.last

existing_row = rows.find { |item| item[:label].include?(variable_name) }

if existing_row.present?
existing_row[:values] << value.to_i
else
rows << {
label: variable_name,
values: [value.to_i],
}
csv_headers[1..].map do |header|
values = csv_rows.map do |row|
row[header].to_f
end
end

rows
{
label: header,
values:,
}
end
end

def attachment
Expand All @@ -39,16 +30,24 @@ def attachment
private

def csv_rows
@csv_rows ||= begin
rows = if attachment
CSV.new(URI.parse(attachment.url).open, headers: true).map(&:to_h)
else
# SCAFFOLDING
csv_file_path = Rails.root.join("#{STATISTICS_DATA_PATH}/#{data['csv_file']}")
CSV.read(csv_file_path, headers: true).map(&:to_h)
end
rows.each(&:deep_symbolize_keys!)
end
@csv_rows ||= opened_csv.map(&:to_h)
end

def csv_headers
opened_csv.headers
end

def opened_csv
@opened_csv ||= attachment ? csv_from_url : csv_from_file
end

def csv_from_url
CSV.parse(URI.parse(attachment.url).open, headers: true)
end

def csv_from_file
csv_file_path = Rails.root.join("#{STATISTICS_DATA_PATH}/#{data['csv_file']}")
CSV.read(csv_file_path, headers: true)
end
end
end
22 changes: 22 additions & 0 deletions spec/factories/content_items.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,28 @@
title: "Data Two",
url: "https://www.asset.test.gov.uk/data_two.csv",
},
{
accessible: false,
attachment_type: "document",
content_type: "text/csv",
file_size: 123,
filename: "data_three.csv",
id: 12_347,
preview_url: "https://www.asset.test.gov.uk/data_three.csv/preview",
title: "Data Three",
url: "https://www.asset.test.gov.uk/data_three.csv",
},
{
accessible: false,
attachment_type: "document",
content_type: "text/csv",
file_size: 123,
filename: "data_four.csv",
id: 12_348,
preview_url: "https://www.asset.test.gov.uk/data_four.csv/preview",
title: "Data Four",
url: "https://www.asset.test.gov.uk/data_four.csv",
},
],
}
end
Expand Down
2 changes: 1 addition & 1 deletion spec/models/content_item_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@

describe "#attachments" do
it "loads the attachment data from the content item" do
expect(subject.attachments.count).to eq(2)
expect(subject.attachments.count).to eq(4)
expect(subject.attachments[0].title).to eq("Data One")
end
end
Expand Down
96 changes: 71 additions & 25 deletions spec/models/landing_page/block/statistics_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,60 +14,106 @@
before do
stub_request(:get, "https://www.asset.test.gov.uk/data_one.csv").to_return(status: 200, body: File.read("spec/fixtures/landing_page_statistics_data/data_one.csv"), headers: {})
stub_request(:get, "https://www.asset.test.gov.uk/data_two.csv").to_return(status: 200, body: File.read("spec/fixtures/landing_page_statistics_data/data_two.csv"), headers: {})
stub_request(:get, "https://www.asset.test.gov.uk/data_three.csv").to_return(status: 200, body: File.read("spec/fixtures/landing_page_statistics_data/data_three.csv"), headers: {})
stub_request(:get, "https://www.asset.test.gov.uk/data_four.csv").to_return(status: 200, body: File.read("spec/fixtures/landing_page_statistics_data/data_four.csv"), headers: {})
end

describe "#x_axis_keys" do
it "gets all of the x-axis data points" do
expected_keys = %w[
2024-01-01
2024-02-01
2024-03-01
2024-04-01
2024-05-01
2024-06-01
1/6/2013
1/6/2014
1/6/2015
1/6/2016
1/6/2017
1/6/2018
1/6/2019
]

expect(subject.x_axis_keys).to eq(expected_keys)
end
end

it "gets all of the unique x-axis data points" do
expected_keys = %w[
2024-01-01
2024-02-01
2024-03-01
describe "#rows" do
it "gets the rows for one line of data with decimals" do
expected_rows = [
{
label: "Percentage of people being kinder to one and other",
values: [
0.5,
0.6,
0.7,
0.5,
0.6,
0.7,
0.55,
],
},
]
blocks_hash["csv_file"] = "data_two.csv"

expect(subject.x_axis_keys).to eq(expected_keys)
expect(subject.rows).to eq(expected_rows)
end
end

describe "#rows" do
it "gets the rows for one line of data" do
it "gets the rows for one line of data with whole numbers" do
blocks_hash["csv_file"] = "data_three.csv"

expected_rows = [
{
label: "variable_name",
values: [10, 11, 12, 13, 14, 15],
label: "The number of people working smarter not harder",
values: [
45_775.0,
47_518.0,
50_546.0,
56_042.0,
45_768.0,
34_530.0,
29_585.0,
],
},
]

expect(subject.rows).to eq(expected_rows)
end

it "gets the rows for multiple lines of data" do
it "gets the rows for one line of data when some rows are missing" do
blocks_hash["csv_file"] = "data_two.csv"

expected_rows = [
{
label: "Percentage of people being kinder to one and other",
values: [
0.5,
0.6,
0.7,
0.5,
0.6,
0.7,
0.5,
0.0,
0.0,
0.5,
0.6,
],
},
]

expect(subject.rows).to eq(expected_rows)
end

it "gets the rows for two lines of data" do
blocks_hash["csv_file"] = "data_four.csv"

expected_rows = [
{
label: "variable_name",
values: [10, 11, 12],
label: "Generation X",
values: [10.0, 20.0, 25.0, 30.0],
},
{
label: "variable_name_two",
values: [13, 14, 15],
label: "Millenials",
values: [15.0, 25.0, 30.0, 35.0],
},
]

blocks_hash["csv_file"] = "data_two.csv"

expect(subject.rows).to eq(expected_rows)
end
end
Expand Down

0 comments on commit 86e75c0

Please sign in to comment.