Skip to content

Commit

Permalink
Update data structure
Browse files Browse the repository at this point in the history
  • Loading branch information
balagurova committed Jul 10, 2024
1 parent 3dd4931 commit 563ba91
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 147 deletions.
130 changes: 62 additions & 68 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,48 +3,63 @@ import { csv } from 'd3-fetch';
import { ChoroplethMap } from './Components/Graphs/Maps/ChoroplethMap';
import Header from './Components/Header';
import FilterCountryGroup from './Components/Filter';
import { PROGRAMMES } from './Components/Constants';
import { PROGRAMMES, SPECIFIED_PROGRAMMES } from './Components/Constants';
import { ProgrammeProvider, useProgramme } from './Components/ProgrammeContext';
import CheckboxGroup from './Components/CheckboxGroup';
import { ChoroplethMapDataType } from './Types';
import Summary from './Components/Summary';
import Cards from './Components/Table';
import Cards from './Components/Cards';

function AppContent() {
const [data, setData] = useState<any[]>([]);
const [selectedRadio, setSelectedRadio] = useState<string>('allCountries');
const [selectedCheckboxes, setSelectedCheckboxes] = useState<string[]>([]);
const { currentProgramme, setCurrentProgramme } = useProgramme();

useEffect(() => {
csv(
`https://raw.githubusercontent.com/UNDP-Data/dv-sustainable-finance-hub-data-repo/main/SFH_data.csv`,
)
.then((loadedData: any) => {
setData(loadedData);
console.log(loadedData);
// Transform the loaded data
const transformedData = loadedData.map((item: any) => {
const allProgrammesSum = SPECIFIED_PROGRAMMES.reduce(
(sum, program) => {
return sum + (parseInt(item[program.value], 10) || 0);
},
0,
);

const publicFinanceSum = [
'public_tax',
'public_debt',
'public_budget',
'public_insurance',
].reduce((sum, key) => sum + (parseInt(item[key], 10) || 0), 0);

const privateCapitalSum = [
'private_pipelines',
'private_impact',
'private_environment',
].reduce((sum, key) => sum + (parseInt(item[key], 10) || 0), 0);

return {
...item,
all_programmes: allProgrammesSum,
public: publicFinanceSum,
private: privateCapitalSum,
};
});
setData(transformedData);
})
.catch((err: any) => {
console.error('Error loading the CSV file:', err);
});
}, []);

useEffect(() => {
if (currentProgramme.subcategories) {
setSelectedCheckboxes(
currentProgramme.subcategories.map(sub => sub.value),
);
}
}, [currentProgramme]);

const handleSegmentChange = (value: string | number) => {
const programme = PROGRAMMES.find(p => p.value === value);
if (programme) {
setCurrentProgramme(programme);
if (programme.subcategories) {
setSelectedCheckboxes(programme.subcategories.map(sub => sub.value));
} else {
setSelectedCheckboxes([]);
}
}
};

Expand All @@ -71,51 +86,34 @@ function AppContent() {
countryCode: item.iso,
data: {
country: item.country,
programmeValue: item[programme],
public_finance_budget: item.public_finance_budget,
insurance_and_risk: item.insurance_and_risk,
public_finance_tax: item.public_finance_tax,
public_finance_debt: item.public_finance_debt,
private_capital: item.private_capital,
...item,
},
}));
};

const calculateProgrammeTotals = (
rawData: any[],
programme: {
value: string;
subcategories?: { label: string; value: string }[];
},
) => {
const programmeTotal = rawData.reduce((sum, item) => {
return sum + (item[programme.value] === '1' ? 1 : 0);
}, 0);

const subcategoryTotals =
programme.subcategories?.map(subcategory => ({
label: subcategory.label,
total: data.reduce((sum, item) => {
return sum + (item[subcategory.value] === '1' ? 1 : 0);
}, 0),
})) || [];

return { programmeTotal, subcategoryTotals };
};

const transformedData = transformData(
data,
currentProgramme.value,
selectedRadio,
);
const programmeTotals = calculateProgrammeTotals(data, currentProgramme);

const allProgramsData = data.map(item => ({
country: item.country,
iso: item.iso,
...item,
}));

