Skip to content

Commit

Permalink
Merge pull request #4731 from wri/develop
Browse files Browse the repository at this point in the history
Deploy
  • Loading branch information
willian-viana authored Dec 1, 2023
2 parents 2fd2fc8 + 55bf126 commit b28730e
Show file tree
Hide file tree
Showing 9 changed files with 216 additions and 121 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
55 changes: 34 additions & 21 deletions components/widgets/land-cover/fao-cover/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default {
widget: 'faoCover',
title: {
initial: 'FAO forest cover in {location}',
global: 'Global FAO forest cover'
global: 'Global FAO forest cover',
},
chartType: 'pieChart',
categories: ['land-cover'],
Expand All @@ -21,47 +21,60 @@ export default {
dataType: 'fao',
metaKey: 'widget_forest_cover_fao',
sortOrder: {
landCover: 5
landCover: 5,
},
settings: {
unit: 'ha'
unit: 'ha',
faoYear: 2020,
},
refetchKeys: ['faoYear'],
sentences: {
globalInitial:
'FAO data from 2015 shows that there are {extent} of forest {location}, with primary forest occupying {primaryPercent} of the world.',
globalNoPrimary:
'FAO data from 2015 shows that there are {extent} of forest {location}, which occupies {primaryPercent} of the world.',
'According to the FAO, in {year}, {percent} ({amountInHectares}) of the globe was covered by forest. {primaryPercent} of that forest was classified as primary forest.',
initial:
'FAO data from 2015 shows that {location} contains {extent} of forest, with primary forest occupying {primaryPercent} of the country.',
'According to the FAO, in {year}, {percent} ({amountInHectares}) of {country} was covered by forest. {primaryPercent} of that forest was classified as primary forest.',
noPrimary:
'FAO data from 2015 shows that {location} contains {extent} of forest, which occupies {primaryPercent} of the country.'
'According to the FAO, in {year},{primaryPercent} ({extent}) of {location} was covered by forest. <b>0%</b> of that forest was classified as primary forest.',
},
getData: params =>
all([getFAOExtent({ ...params }), getRanking({ ...params })]).then(
getSettingsConfig: () => {
return [
{
key: 'faoYear',
label: 'Period',
type: 'select',
clearable: false,
border: true,
},
];
},
getData: (params) => {
return all([getFAOExtent({ ...params }), getRanking({ ...params })]).then(
spread((getFAOResponse, getRankingResponse) => {
let data = {};
const fao = getFAOResponse.data.rows;
const ranking = getRankingResponse.data.rows;

if (fao.length && ranking.length) {
const faoTotal = fao.map(f => ({
...f,
area_ha: parseFloat(f.area_ha.replace(',', '')) * 1000
}));
let faoData = faoTotal[0];
let faoData = fao[0];

if (fao.length > 1) {
faoData = {};
Object.keys(omit(faoTotal[0], ['iso', 'name'])).forEach(k => {
faoData[k] = sumBy(faoTotal, k) || 0;
Object.keys(omit(fao[0], ['iso', 'country'])).forEach((k) => {
faoData[k] = sumBy(fao, k) || 0;
});
}

data = {
...faoData,
rank: ranking[0].rank || 0
rank: ranking[0].rank || 0,
};
}
return data;
})
),
getDataURL: ({ params }) => [getFAOExtent({ ...params, download: true })],
getWidgetProps
);
},
getDataURL: async (params) => [
await getFAOExtent({ ...params, download: true }),
],
getWidgetProps,
};
60 changes: 37 additions & 23 deletions components/widgets/land-cover/fao-cover/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,21 @@ const getLocationName = (state) => state.locationLabel;
const getColors = (state) => state.colors;
const getSentences = (state) => state.sentences;
const getTitle = (state) => state.title;
const getSettings = (state) => state.settings;

// get lists selected
export const parseData = createSelector(
[getData, getColors],
(data, colors) => {
if (isEmpty(data)) return null;
const {
area_ha,
extent,
planted_forest,
forest_primary,
forest_regenerated,
} = data;
const otherCover =
extent - (forest_regenerated + forest_primary + planted_forest);
if (isEmpty(data)) {
return null;
}

const { area_ha, extent, planted_forest, forest_primary } = data;
const otherCover = extent - (forest_primary + planted_forest);
const nonForest = area_ha - extent;
return [
{
label: 'Naturally Regenerated Forest',
value: forest_regenerated,
percentage: (forest_regenerated / area_ha) * 100,
color: colors.naturalForest,
},

const chartItems = [
{
label: 'Primary Forest',
value: forest_primary || 0,
Expand All @@ -56,28 +48,50 @@ export const parseData = createSelector(
color: colors.nonForest,
},
];

if (forest_primary === null) {
return chartItems.slice(1, chartItems.length);
}

return chartItems;
}
);

export const parseSentence = createSelector(
[getData, getLocationName, getSentences],
(data, locationName, sentences) => {
[getData, getLocationName, getSentences, getSettings],
(data, locationName, sentences, settings) => {
if (isEmpty(data)) return null;
const { initial, noPrimary, globalInitial, globalNoPrimary } = sentences;

const { initial, noPrimary, globalInitial } = sentences;
const { area_ha, extent, forest_primary } = data;
const { faoYear } = settings;

const primaryPercent =
forest_primary > 0
? (forest_primary / area_ha) * 100
? (forest_primary / extent) * 100
: (extent / area_ha) * 100;

const percent = (extent / area_ha) * 100;
const params = {
location: locationName === 'global' ? 'globally' : locationName,
extent: formatNumber({ num: extent, unit: 'ha', spaceUnit: true }),
primaryPercent: formatNumber({ num: primaryPercent, unit: '%' }),
year: faoYear,
percent: formatNumber({ num: percent, unit: '%' }),
amountInHectares: formatNumber({
num: extent,
unit: 'ha',
spaceUnit: true,
}),
country: locationName,
};
let sentence = forest_primary > 0 ? initial : noPrimary;

let sentence = forest_primary !== null ? initial : noPrimary;

if (locationName === 'global') {
sentence = forest_primary > 0 ? globalInitial : globalNoPrimary;
sentence = globalInitial;
}

return {
sentence,
params,
Expand Down
4 changes: 4 additions & 0 deletions components/widgets/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,17 @@ import confidence from 'data/confidence.json';
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),
landCategory: landCategory.filter((l) => !l.hidden),
threshold,
decile,
firesThreshold,
faoYear,
yearRange,
unit,
gasesIncluded,
period,
Expand Down
Loading

0 comments on commit b28730e

Please sign in to comment.