Skip to content

Commit

Permalink
Profile tab and profile detail skeleton loader (#13)
Browse files Browse the repository at this point in the history
* Initial skeleton loader

* Fix loader look

* Profile tab loader

* Search bar skeleton loader + all static text

* Set is loading for chart container skeleton from hurumap-ui CodeForAfrica/HURUmap-UI#44

* Bump hurumap-ui version

* Fix title grid

* Fix chart factory to new hurumap-ui requirements
  • Loading branch information
karimkawambwa committed Aug 27, 2019
1 parent bb60120 commit f380ebc
Show file tree
Hide file tree
Showing 7 changed files with 383 additions and 177 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"private": true,
"homepage": "https://dev.dominion.africa",
"dependencies": {
"@codeforafrica/hurumap-ui": "^0.1.0-rc.11",
"@codeforafrica/hurumap-ui": "^0.1.0-rc.13",
"@fortawesome/fontawesome-free": "^5.9.0",
"@fortawesome/fontawesome-svg-core": "^1.2.19",
"@fortawesome/free-brands-svg-icons": "^5.6.3",
Expand Down
173 changes: 113 additions & 60 deletions src/components/ChartFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@ export default class ChartFactory {
? summedReferenceData
: summedData;
return (
// Due to responsiveness of nstedchart
<div>
<div style={{ width: !isComparison ? 200 : 650 }}>
<NestedProportionalAreaChart
key={key}
square={visualType === 'square_nested_proportional_area'}
Expand Down Expand Up @@ -117,78 +116,132 @@ export default class ChartFactory {
/>
</div>
);
case 'grouped_column':
return (
<BarChart
key={key}
responsive
width={width}
height={height || 200}
barWidth={barWidth || 50}
horizontal={horizontal}
labels={datum => numberFormatter.format(datum.y)}
// Disable tooltip behaviour
labelComponent={undefined}
data={[...new Set(data.map(d => d.groupBy))].map(group => ({
label: group,
data: !aggregate
? data.filter(d => d.groupBy === group)
: aggregateData(
aggregate,
data.filter(d => d.groupBy === group)
)
}))}
/>
case 'grouped_column': {
// Create array of grouped data arrays
let groupedData = [...new Set(data.map(d => d.groupBy))].map(group =>
!aggregate
? data.filter(d => d.groupBy === group)
: aggregateData(
aggregate,
data.filter(d => d.groupBy === group)
).map(d => ({ ...d, x: group }))
);
case 'column':
if (isComparison) {
const pData = !aggregate ? data : aggregateData(aggregate, data);
const pComparisonData = !aggregate
? comparisonData
: aggregateData(aggregate, comparisonData);
return (
// Transpose
groupedData = groupedData[0].map((_c, i) => groupedData.map(r => r[i]));

return (
<div
style={{
width: groupedData.length * groupedData[0].length * 45,
height: '300px'
}}
>
<BarChart
key={key}
responsive
width={width}
height={height || 200}
barWidth={barWidth || 100}
offset={45}
barWidth={40}
width={groupedData.length * groupedData[0].length * 45}
height={height || 300}
horizontal={horizontal}
labels={datum => numberFormatter.format(datum.y)}
// Disable tooltip behaviour
labelComponent={undefined}
data={pData.map(d => ({
label: d.x[0].toUpperCase() + d.x.slice(1),
data: [
{
x: 'Country 1',
y: d.y
},
{
x: 'Country 2',
y: pComparisonData.find(z => z.x === d.x)
? pComparisonData.find(z => z.x === d.x).y
: null
data={groupedData}
parts={{
axis: {
labelWidth: 40,
independent: {
style: {
tickLabels: {
display: 'block'
}
}
}
]
}))}
}
}}
/>
</div>
);
}
case 'column': {
const processedData = aggregate ? aggregateData(aggregate, data) : data;
if (isComparison) {
const processedComparisonData = aggregate
? aggregateData(aggregate, comparisonData)
: comparisonData;
return (
<div
style={{
width: processedData.length * 2 * (barWidth || 40) + 5,
height: '300px'
}}
>
<BarChart
key={key}
responsive
offset={45}
barWidth={barWidth || 40}
width={processedData.length * 2 * ((barWidth || 40) + 5)}
height={height || 300}
horizontal={horizontal}
labels={datum => numberFormatter.format(datum.y)}
// Disable tooltip behaviour
labelComponent={undefined}
data={[processedData, processedComparisonData]}
parts={{
axis: {
independent: {
style: {
axis: {
display: 'block'
},
ticks: {
display: 'block'
},
tickLabels: {
display: 'block'
}
}
}
}
}}
/>
</div>
);
}
return (
<BarChart
key={key}
responsive
width={width}
height={height || 200}
barWidth={barWidth || 100}
labels={datum => numberFormatter.format(datum.y)}
// Disable tooltip behaviour
labelComponent={undefined}
horizontal={horizontal}
data={!aggregate ? data : aggregateData(aggregate, data)}
/>
<div
style={{
width: processedData.length * (barWidth || 80) + 5,
height: '300px'
}}
>
<BarChart
key={key}
horizontal={horizontal}
barWidth={barWidth || 80}
width={processedData.length * ((barWidth || 80) + 5)}
height={height || 300}
labels={datum => numberFormatter.format(datum.y)}
// Disable tooltip behaviour
labelComponent={undefined}
data={processedData}
parts={{
axis: {
independent: {
style: {
tickLabels: {
display: 'block'
}
}
}
}
}}
/>
</div>
);
}
default:
return null;
}
Expand Down
87 changes: 81 additions & 6 deletions src/components/Hero/Hero.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Grid, Typography } from '@material-ui/core';
import { withStyles } from '@material-ui/core/styles';
import classNames from 'classnames';

import { ContentLoader } from '@codeforafrica/hurumap-ui';
import ArrowButton from '../ArrowButton';

const styles = theme => ({
Expand All @@ -18,7 +19,6 @@ const styles = theme => ({
pointerEvents: 'all',
zIndex: '100',
color: 'white',
display: 'flex',
[theme.breakpoints.down('sm')]: {
margin: '2rem',
marginTop: 0
Expand Down Expand Up @@ -96,6 +96,8 @@ function HeroTitleGridComponent({ classes, children, quater, head2head }) {
sm={12}
md={quater ? 4 : 8}
lg={quater ? 4 : 8}
wrap="nowrap"
direction="column"
alignContent="center"
className={classNames(classes.titleTextGrid, {
[classes.h2hTitleGrid]: head2head
Expand Down Expand Up @@ -123,7 +125,22 @@ HeroTitleGridComponent.defaultProps = {

const HeroTitleGrid = withStyles(styles)(HeroTitleGridComponent);

function HeroTitleComponent({ classes, children, breakWord, small }) {
function HeroTitleComponent({
classes,
loaderWidth,
loading,
children,
breakWord,
small
}) {
if (loading) {
return (
<ContentLoader style={{ width: loaderWidth, height: 100 }}>
<rect x="0" y="0" rx="2px" ry="2px" width="100%" height="45%" />
<rect x="0" y="50%" rx="2px" ry="2px" width="50%" height="45%" />
</ContentLoader>
);
}
return (
<Typography
variant="h1"
Expand All @@ -142,12 +159,16 @@ HeroTitleComponent.propTypes = {
classes: PropTypes.shape({}).isRequired,
children: PropTypes.string.isRequired,
breakWord: PropTypes.bool,
small: PropTypes.bool
small: PropTypes.bool,
loading: PropTypes.bool,
loaderWidth: PropTypes.oneOf([PropTypes.number, PropTypes.string])
};

HeroTitleComponent.defaultProps = {
breakWord: false,
small: false
small: false,
loading: false,
loaderWidth: '100%'
};

const HeroTitle = withStyles(styles)(HeroTitleComponent);
Expand All @@ -170,7 +191,44 @@ HeroDescriptionComponent.propTypes = {

const HeroDescription = withStyles(styles)(HeroDescriptionComponent);

function HeroDetailComponent({ classes, children, label, small }) {
function HeroDetailComponent({
classes,
hidden,
loading,
children,
label,
small,
loader
}) {
if (hidden) {
return null;
}

if (loading) {
return (
<ContentLoader
className={classes.detailComponent}
style={{ height: small ? 61 : 74 }}
>
<rect
x="0"
y="0"
rx="2px"
ry="2px"
width={loader.detailWidth}
height="50%"
/>
<rect
x="0"
y="60%"
rx="2px"
ry="2px"
width={loader.detailLabelWidth}
height="30%"
/>
</ContentLoader>
);
}
return (
<Grid className={classes.detailComponent}>
<Typography
Expand All @@ -194,7 +252,24 @@ HeroDetailComponent.propTypes = {
classes: PropTypes.shape({}).isRequired,
children: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
small: PropTypes.bool.isRequired
small: PropTypes.bool.isRequired,
loading: PropTypes.bool,
hidden: PropTypes.bool,
loader: PropTypes.shape({
detailWidth: PropTypes.oneOf([PropTypes.number, PropTypes.string])
.isRequired,
detailLabelWidth: PropTypes.oneOf([PropTypes.number, PropTypes.string])
.isRequired
})
};

HeroDetailComponent.defaultProps = {
loading: false,
hidden: false,
loader: {
detailWdith: 100,
detailLabelWidth: 50
}
};

const HeroDetail = withStyles(styles)(HeroDetailComponent);
Expand Down

0 comments on commit f380ebc

Please sign in to comment.