Skip to content

Commit

Permalink
Fix display of very small percentage values. (#21368)
Browse files Browse the repository at this point in the history
* Fix display of very small percentage values.

* Adding license headers & changelog snippet.

* Defaulting to 2 fraction digits for percentages.
  • Loading branch information
dennisoelkers authored Jan 21, 2025
1 parent f33588e commit 8b91f4f
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 4 deletions.
5 changes: 5 additions & 0 deletions changelog/unreleased/issue-21185.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
type = "f"
message = "Fix displaying very small percentages."

issues = ["21185"]
pulls = ["21368"]
65 changes: 65 additions & 0 deletions graylog2-web-interface/src/util/NumberFormatting.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright (C) 2020 Graylog, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the Server Side Public License, version 1,
* as published by MongoDB, Inc.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Server Side Public License for more details.
*
* You should have received a copy of the Server Side Public License
* along with this program. If not, see
* <http://www.mongodb.com/licensing/server-side-public-license>.
*/
import { formatNumber, formatPercentage, formatTrend } from './NumberFormatting';

describe('NumberFormatting', () => {
describe('formatNumber', () => {
it('formats with 2 fraction digits by default', () => {
expect(formatNumber(42.23)).toEqual('42.23');
expect(formatNumber(42)).toEqual('42');
expect(formatNumber(137.991)).toEqual('137.99');
expect(formatNumber(137.999)).toEqual('138');
expect(formatNumber(137.111)).toEqual('137.11');
expect(formatNumber(137.115)).toEqual('137.12');
});
});

describe('formatTrend', () => {
it('does show sign', () => {
expect(formatTrend(42.23)).toEqual('+42.23');
expect(formatTrend(-42)).toEqual('-42');
expect(formatTrend(-137.991)).toEqual('-137.99');
expect(formatTrend(137.999)).toEqual('+138');
expect(formatTrend(-137.111)).toEqual('-137.11');
expect(formatTrend(137.115)).toEqual('+137.12');
expect(formatTrend(0)).toEqual('0');
});

it('does show percentage', () => {
const options = { percentage: true };

expect(formatTrend(42.23 / 100, options)).toEqual('+42.23%');
expect(formatTrend(-42 / 100, options)).toEqual('-42.00%');
expect(formatTrend(-137.991 / 100, options)).toEqual('-137.99%');
expect(formatTrend(137.999 / 100, options)).toEqual('+138.00%');
expect(formatTrend(-137.111 / 100, options)).toEqual('-137.11%');
expect(formatTrend(137.115 / 100, options)).toEqual('+137.12%');
expect(formatTrend(0 / 100, options)).toEqual('0.00%');
});
});

describe('formatPercentage', () => {
it('formats with 2 fraction digits by default', () => {
expect(formatPercentage(42.23 / 100)).toEqual('42.23%');
expect(formatPercentage(42 / 100)).toEqual('42.00%');
expect(formatPercentage(137.991 / 100)).toEqual('137.99%');
expect(formatPercentage(137.999 / 100)).toEqual('138.00%');
expect(formatPercentage(137.111 / 100)).toEqual('137.11%');
expect(formatPercentage(137.115 / 100)).toEqual('137.12%');
});
});
});
39 changes: 39 additions & 0 deletions graylog2-web-interface/src/util/NumberFormatting.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright (C) 2020 Graylog, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the Server Side Public License, version 1,
* as published by MongoDB, Inc.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Server Side Public License for more details.
*
* You should have received a copy of the Server Side Public License
* along with this program. If not, see
* <http://www.mongodb.com/licensing/server-side-public-license>.
*/
type Options = {
signDisplay?: 'auto' | 'always' | 'exceptZero',
maximumFractionDigits?: number,
minimumFractionDigits?: number,
};

const defaultOptions = {
maximumFractionDigits: 2,
} as const;

const defaultPercentageOptions = {
...defaultOptions,
minimumFractionDigits: 2,
style: 'percent',
} as const;

export const formatNumber = (num: number, options: Options = {}) => new Intl.NumberFormat(undefined, { ...defaultOptions, ...options }).format(num);
export const formatPercentage = (num: number, options: Options = {}) => new Intl.NumberFormat(undefined, { ...defaultPercentageOptions, ...options }).format(num);

type TrendOptions = {
percentage?: boolean,
}
export const formatTrend = (num: number, options: TrendOptions = {}) => (options.percentage === true ? formatPercentage : formatNumber)(num, { signDisplay: 'exceptZero' });
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright (C) 2020 Graylog, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the Server Side Public License, version 1,
* as published by MongoDB, Inc.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Server Side Public License for more details.
*
* You should have received a copy of the Server Side Public License
* along with this program. If not, see
* <http://www.mongodb.com/licensing/server-side-public-license>.
*/
import * as React from 'react';
import { render, screen } from 'wrappedTestingLibrary';

import PercentageField from './PercentageField';

describe('PercentageField', () => {
it('does not show very small values as `NaN%`', async () => {
render(<PercentageField value={2.744906525058769E-9} />);
await screen.findByText('0.00%');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@
*/
import * as React from 'react';
import { useMemo } from 'react';
import numeral from 'numeral';
import styled from 'styled-components';

import { formatPercentage } from 'util/NumberFormatting';

type Props = {
value: number,
}
Expand All @@ -28,7 +29,7 @@ const NumberCell = styled.span`
`;

const PercentageField = ({ value }: Props) => {
const formatted = useMemo(() => numeral(value).format('0.00%'), [value]);
const formatted = useMemo(() => formatPercentage(value), [value]);

return <NumberCell title={String(value)}>{formatted}</NumberCell>;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
* along with this program. If not, see
* <http://www.mongodb.com/licensing/server-side-public-license>.
*/
import numeral from 'numeral';
import { formatNumber as _formatNumber } from 'util/NumberFormatting';

const formatNumber = (value: number): string => numeral(value).format('0,0.[0000000]');
const formatNumber = (value: number): string => _formatNumber(value, { maximumFractionDigits: 7 });

export default formatNumber;

0 comments on commit 8b91f4f

Please sign in to comment.