From 030a5bcba0578bcf03f8cfe04935ddcfc89c717c Mon Sep 17 00:00:00 2001 From: Leena Gupte Date: Wed, 9 Oct 2024 12:41:49 +0100 Subject: [PATCH 01/10] Add YAML content and data for a statistics block Statistics data will be read in from a CSV to be provided by departments and then converted into a chart in the statistics block on landing pages. It is assumed that users will not need to be able to download the CSV files directly and that a link will be provided to an externally hosted data source, e.g. ONS data. --- .../landing_page_content_items/landing_page.yaml | 14 ++++++++++++++ .../statistics/data_one.csv | 7 +++++++ .../statistics/data_two.csv | 7 +++++++ spec/fixtures/landing_page.yaml | 9 ++++++++- .../landing_page_statistics_data/data_one.csv | 7 +++++++ 5 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 lib/data/landing_page_content_items/statistics/data_one.csv create mode 100644 lib/data/landing_page_content_items/statistics/data_two.csv create mode 100644 spec/fixtures/landing_page_statistics_data/data_one.csv diff --git a/lib/data/landing_page_content_items/landing_page.yaml b/lib/data/landing_page_content_items/landing_page.yaml index 2c226a91d4..fb5a4f98c4 100644 --- a/lib/data/landing_page_content_items/landing_page.yaml +++ b/lib/data/landing_page_content_items/landing_page.yaml @@ -167,6 +167,20 @@ blocks: - type: govspeak inverse: true content:

Title 2 govspeak title goes here

+- type: statistics + title: "Chart to visually represent data" + x_axis_label: "X Axis" + y_axis_label: "Y Axis" + csv_file: "data_one.csv" + data_source_link_text: "Data source" + data_source_link: https://www.ons.gov.uk/economy/grossdomesticproductgdp/timeseries/ihyq/qna +- type: statistics + title: "Chart to visually represent data" + x_axis_label: "X Axis" + y_axis_label: "Y Axis" + csv_file: "data_two.csv" + data_source_link_text: "Data source" + data_source_link: https://www.ons.gov.uk/economy/inflationandpriceindices/timeseries/l55o/mm23 - type: share_links links: - href: "/twitter-share-link" diff --git a/lib/data/landing_page_content_items/statistics/data_one.csv b/lib/data/landing_page_content_items/statistics/data_one.csv new file mode 100644 index 0000000000..04a74a1292 --- /dev/null +++ b/lib/data/landing_page_content_items/statistics/data_one.csv @@ -0,0 +1,7 @@ +Date,variable,value +2024-01-01,variable_name,10 +2024-02-01,variable_name,11 +2024-03-01,variable_name,12 +2024-04-01,variable_name,13 +2024-05-01,variable_name,14 +2024-06-01,variable_name,15 \ No newline at end of file diff --git a/lib/data/landing_page_content_items/statistics/data_two.csv b/lib/data/landing_page_content_items/statistics/data_two.csv new file mode 100644 index 0000000000..c408613689 --- /dev/null +++ b/lib/data/landing_page_content_items/statistics/data_two.csv @@ -0,0 +1,7 @@ +Date,variable,value +2023-01-01,variable_name,20 +2023-02-01,variable_name,21 +2023-03-01,variable_name,22 +2023-04-01,variable_name,23 +2023-05-01,variable_name,24 +2023-06-01,variable_name,25 \ No newline at end of file diff --git a/spec/fixtures/landing_page.yaml b/spec/fixtures/landing_page.yaml index b34accb74b..dba5f60990 100644 --- a/spec/fixtures/landing_page.yaml +++ b/spec/fixtures/landing_page.yaml @@ -109,7 +109,7 @@ blocks: card_content: blocks: - type: govspeak - inverse: true + inverse: true content:

Title 2 govspeak title goes here

- type: card image: @@ -146,3 +146,10 @@ blocks: - type: govspeak inverse: true content:

Title 2 govspeak title goes here

