From 718a731d2fbd3b7f2f6b8a17f57a24783f94a7da Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Fri, 29 Aug 2025 11:31:13 +0200 Subject: [PATCH] fix: Show 100% instead of Infinity% if you've not created any flags (#10575) JS gives you positive infinity if you divide a positive number by 0, which isn't very helpful here. Instead, let's show 100%. If you divide 0 by 0, then you get NaN, which we also need to handle explicitly because it doesn't work with math.min. Before: image image After: image image Fixes 1-4033. --- .../calculate-ratio/calculate-ratio.test.ts | 17 +++++++++++++++++ .../insights/calculate-ratio/calculate-ratio.ts | 12 ++++++++++++ .../CreationArchiveRatioTooltip.tsx | 4 +++- .../CreationArchiveStats.tsx | 5 ++--- 4 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 frontend/src/component/insights/calculate-ratio/calculate-ratio.test.ts create mode 100644 frontend/src/component/insights/calculate-ratio/calculate-ratio.ts 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 }) => ({