diff --git a/frontend/src/component/insights/calculate-ratio/calculate-ratio.test.ts b/frontend/src/component/insights/calculate-ratio/calculate-ratio.test.ts new file mode 100644 index 0000000000..61548cd669 --- /dev/null +++ b/frontend/src/component/insights/calculate-ratio/calculate-ratio.test.ts @@ -0,0 +1,17 @@ +import { calculateRatio } from './calculate-ratio.ts'; + +test('A ratio of anything to 0 is 100', () => { + expect(calculateRatio(0, 0)).toBe(100); + expect(calculateRatio(5, 0)).toBe(100); +}); + +test('Normal ratios work as expected', () => { + expect(calculateRatio(0, 1)).toBe(0); + expect(calculateRatio(1, 1)).toBe(100); + expect(calculateRatio(1, 2)).toBe(50); + expect(calculateRatio(5, 2)).toBe(250); +}); + +test('Numbers are rounded to the nearest integer', () => { + expect(calculateRatio(5, 9)).toBe(56); +}); diff --git a/frontend/src/component/insights/calculate-ratio/calculate-ratio.ts b/frontend/src/component/insights/calculate-ratio/calculate-ratio.ts new file mode 100644 index 0000000000..ad5e1066a6 --- /dev/null +++ b/frontend/src/component/insights/calculate-ratio/calculate-ratio.ts @@ -0,0 +1,12 @@ +export const calculateRatio = ( + antecedent: number, + consequent: number, +): number => { + const rawRatio = Math.round((antecedent / consequent) * 100); + + if (Number.isNaN(rawRatio) || rawRatio === Number.POSITIVE_INFINITY) { + return 100; + } + + return rawRatio; +}; diff --git a/frontend/src/component/insights/componentsChart/CreationArchiveChart/CreationArchiveRatioTooltip.tsx b/frontend/src/component/insights/componentsChart/CreationArchiveChart/CreationArchiveRatioTooltip.tsx index d88783627c..721ea7385a 100644 --- a/frontend/src/component/insights/componentsChart/CreationArchiveChart/CreationArchiveRatioTooltip.tsx +++ b/frontend/src/component/insights/componentsChart/CreationArchiveChart/CreationArchiveRatioTooltip.tsx @@ -3,6 +3,7 @@ import { Paper, Typography, styled } from '@mui/material'; import type { TooltipState } from 'component/insights/components/LineChart/ChartTooltip/ChartTooltip'; import { ChartTooltipContainer } from 'component/insights/components/LineChart/ChartTooltip/ChartTooltip'; import type { WeekData } from './types.ts'; +import { calculateRatio } from 'component/insights/calculate-ratio/calculate-ratio.ts'; const StyledTooltipItemContainer = styled(Paper)(({ theme }) => ({ padding: theme.spacing(2), @@ -49,7 +50,8 @@ export const CreationArchiveRatioTooltip: FC< const rawData = tooltip.dataPoints[0].raw as WeekData; const archivedCount = rawData.archivedFlags || 0; const createdCount = rawData.totalCreatedFlags || 0; - const ratio = Math.round((archivedCount / createdCount) * 100); + + const ratio = calculateRatio(archivedCount, createdCount); return ( diff --git a/frontend/src/component/insights/componentsStat/CreationArchiveStats/CreationArchiveStats.tsx b/frontend/src/component/insights/componentsStat/CreationArchiveStats/CreationArchiveStats.tsx index c250bf5c66..6c9a2251c1 100644 --- a/frontend/src/component/insights/componentsStat/CreationArchiveStats/CreationArchiveStats.tsx +++ b/frontend/src/component/insights/componentsStat/CreationArchiveStats/CreationArchiveStats.tsx @@ -7,6 +7,7 @@ import { StatsExplanation } from 'component/insights/InsightsCharts.styles'; import type { GroupedDataByProject } from 'component/insights/hooks/useGroupedProjectTrends'; import type { InstanceInsightsSchema } from 'openapi'; import { Link } from 'react-router-dom'; +import { calculateRatio } from 'component/insights/calculate-ratio/calculate-ratio'; function getCurrentArchiveRatio( groupedCreationArchiveData: GroupedDataByProject< @@ -34,9 +35,7 @@ function getCurrentArchiveRatio( } }); - return totalCreated > 0 - ? Math.round((totalArchived / totalCreated) * 100) - : 0; + return calculateRatio(totalArchived, totalCreated); } const StyledRatioContainer = styled(Box)(({ theme }) => ({