+- type: statistics + title: "Chart to visually represent data" + x_axis_label: "X Axis" + y_axis_label: "Y Axis" + csv_file: "data_one.csv" + data_source_link_text: "Data source" + data_source_link: https://www.example.com diff --git a/spec/fixtures/landing_page_statistics_data/data_one.csv b/spec/fixtures/landing_page_statistics_data/data_one.csv new file mode 100644 index 0000000000..04a74a1292 --- /dev/null +++ b/spec/fixtures/landing_page_statistics_data/data_one.csv @@ -0,0 +1,7 @@ +Date,variable,value +2024-01-01,variable_name,10 +2024-02-01,variable_name,11 +2024-03-01,variable_name,12 +2024-04-01,variable_name,13 +2024-05-01,variable_name,14 +2024-06-01,variable_name,15 \ No newline at end of file From 7414e9976f3f2bdfefa2512c60d983a760130a06 Mon Sep 17 00:00:00 2001 From: Leena Gupte Date: Wed, 9 Oct 2024 12:43:44 +0100 Subject: [PATCH 02/10] Add a model for the statistics block It's unclear exactly how the data from the CSV files will be used to display the graphs, so for the moment the unmodified rows are just being returned. --- app/models/block/statistics.rb | 33 ++++++++++++++ spec/models/block/statistics_spec.rb | 66 ++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 app/models/block/statistics.rb create mode 100644 spec/models/block/statistics_spec.rb diff --git a/app/models/block/statistics.rb b/app/models/block/statistics.rb new file mode 100644 index 0000000000..3c2d29ad84 --- /dev/null +++ b/app/models/block/statistics.rb @@ -0,0 +1,33 @@ +require "csv" + +module Block + class Statistics < Block::Base + STATISTICS_DATA_PATH = "lib/data/landing_page_content_items/statistics".freeze + + def title + data["title"] + end + + def x_axis_label + data["x_axis_label"] + end + + def y_axis_label + data["y_axis_label"] + end + + def rows + CSV.read(csv_file_path, headers: true).map(&:to_h) + end + + def data_source_link + data["data_source_link"] + end + + private + + def csv_file_path + @csv_file_path ||= Rails.root.join("#{STATISTICS_DATA_PATH}/#{data['csv_file']}") + end + end +end diff --git a/spec/models/block/statistics_spec.rb b/spec/models/block/statistics_spec.rb new file mode 100644 index 0000000000..93d2aa736d --- /dev/null +++ b/spec/models/block/statistics_spec.rb @@ -0,0 +1,66 @@ +RSpec.describe Block::Statistics do + let(:blocks_hash) do + { + "type" => "statistics", + "title" => "Chart to visually represent data", + "x_axis_label" => "X Axis", + "y_axis_label" => "Y Axis", + "csv_file" => "data_one.csv", + "data_source_link_text" => "Data source", + "data_source_link" => "https://www.example.com", + } + end + + before do + Block::Statistics.send(:remove_const, "STATISTICS_DATA_PATH") + Block::Statistics.const_set("STATISTICS_DATA_PATH", "spec/fixtures/landing_page_statistics_data") + end + + after do + Block::Statistics.send(:remove_const, "STATISTICS_DATA_PATH") + Block::Statistics.const_set("STATISTICS_DATA_PATH", "lib/data/landing_page_content_items/statistics") + end + + describe "statistics content" do + describe "#title" do + it "gets statistics title" do + expect(described_class.new(blocks_hash).title).to eq("Chart to visually represent data") + end + end + + describe "#x_axis_label" do + it "gets the label for the x-axix" do + expect(described_class.new(blocks_hash).x_axis_label).to eq("X Axis") + end + end + + describe "#y_axis_label" do + it "gets the label for the y-axis" do + expect(described_class.new(blocks_hash).y_axis_label).to eq("Y Axis") + end + end + end + + describe "chart data" do + describe "#rows" do + it "returns the row data for the chart" do + expected_rows = [ + { "Date" => "2024-01-01", "value" => "10", "variable" => "variable_name" }, + { "Date" => "2024-02-01", "value" => "11", "variable" => "variable_name" }, + { "Date" => "2024-03-01", "value" => "12", "variable" => "variable_name" }, + { "Date" => "2024-04-01", "value" => "13", "variable" => "variable_name" }, + { "Date" => "2024-05-01", "value" => "14", "variable" => "variable_name" }, + { "Date" => "2024-06-01", "value" => "15", "variable" => "variable_name" }, + ] + + expect(described_class.new(blocks_hash).rows).to eq(expected_rows) + end + end + + describe "#data_source_link" do + it "returns the link to the external data source" do + expect(described_class.new(blocks_hash).data_source_link).to eq("https://www.example.com") + end + end + end +end From c6b5dc248a7d4fc54744da028c3c6d7cbfc984a9 Mon Sep 17 00:00:00 2001 From: Leena Gupte Date: Wed, 9 Oct 2024 12:44:56 +0100 Subject: [PATCH 03/10] Add a placeholder view to display the modeled statistics data. The block should render twice as two statistics have been added to the sample content item data. --- app/views/landing_page/blocks/_statistics.html.erb | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 app/views/landing_page/blocks/_statistics.html.erb diff --git a/app/views/landing_page/blocks/_statistics.html.erb b/app/views/landing_page/blocks/_statistics.html.erb new file mode 100644 index 0000000000..43fb7502c5 --- /dev/null +++ b/app/views/landing_page/blocks/_statistics.html.erb @@ -0,0 +1,7 @@ +

