app/assets/javascripts/countries/views/CountryReportView.js
define(
[
'backbone',
'handlebars',
'mps',
'nouislider',
'moment',
'underscore',
'_string',
'helpers/NumbersHelper',
'countries/services/ReportService',
'services/ContinentService',
'countries/views/report/SummaryChartView',
'countries/views/report/HistoricalTrendChartView',
'countries/views/report/PieChartView',
'countries/views/report/ProvincesTopChartView',
'countries/views/report/CountryGeoView',
'text!countries/templates/countryReport.handlebars'
],
function(
Backbone,
Handlebars,
mps,
nouislider,
moment,
_,
_string,
NumbersHelper,
ReportService,
ContinentService,
SummaryChartView,
HistoricalTrendChartView,
PieChartView,
ProvincesTopChartView,
CountryGeoView,
tpl
) {
'use strict';
var ENDPOINT_ACCURACY =
"/query/a1669972-d748-4542-8fa9-94f446f65c11?sql=SELECT * FROM data WHERE (iso IN ('%s'))";
var CountryReportView = Backbone.View.extend({
el: '#report',
template: Handlebars.compile(tpl),
status: new (Backbone.Model.extend())(),
continents: ['AF', 'AS', 'SA'],
isCountry: true,
defaults: {
settings: {
reference_start_year: '2001',
reference_end_year: '2010',
monitor_start_year: '2011',
monitor_end_year: '2017',
thresh: '30',
below: 'false',
primary_forest: 'false',
exclude_plantations: 'false',
co2: 'true'
},
minYear: 2001,
maxYear: 2017
},
events: {
'change .js-report-param': '_handleReportParamsChange',
'click #update-report-btn': '_updateReport',
'click #report-updates-submit': '_subscribeUpdates'
},
initialize: function(params) {
this.options = this._getOptions(params);
this.indicatorsList = this.options.indicators;
this.defaultSettings = this.options.settings;
this.iso = this.options.iso;
if (this.continents.indexOf(this.iso) > -1) {
this.isCountry = false;
}
if (_.isEmpty(this.options.params)) {
this._setDefaultParams();
} else {
this.status.clear({ silent: true }).set(this.options.params);
this._getData();
}
},
_getOptions: function(params) {
var options = _.extend(this.defaults, params);
if (
!params.params.primary_forest &&
this._hasPrimaryForest(params.iso) &&
this._isDefaultPrimaryForest(params.iso)
) {
options.settings.primary_forest = 'true';
}
if (
!params.params.exclude_plantations &&
this._hasPlantations(params.iso) &&
this._isDefaultExcludePlantations(params.iso)
) {
options.settings.exclude_plantations = 'true';
}
return options;
},
// TODO: make this dynamic !!!
_hasPrimaryForest: function(iso) {
var hasPrimaryForest = ['COD', 'IDN'];
return hasPrimaryForest.indexOf(iso) >= 0;
},
_hasPlantations: function(iso) {
var hasPlantations = ['BRA', 'IDN', 'MYS', 'COL', 'KHM', 'LBR', 'PER'];
return hasPlantations.indexOf(iso) >= 0;
},
_isDefaultPrimaryForest: function(iso) {
var primaryForestDefault = ['COD'];
return primaryForestDefault.indexOf(iso) >= 0;
},
_isDefaultExcludePlantations: function(iso) {
var excludePlantationsDefault = ['IDN', 'MYS', 'BRA'];
return excludePlantationsDefault.indexOf(iso) >= 0;
},
_cache: function() {
this.yearSelector = this.el.querySelector('.js-year-selector');
this.yearSelectorReference = this.el.querySelector(
'.js-reference-slider'
);
this.yearSelectorMonitor = this.el.querySelector('.js-monitor-slider');
},
render: function() {
this.$el.removeClass('is-loading');
this.$el.html(this.template(this.parseTemplate()));
this.updateBox = this.$('.updates-box');
this._cache();
this._initModules();
this._listenModules();
},
parseTemplate: function() {
var currentDate = moment();
var totalReference = '';
var totalMonitoring = '';
var increase = '';
var factorAbovegroundBiomass = '';
var factorBelowgroundBiomass = '';
var factorTotalEmission = '';
var hasProvinces = false;
var co2EmissionsByProvinces = '';
if (this.data) {
if (this.data.emissions) {
totalReference = NumbersHelper.round(
this.data.emissions.reference.average,
6
);
totalMonitoring = NumbersHelper.round(
this.data.emissions.monitor.average,
6
);
increase = Math.round(
(totalMonitoring - totalReference) / totalReference * 100
);
factorAbovegroundBiomass = Math.round(
this.data.emission_factors.aboveground
);
factorBelowgroundBiomass = Math.round(
this.data.emission_factors.belowground
);
}
if (this.data.provinces) {
hasProvinces = this.data.provinces.emissions.top_five.length > 0;
co2EmissionsByProvinces = this.data.provinces.emissions.top_five;
}
if (this.data.emission_factors) {
factorTotalEmission = Math.round(this.data.emission_factors.total);
}
}
return {
country: this.data.country,
date: currentDate.format('MM/DD/YYYY'),
year: currentDate.year(),
monitorStart: this.status.get('monitor_start_year'),
monitorEnd: this.status.get('monitor_end_year'),
referenceStart: this.status.get('reference_start_year'),
referenceEnd: this.status.get('reference_end_year'),
primaryForest: {
disabled: !this._hasPrimaryForest(this.options.iso),
checked: this.status.get('primary_forest') === 'true'
},
excludePlantations: {
disabled: !this._hasPlantations(this.options.iso),
checked: this.status.get('exclude_plantations') === 'true'
},
below: this.status.get('below') === 'true',
co2: this.status.get('co2') === 'true',
totalReference: totalReference,
totalMonitoring: totalMonitoring,
increase: increase,
increaseDisplay: Math.abs(increase),
hasIncreased: increase > -1,
hasProvinces: hasProvinces,
factorAbovegroundBiomass: factorAbovegroundBiomass,
factorBelowgroundBiomass: factorBelowgroundBiomass,
factorTotalEmission: factorTotalEmission,
co2EmissionsByProvinces: co2EmissionsByProvinces,
accuracyData: this.accuracyData
};
},
_setDefaultParams: function() {
mps.publish('Router/change', [this.defaultSettings]);
this.status.clear({ silent: true }).set(this.defaultSettings);
},
_updateParams: function() {
mps.publish('Router/change', [this.status.attributes]);
},
_getData: function() {
this.status.set(
{
iso: this.iso
},
{ silent: true }
);
ReportService.get(this.status.toJSON()).then(
function(data) {
this.data = data;
this._getAccuracyData();
}.bind(this)
);
},
_getAccuracyData: function() {
var url =
window.gfw.config.GFW_API_HOST_PRO +
_.str.sprintf(ENDPOINT_ACCURACY, this.iso);
$.when($.getJSON(url)).then(
function(res) {
this.accuracyData = res.data[0];
this.render();
}.bind(this)
);
},
_initModules: function() {
this._initSlides();
this.summaryChart = new SummaryChartView({
data: this.data.emissions,
country: this.data.country,
startYear: parseInt(this.status.get('reference_start_year'), 10),
endYear: parseInt(this.status.get('monitor_end_year'), 10),
commonYear: this.status.get('reference_end_year'),
minYear: this.defaults.minYear,
maxYear: this.defaults.maxYear
});
this.historicalTrendChart = new HistoricalTrendChartView({
el: '#historical-trend-chart',
data: this.data.forest_loss
});
this.forestRelatedEmissionsChart = new HistoricalTrendChartView({
el: '#forest-related-emissions-chart',
data: this.data.emissions || {},
customLabel: 'Emissions (Mt CO2/yr)'
});
if (this.isCountry) {
this.forestLossByProvinceChart = new ProvincesTopChartView({
el: '#forest-loss-province-chart',
data:
(this.data.provinces &&
this.data.provinces.forest_loss.top_five) ||
{}
});
this.co2EmissionsByProvinceChart = new ProvincesTopChartView({
el: '#co2-emissions-province-chart',
data:
(this.data.provinces && this.data.provinces.emissions.top_five) ||
{},
customLabel: 'Mt CO2/yr'
});
this.countryGeo = new CountryGeoView({
el: '#report-country-geo',
iso: this.iso,
country: this.data.country,
ha: this.data.area
});
} else {
ContinentService.getContinents({ geo: true }).then(
function(continents) {
const topojson = _.findWhere(continents, { iso: this.iso })
.topojson;
this.countryGeo = new CountryGeoView({
el: '#report-country-geo',
iso: this.iso,
country: this.data.country,
ha: this.data.area,
topojson: topojson
});
}.bind(this)
);
}
},
_listenModules: function() {
this.listenTo(
this.summaryChart,
'summary:slider:change',
function(data) {
this._updateYearsRange(data);
}.bind(this)
);
},
_updateYearsRange: function(params) {
this.status.set({
reference_start_year: params.startYear.toString(),
reference_end_year: params.commonYear.toString(),
monitor_start_year:
params.commonYear === params.endYear
? params.endYear.toString()
: (params.commonYear + 1).toString(),
monitor_end_year: params.endYear.toString()
});
this._setUpdateButtonVisibility(true);
},
_initSlides: function() {
this._initHeightSlider();
this._initCrownSlider();
},
_initHeightSlider: function() {
this.heightSlider = document.getElementById('height-slider');
nouislider.create(this.heightSlider, {
start: 5,
step: 1,
animate: true,
orientation: 'vertical',
connect: [false, true],
tooltips: {
to: function(value) {
return value + 'm';
}
},
range: {
min: 0,
max: 10
}
});
this.heightSlider.setAttribute('disabled', true);
},
_initCrownSlider: function() {
this.crownSlider = document.getElementById('crown-cover-slider');
nouislider.create(this.crownSlider, {
start: this.status.get('thresh'),
animate: true,
connect: [false, true],
tooltips: {
to: function(value) {
return '> ' + value + '%';
}
},
snap: true,
range: {
min: 10,
'15%': 15,
'20%': 20,
'25%': 25,
'30%': 30,
'50%': 50,
max: 75
}
});
this.crownSlider.noUiSlider.on(
'change',
function(value) {
this.status.set(
{
thresh: parseInt(value[0], 10)
},
{ silent: true }
);
this._setUpdateButtonVisibility(true);
}.bind(this)
);
},
_handleReportParamsChange: function(e) {
if (this.defaults.settings[e.target.name]) {
var status = {};
if (e.target.type === 'checkbox') {
status[e.target.name] = e.target.checked;
} else {
status[e.target.name] = e.target.value;
}
this.status.set(status, { silent: true });
}
this._setUpdateButtonVisibility(this._checkInputsDiff());
},
_checkInputsDiff: function() {
// TODO: remove the update button if there aren't inputs changes
return true;
},
_updateReport: function() {
window.scrollTo(0, 0);
this._remove();
this.$el.addClass('is-loading');
this._updateParams();
this._getData();
},
_setUpdateButtonVisibility: function(visible) {
if (this.updateBox) {
if (visible) {
this.updateBox.removeClass('-hide');
} else {
this.updateBox.addClass('-hide');
}
}
},
_validateEmail: function(email) {
var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(email);
},
_subscribeUpdates: function(ev) {
ev.preventDefault();
var btnContainer = this.$el.find('#report-updates-submit');
btnContainer.addClass('is-loading');
var emailInput = this.$el.find('#sign-up-email');
var email = emailInput.val();
if (this._validateEmail(email)) {
emailInput.removeClass('error');
btnContainer.prop('disabled', true);
$.ajax({
type: 'POST',
url: window.gfw.config.CLIMATE_API_HOST + '/report-sign-up',
crossDomain: true,
data: {
email: email
},
dataType: 'json',
success: function() {
btnContainer.addClass('-success');
},
error: function(responseData) {
if (responseData.responseJSON && responseData.responseJSON.msg) {
alert(responseData.responseJSON.msg);
}
},
complete: function() {
btnContainer.removeClass('is-loading');
}
});
} else {
emailInput.addClass('error');
btnContainer.removeClass('is-loading');
}
},
_remove() {
this.$el.empty();
this.summaryChart && this.summaryChart.remove();
this.historicalTrendChart && this.historicalTrendChart.remove();
this.historicalLosstByProvinceChart &&
this.historicalLosstByProvinceChart.remove();
this.cStocksByProvinceChart && this.cStocksByProvinceChart.remove();
this.forestRelatedEmissionsChart &&
this.forestRelatedEmissionsChart.remove();
}
});
return CountryReportView;
}
);