Skip to content

Commit

Permalink
Merge branch 'release/2.0.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
TaiWilkin committed Jan 31, 2022
2 parents 7869303 + 87b8854 commit 2cc2add
Show file tree
Hide file tree
Showing 17 changed files with 350 additions and 189 deletions.
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Removed

# 2.0.1

### Added

- Allow users to select multiple years [#138](https://github.com/azavea/fb-gender-survey-dashboard/pull/138)
- Format comparative bar charts [#142](https://github.com/azavea/fb-gender-survey-dashboard/pull/142)
- View 'out of ten' charts in comparative view [#143](https://github.com/azavea/fb-gender-survey-dashboard/pull/143)
- Allow comparative chart download [#144](https://github.com/azavea/fb-gender-survey-dashboard/pull/144)
- Show available years for options [#150](https://github.com/azavea/fb-gender-survey-dashboard/pull/150)

### Changed

- Update meta tags and handle null geoMode [#140](https://github.com/azavea/fb-gender-survey-dashboard/pull/140)

### Fixed

- Format quotes [#146](https://github.com/azavea/fb-gender-survey-dashboard/pull/146)

### Removed

# 2.0.0

### Added
Expand Down
4 changes: 2 additions & 2 deletions src/app/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@
<meta property="og:title" content="Gender Equality at Home" />
<meta
property="og:description"
content="Visualize aggregate data from over the 2020 Survey on Gender Equality at Home, which reached over 460,000 Facebook users in 208 locations around the world."
content="Explore the country and region-level data from the 2020 and 2021 waves of the Survey on Gender Equality at Home."
/>
<meta property="og:image" content="%PUBLIC_URL%/meta_image.jpg" />

Expand All @@ -86,7 +86,7 @@
<meta property="twitter:title" content="Gender Equality at Home" />
<meta
property="twitter:description"
content="Visualize aggregate data from over the 2020 Survey on Gender Equality at Home, which reached over 460,000 Facebook users in 208 locations around the world."
content="Explore the country and region-level data from the 2020 and 2021 waves of the Survey on Gender Equality at Home."
/>
<meta property="twitter:image" content="%PUBLIC_URL%/meta_image.jpg" />
</head>
Expand Down
16 changes: 14 additions & 2 deletions src/app/src/App.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useEffect } from 'react';
import { useDispatch } from 'react-redux';
import { useDispatch, useSelector } from 'react-redux';
import { ChakraProvider } from '@chakra-ui/react';
import { Switch, Route, BrowserRouter as Router } from 'react-router-dom';
import 'focus-visible/dist/focus-visible';
Expand All @@ -15,11 +15,13 @@ import SurveyNotification from './components/SurveyNotification';
import NotFound from './components/NotFound';
import theme from './theme';

import { setData } from './redux/app.actions';
import { setData, setGeoSelectionMode } from './redux/app.actions';
import { GEO_COUNTRY, GEO_REGION, ROUTES } from './utils/constants';
import { isValidGeoMode } from './utils';

function App() {
const dispatch = useDispatch();
const geoMode = useSelector(state => state.app.geoMode);

useEffect(() => {
// Fetch data at application start
Expand All @@ -36,6 +38,16 @@ function App() {
});
}, [dispatch]);

useEffect(() => {
if (!isValidGeoMode(geoMode)) {
dispatch(setGeoSelectionMode(GEO_COUNTRY));
}
}, [geoMode, dispatch]);

if (!isValidGeoMode(geoMode)) {
return null;
}

return (
<Router>
<ChakraProvider resetCss theme={theme}>
Expand Down
4 changes: 3 additions & 1 deletion src/app/src/components/Chart.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import React from 'react';
import { useSelector } from 'react-redux';
import { Box, Text } from '@chakra-ui/react';

import StackedBarChart from './StackedBarChart';
import WaffleChart from './WaffleChart';
import GroupedBarChart from './GroupedBarChart';

const Chart = ({ items }) => {
const { currentYears } = useSelector(state => state.app);
const { question } = items[0];

const data = items.filter(
Expand Down Expand Up @@ -43,7 +45,7 @@ const Chart = ({ items }) => {
let chart;
if (question.type === 'stack') {
chart = <StackedBarChart items={data} />;
} else if (question.type === 'ten') {
} else if (question.type === 'ten' && currentYears.length < 2) {
chart = <WaffleChart items={data} />;
} else {
chart = <GroupedBarChart items={data} />;
Expand Down
2 changes: 1 addition & 1 deletion src/app/src/components/DownloadMenu.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ const DownloadMenu = ({
: chartCanvases[0];

const title = `Question ${question.qcode}${
question.type === 'ten'
question.type === 'ten' && currentYears.length < 2
? ` in ${question.geo} in ${question.year}`
: ''
}: ${question.question}`;
Expand Down
56 changes: 46 additions & 10 deletions src/app/src/components/GroupedBarChart.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,50 @@
import React, { useRef } from 'react';
import { useSelector } from 'react-redux';
import { Box } from '@chakra-ui/react';
import { ResponsiveBarCanvas } from '@nivo/bar';
import sortBy from 'lodash/sortBy';
import flatMap from 'lodash/flatMap';

import DownloadMenu from './DownloadMenu';
import { formatGroupedCSV } from '../utils/csv';

const formatResponsesForChart = ({ items, sortedYears }) => {
let data = sortedYears
.map(year => {
return items
.filter(
({ response }) =>
response.year === year && !response.dataUnavailable
)
.map(({ response }) => ({
...response,
geoyear: `${response.geo} ${response.year}`,
Men: response.male,
Women: response.female,
Total: response.combined,
}))
.reverse();
})
.filter(yearData => yearData.length);

return flatMap(data, (yearData, index, array) =>
array.length - 1 !== index ? [yearData, { geoyear: '' }] : yearData
).flat();
};

const getMaxValue = type => {
if (type === 'pct') return 100;

if (type === 'ten') return 10;

return 'auto';
};

const GroupedBarChart = ({ items }) => {
const data = items
.map(({ response }) => ({
...response,
geoyear: `${response.geo} ${response.year}`,
Men: response.male,
Women: response.female,
Total: response.combined,
}))
.reverse();
const { currentYears } = useSelector(state => state.app);
const sortedYears = sortBy(currentYears, year => parseInt(year)).reverse();

const data = formatResponsesForChart({ items, sortedYears });

const keys = ['Total', 'Men', 'Women'];

Expand Down Expand Up @@ -55,6 +85,7 @@ const GroupedBarChart = ({ items }) => {
const containerRef = useRef();

const height = 150 + data.length * 50;
const maxValue = getMaxValue(type);

return (
<Box
Expand Down Expand Up @@ -90,7 +121,7 @@ const GroupedBarChart = ({ items }) => {
enableGridX={true}
enableGridY={false}
minValue='auto'
maxValue={isPercent ? 100 : 'auto'}
maxValue={maxValue}
groupMode='grouped'
layout='horizontal'
colors={item => {
Expand All @@ -116,6 +147,11 @@ const GroupedBarChart = ({ items }) => {
legendPosition: 'middle',
legendOffset: -15,
}}
axisLeft={{
tickSize: 0,
tickPadding: 5,
tickRotation: 0,
}}
axisBottom={axisBottom}
tooltipFormat={formatValue}
theme={{
Expand Down
32 changes: 28 additions & 4 deletions src/app/src/components/QuestionSelector.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
AccordionIcon,
AccordionPanel,
AccordionButton,
Badge,
Box,
Button,
Checkbox,
Expand Down Expand Up @@ -200,7 +201,9 @@ const QuestionSelector = () => {
};

Object.entries(config.survey)
.filter(([key, question]) => !dataIndexer.isDataUnavailable(key))
.filter(([key, question]) =>
currentYears.some(year => !dataIndexer.isDataUnavailable(key, year))
)
.forEach(([key, question]) => {
const categoryCode = question.qcode[0].toUpperCase();

Expand All @@ -221,6 +224,19 @@ const QuestionSelector = () => {
});

const getQuestionCheckboxLabel = key => {
const availableYears = currentYears.filter(
year => !dataIndexer.isDataUnavailable(key, year)
);
const isMultiYear = currentYears.length > 1;
const availableYearsNote =
isMultiYear && availableYears.length
? availableYears.map(year => (
<Badge colorScheme='red' ml={1}>
{year}
</Badge>
))
: '';

// Generate a checkbox for a question. The checkbox text will differ
// depending on the type of question this is. Questions that are of type
// "stack" will not include response text in the text, nor will the
Expand All @@ -233,7 +249,9 @@ const QuestionSelector = () => {
if (item.cat) {
return (
<Box fontWeight='400'>
<Text fontSize='inherit'>{item.question}</Text>
<Text fontSize='inherit'>
{item.question} {availableYearsNote}
</Text>
<Text
fontSize='inherit'
fontWeight='bold'
Expand All @@ -244,7 +262,9 @@ const QuestionSelector = () => {

return (
<Box fontWeight='regular'>
<Text fontSize='inherit'>{item.question}</Text>
<Text fontSize='inherit'>
{item.question} {availableYearsNote}
</Text>
</Box>
);
}
Expand All @@ -253,7 +273,11 @@ const QuestionSelector = () => {
// the question from any of the respones/question paris that share the
// qcode.
const item = Object.values(config.survey).find(q => q.qcode === key);
return item.question;
return (
<span>
{item.question} {availableYearsNote}
</span>
);
};

const categories = getCategoryData(query).map(
Expand Down
70 changes: 48 additions & 22 deletions src/app/src/components/StackedBarChart.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,61 @@ import React from 'react';
import { useSelector } from 'react-redux';
import { Box } from '@chakra-ui/react';
import { ResponsiveBarCanvas } from '@nivo/bar';
import sortBy from 'lodash/sortBy';
import flatMap from 'lodash/flatMap';

import DownloadMenu from './DownloadMenu';
import useRefs from '../hooks/useRefs';
import { formatStackedCSV } from '../utils/csv';

const formatResponsesForChart = ({ question, responses, sortedYears }) => {
let data = sortedYears
.map(year => {
const validResponses = responses.filter(
r => r.year === year && !r.dataUnavailable
);
return validResponses.length
? validResponses.reduce(
(acc, curr) => {
acc[0][curr.cat] = Math.round(curr.combined, 2);
acc[1][curr.cat] = Math.round(curr.male, 2);
acc[2][curr.cat] = Math.round(curr.female, 2);
return acc;
},
[
{ index: `Total ${year}` },
{ index: `Men ${year}` },
{ index: `Women ${year}` },
]
)
: [];
})
.filter(yearData => yearData.length);

return flatMap(data, (yearData, index, array) =>
array.length - 1 !== index ? [yearData, { index: '' }] : yearData
).flat();
};

const keys = ['Neutral', 'Strongly Agree/Agree', 'Strongly Disagree/Disagree'];
const formatValue = v => `${v}%`;

const StackedBarChart = ({ items }) => {
const { currentYears } = useSelector(state => state.app);
const containerRefs = useRefs(items.length);
const sortedYears = sortBy(currentYears, parseInt).reverse();
return items.map(({ question, responses }, i) => {
const data = currentYears
.map(year =>
responses
.filter(r => r.year === year)
.reduce(
(acc, curr) => {
acc[0][curr.cat] = Math.round(curr.combined, 2);
acc[1][curr.cat] = Math.round(curr.male, 2);
acc[2][curr.cat] = Math.round(curr.female, 2);
return acc;
},
[
{ index: `Total ${year}` },
{ index: `Men ${year}` },
{ index: `Women ${year}` },
]
)
)
.flat();
const keys = responses.map(r => r.cat);
const formatValue = v => `${v}%`;
const data = formatResponsesForChart({
question,
responses,
sortedYears,
});

const height = 100 + data.length * 35;

return (
<Box
h={200}
h={height}
className='chart-container'
key={`stacked-${question.question.qcode}-${responses[0].geo}`}
ref={containerRefs.current[i]}
Expand Down Expand Up @@ -98,6 +119,11 @@ const StackedBarChart = ({ items }) => {
legendPosition: 'middle',
legendOffset: 45,
}}
axisLeft={{
tickSize: 0,
tickPadding: 10,
tickRotation: 0,
}}
tooltipFormat={formatValue}
theme={{
fontSize: 14,
Expand Down
10 changes: 6 additions & 4 deletions src/app/src/components/Visualizations.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,12 @@ const Visualizations = () => {
setSaved(true);
};

const createKey = items =>
items[0].response
? `${items[0].response.key}-${items[0].response.geo}`
: `${items[0].responses[0].key}-${items[0].responses[0].geo}`;
const createKey = items => {
const response = items[0].response
? items[0].response
: items[0].responses[0];
return `${response.key}-${response.geo}-${response.year}`;
};

return (
<Box>
Expand Down
Loading

0 comments on commit 2cc2add

Please sign in to comment.