Skip to content

Commit

Permalink
Add count tags
Browse files Browse the repository at this point in the history
  • Loading branch information
balagurova committed Jul 13, 2024
1 parent 7426108 commit ba61faa
Show file tree
Hide file tree
Showing 4 changed files with 208 additions and 36 deletions.
89 changes: 61 additions & 28 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { Segmented } from 'antd';
import { ChoroplethMap } from './Components/Graphs/Maps/ChoroplethMap';
import Header from './Components/Header';
import FilterCountryGroup from './Components/Filter';
import { PROGRAMMES } from './Components/Constants';
import { GROUPS, PROGRAMMES } from './Components/Constants';
import { ProgrammeProvider, useProgramme } from './Components/ProgrammeContext';
import CheckboxGroup from './Components/CheckboxGroup';
import { ChoroplethMapDataType } from './Types';
Expand Down Expand Up @@ -154,35 +154,78 @@ function AppContent() {
if (countryGroup === 'allCountries') return true;
if (countryGroup === 'sids') return sidsCountries.includes(item.iso);
if (countryGroup === 'ldc') return ldcCountries.includes(item.iso);
if (countryGroup === 'fragile') return item.fragile > 0;
return item[countryGroup] > 0;
if (countryGroup === 'fragile') return item.fragile === 1;
return item[countryGroup] === 1;
});

console.log('Filtered by country:', filteredByCountry);

if (selectedCheckboxes.length === 0) return filteredByCountry;

const filteredByCheckboxes = filteredByCountry.filter(item =>
return filteredByCountry.filter(item =>
selectedCheckboxes.some(
sub => typeof sub === 'string' && item[sub] > 0,
sub => typeof sub === 'string' && item[sub] === 1,
),
);

console.log('Filtered by checkboxes:', filteredByCheckboxes);
return filteredByCheckboxes;
},
[sidsCountries, ldcCountries, selectedCheckboxes],
);

const calculateProgrammeCounts = (
filteredData: any[],
programmes: any[],
): any => {
const result: any = {};
programmes.forEach(programme => {
let sum = 0;
if (programme.subprogrammes) {
sum = calculateProgrammeCounts(
filteredData,
programme.subprogrammes,
).total;
} else {
sum = filteredData.reduce(
(acc, item) => acc + (item[programme.value] || 0),
0,
);
}
result[programme.value] = sum;
result.total = (result.total || 0) + sum;
});
return result;
};

const calculateCountryGroupCounts = (
datum: any[],
countryGroups: any[],
): any[] => {
return countryGroups.map(group => {
const filteredData = filterData(datum, group.value);
const countryCount = filteredData.length;
return {
label: group.label,
value: group.value,
count: countryCount,
};
});
};

const filteredData = filterData(data, selectedRadio);

const sums = calculateProgrammeCounts(
filteredData,
currentProgramme.subprogrammes || PROGRAMMES,
);

const countryGroupCounts = calculateCountryGroupCounts(data, GROUPS);

