Skip to content

Commit

Permalink
Add a table for phase data in tooltips; COUNTRY=cameroon (#867)
Browse files Browse the repository at this point in the history
  • Loading branch information
ericboucher authored Jul 24, 2023
1 parent 23df73f commit 5797e92
Show file tree
Hide file tree
Showing 2 changed files with 150 additions and 17 deletions.
163 changes: 148 additions & 15 deletions frontend/src/components/MapView/MapTooltip/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,86 @@ import {
withStyles,
WithStyles,
LinearProgress,
Typography,
} from '@material-ui/core';
import { isEqual } from 'lodash';
import { tooltipSelector } from 'context/tooltipStateSlice';
import { isEmpty, isEqual, sum } from 'lodash';
import { PopupData, tooltipSelector } from 'context/tooltipStateSlice';
import { isEnglishLanguageSelected, useSafeTranslation } from 'i18n';
import { TFunction } from 'utils/data-utils';
import { ClassNameMap } from '@material-ui/styles';

// This function prepares phasePopulationTable for rendering and is specific
// to the data structure of the phase classification layer.
// Note - this is a bit hacky for now and will likely need to be revamped if we
// encounter other complex needs for tooltips.
const generatePhasePopulationTable = (
popupData: PopupData,
t: TFunction,
classes: ClassNameMap,
): JSX.Element | null => {
const phasePopulations: Record<string, number> = Object.entries(
popupData,
).reduce((acc: any, cur: any) => {
const [key, value] = cur;
if (key.includes('Population in phase ')) {
// extract number from string looking like "Phase classification 1"
const phaseNumber = key.replace('Population in phase ', '');
if (phaseNumber) {
return { ...acc, [phaseNumber]: value.data };
}
}
return acc;
}, {});

if (isEmpty(phasePopulations)) {
return null;
}

// calculate total population
// eslint-disable-next-line no-param-reassign, fp/no-mutation
phasePopulations.Total =
sum(Object.values(phasePopulations)) - phasePopulations['3 to 5'];

const phasePopulationTable = (
<div>
<Typography display="inline" variant="h4" color="inherit">
{t('Ref. period')}: {popupData['Reference period start']?.data} -{' '}
{popupData['Reference period end']?.data}
</Typography>
<Typography variant="h4" color="inherit">
{t('Population and percentage by phase classification')}
</Typography>
<table className={classes.phasePopulationTable}>
<tr className={classes.phasePopulationTableRow}>
{Object.keys(phasePopulations).map((phaseName: string) => (
<th>{t(phaseName)}</th>
))}
</tr>
<tr className={classes.phasePopulationTableRow}>
{Object.values(phasePopulations).map((populationInPhase: number) => (
<th>{populationInPhase.toLocaleString()}</th>
))}
</tr>
<tr className={classes.phasePopulationTableRow}>
{Object.values(phasePopulations).map((populationInPhase: number) => (
<th>
{Math.round((populationInPhase / phasePopulations.Total) * 100)}%
</th>
))}
</tr>
</table>
</div>
);

return phasePopulationTable;
};

const MapTooltip = memo(({ classes }: TooltipProps) => {
const popup = useSelector(tooltipSelector);
const { t, i18n } = useSafeTranslation();

const popupData = popup.data;

const popupTitle = useMemo(() => {
if (isEnglishLanguageSelected(i18n)) {
return popup.locationName;
Expand All @@ -23,21 +94,64 @@ const MapTooltip = memo(({ classes }: TooltipProps) => {
}, [i18n, popup.locationLocalName, popup.locationName]);

const renderedPopupContent = useMemo(() => {
return Object.entries(popup.data)
const phasePopulationTable = generatePhasePopulationTable(
popupData,
t,
classes,
);
// filter out popupData where key value contains "Population in phase "
const popupDataWithoutPhasePopulations: PopupData = Object.entries(
popupData,
).reduce((acc: any, cur: any) => {
const [key, value] = cur;
if (
// keep "Population in phase 1" as a placeholder for the phase population table
key === 'Population in phase 1' ||
(!key.includes('Population in phase ') &&
!key.includes('Reference period '))
) {
return { ...acc, [key]: value };
}
return acc;
}, {});
return Object.entries(popupDataWithoutPhasePopulations)
.filter(([, value]) => {
return isEqual(value.coordinates, popup.coordinates);
})
.map(([key, value]) => {
return (
<Fragment key={key}>
<h4 key={key}>{`${t(key)}: ${value.data}`}</h4>
<h4>
{/* Allow users to show data without a key/title */}
{!key.includes('do_not_display') &&
key !== 'Population in phase 1' && (
<Typography
display="inline"
variant="h4"
color="inherit"
className={classes.text}
>
{`${t(key)}: `}
</Typography>
)}
{key !== 'Population in phase 1' && (
<Typography
display="inline"
variant="h4"
color="inherit"
className={classes.text}
>
{`${value.data}`}
</Typography>
)}
{/* Phase classification data */}
<Typography variant="h4" color="inherit">
{value.adminLevel && `${t('Admin Level')}: ${value.adminLevel}`}
</h4>
</Typography>
{key === 'Population in phase 1' && phasePopulationTable}
</Fragment>
);
});
}, [popup.coordinates, popup.data, t]);
}, [classes, popup.coordinates, popupData, t]);

const renderedPopupLoader = useMemo(() => {
if (!popup.wmsGetFeatureInfoLoading) {
Expand All @@ -51,18 +165,17 @@ const MapTooltip = memo(({ classes }: TooltipProps) => {
return null;
}
return (
<Popup
anchor="bottom"
coordinates={popup.coordinates}
className={classes.popup}
>
<h4>{popupTitle}</h4>
<Popup coordinates={popup.coordinates} className={classes.popup}>
<Typography variant="h4" color="inherit" className={classes.title}>
{popupTitle}
</Typography>
{renderedPopupContent}
{renderedPopupLoader}
</Popup>
);
}, [
classes.popup,
classes.title,
popup.coordinates,
popup.showing,
popupTitle,
Expand All @@ -73,17 +186,37 @@ const MapTooltip = memo(({ classes }: TooltipProps) => {

const styles = () =>
createStyles({
phasePopulationTable: {
tableLayout: 'fixed',
borderCollapse: 'collapse',
width: '100%',
borderWidth: '1px;',
borderColor: 'inherit',
borderStyle: 'solid',
border: '1px solid white',
},
phasePopulationTableRow: {
border: '1px solid white',
},
title: {
fontWeight: 600,
marginBottom: '8px',
},
text: {
marginBottom: '4px',
},
popup: {
'& div.mapboxgl-popup-content': {
background: 'black',
color: 'white',
padding: '10px 10px 10px',
padding: '5px 5px 5px 5px',
maxWidth: '30em',
maxHeight: '12em',
maxHeight: '20em',
overflow: 'auto',
},
'& div.mapboxgl-popup-tip': {
'border-top-color': 'black',
'border-bottom-color': 'black',
},
},
});
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/config/southsudan/layers.json
Original file line number Diff line number Diff line change
Expand Up @@ -3066,11 +3066,11 @@
},
"event_date": {
"type": "string",
"dataTitle": "Date"
"dataTitle": "do_not_display_date"
},
"notes": {
"type": "string",
"dataTitle": "Details"
"dataTitle": "do_not_display_details"
}
}
},
Expand Down

0 comments on commit 5797e92

Please sign in to comment.