let subcategoriesToShow: { label: string; value: string }[] = [];
if (currentProgramme.value === 'public') {
subcategoriesToShow = SPECIFIED_PROGRAMMES.filter(program =>
[
'public_budget',
'public_tax',
'public_debt',
'public_insurance',
].includes(program.value),
).map(program => ({ label: program.label, value: program.value }));
} else if (currentProgramme.value === 'private') {
subcategoriesToShow = SPECIFIED_PROGRAMMES.filter(program =>
['private_pipelines', 'private_impact', 'private_environment'].includes(
program.value,
),
).map(program => ({ label: program.label, value: program.value }));
}
return (
<div className='undp-container flex-div gap-06 flex-wrap flex-hor-align-center padding-04'>
<Header onSegmentChange={handleSegmentChange} />
Expand All @@ -131,21 +129,17 @@ function AppContent() {
onRadioChange={handleRadioChange}
selectedRadio={selectedRadio}
/>
{currentProgramme.value !== 'all_programmes' &&
currentProgramme?.subcategories && (
<CheckboxGroup
options={currentProgramme.subcategories.map(
(sub: { label: any; value: any }) => ({
label: sub.label,
value: sub.value,
}),
)}
onChange={handleCheckboxChange}
value={selectedCheckboxes}
/>
)}
{subcategoriesToShow.length > 0 && (
<CheckboxGroup
options={subcategoriesToShow.map(sub => ({
label: sub.label,
value: sub.value,
}))}
onChange={handleCheckboxChange}
value={selectedCheckboxes}
/>
)}
</div>
<Summary totals={programmeTotals} />
</div>
<div
className='flex-div flex-column grow'
Expand All @@ -162,7 +156,7 @@ function AppContent() {
/>
</div>
</div>
<Cards data={allProgramsData} />
<Cards data={data} programmes={SPECIFIED_PROGRAMMES} />
</div>
);
}
Expand Down
17 changes: 9 additions & 8 deletions src/Components/Table.tsx → src/Components/Cards.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import { Search } from 'lucide-react';
import React, { useState } from 'react';
import { Input, Tag } from 'antd';
import styled from 'styled-components';
import { PROGRAMMES } from './Constants';
import { Programme } from './Constants';

interface Props {
data: any[]; // Use any[] to accommodate the raw data structure
programmes: Programme[];
}

const CardContainer = styled.div`
Expand Down Expand Up @@ -41,7 +42,7 @@ const NoProgrammes = styled.div`
`;

function Cards(props: Props) {
const { data } = props;
const { data, programmes } = props;
const [searchTerm, setSearchTerm] = useState('');

const filteredData = data.filter(item =>
Expand All @@ -62,8 +63,8 @@ function Cards(props: Props) {
style={{ height: '500px' }}
>
{filteredData.map((item, index) => {
const programmes = PROGRAMMES.filter(
field => item[field.value] === '1',
const programmesForCountry = programmes.filter(
program => item[program.value] === '1',
);
return (
<Card key={index}>
Expand All @@ -76,10 +77,10 @@ function Cards(props: Props) {
</h6>
</CountryDiv>
<ProgramsDiv>
{programmes.length > 0 ? (
programmes.map(field => (
<Tag key={field.value} color={field.color}>
{field.short}
{programmesForCountry.length > 0 ? (
programmesForCountry.map(program => (
<Tag key={program.value} color={program.color}>
{program.label}
</Tag>
))
) : (
Expand Down
16 changes: 7 additions & 9 deletions src/Components/CheckboxGroup.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Checkbox, CheckboxOptionType } from 'antd';
import { Checkbox } from 'antd';
import styled from 'styled-components';

const StyledCheckboxGroup = styled(Checkbox.Group)`
Expand All @@ -11,25 +11,23 @@ const StyledCheckboxGroup = styled(Checkbox.Group)`
`;

interface CheckboxGroupProps {
options: CheckboxOptionType[];
value: string[];
options: { label: string; value: string }[];
onChange: (checkedValues: string[]) => void;
value: string[];
}

function CheckboxGroup(props: CheckboxGroupProps): JSX.Element {
const { options, value, onChange } = props;

function CheckboxGroup({ options, onChange, value }: CheckboxGroupProps) {
return (
<div
className='padding-04'
style={{ border: '0.06rem solid var(--gray-400)' }}
>
<p className='undp-typography label'>Filter by subprogrammes</p>
<p className='undp-typography label'>Filter by subcategories</p>
<StyledCheckboxGroup
options={options}
value={value}
className='undp-checkbox'
onChange={(checkedValues: any[]) => onChange(checkedValues as string[])}
onChange={onChange}
value={value}
/>
</div>
);
Expand Down
Loading

0 comments on commit 563ba91

Please sign in to comment.