Placeholder statistics partial

+<%= block.row_header %> +
+<%= block.rows %> +
+<%= link_to block.data["data_source_link_text"], block.data_source_link %> + From e6b5d9c89b7d2bf64d10e2f9735f3cbef34b5280 Mon Sep 17 00:00:00 2001 From: Andy Sellick Date: Tue, 15 Oct 2024 16:24:02 +0100 Subject: [PATCH 04/10] WIP use chart component --- app/assets/javascripts/dependencies.js | 2 + app/models/block/statistics.rb | 4 ++ .../landing_page/blocks/_statistics.html.erb | 43 ++++++++++++++++--- .../landing_page.yaml | 5 ++- 4 files changed, 46 insertions(+), 8 deletions(-) diff --git a/app/assets/javascripts/dependencies.js b/app/assets/javascripts/dependencies.js index 6c8378d368..1996052ccc 100644 --- a/app/assets/javascripts/dependencies.js +++ b/app/assets/javascripts/dependencies.js @@ -8,3 +8,5 @@ //= require govuk_publishing_components/components/step-by-step-nav //= require govuk_publishing_components/components/table //= require govuk_publishing_components/components/tabs + +//= require govuk_publishing_components/components/chart diff --git a/app/models/block/statistics.rb b/app/models/block/statistics.rb index 3c2d29ad84..240e5faa7a 100644 --- a/app/models/block/statistics.rb +++ b/app/models/block/statistics.rb @@ -16,6 +16,10 @@ def y_axis_label data["y_axis_label"] end + def hide_legend + data["hide_legend"] + end + def rows CSV.read(csv_file_path, headers: true).map(&:to_h) end diff --git a/app/views/landing_page/blocks/_statistics.html.erb b/app/views/landing_page/blocks/_statistics.html.erb index 43fb7502c5..fa48274fbb 100644 --- a/app/views/landing_page/blocks/_statistics.html.erb +++ b/app/views/landing_page/blocks/_statistics.html.erb @@ -1,7 +1,38 @@ -

Placeholder statistics partial

