mirror of
https://github.com/Unleash/unleash.git
synced 2025-11-10 01:19:53 +01:00
fix: impact metrics formatting (#10715)
This commit is contained in:
parent
b409cc8034
commit
921130a9c0
@ -1,8 +1,8 @@
|
||||
import type { FC } from 'react';
|
||||
import millify from 'millify';
|
||||
import { Tooltip } from '@mui/material';
|
||||
import { LARGE_NUMBER_PRETTIFIED } from 'utils/testIds';
|
||||
import { ConditionallyRender } from '../ConditionallyRender/ConditionallyRender.tsx';
|
||||
import { prettifyLargeNumber } from './formatLargeNumber.js';
|
||||
|
||||
interface IPrettifyLargeNumberProps {
|
||||
/**
|
||||
@ -25,15 +25,6 @@ interface IPrettifyLargeNumberProps {
|
||||
'data-loading'?: string;
|
||||
}
|
||||
|
||||
export const prettifyLargeNumber =
|
||||
(threshold: number = 1_000_000, precision: number = 2) =>
|
||||
(value: number) => {
|
||||
if (value < threshold) {
|
||||
return value.toLocaleString();
|
||||
}
|
||||
return millify(value, { precision });
|
||||
};
|
||||
|
||||
export const PrettifyLargeNumber: FC<IPrettifyLargeNumberProps> = ({
|
||||
value,
|
||||
threshold = 1_000_000,
|
||||
|
||||
@ -0,0 +1,10 @@
|
||||
import millify from 'millify';
|
||||
|
||||
export const prettifyLargeNumber =
|
||||
(threshold: number = 1_000_000, precision: number = 2) =>
|
||||
(value: number) => {
|
||||
if (value < threshold) {
|
||||
return value.toLocaleString();
|
||||
}
|
||||
return millify(value, { precision });
|
||||
};
|
||||
@ -5,7 +5,7 @@ import { SeriesSelector } from './SeriesSelector/SeriesSelector.tsx';
|
||||
import { RangeSelector } from './RangeSelector/RangeSelector.tsx';
|
||||
import { ModeSelector } from './ModeSelector/ModeSelector.tsx';
|
||||
import type { ChartFormState } from '../../hooks/useChartFormState.ts';
|
||||
import { getMetricType } from '../../utils.ts';
|
||||
import { getMetricType } from '../../metricsFormatters.ts';
|
||||
|
||||
export type ImpactMetricsControlsProps = {
|
||||
formData: ChartFormState['formData'];
|
||||
|
||||
@ -7,7 +7,11 @@ import {
|
||||
} from '../insights/components/LineChart/LineChart.tsx';
|
||||
import { useImpactMetricsData } from 'hooks/api/getters/useImpactMetricsData/useImpactMetricsData';
|
||||
import { usePlaceholderData } from '../insights/hooks/usePlaceholderData.js';
|
||||
import { getDisplayFormat, getTimeUnit, formatLargeNumbers } from './utils.ts';
|
||||
import {
|
||||
getDisplayFormat,
|
||||
getTimeUnit,
|
||||
formatLargeNumbers,
|
||||
} from './metricsFormatters.js';
|
||||
import { fromUnixTime } from 'date-fns';
|
||||
import { useChartData } from './hooks/useChartData.ts';
|
||||
import type { AggregationMode } from './types.ts';
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { useMemo } from 'react';
|
||||
import { useTheme } from '@mui/material';
|
||||
import type { ImpactMetricsSeries } from 'hooks/api/getters/useImpactMetricsData/useImpactMetricsData';
|
||||
import { getSeriesLabel } from '../utils.ts';
|
||||
import { getSeriesLabel } from '../metricsFormatters.ts';
|
||||
|
||||
const getColorStartingIndex = (modulo: number, series?: string): number => {
|
||||
if (!series || series.length === 0 || modulo <= 0) {
|
||||
|
||||
@ -2,7 +2,7 @@ import { useState, useEffect } from 'react';
|
||||
import { useImpactMetricsData } from 'hooks/api/getters/useImpactMetricsData/useImpactMetricsData';
|
||||
import type { AggregationMode, ChartConfig } from '../types.ts';
|
||||
import type { ImpactMetricsLabels } from 'hooks/api/getters/useImpactMetricsData/useImpactMetricsData';
|
||||
import { getDefaultAggregation, getMetricType } from '../utils.ts';
|
||||
import { getDefaultAggregation, getMetricType } from '../metricsFormatters.ts';
|
||||
|
||||
type UseChartConfigParams = {
|
||||
open: boolean;
|
||||
|
||||
@ -0,0 +1,41 @@
|
||||
import { formatLargeNumbers } from './metricsFormatters.js';
|
||||
|
||||
describe('formatLargeNumbers', () => {
|
||||
it('formats small numbers with locale formatting', () => {
|
||||
expect(formatLargeNumbers(0)).toBe('0');
|
||||
expect(formatLargeNumbers(999)).toBe('999');
|
||||
});
|
||||
|
||||
it('formats thousands correctly', () => {
|
||||
expect(formatLargeNumbers(1000)).toBe('1k');
|
||||
expect(formatLargeNumbers(1200)).toBe('1.2k');
|
||||
expect(formatLargeNumbers(1400)).toBe('1.4k');
|
||||
expect(formatLargeNumbers(1600)).toBe('1.6k');
|
||||
expect(formatLargeNumbers(5000)).toBe('5k');
|
||||
expect(formatLargeNumbers(9500)).toBe('9.5k');
|
||||
expect(formatLargeNumbers(10000)).toBe('10k');
|
||||
expect(formatLargeNumbers(999000)).toBe('999k');
|
||||
});
|
||||
|
||||
it('formats millions correctly', () => {
|
||||
expect(formatLargeNumbers(1000000)).toBe('1M');
|
||||
expect(formatLargeNumbers(1500000)).toBe('1.5M');
|
||||
expect(formatLargeNumbers(2700000)).toBe('2.7M');
|
||||
expect(formatLargeNumbers(5000000)).toBe('5M');
|
||||
expect(formatLargeNumbers(9900000)).toBe('9.9M');
|
||||
expect(formatLargeNumbers(10000000)).toBe('10M');
|
||||
});
|
||||
|
||||
it('formats billions correctly', () => {
|
||||
expect(formatLargeNumbers(1000000000)).toBe('1B');
|
||||
expect(formatLargeNumbers(1500000000)).toBe('1.5B');
|
||||
expect(formatLargeNumbers(10000000000)).toBe('10B');
|
||||
expect(formatLargeNumbers(999000000000)).toBe('999B');
|
||||
});
|
||||
|
||||
it('formats trillions correctly', () => {
|
||||
expect(formatLargeNumbers(1000000000000)).toBe('1T');
|
||||
expect(formatLargeNumbers(2500000000000)).toBe('2.5T');
|
||||
expect(formatLargeNumbers(10000000000000)).toBe('10T');
|
||||
});
|
||||
});
|
||||
@ -1,3 +1,5 @@
|
||||
import { prettifyLargeNumber } from '../common/PrettifyLargeNumber/formatLargeNumber.js';
|
||||
|
||||
export const getTimeUnit = (timeRange: string) => {
|
||||
switch (timeRange) {
|
||||
case 'hour':
|
||||
@ -52,13 +54,9 @@ export const getSeriesLabel = (metric: Record<string, string>): string => {
|
||||
};
|
||||
|
||||
export const formatLargeNumbers = (value: number): string => {
|
||||
if (value >= 1000000) {
|
||||
return `${(value / 1000000).toFixed(0)}M`;
|
||||
}
|
||||
if (value >= 1000) {
|
||||
return `${(value / 1000).toFixed(0)}k`;
|
||||
}
|
||||
return value.toString();
|
||||
const formatter = prettifyLargeNumber(1000, 1);
|
||||
const result = formatter(value);
|
||||
return result.replace(/K/g, 'k');
|
||||
};
|
||||
|
||||
export const getMetricType = (seriesName: string) => {
|
||||
@ -4,10 +4,8 @@ import { FilterItemParam } from 'utils/serializeQueryParams';
|
||||
import { InsightsSection } from 'component/insights/sections/InsightsSection';
|
||||
import { LifecycleChart } from '../components/LifecycleChart/LifecycleChart.tsx';
|
||||
import { styled, useTheme } from '@mui/material';
|
||||
import {
|
||||
prettifyLargeNumber,
|
||||
PrettifyLargeNumber,
|
||||
} from 'component/common/PrettifyLargeNumber/PrettifyLargeNumber.tsx';
|
||||
import { prettifyLargeNumber } from 'component/common/PrettifyLargeNumber/formatLargeNumber.js';
|
||||
import { PrettifyLargeNumber } from 'component/common/PrettifyLargeNumber/PrettifyLargeNumber.tsx';
|
||||
import { FeatureLifecycleStageIcon } from 'component/common/FeatureLifecycle/FeatureLifecycleStageIcon.tsx';
|
||||
import { normalizeDays } from './normalize-days.ts';
|
||||
import useLoading from 'hooks/useLoading.ts';
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { prettifyLargeNumber } from 'component/common/PrettifyLargeNumber/PrettifyLargeNumber';
|
||||
import { prettifyLargeNumber } from 'component/common/PrettifyLargeNumber/formatLargeNumber.js';
|
||||
|
||||
const prettifyNumber = prettifyLargeNumber(1000, 2);
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user