const transformData = useCallback(
(
rawData: any[],
programme: string,
countryGroup: string,
): ChoroplethMapDataType[] => {
const filteredData = filterData(rawData, countryGroup);
const filteredDatum = filterData(rawData, countryGroup);

return filteredData.map(item => {
return filteredDatum.map(item => {
let value = 0;

if (programme === 'all_programmes') {
Expand All @@ -199,12 +242,12 @@ function AppContent() {
];

value = relevantSubprogrammes.reduce(
(sum, sub) => sum + (item[sub] || 0),
(sum, subProg) => sum + (item[subProg] || 0),
0,
);
} else if (currentProgramme.subprogrammes) {
value = currentProgramme.subprogrammes.reduce(
(sum, sub) => sum + (item[sub.value] || 0),
(sum, subProg) => sum + (item[subProg.value] || 0),
0,
);
} else {
Expand All @@ -221,20 +264,12 @@ function AppContent() {
[filterData, selectedCheckboxes, currentProgramme],
);

useEffect(() => {
console.log('Current Programme:', currentProgramme);
}, [currentProgramme]);

const filteredAndTransformedData = transformData(
data,
currentProgramme.value,
selectedRadio,
);

useEffect(() => {
console.log('Filtered and Transformed Data:', filteredAndTransformedData);
}, [filteredAndTransformedData]);

const filteredDataForCards = filterData(data, selectedRadio);

const subcategoriesToShow = currentProgramme.subprogrammes || [];
Expand All @@ -243,11 +278,7 @@ function AppContent() {
const subcategories = subcategoriesToShow.map(sub => sub.value);
setSelectedCheckboxes(subcategories);
}, [currentProgramme, subcategoriesToShow]);

useEffect(() => {
console.log('Filtered Data for Cards:', filteredDataForCards);
}, [filteredDataForCards]);

console.log(filteredData, countryGroupCounts);
return (
<div
className='undp-container flex-div gap-00 flex-wrap flex-hor-align-center'
Expand Down Expand Up @@ -291,6 +322,7 @@ function AppContent() {
<FilterCountryGroup
onRadioChange={handleRadioChange}
selectedRadio={selectedRadio}
groups={countryGroupCounts}
/>
</div>
</div>
Expand All @@ -317,7 +349,7 @@ function AppContent() {
letterSpacing: '.03em',
}}
>
Filter By Programmes
Filter By SubProgrammes
</h6>
</button>
<div
Expand All @@ -328,6 +360,7 @@ function AppContent() {
options={subcategoriesToShow.map(sub => ({
label: sub.short,
value: sub.value,
count: sums[sub.value] || 0,
}))}
onChange={handleCheckboxChange}
value={selectedCheckboxes}
Expand Down
69 changes: 69 additions & 0 deletions src/Components/Calculations.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { PROGRAMMES } from './Constants';

export interface ProgrammeCount {
value: string;
label: string;
count: number;
subprogrammes?: ProgrammeCount[];
}

const calculateCount = (data: any[], value: string): number => {
return data.reduce((sum, item) => sum + (item[value] || 0), 0);
};

const calculateSubprogrammeCounts = (
data: any[],
subprogrammes: any[] = [],
): ProgrammeCount[] => {
return subprogrammes.map(subProg => {
const subprogrammeCounts = subProg.subprogrammes
? calculateSubprogrammeCounts(data, subProg.subprogrammes)
: undefined;

const subProgrammeCount = subprogrammeCounts
? subprogrammeCounts.reduce((acc, sub) => acc + sub.count, 0)
: calculateCount(data, subProg.value);

return {
value: subProg.value,
label: subProg.short,
count: subProgrammeCount,
subprogrammes: subprogrammeCounts,
};
});
};

export const calculateProgrammeCounts = (data: any[]): ProgrammeCount[] => {
const mainProgrammes = PROGRAMMES[0].subprogrammes || [];

const programmeCounts: ProgrammeCount[] = mainProgrammes.map(prog => {
const subprogrammeCounts = calculateSubprogrammeCounts(
data,
prog.subprogrammes,
);
const mainProgrammeCount =
subprogrammeCounts.reduce((acc, sub) => acc + sub.count, 0) +
calculateCount(data, prog.value);

return {
value: prog.value,
label: prog.short,
count: mainProgrammeCount,
subprogrammes: subprogrammeCounts,
};
});

const allProgrammesCount = programmeCounts.reduce(
(acc, programme) => acc + programme.count,
0,
);

return [
{
value: 'all_programmes',
label: 'All Programmes',
count: allProgrammesCount,
subprogrammes: programmeCounts,
},
];
};
35 changes: 33 additions & 2 deletions src/Components/CheckboxGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,55 @@ import styled from 'styled-components';

const StyledCheckboxGroup = styled(Checkbox.Group)`
display: inline-grid;
width: 100%;
.ant-checkbox-wrapper {
border-bottom: 0.07rem solid var(--gray-300);
padding: 4px 0;
&:last-child {
border-bottom: none;
}
span:first-child {
width: 18px;
}
span:last-child {
font-size: 14px !important;
line-height: 1.8;
width: 100%;
}
}
`;

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

function CheckboxGroup({ options, onChange, value }: CheckboxGroupProps) {
const optionsWithCounts = options.map(option => ({
label: (
<div className='flex-div flex-space-between'>
<div>{option.label} </div>
<p
style={{
fontSize: '12px',
lineHeight: '200%',
backgroundColor: 'var(--gray-300)',
borderRadius: '100px',
padding: '0 8px',
margin: '0',
}}
>
{option.count}
</p>
</div>
),
value: option.value,
}));

return (
<StyledCheckboxGroup
options={options}
options={optionsWithCounts}
className='undp-checkbox margin-top-04'
onChange={onChange}
value={value}
Expand Down
51 changes: 45 additions & 6 deletions src/Components/Filter.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,73 @@
import { Radio } from 'antd';
import styled from 'styled-components';
import { GROUPS } from './Constants';

const StyledRadioGroup = styled(Radio.Group)`
display: flex;
flex-direction: column;
width: 100%;
.ant-radio-wrapper {
padding: 4px 0;
border-bottom: 0.07rem solid var(--gray-300);
width: 100%;
&:last-child {
border-bottom: none;
}
span:first-child {
width: 18px !important;
}
span:last-child {
font-size: 14px !important;
line-height: 1.8;
width: 100%;
display: flex;
justify-content: space-between;
}
}
`;

interface CountryGroupProps {
onRadioChange: (value: string) => void; // Callback function prop for Radio Group
selectedRadio: string; // Selected radio value
onRadioChange: (value: string) => void;
selectedRadio: string;
groups: { label: string; value: string; count?: number }[];
}

function FilterCountryGroup(props: CountryGroupProps): JSX.Element {
const { onRadioChange, selectedRadio } = props;
const { onRadioChange, selectedRadio, groups } = props;

return (
<StyledRadioGroup
options={GROUPS}
value={selectedRadio}
onChange={(e: any) => onRadioChange(e.target.value)}
className='undp-radio margin-top-04'
/>
>
{groups.map(group => (
<Radio key={group.value} value={group.value}>
<div
className='flex-div flex-space-between'
style={{ width: '100%' }}
>
<div>{group.label}</div>
{group.count !== undefined ? (
<p
style={{
fontSize: '12px',
lineHeight: '200%',
backgroundColor: 'var(--gray-300)',
borderRadius: '100px',
padding: '0 8px',
margin: '0',
}}
>
{group.count}
</p>
) : (
''
)}
</div>
</Radio>
))}
</StyledRadioGroup>
);
}

Expand Down

0 comments on commit ba61faa

Please sign in to comment.