-<%= block.row_header %> -
-<%= block.rows %> -
-<%= link_to block.data["data_source_link_text"], block.data_source_link %> +<% + add_gem_component_stylesheet("chart") + + rows = [] + lines = {} + keys = [] + block.rows.each_with_index do |row, i| + keys << row["Date"] + if lines.key?(row["variable"].to_sym) + lines[row["variable"].to_sym][:values] << row["value"].to_i + else + lines[row["variable"].to_sym] = { + label: row["Date"], + values: [ + row["value"].to_i + ] + } + end + + end + lines.each do |key, array| + rows << { + label: key.to_s, + values: lines[key][:values] + } + end +%> + +<%= render "govuk_publishing_components/components/chart", { + chart_heading: block.title, + h_axis_title: block.x_axis_label, + v_axis_title: block.y_axis_label, + hide_legend: block.hide_legend, + keys: keys, + rows: rows, +} %> +<%= link_to block.data["data_source_link_text"], block.data_source_link %> diff --git a/lib/data/landing_page_content_items/landing_page.yaml b/lib/data/landing_page_content_items/landing_page.yaml index fb5a4f98c4..bb70148b22 100644 --- a/lib/data/landing_page_content_items/landing_page.yaml +++ b/lib/data/landing_page_content_items/landing_page.yaml @@ -168,14 +168,15 @@ blocks: inverse: true content:

Title 2 govspeak title goes here

