diff --git a/components/widgets/forest-change/fao-reforest/index.js b/components/widgets/forest-change/fao-reforest/index.js index 340b3ffd49..e5171bef5a 100644 --- a/components/widgets/forest-change/fao-reforest/index.js +++ b/components/widgets/forest-change/fao-reforest/index.js @@ -14,9 +14,11 @@ export default { admins: ['global', 'adm0'], settingsConfig: [ { - key: 'period', + key: 'yearRange', label: 'period', type: 'select', + clearable: false, + border: true, }, ], chartType: 'rankedList', @@ -25,17 +27,17 @@ export default { sortOrder: { forestChange: 8, }, - refetchKeys: ['period'], + refetchKeys: ['yearRange'], colors: 'gain', sentences: { globalInitial: - 'According to the FAO, the {location} rate of reforestation in {year} was {rate} per year.', + 'According to the FAO, the {location} rate of reforestation in between {startYearRange} and {endYearRange} was {rate} per year.', initial: - 'According to the FAO, the rate of reforestation in {location} was {rate} per year in {year}.', + 'According to the FAO, the rate of reforestation in {location} was {rate} per year between {startYearRange} and {endYearRange}.', noReforest: 'No reforestation data in {location}.', }, settings: { - period: 2010, + yearRange: '2015-2020', unit: 'ha/year', pageSize: 5, page: 0, @@ -44,8 +46,11 @@ export default { getFAOReforest({ ...params }).then((response) => { const data = response.data.rows; const hasCountryData = (data.length && data.find((d) => d.iso)) || null; + return hasCountryData ? data : {}; }), - getDataURL: (params) => [getFAOReforest({ ...params, download: true })], + getDataURL: async (params) => [ + await getFAOReforest({ ...params, download: true }), + ], getWidgetProps, }; diff --git a/components/widgets/forest-change/fao-reforest/selectors.js b/components/widgets/forest-change/fao-reforest/selectors.js index 6bf61fc297..0f2938880d 100644 --- a/components/widgets/forest-change/fao-reforest/selectors.js +++ b/components/widgets/forest-change/fao-reforest/selectors.js @@ -4,16 +4,17 @@ import findIndex from 'lodash/findIndex'; import sortBy from 'lodash/sortBy'; import { formatNumber } from 'utils/format'; -const getData = (state) => state.data || null; -const getAdm0 = (state) => state.adm0 || null; +const getData = (state) => state.data; +const getAdm0 = (state) => state.adm0; const getColors = (state) => state.colors || null; const getLocationName = (state) => state.locationLabel || null; -const getPeriod = (state) => state.settings.period || null; +const getSettings = (state) => state.settings; const getSentences = (state) => state.sentences; const getTitle = (state) => state.title; export const getSortedData = createSelector([getData], (data) => { if (!data || !data.length) return null; + return sortBy(uniqBy(data, 'iso'), 'rate') .reverse() .map((d, i) => ({ @@ -27,22 +28,26 @@ export const parseData = createSelector( (data, adm0, colors) => { if (!data || !data.length) return null; let dataTrimmed = data; + if (adm0) { const locationIndex = findIndex(data, (d) => d.iso === adm0); let trimStart = locationIndex - 2; let trimEnd = locationIndex + 3; + if (locationIndex < 2) { trimStart = 0; trimEnd = 5; } - if (locationIndex > data.length - 3) { - trimStart = data.length - 5; - trimEnd = data.length; + + if (locationIndex > data?.length - 3) { + trimStart = data?.length - 5; + trimEnd = data?.length; } - dataTrimmed = data.slice(trimStart, trimEnd); + + dataTrimmed = data?.slice(trimStart, trimEnd); } - return dataTrimmed.map((d) => ({ + return dataTrimmed?.map((d) => ({ ...d, label: d.name, color: colors.main, @@ -52,28 +57,43 @@ export const parseData = createSelector( ); export const parseSentence = createSelector( - [getSortedData, parseData, getPeriod, getSentences, getLocationName, getAdm0], - (sortedData, data, period, sentences, locationName, adm0) => { + [ + getSortedData, + parseData, + getSettings, + getSentences, + getLocationName, + getAdm0, + ], + (sortedData, data, settings, sentences, locationName, adm0) => { if (!data || !data.length) return null; const { initial, noReforest, globalInitial } = sentences; const countryData = data.find((d) => adm0 === d.iso) || null; + const yearRangeSeparated = settings.yearRange.split('-'); + const startYearRange = yearRangeSeparated[0]; + const endYearRange = yearRangeSeparated[1]; + let globalRate = 0; + Object.keys(sortedData).forEach((k) => { globalRate += sortedData[k].rate; }); - const rate = - locationName === 'global' ? globalRate : countryData && countryData.value; + + const rate = locationName === 'global' ? globalRate : countryData?.value; + const formatType = rate < 1 ? '.3r' : '.3s'; let sentence = globalInitial; + if (locationName !== 'global') { sentence = countryData && countryData.value > 0 ? initial : noReforest; } - const formatType = rate < 1 ? '.3r' : '.3s'; const params = { location: locationName, - year: period, + year: settings.yearRange, + startYearRange, + endYearRange, rate: formatNumber({ num: rate, unit: 'ha', diff --git a/services/forest-data.js b/services/forest-data.js index a76c42b32b..a76aad5f71 100644 --- a/services/forest-data.js +++ b/services/forest-data.js @@ -9,7 +9,9 @@ const NEW_SQL_QUERIES = { faoExtent: 'SELECT iso, country, "planted forest (ha)" AS planted_forest__ha, "primary (ha)" AS primary_forest__ha, "naturally regenerating forest (ha)" AS regenerated_forest__ha, "forest (ha)" AS fao_treecover__ha, "total land area (ha)" as area_ha FROM data WHERE {location} AND year = {year}', faoReforest: - 'SELECT country AS iso, name, year, reforest * 1000 AS reforestation__rate, forest*1000 AS fao_treecover_reforest__ha FROM table_1_forest_area_and_characteristics as fao WHERE fao.year = {period} AND reforest > 0 ORDER BY reforestation__rate DESC', + 'SELECT iso, country AS name, year, "reforestation (ha per year)" AS reforestation__rate, "forest expansion (ha per year)" AS fao_treecover_reforest__ha FROM table_1_forest_area_and_characteristics as fao WHERE fao.year = {yearRange} AND "reforestation (ha per year)" > 0 ORDER BY reforestation__rate DESC', + faoReforestDownload: + 'SELECT iso, country AS name, year, "reforestation (ha per year)" AS reforestation__rate FROM table_1_forest_area_and_characteristics as fao WHERE fao.year = {yearRange} AND "reforestation (ha per year)" > 0 ORDER BY reforestation__rate DESC', faoDeforest: 'SELECT iso, country as name, "deforestation (ha per year)" as fao_treecover_deforest__ha, "reforestation (ha per year)" as fao_reforestation__ha, "forest expansion (ha per year)" as fao_expansion__ha, year FROM data where year = {yearRange}', faoDeforestRank: @@ -86,23 +88,30 @@ export const getFAOExtent = async ({ adm0, faoYear = 2020, download }) => { return widgetData; }; -export const getFAOReforest = ({ period, download }) => { - const url = `/sql?q=${NEW_SQL_QUERIES.faoReforest}`.replace( - '{period}', - period +export const getFAOReforest = async ({ yearRange = '2015-2020', download }) => { + const target = download ? 'download/csv' : 'query/json'; + const query = download + ? NEW_SQL_QUERIES.faoReforestDownload + : NEW_SQL_QUERIES.faoReforest; + const url = `/dataset/fao_forest_change/v2020/${target}?sql=${query}`.replace( + /{yearRange}/g, + `'${yearRange}'` ); if (download) { return { name: 'fao_treecover_reforestation__ha', - url: `${CARTO_API}${url}&format=csv`, + url: new URL( + `${window.location.origin}${PROXIES.DATA_API}${url}` + ).toString(), }; } - return cartoRequest.get(url).then((response) => ({ - ...response, + const response = await dataRequest.get(url); + + const widgetData = { data: { - rows: response.data.rows.map((o) => { + rows: response.data.map((o) => { delete Object.assign(o, { rate: o.reforestation__rate }) .reforestation__rate; delete Object.assign(o, { extent: o.fao_treecover_reforest__ha }) @@ -110,7 +119,9 @@ export const getFAOReforest = ({ period, download }) => { return o; }), }, - })); + }; + + return widgetData; }; export const getFAODeforest = async ({