Skip to content

Commit

Permalink
Merge pull request #4722 from wri/feat/flag-925
Browse files Browse the repository at this point in the history
FLAG-925: Update FAO deforest Widget data source and filter
  • Loading branch information
willian-viana authored Dec 1, 2023
2 parents 450713e + a5f06ce commit 55bf126
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 65 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ class WidgetDownloadButton extends PureComponent {
filename = filename.concat('.csv');
}
} catch (error) {
filename = `file ${index + 1}.csv`;
filename = `error.csv`;
}

zip.file(filename, urlToPromise(url), { binary: true });
Expand Down
26 changes: 12 additions & 14 deletions components/widgets/forest-change/fao-deforest/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ export default {
admins: ['global', 'adm0'],
settingsConfig: [
{
key: 'period',
key: 'yearRange',
label: 'period',
type: 'select',
clearable: false,
border: true,
},
],
chartType: 'rankedList',
Expand All @@ -28,38 +30,34 @@ export default {
sortOrder: {
forestChange: 5,
},
refetchKeys: ['period'],
refetchKeys: ['yearRange'],
sentences: {
globalInitial:
'According to the FAO, the {location} rate of deforestation in {year} was {rate} per year.',
globalHuman:
'According to the FAO, the {location} rate of deforestation in {year} was {rate} per year, of which {human} per year was due to human activity.',
'According to the FAO, the {location} rate of deforestation in between {startYearRange} and {endYearRange} was {rate} per year.',
initial:
'According to the FAO, the rate of deforestation in {location} was {rate} per year in {year}.',
humanDeforest:
'According to the FAO, the rate of deforestation in {location} was {rate} per year in {year}, of which {human} per year was due to human activity.',
noDeforest: 'No deforestation data in {location}.',
'According to the FAO, the rate of deforestation in {location} was {rate} per year between {startYearRange} and {endYearRange}.',
noDeforest: 'No FAO deforestation data in {location}.',
},
settings: {
period: 2010,
yearRange: '2015-2020',
unit: 'ha/year',
pageSize: 5,
page: 0,
},
getData: (params) =>
all([getFAODeforest(params), getFAODeforestRank(params)]).then(
spread((getFAODeforestResponse, getFAODeforestRankResponse) => {
const fao = getFAODeforestResponse.data.rows;
const fao = getFAODeforestResponse.data;
const rank = getFAODeforestRankResponse.data.rows;
return {
fao,
rank,
};
})
),
getDataURL: (params) => [
getFAODeforest({ ...params, download: true }),
getFAODeforestRank({ ...params, download: true }),
getDataURL: async (params) => [
await getFAODeforest({ ...params, download: true }),
await getFAODeforestRank({ ...params, download: true }),
],
getWidgetProps,
};
72 changes: 42 additions & 30 deletions components/widgets/forest-change/fao-deforest/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ const getAdm0 = (state) => state.adm0;
const getLocationName = (state) => state.locationLabel;
const getColors = (state) => state.colors;
const getSettings = (state) => state.settings;
const getPeriod = (state) => state.settings.period;
const getSentences = (state) => state.sentences;
const getTitle = (state) => state.title;

Expand All @@ -17,70 +16,83 @@ export const parseData = createSelector(
(data, adm0, colors) => {
if (!data || !data.rank) return null;
const { rank } = data;

let dataTrimmed = rank;

dataTrimmed = dataTrimmed.map((d, i) => ({
...d,
rank: i + 1,
}));

if (adm0) {
const locationIndex = findIndex(rank, (d) => d.iso === adm0);

let trimStart = locationIndex - 2;
let trimEnd = locationIndex + 3;

if (locationIndex < 2) {
trimStart = 0;
trimEnd = 5;
}

if (locationIndex > rank.length - 3) {
trimStart = rank.length - 5;
trimEnd = rank.length;
}
dataTrimmed = rank.slice(trimStart, trimEnd);

dataTrimmed = dataTrimmed.slice(trimStart, trimEnd);
}

return dataTrimmed.map((d) => ({
...d,
label: d.name,
label: d.country,
color: colors.main,
value: d.deforest,
value: d.def_per_year,
}));
}
);

export const parseSentence = createSelector(
[getData, getLocationName, getSettings, getPeriod, getSentences],
(data, currentLabel, settings, period, sentences) => {
[getData, getLocationName, getSettings, getSentences, getAdm0],
(data, currentLabel, settings, sentences, adm0) => {
if (!data || !data.fao) return null;
const {
initial,
noDeforest,
humanDeforest,
globalInitial,
globalHuman,
} = sentences;
const topFao = data.fao.filter((d) => d.year === settings.period);
const { deforest, humdef } = topFao[0] || {};
const totalDeforest = sumBy(data.rank, 'deforest') || 0;
const rate = currentLabel === 'global' ? totalDeforest : deforest;

let sentence = humdef ? humanDeforest : initial;
if (currentLabel === 'global') {
sentence = humdef ? globalHuman : globalInitial;
} else if (!deforest) sentence = noDeforest;

const { initial, noDeforest, globalInitial } = sentences;
const yearRangeSeparated = settings.yearRange.split('-');
const startYearRange = yearRangeSeparated[0];
const endYearRange = yearRangeSeparated[1];

const globalDeforestation = sumBy(data.rank, 'def_per_year') || 0;
const countryDeforestation = data.rank.filter(
(country) => country.iso === adm0
)[0];
const rate =
currentLabel === 'global'
? globalDeforestation
: countryDeforestation?.def_per_year;
const rateFormat = rate < 1 ? '.3r' : '.3s';
const humanFormat = humdef < 1 ? '.3r' : '.3s';

let sentence = initial;

if (currentLabel === 'global') {
sentence = globalInitial;
}

if (currentLabel !== 'global' && !countryDeforestation) {
sentence = noDeforest;
}

const params = {
location: currentLabel,
year: period,
year: settings.yearRange,
startYearRange,
endYearRange,
rate: formatNumber({
num: rate,
unit: 'ha',
spaceUnit: true,
specialSpecifier: rateFormat,
}),
human: formatNumber({
num: humdef,
unit: 'ha',
spaceUnit: true,
specialSpecifier: humanFormat,
}),
};

return {
Expand Down
2 changes: 2 additions & 0 deletions components/widgets/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import bioTypes from 'data/biodiversity-int.json';
import ifl from 'data/ifl.json';
import source from 'data/sources.json';
import faoYear from 'data/fao-cover-years.json';
import yearRange from 'data/year-range.json';

export default {
forestType: forestType.filter((f) => !f.hidden),
Expand All @@ -27,6 +28,7 @@ export default {
decile,
firesThreshold,
faoYear,
yearRange,
unit,
gasesIncluded,
period,
Expand Down
14 changes: 14 additions & 0 deletions data/year-range.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[
{
"label": "2000-2010",
"value": "2000-2010"
},
{
"label": "2010-2015",
"value": "2010-2015"
},
{
"label": "2015-2020",
"value": "2015-2020"
}
]
54 changes: 34 additions & 20 deletions services/forest-data.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ const NEW_SQL_QUERIES = {
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',
faoDeforest:
'SELECT fao.country as iso, fao.name, fao.deforest * 1000 AS fao_treecover_deforest__ha, fao.humdef, fao.year FROM table_1_forest_area_and_characteristics as fao {location}',
'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:
'WITH mytable AS (SELECT fao.country as iso, fao.name, fao.deforest * 1000 AS deforest, fao.humdef FROM table_1_forest_area_and_characteristics as fao WHERE fao.year = {year} AND deforest is not null), rank AS (SELECT deforest, iso, name from mytable ORDER BY mytable.deforest DESC) SELECT row_number() over () as rank, iso, name, deforest as fao_treecover_deforest__ha from rank',
'SELECT iso, country, "deforestation (ha per year)" as def_per_year FROM mytable WHERE "deforestation (ha per year)" IS NOT NULL AND year = {yearRange} ORDER BY def_per_year DESC',
faoEcoLive:
'SELECT fao.country as iso, fao.forempl as total_forest_employees, fao.femempl as female_forest_employees, fao.usdrev as revenue__usd, fao.usdexp as expenditure__usd, fao.gdpusd2012 as gdp_2012__usd, fao.totpop1000, fao.year FROM table_7_economics_livelihood as fao WHERE fao.year = 2000 or fao.year = 2005 or fao.year = 2010 or fao.year = 9999',
globalLandCover: 'SELECT * FROM global_land_cover_adm2 WHERE {location}',
Expand Down Expand Up @@ -113,49 +113,63 @@ export const getFAOReforest = ({ period, download }) => {
}));
};

export const getFAODeforest = ({ adm0, download }) => {
const url = `/sql?q=${NEW_SQL_QUERIES.faoDeforest}`.replace(
'{location}',
adm0 ? `WHERE fao.country = '${adm0}'` : ''
);
export const getFAODeforest = async ({
adm0,
yearRange = '2015-2020',
download,
}) => {
const target = download ? 'download/csv' : 'query/json';
const url =
`/dataset/fao_forest_change/v2020/${target}?sql=${NEW_SQL_QUERIES.faoDeforest}`
.replace(/{yearRange}/g, `'${yearRange}'`)
.replace(/{location}/g, adm0 ? `AND iso = '${adm0}'` : '');

if (download) {
return {
name: 'fao_treecover_deforestation__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, { country: o.iso }).iso;
delete Object.assign(o, { deforest: o.fao_treecover_deforest__ha })
.fao_treecover_deforest__ha;
return o;
}),
},
}));
};

return widgetData;
};

export const getFAODeforestRank = ({ period, download }) => {
const url = `/sql?q=${NEW_SQL_QUERIES.faoDeforestRank}`.replace(
'{year}',
period
);
export const getFAODeforestRank = ({ yearRange = '2015-2020', download }) => {
const target = download ? 'download/csv' : 'query/json';
const url =
`/dataset/fao_forest_change/v2020/${target}?sql=${NEW_SQL_QUERIES.faoDeforestRank}`.replace(
/{yearRange}/g,
`'${yearRange}'`
);

if (download) {
return {
name: 'fao_treecover_deforestation_rank',
url: `${CARTO_API}${url}&format=csv`,
url: new URL(
`${window.location.origin}${PROXIES.DATA_API}${url}`
).toString(),
};
}

return cartoRequest.get(url).then((response) => ({
return dataRequest.get(url).then((response) => ({
...response,
data: {
rows: response.data.rows.map((o) => {
rows: response.data.map((o) => {
delete Object.assign(o, { deforest: o.fao_treecover_deforest__ha })
.fao_treecover_deforest__ha;
return o;
Expand Down

0 comments on commit 55bf126

Please sign in to comment.