Skip to content

Commit

Permalink
feat: ASCOR emissions chart data
Browse files Browse the repository at this point in the history
  • Loading branch information
martintomas committed Oct 3, 2023
1 parent e947b33 commit 07b8224
Show file tree
Hide file tree
Showing 9 changed files with 245 additions and 0 deletions.
26 changes: 26 additions & 0 deletions app/assets/stylesheets/tpi/pages/ascor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,32 @@
}
}

.emissions-chart-header {
margin-bottom: 20px;

@include desktop {
display: flex;
justify-content: space-between;
align-items: center;
}

&__assessment-dropdown {
display: flex;
align-items: center;
gap: 10px;
}
}

.emissions-chart-description {
margin-bottom: 40px;
font-size: 14px;
line-height: 1.75;

@include desktop {
max-width: 60%;
}
}

section {
margin-top: 70px;

Expand Down
18 changes: 18 additions & 0 deletions app/controllers/tpi/ascor_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ class ASCORController < TPIController
before_action :fetch_ascor_countries, only: [:index, :show]
before_action :fetch_ascor_country, only: [:show]
before_action :fetch_assessment_date, only: [:index, :show, :index_assessment]
before_action :fetch_emissions_assessment_date, only: [:index]
before_action :fetch_ascor_assessment_results, only: [:index, :index_assessment]

def index
Expand All @@ -22,6 +23,19 @@ def show

def index_assessment; end

def index_emissions_assessment; end

def emissions_chart_data
data = ::Api::ASCOR::EmissionsChart.new(
@emissions_assessment_date,
params[:emissions_metric],
params[:emissions_boundary],
params[:country_ids]
).call

render json: data.chart_json
end

def user_download
render zip: {
'ASCOR_countries.xlsx' => Api::CSVToExcel.new(CSVExport::ASCOR::Countries.new.call).call,
Expand All @@ -47,6 +61,10 @@ def fetch_assessment_date
@assessment_date = params[:assessment_date] || ASCOR::Assessment.maximum(:assessment_date)
end

def fetch_emissions_assessment_date
@emissions_assessment_date = params[:emissions_assessment_date] || ASCOR::Assessment.maximum(:assessment_date)
end

def fetch_ascor_assessment_results
@ascor_assessment_results = Api::ASCOR::BubbleChart.new(@assessment_date).call
end
Expand Down
1 change: 1 addition & 0 deletions app/models/ascor/country.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class ASCOR::Country < ApplicationRecord
'Annex I',
'Non-Annex I'
].freeze
DEFAULT_COUNTRIES = %w[USA CAN GBR FRA DEU ITA JPN RUS].freeze

friendly_id :name, use: [:slugged, :history], routes: :default

Expand Down
51 changes: 51 additions & 0 deletions app/services/api/ascor/emissions_chart.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
module Api
module ASCOR
class EmissionsChart
attr_accessor :assessment_date, :emissions_assessment_date, :emissions_metric, :emissions_boundary, :country_ids

def initialize(assessment_date, emissions_metric, emissions_boundary, country_ids)
@assessment_date = assessment_date
@emissions_metric = emissions_metric || 'Absolute'
@emissions_boundary = emissions_boundary || 'Production - excluding LULUCF'
@country_ids = country_ids
end

def call
{data: collect_data, metadata: collect_metadata}
end

private

def collect_data
countries.each_with_object({}) do |country, result|
pathway = pathways[country.id]&.first
result[country.id] = {
emissions: pathway&.emissions || {},
last_historical_year: pathway&.last_historical_year
}
end
end

def collect_metadata
{unit: pathways.values.flatten.first.units}
end

def countries
@countries ||= if country_ids.blank?
::ASCOR::Country.where(iso: ::ASCOR::Country::DEFAULT_COUNTRIES)
else
::ASCOR::Country.where(id: country_ids)
end
end

def pathways
@pathways ||= ::ASCOR::Pathway.where(
country: countries,
emissions_metric: emissions_metric,
emissions_boundary: emissions_boundary,
assessment_date: assessment_date
).group_by(&:country_id)
end
end
end
end
10 changes: 10 additions & 0 deletions app/views/tpi/ascor/_emissions_chart.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!-- TODO: React components need to be replaced!!! -->
<%#= react_component('TODO', {
emissions_metric_filter: ASCOR::EmissionsMetric::VALUES,
default_emissions_metric_filter: 'Absolute',
emissions_boundary_filter: ASCOR::EmissionsBoundary::VALUES,
default_emissions_boundary_filter: 'Production - excluding LULUCF',
countries: ASCOR::Country.all.map { |c| { id: c.id, iso: c.iso, name: c.name } },
default_countries: ASCOR::Country.where(iso: ASCOR::Country::DEFAULT_COUNTRIES).map(&:id),
emissions_data_url: index_emissions_assessment_tpi_ascor_index_path
}) %>
7 changes: 7 additions & 0 deletions app/views/tpi/ascor/_index_emissions_assessment.js.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
(function () {
document.getElementById('emissions-chart').innerHTML = "<%= j render('emissions_chart') %>";
const newUrl = new URL(window.location.href);
newUrl.searchParams.set('emissions_assessment_date', <%= @assessment_date %>);
window.history.replaceState({}, '', newUrl.href);
ReactRailsUJS.mountComponents('#emissions-charts');
})();
31 changes: 31 additions & 0 deletions app/views/tpi/ascor/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,37 @@
</div>
</section>