- type: statistics - title: "Chart to visually represent data" + title: "Chart to visually represent some data" x_axis_label: "X Axis" y_axis_label: "Y Axis" + hide_legend: true csv_file: "data_one.csv" data_source_link_text: "Data source" data_source_link: https://www.ons.gov.uk/economy/grossdomesticproductgdp/timeseries/ihyq/qna - type: statistics - title: "Chart to visually represent data" + title: "Chart to visually represent some more data" x_axis_label: "X Axis" y_axis_label: "Y Axis" csv_file: "data_two.csv" From 31b122e3f9ab15dfd29d3f29100c761f32f27cde Mon Sep 17 00:00:00 2001 From: Leena Gupte Date: Fri, 18 Oct 2024 11:14:24 +0100 Subject: [PATCH 05/10] Add a method to get the x-axis keys --- app/models/block/statistics.rb | 4 +++ .../landing_page/blocks/_statistics.html.erb | 4 +-- .../statistics/data_two.csv | 6 ++--- .../landing_page_statistics_data/data_two.csv | 7 +++++ spec/models/block/statistics_spec.rb | 26 +++++++++++++++++++ 5 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 spec/fixtures/landing_page_statistics_data/data_two.csv diff --git a/app/models/block/statistics.rb b/app/models/block/statistics.rb index 240e5faa7a..5cd2c5a8aa 100644 --- a/app/models/block/statistics.rb +++ b/app/models/block/statistics.rb @@ -20,6 +20,10 @@ def hide_legend data["hide_legend"] end + def x_axis_keys + @x_axis_keys ||= csv_rows.map { |row| row[row.keys.first] }.uniq + end + def rows CSV.read(csv_file_path, headers: true).map(&:to_h) end diff --git a/app/views/landing_page/blocks/_statistics.html.erb b/app/views/landing_page/blocks/_statistics.html.erb index fa48274fbb..def267809a 100644 --- a/app/views/landing_page/blocks/_statistics.html.erb +++ b/app/views/landing_page/blocks/_statistics.html.erb @@ -3,9 +3,7 @@ rows = [] lines = {} - keys = [] block.rows.each_with_index do |row, i| - keys << row["Date"] if lines.key?(row["variable"].to_sym) lines[row["variable"].to_sym][:values] << row["value"].to_i else @@ -32,7 +30,7 @@ h_axis_title: block.x_axis_label, v_axis_title: block.y_axis_label, hide_legend: block.hide_legend, - keys: keys, + keys: block.x_axis_keys, rows: rows, } %> <%= link_to block.data["data_source_link_text"], block.data_source_link %> diff --git a/lib/data/landing_page_content_items/statistics/data_two.csv b/lib/data/landing_page_content_items/statistics/data_two.csv index c408613689..35ec1131d6 100644 --- a/lib/data/landing_page_content_items/statistics/data_two.csv +++ b/lib/data/landing_page_content_items/statistics/data_two.csv @@ -2,6 +2,6 @@ Date,variable,value 2023-01-01,variable_name,20 2023-02-01,variable_name,21 2023-03-01,variable_name,22 -2023-04-01,variable_name,23 -2023-05-01,variable_name,24 -2023-06-01,variable_name,25 \ No newline at end of file +2023-01-01,variable_name_two,23 +2023-02-01,variable_name_two,24 +2023-03-01,variable_name_two,25 \ No newline at end of file diff --git a/spec/fixtures/landing_page_statistics_data/data_two.csv b/spec/fixtures/landing_page_statistics_data/data_two.csv new file mode 100644 index 0000000000..3d5cd8bcad --- /dev/null +++ b/spec/fixtures/landing_page_statistics_data/data_two.csv @@ -0,0 +1,7 @@ +Date,variable,value +2024-01-01,variable_name,10 +2024-02-01,variable_name,11 +2024-03-01,variable_name,12 +2024-01-01,variable_name_two,13 +2024-02-01,variable_name_two,14 +2024-03-01,variable_name_two,15 \ No newline at end of file diff --git a/spec/models/block/statistics_spec.rb b/spec/models/block/statistics_spec.rb index 93d2aa736d..54fdc92004 100644 --- a/spec/models/block/statistics_spec.rb +++ b/spec/models/block/statistics_spec.rb @@ -62,5 +62,31 @@ expect(described_class.new(blocks_hash).data_source_link).to eq("https://www.example.com") end 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 + ] + + expect(described_class.new(blocks_hash).x_axis_keys).to eq(expected_keys) + end + + it "gets all of the unique x-axis data points" do + expected_keys = %w[ + 2024-01-01 + 2024-02-01 + 2024-03-01 + ] + blocks_hash["csv_file"] = "data_two.csv" + + expect(described_class.new(blocks_hash).x_axis_keys).to eq(expected_keys) + end + end end end From cbbfbac122f80340f173d4b6d9bbca7fce4d64e4 Mon Sep 17 00:00:00 2001 From: Leena Gupte Date: Fri, 18 Oct 2024 13:55:59 +0100 Subject: [PATCH 06/10] Rename "rows" method in statistics block A new "rows" method will be created in the next commit --- app/models/block/statistics.rb | 2 +- spec/models/block/statistics_spec.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/models/block/statistics.rb b/app/models/block/statistics.rb index 5cd2c5a8aa..dc9b53ac1d 100644 --- a/app/models/block/statistics.rb +++ b/app/models/block/statistics.rb @@ -24,7 +24,7 @@ def x_axis_keys @x_axis_keys ||= csv_rows.map { |row| row[row.keys.first] }.uniq end - def rows + def csv_rows CSV.read(csv_file_path, headers: true).map(&:to_h) end diff --git a/spec/models/block/statistics_spec.rb b/spec/models/block/statistics_spec.rb index 54fdc92004..248debd85b 100644 --- a/spec/models/block/statistics_spec.rb +++ b/spec/models/block/statistics_spec.rb @@ -42,7 +42,7 @@ end describe "chart data" do - describe "#rows" do + describe "#csv_rows" do it "returns the row data for the chart" do expected_rows = [ { "Date" => "2024-01-01", "value" => "10", "variable" => "variable_name" }, @@ -53,7 +53,7 @@ { "Date" => "2024-06-01", "value" => "15", "variable" => "variable_name" }, ] - expect(described_class.new(blocks_hash).rows).to eq(expected_rows) + expect(described_class.new(blocks_hash).csv_rows).to eq(expected_rows) end end From e4aae75679e76da53c912a5488d6b305e4924a6a Mon Sep 17 00:00:00 2001 From: Leena Gupte Date: Fri, 18 Oct 2024 13:56:24 +0100 Subject: [PATCH 07/10] Add a rows method to return a row for each y-axis variable --- app/models/block/statistics.rb | 27 +++++++++++++++++++++++++ spec/models/block/statistics_spec.rb | 30 ++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/app/models/block/statistics.rb b/app/models/block/statistics.rb index dc9b53ac1d..88924130c4 100644 --- a/app/models/block/statistics.rb +++ b/app/models/block/statistics.rb @@ -24,6 +24,33 @@ def x_axis_keys @x_axis_keys ||= csv_rows.map { |row| row[row.keys.first] }.uniq end + def rows + lines = {} + rows = [] + + csv_rows.each_with_index do |row, _i| + if lines.key?(row["variable"].to_sym) + lines[row["variable"].to_sym][:values] << row["value"].to_i + else + lines[row["variable"].to_sym] = { + label: row["Date"], + values: [ + row["value"].to_i, + ], + } + end + end + + lines.each_key do |key| + rows << { + label: key.to_s, + values: lines[key][:values], + } + end + + rows + end + def csv_rows CSV.read(csv_file_path, headers: true).map(&:to_h) end diff --git a/spec/models/block/statistics_spec.rb b/spec/models/block/statistics_spec.rb index 248debd85b..d48e59f52a 100644 --- a/spec/models/block/statistics_spec.rb +++ b/spec/models/block/statistics_spec.rb @@ -88,5 +88,35 @@ expect(described_class.new(blocks_hash).x_axis_keys).to eq(expected_keys) end end + + describe "#rows" do + it "gets the rows for one line of data" do + expected_rows = [ + { + label: "variable_name", + values: [10, 11, 12, 13, 14, 15], + }, + ] + + expect(described_class.new(blocks_hash).rows).to eq(expected_rows) + end + + it "gets the rows for multiple lines of data" do + expected_rows = [ + { + label: "variable_name", + values: [10, 11, 12], + }, + { + label: "variable_name_two", + values: [13, 14, 15], + }, + ] + + blocks_hash["csv_file"] = "data_two.csv" + + expect(described_class.new(blocks_hash).rows).to eq(expected_rows) + end + end end end From 222e88ba5aca5439be4a7cd58ade8624088eb5fe Mon Sep 17 00:00:00 2001 From: Leena Gupte Date: Fri, 18 Oct 2024 13:07:13 +0100 Subject: [PATCH 08/10] Use new rows method in the view --- .../landing_page/blocks/_statistics.html.erb | 25 +------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/app/views/landing_page/blocks/_statistics.html.erb b/app/views/landing_page/blocks/_statistics.html.erb index def267809a..e1b955f5d1 100644 --- a/app/views/landing_page/blocks/_statistics.html.erb +++ b/app/views/landing_page/blocks/_statistics.html.erb @@ -1,28 +1,5 @@ <% add_gem_component_stylesheet("chart") - - rows = [] - lines = {} - block.rows.each_with_index do |row, i| - if lines.key?(row["variable"].to_sym) - lines[row["variable"].to_sym][:values] << row["value"].to_i - else - lines[row["variable"].to_sym] = { - label: row["Date"], - values: [ - row["value"].to_i - ] - } - end - - end - - lines.each do |key, array| - rows << { - label: key.to_s, - values: lines[key][:values] - } - end %> <%= render "govuk_publishing_components/components/chart", { @@ -31,6 +8,6 @@ v_axis_title: block.y_axis_label, hide_legend: block.hide_legend, keys: block.x_axis_keys, - rows: rows, + rows: block.rows, } %> <%= link_to block.data["data_source_link_text"], block.data_source_link %> From 4d721d3089660a7c916f6f653a4618646dbf82d2 Mon Sep 17 00:00:00 2001 From: Leena Gupte Date: Fri, 18 Oct 2024 14:18:35 +0100 Subject: [PATCH 09/10] Make csv_rows method private and remove tests --- app/models/block/statistics.rb | 8 ++++---- spec/models/block/statistics_spec.rb | 15 --------------- 2 files changed, 4 insertions(+), 19 deletions(-) diff --git a/app/models/block/statistics.rb b/app/models/block/statistics.rb index 88924130c4..e757571052 100644 --- a/app/models/block/statistics.rb +++ b/app/models/block/statistics.rb @@ -51,16 +51,16 @@ def rows rows end - def csv_rows - CSV.read(csv_file_path, headers: true).map(&:to_h) - end - def data_source_link data["data_source_link"] end private + def csv_rows + CSV.read(csv_file_path, headers: true).map(&:to_h) + end + def csv_file_path @csv_file_path ||= Rails.root.join("#{STATISTICS_DATA_PATH}/#{data['csv_file']}") end diff --git a/spec/models/block/statistics_spec.rb b/spec/models/block/statistics_spec.rb index d48e59f52a..20017fd86b 100644 --- a/spec/models/block/statistics_spec.rb +++ b/spec/models/block/statistics_spec.rb @@ -42,21 +42,6 @@ end describe "chart data" do - describe "#csv_rows" do - it "returns the row data for the chart" do - expected_rows = [ - { "Date" => "2024-01-01", "value" => "10", "variable" => "variable_name" }, - { "Date" => "2024-02-01", "value" => "11", "variable" => "variable_name" }, - { "Date" => "2024-03-01", "value" => "12", "variable" => "variable_name" }, - { "Date" => "2024-04-01", "value" => "13", "variable" => "variable_name" }, - { "Date" => "2024-05-01", "value" => "14", "variable" => "variable_name" }, - { "Date" => "2024-06-01", "value" => "15", "variable" => "variable_name" }, - ] - - expect(described_class.new(blocks_hash).csv_rows).to eq(expected_rows) - end - end - describe "#data_source_link" do it "returns the link to the external data source" do expect(described_class.new(blocks_hash).data_source_link).to eq("https://www.example.com") From 3e54bb9c8700916921873ea84637ed15b599a297 Mon Sep 17 00:00:00 2001 From: Leena Gupte Date: Fri, 18 Oct 2024 14:24:21 +0100 Subject: [PATCH 10/10] Refactor the rows method in the statistics block Divides the rows method to a small public rows method and a private `row_lines` method. This allows further refactoring without having to change the tests. Use a map rather than an each in rows method to make the method slightly smaller. `each_with_index` has been replaced with `each_with_object` for the same reason. The CSV rows are being returned with symbol keys to that `to_sym` doesn't need to be used in multiple places. Finally, the row keys and values are being obfuscated. We can't guarantee what the keys will be named so it's better not to rely on them. We're still assuming that each row will have 3 columns: - x-axis value - variable / line name - y-axis value --- app/models/block/statistics.rb | 45 +++++++++++++++++----------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/app/models/block/statistics.rb b/app/models/block/statistics.rb index e757571052..de35eef3c0 100644 --- a/app/models/block/statistics.rb +++ b/app/models/block/statistics.rb @@ -25,30 +25,12 @@ def x_axis_keys end def rows - lines = {} - rows = [] - - csv_rows.each_with_index do |row, _i| - if lines.key?(row["variable"].to_sym) - lines[row["variable"].to_sym][:values] << row["value"].to_i - else - lines[row["variable"].to_sym] = { - label: row["Date"], - values: [ - row["value"].to_i, - ], - } - end - end - - lines.each_key do |key| - rows << { + row_lines.map do |key, value| + { label: key.to_s, - values: lines[key][:values], + values: value[:values], } end - - rows end def data_source_link @@ -57,8 +39,27 @@ def data_source_link private + def row_lines + csv_rows.each_with_object({}) do |row, lines| + label = row.keys.first + variable_name = row.values.second + value = row.values.last + if lines.key?(variable_name) + lines[variable_name][:values] << value.to_i + else + lines[variable_name] = { + label:, + values: [ + value.to_i, + ], + } + end + end + end + def csv_rows - CSV.read(csv_file_path, headers: true).map(&:to_h) + rows = CSV.read(csv_file_path, headers: true).map(&:to_h) + rows.each(&:deep_symbolize_keys!) end def csv_file_path