diff --git a/frontend/src/components/charts/horizontal-bar-chart/index.tsx b/frontend/src/components/charts/horizontal-bar-chart/index.tsx index 2e60c795..c5187cec 100644 --- a/frontend/src/components/charts/horizontal-bar-chart/index.tsx +++ b/frontend/src/components/charts/horizontal-bar-chart/index.tsx @@ -4,6 +4,7 @@ import { format } from 'd3-format'; import TooltipButton from '@/components/tooltip-button'; import { cn } from '@/lib/classnames'; +import { formatPercentage } from '@/lib/utils/formats'; const DEFAULT_MAX_PERCENTAGE = 100; const PROTECTION_TARGET = 30; @@ -34,12 +35,7 @@ const HorizontalBarChart: React.FC = ({ }, []); const protectedAreaPercentage = useMemo(() => { - if (!totalArea || !protectedArea) return format('.0%')(0); - - if (protectedArea / totalArea < 0.01) return format('.3%')(protectedArea / totalArea); - if (protectedArea / totalArea < 0.1) return format('.2%')(protectedArea / totalArea); - - return format('.0%')(protectedArea / totalArea); + return formatPercentage((protectedArea / totalArea) * 100, { displayPercentageSign: false }); }, [totalArea, protectedArea]); const barFillPercentage = useMemo(() => { @@ -58,7 +54,7 @@ const HorizontalBarChart: React.FC = ({
{protectedAreaPercentage} - % + %
diff --git a/frontend/src/containers/map/content/details/table/helpers.ts b/frontend/src/containers/map/content/details/table/helpers.ts index 539e4261..59a69d66 100644 --- a/frontend/src/containers/map/content/details/table/helpers.ts +++ b/frontend/src/containers/map/content/details/table/helpers.ts @@ -1,7 +1,9 @@ import { format } from 'd3-format'; +import { formatPercentage } from '@/lib/utils/formats'; + const percentage = (value: number) => { - return format(',.2r')(value) == '0.0' ? '0' : format(',.2r')(value); + return formatPercentage(value, { displayPercentageSign: false }); }; const area = (value: number) => { diff --git a/frontend/src/containers/map/content/map/popup/protected-area/index.tsx b/frontend/src/containers/map/content/map/popup/protected-area/index.tsx index e75fb8b4..53446716 100644 --- a/frontend/src/containers/map/content/map/popup/protected-area/index.tsx +++ b/frontend/src/containers/map/content/map/popup/protected-area/index.tsx @@ -102,7 +102,8 @@ const ProtectedAreaPopup = ({ locationId }: { locationId: number }) => { if (!DATA) return null; - const globalCoverage = DATA.REP_M_AREA / locationQuery.data?.attributes?.totalMarineArea; + const globalCoveragePercentage = + (DATA.REP_M_AREA / locationQuery.data?.attributes?.totalMarineArea) * 100; const classNameByMPAType = cn({ 'text-green': DATA?.PA_DEF === '1', @@ -125,7 +126,7 @@ const ProtectedAreaPopup = ({ locationId }: { locationId: number }) => {
Global coverage
{format({ - value: globalCoverage, + value: globalCoveragePercentage, id: 'formatPercentage', })}
diff --git a/frontend/src/containers/map/sidebar/details/widgets/marine-conservation/index.tsx b/frontend/src/containers/map/sidebar/details/widgets/marine-conservation/index.tsx index c919949f..979fa9bd 100644 --- a/frontend/src/containers/map/sidebar/details/widgets/marine-conservation/index.tsx +++ b/frontend/src/containers/map/sidebar/details/widgets/marine-conservation/index.tsx @@ -5,6 +5,7 @@ import { groupBy } from 'lodash-es'; import ConservationChart from '@/components/charts/conservation-chart'; import Widget from '@/components/widget'; import { formatKM } from '@/lib/utils/formats'; +import { formatPercentage } from '@/lib/utils/formats'; import { useGetProtectionCoverageStats } from '@/types/generated/protection-coverage-stat'; import type { LocationGroupsDataItemAttributes } from '@/types/generated/strapi.schemas'; @@ -82,10 +83,9 @@ const MarineConservationWidget: React.FC = ({ loc const totalArea = location.totalMarineArea; const lastYearData = mergedProtectionStats[mergedProtectionStats.length - 1]; const { protectedArea } = lastYearData; - const formatter = Intl.NumberFormat('en-US', { - maximumFractionDigits: 0, + const percentageFormatted = formatPercentage((protectedArea / totalArea) * 100, { + displayPercentageSign: false, }); - const percentageFormatted = formatter.format((protectedArea / totalArea) * 100); const protectedAreaFormatted = formatKM(protectedArea); return { diff --git a/frontend/src/lib/utils/formats.ts b/frontend/src/lib/utils/formats.ts index 3ad4f41c..dbd5fb8a 100644 --- a/frontend/src/lib/utils/formats.ts +++ b/frontend/src/lib/utils/formats.ts @@ -1,11 +1,20 @@ -export function formatPercentage(value: number, options?: Intl.NumberFormatOptions) { +export function formatPercentage( + value: number, + options?: Intl.NumberFormatOptions & { displayPercentageSign?: boolean } +) { + const { displayPercentageSign = true, ...intlNumberFormatOptions } = options || {}; + + if (value < 0.1 && value > 0) { + return displayPercentageSign ? '<0.1%' : '<0.1'; + } + const v = Intl.NumberFormat('en-US', { - maximumFractionDigits: 3, - style: 'percent', - ...options, + maximumFractionDigits: 1, + style: displayPercentageSign ? 'percent' : 'decimal', + ...intlNumberFormatOptions, }); - return v.format(value); + return v.format(displayPercentageSign ? value / 100 : value); } export function formatKM(value: number, options?: Intl.NumberFormatOptions) {