<!-- TODO: Finalise emissions chart section -->
<!-- All React component code goes into tpi/ascor/emissions_chart partial -->
<section class="container">
<div class="emissions-chart-header">
<h2 class="is-size-4">
Country emission pathways
</h2>

<div class="emissions-chart-header__assessment-dropdown">
<div class="caption">
Assessment Date:
</div>
<div class="date-dropdown">
<%= react_component('RemoteDropdown', {
name: 'emissions_assessment_date',
remote: true,
url: index_emissions_assessment_tpi_ascor_index_path,
data: @assessment_dates.map {|v| {label: v&.strftime('%d %B %Y'), value: v}},
selected: @emissions_assessment_date
}) %>
</div>
</div>
</div>
<div class="emissions-chart-description">
Country emission pathways are assessed in several ways to account for a variety of factors and uncertainties. The emission metrics considered include the following options: production and consumption-based emissions; exclusion of LULUCF emissions and LULUCF emissions alone; and emissions on an absolute and intensity basis (per capita and per PPP-adjusted GDP). Targeted future pathways are included only for absolute production-based emissions excluding LULUCF as this is the basis on which 2030 targets are assessed. Note that pathways end in 2030 because long-term net zero targets are often stated on a different emission boundary from the one considered in the 2030 target assessments (e.g. including only CO₂ emissions rather than all Kyoto greenhouse gases).
</div>
<div id="emissions-chart">
<%= render 'tpi/ascor/emissions_chart' %>
</div>
</section>

<% if @methodology_publication.present? %>
<section id="methodology" class="container">
<div class="columns">
Expand Down
2 changes: 2 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@
resources :ascor, only: [:show, :index] do
collection do
get :index_assessment
get :index_emissions_assessment
get :emissions_chart_data
get :user_download
end
end
Expand Down
99 changes: 99 additions & 0 deletions spec/services/api/ascor/emissions_chart_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
require 'rails_helper'

RSpec.describe Api::ASCOR::EmissionsChart do
subject { described_class.new(assessment_date, emissions_metric, emissions_boundary, country_ids).call }

before_all do
@usa = create(:ascor_country, id: 1, name: 'USA', iso: 'USA')
@czechia = create(:ascor_country, id: 2, name: 'Czechia', iso: 'CZE')

create :ascor_pathway,
country: @usa,
assessment_date: Date.new(2019, 1, 1),
emissions_metric: 'Intensity per capita',
emissions_boundary: 'Consumption - excluding LULUCF',
emissions: {2013 => 100, 2014 => 100, 2015 => 100}
create :ascor_pathway,
country: @usa,
assessment_date: Date.new(2019, 2, 1),
emissions_metric: 'Intensity per capita',
emissions_boundary: 'Consumption - excluding LULUCF',
emissions: {2013 => 110, 2014 => 110, 2015 => 110}
create :ascor_pathway,
country: @czechia,
assessment_date: Date.new(2019, 2, 1),
emissions_metric: 'Intensity per capita',
emissions_boundary: 'Consumption - excluding LULUCF',
emissions: {2013 => 120, 2014 => 120, 2015 => 120}
create :ascor_pathway,
country: @usa,
assessment_date: Date.new(2019, 2, 1),
emissions_metric: 'Absolute',
emissions_boundary: 'Production - excluding LULUCF',
emissions: {2013 => 130, 2014 => 130, 2015 => 130}
create :ascor_pathway,
country: @czechia,
assessment_date: Date.new(2019, 2, 1),
emissions_metric: 'Absolute',
emissions_boundary: 'Production - excluding LULUCF',
emissions: {2013 => 140, 2014 => 140, 2015 => 140}
end

let(:assessment_date) { Date.new(2019, 2, 1) }
let(:emissions_metric) { 'Intensity per capita' }
let(:emissions_boundary) { 'Consumption - excluding LULUCF' }
let(:country_ids) { [@usa.id, @czechia.id] }

it 'returns expected result' do
expect(subject).to eq(
data: {
@usa.id => {
emissions: {'2013' => 110, '2014' => 110, '2015' => 110},
last_historical_year: 2010
},
@czechia.id => {
emissions: {'2013' => 120, '2014' => 120, '2015' => 120},
last_historical_year: 2010
}
},
metadata: {unit: 'MtCO2e'}
)
end

context 'when country_ids are nil' do
let(:country_ids) { nil }

it 'returns expected result' do
expect(subject).to eq(
data: {
@usa.id => {
emissions: {'2013' => 110, '2014' => 110, '2015' => 110},
last_historical_year: 2010
}
},
metadata: {unit: 'MtCO2e'}
)
end
end

context 'when emissions_metric and emissions_boundary is nil' do
let(:emissions_metric) { nil }
let(:emissions_boundary) { nil }

it 'returns expected result' do
expect(subject).to eq(
data: {
@usa.id => {
emissions: {'2013' => 130, '2014' => 130, '2015' => 130},
last_historical_year: 2010
},
@czechia.id => {
emissions: {'2013' => 140, '2014' => 140, '2015' => 140},
last_historical_year: 2010
}
},
metadata: {unit: 'MtCO2e'}
)
end
end
end

0 comments on commit 07b8224

Please sign in to comment.