chore: new y axis unit selector with support for ucum units (#9615)

This commit is contained in:
Amlan Kumar Nandy
2025-11-30 02:41:54 +07:00
committed by GitHub
parent 918a90e3c1
commit cdc18af4a2
23 changed files with 3735 additions and 372 deletions

View File

@@ -1,5 +1,6 @@
/* eslint-disable sonarjs/no-duplicate-string */
import { getYAxisFormattedValue, PrecisionOptionsEnum } from '../yAxisConfig';
import { PrecisionOptionsEnum } from '../types';
import { getYAxisFormattedValue } from '../yAxisConfig';
const testFullPrecisionGetYAxisFormattedValue = (
value: string,

View File

@@ -78,3 +78,18 @@ export interface ITimeRange {
minTime: number | null;
maxTime: number | null;
}
export const DEFAULT_SIGNIFICANT_DIGITS = 15;
// max decimals to keep should not exceed 15 decimal places to avoid floating point precision issues
export const MAX_DECIMALS = 15;
export enum PrecisionOptionsEnum {
ZERO = 0,
ONE = 1,
TWO = 2,
THREE = 3,
FOUR = 4,
FULL = 'full',
}
export type PrecisionOption = 0 | 1 | 2 | 3 | 4 | PrecisionOptionsEnum.FULL;

View File

@@ -16,8 +16,12 @@ import {
} from './Plugin/IntersectionCursor';
import {
CustomChartOptions,
DEFAULT_SIGNIFICANT_DIGITS,
GraphOnClickHandler,
IAxisTimeConfig,
MAX_DECIMALS,
PrecisionOption,
PrecisionOptionsEnum,
StaticLineProps,
} from './types';
import { getToolTipValue, getYAxisFormattedValue } from './yAxisConfig';
@@ -242,3 +246,68 @@ declare module 'chart.js' {
custom: TooltipPositionerFunction<ChartType>;
}
}
/**
* Formats a number for display, preserving leading zeros after the decimal point
* and showing up to DEFAULT_SIGNIFICANT_DIGITS digits after the first non-zero decimal digit.
* It avoids scientific notation and removes unnecessary trailing zeros.
*
* @example
* formatDecimalWithLeadingZeros(1.2345); // "1.2345"
* formatDecimalWithLeadingZeros(0.0012345); // "0.0012345"
* formatDecimalWithLeadingZeros(5.0); // "5"
*
* @param value The number to format.
* @returns The formatted string.
*/
export const formatDecimalWithLeadingZeros = (
value: number,
precision: PrecisionOption,
): string => {
if (value === 0) {
return '0';
}
// Use toLocaleString to get a full decimal representation without scientific notation.
const numStr = value.toLocaleString('en-US', {
useGrouping: false,
maximumFractionDigits: 20,
});
const [integerPart, decimalPart = ''] = numStr.split('.');
// If there's no decimal part, the integer part is the result.
if (!decimalPart) {
return integerPart;
}
// Find the index of the first non-zero digit in the decimal part.
const firstNonZeroIndex = decimalPart.search(/[^0]/);
// If the decimal part consists only of zeros, return just the integer part.
if (firstNonZeroIndex === -1) {
return integerPart;
}
// Determine the number of decimals to keep: leading zeros + up to N significant digits.
const significantDigits =
precision === PrecisionOptionsEnum.FULL
? DEFAULT_SIGNIFICANT_DIGITS
: precision;
const decimalsToKeep = firstNonZeroIndex + (significantDigits || 0);
// max decimals to keep should not exceed 15 decimal places to avoid floating point precision issues
const finalDecimalsToKeep = Math.min(decimalsToKeep, MAX_DECIMALS);
const trimmedDecimalPart = decimalPart.substring(0, finalDecimalsToKeep);
// If precision is 0, we drop the decimal part entirely.
if (precision === 0) {
return integerPart;
}
// Remove any trailing zeros from the result to keep it clean.
const finalDecimalPart = trimmedDecimalPart.replace(/0+$/, '');
// Return the integer part, or the integer and decimal parts combined.
return finalDecimalPart ? `${integerPart}.${finalDecimalPart}` : integerPart;
};

View File

@@ -1,86 +1,17 @@
/* eslint-disable sonarjs/cognitive-complexity */
import { formattedValueToString, getValueFormat } from '@grafana/data';
import * as Sentry from '@sentry/react';
import { UniversalYAxisUnit } from 'components/YAxisUnitSelector/types';
import { isUniversalUnit } from 'components/YAxisUnitSelector/utils';
import { isNaN } from 'lodash-es';
const DEFAULT_SIGNIFICANT_DIGITS = 15;
// max decimals to keep should not exceed 15 decimal places to avoid floating point precision issues
const MAX_DECIMALS = 15;
export enum PrecisionOptionsEnum {
ZERO = 0,
ONE = 1,
TWO = 2,
THREE = 3,
FOUR = 4,
FULL = 'full',
}
export type PrecisionOption = 0 | 1 | 2 | 3 | 4 | PrecisionOptionsEnum.FULL;
/**
* Formats a number for display, preserving leading zeros after the decimal point
* and showing up to DEFAULT_SIGNIFICANT_DIGITS digits after the first non-zero decimal digit.
* It avoids scientific notation and removes unnecessary trailing zeros.
*
* @example
* formatDecimalWithLeadingZeros(1.2345); // "1.2345"
* formatDecimalWithLeadingZeros(0.0012345); // "0.0012345"
* formatDecimalWithLeadingZeros(5.0); // "5"
*
* @param value The number to format.
* @returns The formatted string.
*/
const formatDecimalWithLeadingZeros = (
value: number,
precision: PrecisionOption,
): string => {
if (value === 0) {
return '0';
}
// Use toLocaleString to get a full decimal representation without scientific notation.
const numStr = value.toLocaleString('en-US', {
useGrouping: false,
maximumFractionDigits: 20,
});
const [integerPart, decimalPart = ''] = numStr.split('.');
// If there's no decimal part, the integer part is the result.
if (!decimalPart) {
return integerPart;
}
// Find the index of the first non-zero digit in the decimal part.
const firstNonZeroIndex = decimalPart.search(/[^0]/);
// If the decimal part consists only of zeros, return just the integer part.
if (firstNonZeroIndex === -1) {
return integerPart;
}
// Determine the number of decimals to keep: leading zeros + up to N significant digits.
const significantDigits =
precision === PrecisionOptionsEnum.FULL
? DEFAULT_SIGNIFICANT_DIGITS
: precision;
const decimalsToKeep = firstNonZeroIndex + (significantDigits || 0);
// max decimals to keep should not exceed 15 decimal places to avoid floating point precision issues
const finalDecimalsToKeep = Math.min(decimalsToKeep, MAX_DECIMALS);
const trimmedDecimalPart = decimalPart.substring(0, finalDecimalsToKeep);
// If precision is 0, we drop the decimal part entirely.
if (precision === 0) {
return integerPart;
}
// Remove any trailing zeros from the result to keep it clean.
const finalDecimalPart = trimmedDecimalPart.replace(/0+$/, '');
// Return the integer part, or the integer and decimal parts combined.
return finalDecimalPart ? `${integerPart}.${finalDecimalPart}` : integerPart;
};
import { formatUniversalUnit } from '../YAxisUnitSelector/formatter';
import {
DEFAULT_SIGNIFICANT_DIGITS,
PrecisionOption,
PrecisionOptionsEnum,
} from './types';
import { formatDecimalWithLeadingZeros } from './utils';
/**
* Formats a Y-axis value based on a given format string.
@@ -126,6 +57,17 @@ export const getYAxisFormattedValue = (
return formatDecimalWithLeadingZeros(numValue, precision);
}
// Separate logic for universal units// Separate logic for universal units
if (format && isUniversalUnit(format)) {
const decimals = computeDecimals();
return formatUniversalUnit(
numValue,
format as UniversalYAxisUnit,
precision,
decimals,
);
}
const formatter = getValueFormat(format);
const formattedValue = formatter(numValue, computeDecimals(), undefined);
if (formattedValue.text && formattedValue.text.includes('.')) {
@@ -134,6 +76,7 @@ export const getYAxisFormattedValue = (
precision,
);
}
return formattedValueToString(formattedValue);
} catch (error) {
Sentry.captureEvent({

View File

@@ -3,9 +3,9 @@ import './styles.scss';
import { Select } from 'antd';
import { DefaultOptionType } from 'antd/es/select';
import { UniversalYAxisUnitMappings, Y_AXIS_CATEGORIES } from './constants';
import { UniversalYAxisUnitMappings } from './constants';
import { UniversalYAxisUnit, YAxisUnitSelectorProps } from './types';
import { mapMetricUnitToUniversalUnit } from './utils';
import { getYAxisCategories, mapMetricUnitToUniversalUnit } from './utils';
function YAxisUnitSelector({
value,
@@ -13,6 +13,7 @@ function YAxisUnitSelector({
placeholder = 'Please select a unit',
loading = false,
'data-testid': dataTestId,
source,
}: YAxisUnitSelectorProps): JSX.Element {
const universalUnit = mapMetricUnitToUniversalUnit(value);
@@ -37,6 +38,8 @@ function YAxisUnitSelector({
return aliases.some((alias) => alias.toLowerCase().includes(search));
};
const categories = getYAxisCategories(source);
return (
<div className="y-axis-unit-selector-component">
<Select
@@ -48,7 +51,7 @@ function YAxisUnitSelector({
loading={loading}
data-testid={dataTestId}
>
{Y_AXIS_CATEGORIES.map((category) => (
{categories.map((category) => (
<Select.OptGroup key={category.name} label={category.name}>
{category.units.map((unit) => (
<Select.Option key={unit.id} value={unit.id}>

View File

@@ -1,5 +1,6 @@
import { fireEvent, render, screen } from '@testing-library/react';
import { YAxisSource } from '../types';
import YAxisUnitSelector from '../YAxisUnitSelector';
describe('YAxisUnitSelector', () => {
@@ -10,7 +11,13 @@ describe('YAxisUnitSelector', () => {
});
it('renders with default placeholder', () => {
render(<YAxisUnitSelector value="" onChange={mockOnChange} />);
render(
<YAxisUnitSelector
value=""
onChange={mockOnChange}
source={YAxisSource.ALERTS}
/>,
);
expect(screen.getByText('Please select a unit')).toBeInTheDocument();
});
@@ -20,13 +27,20 @@ describe('YAxisUnitSelector', () => {
value=""
onChange={mockOnChange}
placeholder="Custom placeholder"
source={YAxisSource.ALERTS}
/>,
);
expect(screen.queryByText('Custom placeholder')).toBeInTheDocument();
});
it('calls onChange when a value is selected', () => {
render(<YAxisUnitSelector value="" onChange={mockOnChange} />);
render(
<YAxisUnitSelector
value=""
onChange={mockOnChange}
source={YAxisSource.ALERTS}
/>,
);
const select = screen.getByRole('combobox');
fireEvent.mouseDown(select);
@@ -41,18 +55,30 @@ describe('YAxisUnitSelector', () => {
});
it('filters options based on search input', () => {
render(<YAxisUnitSelector value="" onChange={mockOnChange} />);
render(
<YAxisUnitSelector
value=""
onChange={mockOnChange}
source={YAxisSource.ALERTS}
/>,
);
const select = screen.getByRole('combobox');
fireEvent.mouseDown(select);
const input = screen.getByRole('combobox');
fireEvent.change(input, { target: { value: 'byte' } });
fireEvent.change(input, { target: { value: 'bytes/sec' } });
expect(screen.getByText('Bytes/sec')).toBeInTheDocument();
});
it('shows all categories and their units', () => {
render(<YAxisUnitSelector value="" onChange={mockOnChange} />);
render(
<YAxisUnitSelector
value=""
onChange={mockOnChange}
source={YAxisSource.ALERTS}
/>,
);
const select = screen.getByRole('combobox');
fireEvent.mouseDown(select);

View File

@@ -0,0 +1,951 @@
import { UniversalYAxisUnit } from 'components/YAxisUnitSelector/types';
import {
AdditionalLabelsMappingForGrafanaUnits,
UniversalUnitToGrafanaUnit,
} from '../constants';
import { formatUniversalUnit } from '../formatter';
describe('formatUniversalUnit', () => {
describe('Time', () => {
test.each([
// Days
[31, UniversalYAxisUnit.DAYS, '4.43 weeks'],
[7, UniversalYAxisUnit.DAYS, '1 week'],
[6, UniversalYAxisUnit.DAYS, '6 days'],
[1, UniversalYAxisUnit.DAYS, '1 day'],
// Hours
[25, UniversalYAxisUnit.HOURS, '1.04 days'],
[23, UniversalYAxisUnit.HOURS, '23 hour'],
[1, UniversalYAxisUnit.HOURS, '1 hour'],
// Minutes
[61, UniversalYAxisUnit.MINUTES, '1.02 hours'],
[60, UniversalYAxisUnit.MINUTES, '1 hour'],
[45, UniversalYAxisUnit.MINUTES, '45 min'],
[1, UniversalYAxisUnit.MINUTES, '1 min'],
// Seconds
[100000, UniversalYAxisUnit.SECONDS, '1.16 days'],
[10065, UniversalYAxisUnit.SECONDS, '2.8 hours'],
[61, UniversalYAxisUnit.SECONDS, '1.02 mins'],
[60, UniversalYAxisUnit.SECONDS, '1 min'],
[12, UniversalYAxisUnit.SECONDS, '12 s'],
[1, UniversalYAxisUnit.SECONDS, '1 s'],
// Milliseconds
[1006, UniversalYAxisUnit.MILLISECONDS, '1.01 s'],
[10000000, UniversalYAxisUnit.MILLISECONDS, '2.78 hours'],
[100006, UniversalYAxisUnit.MICROSECONDS, '100 ms'],
[1, UniversalYAxisUnit.MICROSECONDS, '1 µs'],
[12, UniversalYAxisUnit.MICROSECONDS, '12 µs'],
// Nanoseconds
[10000000000, UniversalYAxisUnit.NANOSECONDS, '10 s'],
[10000006, UniversalYAxisUnit.NANOSECONDS, '10 ms'],
[1006, UniversalYAxisUnit.NANOSECONDS, '1.01 µs'],
[1, UniversalYAxisUnit.NANOSECONDS, '1 ns'],
[12, UniversalYAxisUnit.NANOSECONDS, '12 ns'],
])('formats time value %s %s as %s', (value, unit, expected) => {
expect(formatUniversalUnit(value, unit)).toBe(expected);
});
});
describe('Data', () => {
test.each([
// Bytes
[864, UniversalYAxisUnit.BYTES, '864 B'],
[1000, UniversalYAxisUnit.BYTES, '1 kB'],
[1020, UniversalYAxisUnit.BYTES, '1.02 kB'],
// Kilobytes
[512, UniversalYAxisUnit.KILOBYTES, '512 kB'],
[1000, UniversalYAxisUnit.KILOBYTES, '1 MB'],
[1023, UniversalYAxisUnit.KILOBYTES, '1.02 MB'],
// Megabytes
[777, UniversalYAxisUnit.MEGABYTES, '777 MB'],
[1000, UniversalYAxisUnit.MEGABYTES, '1 GB'],
[1023, UniversalYAxisUnit.MEGABYTES, '1.02 GB'],
// Gigabytes
[432, UniversalYAxisUnit.GIGABYTES, '432 GB'],
[1000, UniversalYAxisUnit.GIGABYTES, '1 TB'],
[1023, UniversalYAxisUnit.GIGABYTES, '1.02 TB'],
// Terabytes
[678, UniversalYAxisUnit.TERABYTES, '678 TB'],
[1000, UniversalYAxisUnit.TERABYTES, '1 PB'],
[1023, UniversalYAxisUnit.TERABYTES, '1.02 PB'],
// Petabytes
[845, UniversalYAxisUnit.PETABYTES, '845 PB'],
[1000, UniversalYAxisUnit.PETABYTES, '1 EB'],
[1023, UniversalYAxisUnit.PETABYTES, '1.02 EB'],
// Exabytes
[921, UniversalYAxisUnit.EXABYTES, '921 EB'],
[1000, UniversalYAxisUnit.EXABYTES, '1 ZB'],
[1023, UniversalYAxisUnit.EXABYTES, '1.02 ZB'],
// Zettabytes
[921, UniversalYAxisUnit.ZETTABYTES, '921 ZB'],
[1000, UniversalYAxisUnit.ZETTABYTES, '1 YB'],
[1023, UniversalYAxisUnit.ZETTABYTES, '1.02 YB'],
// Yottabytes
[921, UniversalYAxisUnit.YOTTABYTES, '921 YB'],
[1000, UniversalYAxisUnit.YOTTABYTES, '1000 YB'],
[1023, UniversalYAxisUnit.YOTTABYTES, '1023 YB'],
])('formats data value %s %s as %s', (value, unit, expected) => {
expect(formatUniversalUnit(value, unit)).toBe(expected);
});
});
describe('Data rate', () => {
test.each([
// Bytes/second
[864, UniversalYAxisUnit.BYTES_SECOND, '864 B/s'],
[1000, UniversalYAxisUnit.BYTES_SECOND, '1 kB/s'],
[1020, UniversalYAxisUnit.BYTES_SECOND, '1.02 kB/s'],
// Kilobytes/second
[512, UniversalYAxisUnit.KILOBYTES_SECOND, '512 kB/s'],
[1000, UniversalYAxisUnit.KILOBYTES_SECOND, '1 MB/s'],
[1023, UniversalYAxisUnit.KILOBYTES_SECOND, '1.02 MB/s'],
// Megabytes/second
[777, UniversalYAxisUnit.MEGABYTES_SECOND, '777 MB/s'],
[1000, UniversalYAxisUnit.MEGABYTES_SECOND, '1 GB/s'],
[1023, UniversalYAxisUnit.MEGABYTES_SECOND, '1.02 GB/s'],
// Gigabytes/second
[432, UniversalYAxisUnit.GIGABYTES_SECOND, '432 GB/s'],
[1000, UniversalYAxisUnit.GIGABYTES_SECOND, '1 TB/s'],
[1023, UniversalYAxisUnit.GIGABYTES_SECOND, '1.02 TB/s'],
// Terabytes/second
[678, UniversalYAxisUnit.TERABYTES_SECOND, '678 TB/s'],
[1000, UniversalYAxisUnit.TERABYTES_SECOND, '1 PB/s'],
[1023, UniversalYAxisUnit.TERABYTES_SECOND, '1.02 PB/s'],
// Petabytes/second
[845, UniversalYAxisUnit.PETABYTES_SECOND, '845 PB/s'],
[1000, UniversalYAxisUnit.PETABYTES_SECOND, '1 EB/s'],
[1023, UniversalYAxisUnit.PETABYTES_SECOND, '1.02 EB/s'],
// Exabytes/second
[921, UniversalYAxisUnit.EXABYTES_SECOND, '921 EB/s'],
[1000, UniversalYAxisUnit.EXABYTES_SECOND, '1 ZB/s'],
[1023, UniversalYAxisUnit.EXABYTES_SECOND, '1.02 ZB/s'],
// Zettabytes/second
[921, UniversalYAxisUnit.ZETTABYTES_SECOND, '921 ZB/s'],
[1000, UniversalYAxisUnit.ZETTABYTES_SECOND, '1 YB/s'],
[1023, UniversalYAxisUnit.ZETTABYTES_SECOND, '1.02 YB/s'],
// Yottabytes/second
[921, UniversalYAxisUnit.YOTTABYTES_SECOND, '921 YB/s'],
[1000, UniversalYAxisUnit.YOTTABYTES_SECOND, '1000 YB/s'],
[1023, UniversalYAxisUnit.YOTTABYTES_SECOND, '1023 YB/s'],
])('formats data value %s %s as %s', (value, unit, expected) => {
expect(formatUniversalUnit(value, unit)).toBe(expected);
});
});
describe('Bit', () => {
test.each([
// Bits
[1, UniversalYAxisUnit.BITS, '1 b'],
[250, UniversalYAxisUnit.BITS, '250 b'],
[1000, UniversalYAxisUnit.BITS, '1 kb'],
[1023, UniversalYAxisUnit.BITS, '1.02 kb'],
// Kilobits
[0.5, UniversalYAxisUnit.KILOBITS, '500 b'],
[375, UniversalYAxisUnit.KILOBITS, '375 kb'],
[1000, UniversalYAxisUnit.KILOBITS, '1 Mb'],
[1023, UniversalYAxisUnit.KILOBITS, '1.02 Mb'],
// Megabits
[0.5, UniversalYAxisUnit.MEGABITS, '500 kb'],
[640, UniversalYAxisUnit.MEGABITS, '640 Mb'],
[1000, UniversalYAxisUnit.MEGABITS, '1 Gb'],
[1023, UniversalYAxisUnit.MEGABITS, '1.02 Gb'],
// Gigabits
[0.5, UniversalYAxisUnit.GIGABITS, '500 Mb'],
[875, UniversalYAxisUnit.GIGABITS, '875 Gb'],
[1000, UniversalYAxisUnit.GIGABITS, '1 Tb'],
[1023, UniversalYAxisUnit.GIGABITS, '1.02 Tb'],
// Terabits
[0.5, UniversalYAxisUnit.TERABITS, '500 Gb'],
[430, UniversalYAxisUnit.TERABITS, '430 Tb'],
[1000, UniversalYAxisUnit.TERABITS, '1 Pb'],
[1023, UniversalYAxisUnit.TERABITS, '1.02 Pb'],
// Petabits
[0.5, UniversalYAxisUnit.PETABITS, '500 Tb'],
[590, UniversalYAxisUnit.PETABITS, '590 Pb'],
[1000, UniversalYAxisUnit.PETABITS, '1 Eb'],
[1023, UniversalYAxisUnit.PETABITS, '1.02 Eb'],
// Exabits
[0.5, UniversalYAxisUnit.EXABITS, '500 Pb'],
[715, UniversalYAxisUnit.EXABITS, '715 Eb'],
[1000, UniversalYAxisUnit.EXABITS, '1 Zb'],
[1023, UniversalYAxisUnit.EXABITS, '1.02 Zb'],
// Zettabits
[0.5, UniversalYAxisUnit.ZETTABITS, '500 Eb'],
[840, UniversalYAxisUnit.ZETTABITS, '840 Zb'],
[1000, UniversalYAxisUnit.ZETTABITS, '1 Yb'],
[1023, UniversalYAxisUnit.ZETTABITS, '1.02 Yb'],
// Yottabits
[0.5, UniversalYAxisUnit.YOTTABITS, '500 Zb'],
[965, UniversalYAxisUnit.YOTTABITS, '965 Yb'],
[1000, UniversalYAxisUnit.YOTTABITS, '1000 Yb'],
[1023, UniversalYAxisUnit.YOTTABITS, '1023 Yb'],
])('formats bit value %s %s as %s', (value, unit, expected) => {
expect(formatUniversalUnit(value, unit)).toBe(expected);
});
});
describe('Bit rate', () => {
test.each([
// Bits/second
[512, UniversalYAxisUnit.BITS_SECOND, '512 b/s'],
[1000, UniversalYAxisUnit.BITS_SECOND, '1 kb/s'],
[1023, UniversalYAxisUnit.BITS_SECOND, '1.02 kb/s'],
// Kilobits/second
[0.5, UniversalYAxisUnit.KILOBITS_SECOND, '500 b/s'],
[512, UniversalYAxisUnit.KILOBITS_SECOND, '512 kb/s'],
[1000, UniversalYAxisUnit.KILOBITS_SECOND, '1 Mb/s'],
[1023, UniversalYAxisUnit.KILOBITS_SECOND, '1.02 Mb/s'],
// Megabits/second
[0.5, UniversalYAxisUnit.MEGABITS_SECOND, '500 kb/s'],
[512, UniversalYAxisUnit.MEGABITS_SECOND, '512 Mb/s'],
[1000, UniversalYAxisUnit.MEGABITS_SECOND, '1 Gb/s'],
[1023, UniversalYAxisUnit.MEGABITS_SECOND, '1.02 Gb/s'],
// Gigabits/second
[0.5, UniversalYAxisUnit.GIGABITS_SECOND, '500 Mb/s'],
[512, UniversalYAxisUnit.GIGABITS_SECOND, '512 Gb/s'],
[1000, UniversalYAxisUnit.GIGABITS_SECOND, '1 Tb/s'],
[1023, UniversalYAxisUnit.GIGABITS_SECOND, '1.02 Tb/s'],
// Terabits/second
[0.5, UniversalYAxisUnit.TERABITS_SECOND, '500 Gb/s'],
[512, UniversalYAxisUnit.TERABITS_SECOND, '512 Tb/s'],
[1000, UniversalYAxisUnit.TERABITS_SECOND, '1 Pb/s'],
[1023, UniversalYAxisUnit.TERABITS_SECOND, '1.02 Pb/s'],
// Petabits/second
[0.5, UniversalYAxisUnit.PETABITS_SECOND, '500 Tb/s'],
[512, UniversalYAxisUnit.PETABITS_SECOND, '512 Pb/s'],
[1000, UniversalYAxisUnit.PETABITS_SECOND, '1 Eb/s'],
[1023, UniversalYAxisUnit.PETABITS_SECOND, '1.02 Eb/s'],
// Exabits/second
[512, UniversalYAxisUnit.EXABITS_SECOND, '512 Eb/s'],
[1000, UniversalYAxisUnit.EXABITS_SECOND, '1 Zb/s'],
[1023, UniversalYAxisUnit.EXABITS_SECOND, '1.02 Zb/s'],
// Zettabits/second
[0.5, UniversalYAxisUnit.ZETTABITS_SECOND, '500 Eb/s'],
[512, UniversalYAxisUnit.ZETTABITS_SECOND, '512 Zb/s'],
[1000, UniversalYAxisUnit.ZETTABITS_SECOND, '1 Yb/s'],
[1023, UniversalYAxisUnit.ZETTABITS_SECOND, '1.02 Yb/s'],
// Yottabits/second
[0.5, UniversalYAxisUnit.YOTTABITS_SECOND, '500 Zb/s'],
[512, UniversalYAxisUnit.YOTTABITS_SECOND, '512 Yb/s'],
[1000, UniversalYAxisUnit.YOTTABITS_SECOND, '1000 Yb/s'],
[1023, UniversalYAxisUnit.YOTTABITS_SECOND, '1023 Yb/s'],
])('formats bit rate value %s %s as %s', (value, unit, expected) => {
expect(formatUniversalUnit(value, unit)).toBe(expected);
});
});
describe('Count', () => {
test.each([
[100, UniversalYAxisUnit.COUNT, '100'],
[875, UniversalYAxisUnit.COUNT, '875'],
[1000, UniversalYAxisUnit.COUNT, '1 K'],
[2500, UniversalYAxisUnit.COUNT, '2.5 K'],
[10000, UniversalYAxisUnit.COUNT, '10 K'],
[25000, UniversalYAxisUnit.COUNT, '25 K'],
[100000, UniversalYAxisUnit.COUNT, '100 K'],
[1000000, UniversalYAxisUnit.COUNT, '1 Mil'],
[10000000, UniversalYAxisUnit.COUNT, '10 Mil'],
[100000000, UniversalYAxisUnit.COUNT, '100 Mil'],
[1000000000, UniversalYAxisUnit.COUNT, '1 Bil'],
[10000000000, UniversalYAxisUnit.COUNT, '10 Bil'],
[100000000000, UniversalYAxisUnit.COUNT, '100 Bil'],
[1000000000000, UniversalYAxisUnit.COUNT, '1 Tri'],
[10000000000000, UniversalYAxisUnit.COUNT, '10 Tri'],
])('formats count value %s %s as %s', (value, unit, expected) => {
expect(formatUniversalUnit(value, unit)).toBe(expected);
});
test.each([
[100, UniversalYAxisUnit.COUNT_SECOND, '100 c/s'],
[875, UniversalYAxisUnit.COUNT_SECOND, '875 c/s'],
[1000, UniversalYAxisUnit.COUNT_SECOND, '1K c/s'],
[2500, UniversalYAxisUnit.COUNT_SECOND, '2.5K c/s'],
[10000, UniversalYAxisUnit.COUNT_SECOND, '10K c/s'],
[25000, UniversalYAxisUnit.COUNT_SECOND, '25K c/s'],
])('formats count per time value %s %s as %s', (value, unit, expected) => {
expect(formatUniversalUnit(value, unit)).toBe(expected);
});
test.each([
[100, UniversalYAxisUnit.COUNT_MINUTE, '100 c/m'],
[875, UniversalYAxisUnit.COUNT_MINUTE, '875 c/m'],
[1000, UniversalYAxisUnit.COUNT_MINUTE, '1K c/m'],
[2500, UniversalYAxisUnit.COUNT_MINUTE, '2.5K c/m'],
[10000, UniversalYAxisUnit.COUNT_MINUTE, '10K c/m'],
[25000, UniversalYAxisUnit.COUNT_MINUTE, '25K c/m'],
])('formats count per time value %s %s as %s', (value, unit, expected) => {
expect(formatUniversalUnit(value, unit)).toBe(expected);
});
});
describe('Operations units', () => {
test.each([
[780, UniversalYAxisUnit.OPS_SECOND, '780 ops/s'],
[1000, UniversalYAxisUnit.OPS_SECOND, '1K ops/s'],
[520, UniversalYAxisUnit.OPS_MINUTE, '520 ops/m'],
[1000, UniversalYAxisUnit.OPS_MINUTE, '1K ops/m'],
[2500, UniversalYAxisUnit.OPS_MINUTE, '2.5K ops/m'],
[10000, UniversalYAxisUnit.OPS_MINUTE, '10K ops/m'],
[25000, UniversalYAxisUnit.OPS_MINUTE, '25K ops/m'],
])(
'formats operations per time value %s %s as %s',
(value, unit, expected) => {
expect(formatUniversalUnit(value, unit)).toBe(expected);
},
);
});
describe('Request units', () => {
test.each([
[615, UniversalYAxisUnit.REQUESTS_SECOND, '615 req/s'],
[1000, UniversalYAxisUnit.REQUESTS_SECOND, '1K req/s'],
[480, UniversalYAxisUnit.REQUESTS_MINUTE, '480 req/m'],
[1000, UniversalYAxisUnit.REQUESTS_MINUTE, '1K req/m'],
[2500, UniversalYAxisUnit.REQUESTS_MINUTE, '2.5K req/m'],
[10000, UniversalYAxisUnit.REQUESTS_MINUTE, '10K req/m'],
[25000, UniversalYAxisUnit.REQUESTS_MINUTE, '25K req/m'],
])('formats requests per time value %s %s as %s', (value, unit, expected) => {
expect(formatUniversalUnit(value, unit)).toBe(expected);
});
});
describe('Read/Write units', () => {
test.each([
[505, UniversalYAxisUnit.READS_SECOND, '505 rd/s'],
[1000, UniversalYAxisUnit.READS_SECOND, '1K rd/s'],
[610, UniversalYAxisUnit.WRITES_SECOND, '610 wr/s'],
[1000, UniversalYAxisUnit.WRITES_SECOND, '1K wr/s'],
[715, UniversalYAxisUnit.READS_MINUTE, '715 rd/m'],
[1000, UniversalYAxisUnit.READS_MINUTE, '1K rd/m'],
[2500, UniversalYAxisUnit.READS_MINUTE, '2.5K rd/m'],
[10000, UniversalYAxisUnit.READS_MINUTE, '10K rd/m'],
[25000, UniversalYAxisUnit.READS_MINUTE, '25K rd/m'],
[830, UniversalYAxisUnit.WRITES_MINUTE, '830 wr/m'],
[1000, UniversalYAxisUnit.WRITES_MINUTE, '1K wr/m'],
[2500, UniversalYAxisUnit.WRITES_MINUTE, '2.5K wr/m'],
[10000, UniversalYAxisUnit.WRITES_MINUTE, '10K wr/m'],
[25000, UniversalYAxisUnit.WRITES_MINUTE, '25K wr/m'],
])(
'formats reads and writes per time value %s %s as %s',
(value, unit, expected) => {
expect(formatUniversalUnit(value, unit)).toBe(expected);
},
);
});
describe('IO Operations units', () => {
test.each([
[777, UniversalYAxisUnit.IOOPS_SECOND, '777 io/s'],
[1000, UniversalYAxisUnit.IOOPS_SECOND, '1K io/s'],
[2500, UniversalYAxisUnit.IOOPS_SECOND, '2.5K io/s'],
[10000, UniversalYAxisUnit.IOOPS_SECOND, '10K io/s'],
[25000, UniversalYAxisUnit.IOOPS_SECOND, '25K io/s'],
])('formats IOPS value %s %s as %s', (value, unit, expected) => {
expect(formatUniversalUnit(value, unit)).toBe(expected);
});
});
describe('Percent units', () => {
it('formats percent as-is', () => {
expect(formatUniversalUnit(456, UniversalYAxisUnit.PERCENT)).toBe('456%');
});
it('multiplies percent_unit by 100', () => {
expect(formatUniversalUnit(9, UniversalYAxisUnit.PERCENT_UNIT)).toBe('900%');
});
});
describe('None unit', () => {
it('formats as plain number', () => {
expect(formatUniversalUnit(742, UniversalYAxisUnit.NONE)).toBe('742');
});
});
describe('Time (additional)', () => {
test.each([
[900, UniversalYAxisUnit.DURATION_MS, '900 milliseconds'],
[1000, UniversalYAxisUnit.DURATION_MS, '1 second'],
[1, UniversalYAxisUnit.DURATION_MS, '1 millisecond'],
[900, UniversalYAxisUnit.DURATION_S, '15 minutes'],
[1, UniversalYAxisUnit.DURATION_HMS, '00:00:01'],
[90005, UniversalYAxisUnit.DURATION_HMS, '25:00:05'],
[90005, UniversalYAxisUnit.DURATION_DHMS, '1 d 01:00:05'],
[900, UniversalYAxisUnit.TIMETICKS, '9 s'],
[1, UniversalYAxisUnit.TIMETICKS, '10 ms'],
[900, UniversalYAxisUnit.CLOCK_MS, '900ms'],
[1, UniversalYAxisUnit.CLOCK_MS, '001ms'],
[1, UniversalYAxisUnit.CLOCK_S, '01s:000ms'],
[900, UniversalYAxisUnit.CLOCK_S, '15m:00s:000ms'],
[900, UniversalYAxisUnit.TIME_HERTZ, '900 Hz'],
[1000, UniversalYAxisUnit.TIME_HERTZ, '1 kHz'],
[1000000, UniversalYAxisUnit.TIME_HERTZ, '1 MHz'],
[1000000000, UniversalYAxisUnit.TIME_HERTZ, '1 GHz'],
[1008, UniversalYAxisUnit.TIME_HERTZ, '1.01 kHz'],
])('formats duration value %s %s as %s', (value, unit, expected) => {
expect(formatUniversalUnit(value, unit)).toBe(expected);
});
});
describe('Data (IEC/Binary)', () => {
test.each([
// Bytes
[900, UniversalYAxisUnit.BYTES_IEC, '900 B'],
[1024, UniversalYAxisUnit.BYTES_IEC, '1 KiB'],
[1080, UniversalYAxisUnit.BYTES_IEC, '1.05 KiB'],
// Kibibytes
[900, UniversalYAxisUnit.KIBIBYTES, '900 KiB'],
[1024, UniversalYAxisUnit.KIBIBYTES, '1 MiB'],
[1080, UniversalYAxisUnit.KIBIBYTES, '1.05 MiB'],
// Mebibytes
[900, UniversalYAxisUnit.MEBIBYTES, '900 MiB'],
[1024, UniversalYAxisUnit.MEBIBYTES, '1 GiB'],
[1080, UniversalYAxisUnit.MEBIBYTES, '1.05 GiB'],
// Gibibytes
[900, UniversalYAxisUnit.GIBIBYTES, '900 GiB'],
[1024, UniversalYAxisUnit.GIBIBYTES, '1 TiB'],
[1080, UniversalYAxisUnit.GIBIBYTES, '1.05 TiB'],
// Tebibytes
[900, UniversalYAxisUnit.TEBIBYTES, '900 TiB'],
[1024, UniversalYAxisUnit.TEBIBYTES, '1 PiB'],
[1080, UniversalYAxisUnit.TEBIBYTES, '1.05 PiB'],
// Pebibytes
[900, UniversalYAxisUnit.PEBIBYTES, '900 PiB'],
[1024, UniversalYAxisUnit.PEBIBYTES, '1 EiB'],
[1080, UniversalYAxisUnit.PEBIBYTES, '1.05 EiB'],
// Exbibytes
[900, UniversalYAxisUnit.EXBIBYTES, '900 EiB'],
[1024, UniversalYAxisUnit.EXBIBYTES, '1 ZiB'],
[1080, UniversalYAxisUnit.EXBIBYTES, '1.05 ZiB'],
// Zebibytes
[900, UniversalYAxisUnit.ZEBIBYTES, '900 ZiB'],
[1024, UniversalYAxisUnit.ZEBIBYTES, '1 YiB'],
[1080, UniversalYAxisUnit.ZEBIBYTES, '1.05 YiB'],
// Yobibytes
[900, UniversalYAxisUnit.YOBIBYTES, '900 YiB'],
[1024, UniversalYAxisUnit.YOBIBYTES, '1024 YiB'],
])('formats IEC bytes value %s %s as %s', (value, unit, expected) => {
expect(formatUniversalUnit(value, unit)).toBe(expected);
});
});
describe('Data Rate (IEC/Binary)', () => {
test.each([
// Kibibytes/second
[900, UniversalYAxisUnit.KIBIBYTES_SECOND, '900 KiB/s'],
[1024, UniversalYAxisUnit.KIBIBYTES_SECOND, '1 MiB/s'],
[1080, UniversalYAxisUnit.KIBIBYTES_SECOND, '1.05 MiB/s'],
// Mebibytes/second
[900, UniversalYAxisUnit.MEBIBYTES_SECOND, '900 MiB/s'],
[1024, UniversalYAxisUnit.MEBIBYTES_SECOND, '1 GiB/s'],
[1080, UniversalYAxisUnit.MEBIBYTES_SECOND, '1.05 GiB/s'],
// Gibibytes/second
[900, UniversalYAxisUnit.GIBIBYTES_SECOND, '900 GiB/s'],
[1024, UniversalYAxisUnit.GIBIBYTES_SECOND, '1 TiB/s'],
[1080, UniversalYAxisUnit.GIBIBYTES_SECOND, '1.05 TiB/s'],
// Tebibytes/second
[900, UniversalYAxisUnit.TEBIBYTES_SECOND, '900 TiB/s'],
[1024, UniversalYAxisUnit.TEBIBYTES_SECOND, '1 PiB/s'],
[1080, UniversalYAxisUnit.TEBIBYTES_SECOND, '1.05 PiB/s'],
// Pebibytes/second
[900, UniversalYAxisUnit.PEBIBYTES_SECOND, '900 PiB/s'],
[1024, UniversalYAxisUnit.PEBIBYTES_SECOND, '1 EiB/s'],
[1080, UniversalYAxisUnit.PEBIBYTES_SECOND, '1.05 EiB/s'],
// Exbibytes/second
[900, UniversalYAxisUnit.EXBIBYTES_SECOND, '900 EiB/s'],
[1024, UniversalYAxisUnit.EXBIBYTES_SECOND, '1 ZiB/s'],
[1080, UniversalYAxisUnit.EXBIBYTES_SECOND, '1.05 ZiB/s'],
// Zebibytes/second
[900, UniversalYAxisUnit.ZEBIBYTES_SECOND, '900 ZiB/s'],
[1024, UniversalYAxisUnit.ZEBIBYTES_SECOND, '1 YiB/s'],
[1080, UniversalYAxisUnit.ZEBIBYTES_SECOND, '1.05 YiB/s'],
// Yobibytes/second
[900, UniversalYAxisUnit.YOBIBYTES_SECOND, '900 YiB/s'],
[1024, UniversalYAxisUnit.YOBIBYTES_SECOND, '1024 YiB/s'],
[1080, UniversalYAxisUnit.YOBIBYTES_SECOND, '1080 YiB/s'],
// Packets/second
[900, UniversalYAxisUnit.DATA_RATE_PACKETS_PER_SECOND, '900 p/s'],
[1000, UniversalYAxisUnit.DATA_RATE_PACKETS_PER_SECOND, '1 kp/s'],
[1080, UniversalYAxisUnit.DATA_RATE_PACKETS_PER_SECOND, '1.08 kp/s'],
])('formats IEC byte rates value %s %s as %s', (value, unit, expected) => {
expect(formatUniversalUnit(value, unit)).toBe(expected);
});
});
describe('Bits (IEC)', () => {
test.each([
[900, UniversalYAxisUnit.BITS_IEC, '900 b'],
[1024, UniversalYAxisUnit.BITS_IEC, '1 Kib'],
[1080, UniversalYAxisUnit.BITS_IEC, '1.05 Kib'],
])('formats IEC bits value %s %s as %s', (value, unit, expected) => {
expect(formatUniversalUnit(value, unit)).toBe(expected);
});
});
describe('Hash Rate', () => {
test.each([
// Hashes/second
[412, UniversalYAxisUnit.HASH_RATE_HASHES_PER_SECOND, '412 H/s'],
[1000, UniversalYAxisUnit.HASH_RATE_HASHES_PER_SECOND, '1 kH/s'],
[1023, UniversalYAxisUnit.HASH_RATE_HASHES_PER_SECOND, '1.02 kH/s'],
// Kilohashes/second
[412, UniversalYAxisUnit.HASH_RATE_KILOHASHES_PER_SECOND, '412 kH/s'],
[1000, UniversalYAxisUnit.HASH_RATE_KILOHASHES_PER_SECOND, '1 MH/s'],
[1023, UniversalYAxisUnit.HASH_RATE_KILOHASHES_PER_SECOND, '1.02 MH/s'],
// Megahashes/second
[412, UniversalYAxisUnit.HASH_RATE_MEGAHASHES_PER_SECOND, '412 MH/s'],
[1000, UniversalYAxisUnit.HASH_RATE_MEGAHASHES_PER_SECOND, '1 GH/s'],
[1023, UniversalYAxisUnit.HASH_RATE_MEGAHASHES_PER_SECOND, '1.02 GH/s'],
// Gigahashes/second
[412, UniversalYAxisUnit.HASH_RATE_GIGAHASHES_PER_SECOND, '412 GH/s'],
[1000, UniversalYAxisUnit.HASH_RATE_GIGAHASHES_PER_SECOND, '1 TH/s'],
[1023, UniversalYAxisUnit.HASH_RATE_GIGAHASHES_PER_SECOND, '1.02 TH/s'],
// Terahashes/second
[412, UniversalYAxisUnit.HASH_RATE_TERAHASHES_PER_SECOND, '412 TH/s'],
[1000, UniversalYAxisUnit.HASH_RATE_TERAHASHES_PER_SECOND, '1 PH/s'],
[1023, UniversalYAxisUnit.HASH_RATE_TERAHASHES_PER_SECOND, '1.02 PH/s'],
// Petahashes/second
[412, UniversalYAxisUnit.HASH_RATE_PETAHASHES_PER_SECOND, '412 PH/s'],
[1000, UniversalYAxisUnit.HASH_RATE_PETAHASHES_PER_SECOND, '1 EH/s'],
[1023, UniversalYAxisUnit.HASH_RATE_PETAHASHES_PER_SECOND, '1.02 EH/s'],
// Exahashes/second
[412, UniversalYAxisUnit.HASH_RATE_EXAHASHES_PER_SECOND, '412 EH/s'],
[1000, UniversalYAxisUnit.HASH_RATE_EXAHASHES_PER_SECOND, '1 ZH/s'],
[1023, UniversalYAxisUnit.HASH_RATE_EXAHASHES_PER_SECOND, '1.02 ZH/s'],
])('formats hash rate value %s %s as %s', (value, unit, expected) => {
expect(formatUniversalUnit(value, unit)).toBe(expected);
});
});
describe('Miscellaneous', () => {
test.each([
[742, UniversalYAxisUnit.MISC_STRING, '742'],
[688, UniversalYAxisUnit.MISC_SHORT, '688'],
[555, UniversalYAxisUnit.MISC_HUMIDITY, '555 %H'],
[812, UniversalYAxisUnit.MISC_DECIBEL, '812 dB'],
[1024, UniversalYAxisUnit.MISC_HEXADECIMAL, '400'],
[1024, UniversalYAxisUnit.MISC_HEXADECIMAL_0X, '0x400'],
[900, UniversalYAxisUnit.MISC_SCIENTIFIC_NOTATION, '9e+2'],
[678, UniversalYAxisUnit.MISC_LOCALE_FORMAT, '678'],
[444, UniversalYAxisUnit.MISC_PIXELS, '444 px'],
])('formats miscellaneous value %s %s as %s', (value, unit, expected) => {
expect(formatUniversalUnit(value, unit)).toBe(expected);
});
});
describe('Acceleration', () => {
test.each([
[
875,
UniversalYAxisUnit.ACCELERATION_METERS_PER_SECOND_SQUARED,
'875 m/sec²',
],
[640, UniversalYAxisUnit.ACCELERATION_FEET_PER_SECOND_SQUARED, '640 f/sec²'],
[512, UniversalYAxisUnit.ACCELERATION_G_UNIT, '512 g'],
[
2500,
UniversalYAxisUnit.ACCELERATION_METERS_PER_SECOND_SQUARED,
'2500 m/sec²',
],
])('formats acceleration value %s %s as %s', (value, unit, expected) => {
expect(formatUniversalUnit(value, unit)).toBe(expected);
});
});
describe('Angular', () => {
test.each([
[415, UniversalYAxisUnit.ANGULAR_DEGREE, '415 °'],
[732, UniversalYAxisUnit.ANGULAR_RADIAN, '732 rad'],
[128, UniversalYAxisUnit.ANGULAR_GRADIAN, '128 grad'],
[560, UniversalYAxisUnit.ANGULAR_ARC_MINUTE, '560 arcmin'],
[945, UniversalYAxisUnit.ANGULAR_ARC_SECOND, '945 arcsec'],
])('formats angular value %s %s as %s', (value, unit, expected) => {
expect(formatUniversalUnit(value, unit)).toBe(expected);
});
});
describe('Area', () => {
test.each([
[210, UniversalYAxisUnit.AREA_SQUARE_METERS, '210 m²'],
[152, UniversalYAxisUnit.AREA_SQUARE_FEET, '152 ft²'],
[64, UniversalYAxisUnit.AREA_SQUARE_MILES, '64 mi²'],
])('formats area value %s %s as %s', (value, unit, expected) => {
expect(formatUniversalUnit(value, unit)).toBe(expected);
});
});
describe('FLOPs', () => {
test.each([
// FLOPS
[150, UniversalYAxisUnit.FLOPS_FLOPS, '150 FLOPS'],
[1000, UniversalYAxisUnit.FLOPS_FLOPS, '1 kFLOPS'],
[1080, UniversalYAxisUnit.FLOPS_FLOPS, '1.08 kFLOPS'],
// MFLOPS
[275, UniversalYAxisUnit.FLOPS_MFLOPS, '275 MFLOPS'],
[1000, UniversalYAxisUnit.FLOPS_MFLOPS, '1 GFLOPS'],
[1080, UniversalYAxisUnit.FLOPS_MFLOPS, '1.08 GFLOPS'],
// GFLOPS
[640, UniversalYAxisUnit.FLOPS_GFLOPS, '640 GFLOPS'],
[1000, UniversalYAxisUnit.FLOPS_GFLOPS, '1 TFLOPS'],
[1080, UniversalYAxisUnit.FLOPS_GFLOPS, '1.08 TFLOPS'],
// TFLOPS
[875, UniversalYAxisUnit.FLOPS_TFLOPS, '875 TFLOPS'],
[1000, UniversalYAxisUnit.FLOPS_TFLOPS, '1 PFLOPS'],
[1080, UniversalYAxisUnit.FLOPS_TFLOPS, '1.08 PFLOPS'],
// PFLOPS
[430, UniversalYAxisUnit.FLOPS_PFLOPS, '430 PFLOPS'],
[1000, UniversalYAxisUnit.FLOPS_PFLOPS, '1 EFLOPS'],
[1080, UniversalYAxisUnit.FLOPS_PFLOPS, '1.08 EFLOPS'],
// EFLOPS
[590, UniversalYAxisUnit.FLOPS_EFLOPS, '590 EFLOPS'],
[1000, UniversalYAxisUnit.FLOPS_EFLOPS, '1 ZFLOPS'],
[1080, UniversalYAxisUnit.FLOPS_EFLOPS, '1.08 ZFLOPS'],
// ZFLOPS
[715, UniversalYAxisUnit.FLOPS_ZFLOPS, '715 ZFLOPS'],
[1000, UniversalYAxisUnit.FLOPS_ZFLOPS, '1 YFLOPS'],
[1080, UniversalYAxisUnit.FLOPS_ZFLOPS, '1.08 YFLOPS'],
// YFLOPS
[840, UniversalYAxisUnit.FLOPS_YFLOPS, '840 YFLOPS'],
[1000, UniversalYAxisUnit.FLOPS_YFLOPS, '1000 YFLOPS'],
])('formats FLOPs value %s %s as %s', (value, unit, expected) => {
expect(formatUniversalUnit(value, unit)).toBe(expected);
});
});
describe('Concentration', () => {
test.each([
[415, UniversalYAxisUnit.CONCENTRATION_PPM, '415 ppm'],
[1000, UniversalYAxisUnit.CONCENTRATION_PPM, '1000 ppm'],
[732, UniversalYAxisUnit.CONCENTRATION_PPB, '732 ppb'],
[1000, UniversalYAxisUnit.CONCENTRATION_PPB, '1000 ppb'],
[128, UniversalYAxisUnit.CONCENTRATION_NG_M3, '128 ng/m³'],
[1000, UniversalYAxisUnit.CONCENTRATION_NG_M3, '1000 ng/m³'],
[560, UniversalYAxisUnit.CONCENTRATION_NG_NORMAL_CUBIC_METER, '560 ng/Nm³'],
[
1000,
UniversalYAxisUnit.CONCENTRATION_NG_NORMAL_CUBIC_METER,
'1000 ng/Nm³',
],
[945, UniversalYAxisUnit.CONCENTRATION_UG_M3, '945 μg/m³'],
[1000, UniversalYAxisUnit.CONCENTRATION_UG_M3, '1000 μg/m³'],
[210, UniversalYAxisUnit.CONCENTRATION_UG_NORMAL_CUBIC_METER, '210 μg/Nm³'],
[
1000,
UniversalYAxisUnit.CONCENTRATION_UG_NORMAL_CUBIC_METER,
'1000 μg/Nm³',
],
[152, UniversalYAxisUnit.CONCENTRATION_MG_M3, '152 mg/m³'],
[64, UniversalYAxisUnit.CONCENTRATION_MG_NORMAL_CUBIC_METER, '64 mg/Nm³'],
[508, UniversalYAxisUnit.CONCENTRATION_G_M3, '508 g/m³'],
[1000, UniversalYAxisUnit.CONCENTRATION_G_M3, '1000 g/m³'],
[377, UniversalYAxisUnit.CONCENTRATION_G_NORMAL_CUBIC_METER, '377 g/Nm³'],
[1000, UniversalYAxisUnit.CONCENTRATION_G_NORMAL_CUBIC_METER, '1000 g/Nm³'],
[286, UniversalYAxisUnit.CONCENTRATION_MG_PER_DL, '286 mg/dL'],
[1000, UniversalYAxisUnit.CONCENTRATION_MG_PER_DL, '1000 mg/dL'],
[675, UniversalYAxisUnit.CONCENTRATION_MMOL_PER_L, '675 mmol/L'],
[1000, UniversalYAxisUnit.CONCENTRATION_MMOL_PER_L, '1000 mmol/L'],
])('formats concentration value %s %s as %s', (value, unit, expected) => {
expect(formatUniversalUnit(value, unit)).toBe(expected);
});
});
describe('Currency', () => {
test.each([
[812, UniversalYAxisUnit.CURRENCY_USD, '$812'],
[645, UniversalYAxisUnit.CURRENCY_GBP, '£645'],
[731, UniversalYAxisUnit.CURRENCY_EUR, '€731'],
[508, UniversalYAxisUnit.CURRENCY_JPY, '¥508'],
[963, UniversalYAxisUnit.CURRENCY_RUB, '₽963'],
[447, UniversalYAxisUnit.CURRENCY_UAH, '₴447'],
[592, UniversalYAxisUnit.CURRENCY_BRL, 'R$592'],
[375, UniversalYAxisUnit.CURRENCY_DKK, '375kr'],
[418, UniversalYAxisUnit.CURRENCY_ISK, '418kr'],
[536, UniversalYAxisUnit.CURRENCY_NOK, '536kr'],
[689, UniversalYAxisUnit.CURRENCY_SEK, '689kr'],
[724, UniversalYAxisUnit.CURRENCY_CZK, 'czk724'],
[381, UniversalYAxisUnit.CURRENCY_CHF, 'CHF381'],
[267, UniversalYAxisUnit.CURRENCY_PLN, 'PLN267'],
[154, UniversalYAxisUnit.CURRENCY_BTC, '฿154'],
[999, UniversalYAxisUnit.CURRENCY_MBTC, 'mBTC999'],
[423, UniversalYAxisUnit.CURRENCY_UBTC, 'μBTC423'],
[611, UniversalYAxisUnit.CURRENCY_ZAR, 'R611'],
[782, UniversalYAxisUnit.CURRENCY_INR, '₹782'],
[834, UniversalYAxisUnit.CURRENCY_KRW, '₩834'],
[455, UniversalYAxisUnit.CURRENCY_IDR, 'Rp455'],
[978, UniversalYAxisUnit.CURRENCY_PHP, 'PHP978'],
[366, UniversalYAxisUnit.CURRENCY_VND, '366đ'],
])('formats currency value %s %s as %s', (value, unit, expected) => {
expect(formatUniversalUnit(value, unit)).toBe(expected);
});
});
describe('Datetime', () => {
it('formats datetime units', () => {
expect(formatUniversalUnit(900, UniversalYAxisUnit.DATETIME_FROM_NOW)).toBe(
'56 years ago',
);
});
});
describe('Power/Electrical', () => {
test.each([
[715, UniversalYAxisUnit.POWER_WATT, '715 W'],
[1000, UniversalYAxisUnit.POWER_WATT, '1 kW'],
[1080, UniversalYAxisUnit.POWER_WATT, '1.08 kW'],
[438, UniversalYAxisUnit.POWER_KILOWATT, '438 kW'],
[1000, UniversalYAxisUnit.POWER_KILOWATT, '1 MW'],
[1080, UniversalYAxisUnit.POWER_KILOWATT, '1.08 MW'],
[582, UniversalYAxisUnit.POWER_MEGAWATT, '582 MW'],
[1000, UniversalYAxisUnit.POWER_MEGAWATT, '1 GW'],
[1080, UniversalYAxisUnit.POWER_MEGAWATT, '1.08 GW'],
[267, UniversalYAxisUnit.POWER_GIGAWATT, '267 GW'],
[853, UniversalYAxisUnit.POWER_MILLIWATT, '853 mW'],
[693, UniversalYAxisUnit.POWER_WATT_PER_SQUARE_METER, '693 W/m²'],
[544, UniversalYAxisUnit.POWER_VOLT_AMPERE, '544 VA'],
[812, UniversalYAxisUnit.POWER_KILOVOLT_AMPERE, '812 kVA'],
[478, UniversalYAxisUnit.POWER_VOLT_AMPERE_REACTIVE, '478 VAr'],
[365, UniversalYAxisUnit.POWER_KILOVOLT_AMPERE_REACTIVE, '365 kVAr'],
[629, UniversalYAxisUnit.POWER_WATT_HOUR, '629 Wh'],
[471, UniversalYAxisUnit.POWER_WATT_HOUR_PER_KG, '471 Wh/kg'],
[557, UniversalYAxisUnit.POWER_KILOWATT_HOUR, '557 kWh'],
[389, UniversalYAxisUnit.POWER_KILOWATT_MINUTE, '389 kW-Min'],
[642, UniversalYAxisUnit.POWER_AMPERE_HOUR, '642 Ah'],
[731, UniversalYAxisUnit.POWER_KILOAMPERE_HOUR, '731 kAh'],
[815, UniversalYAxisUnit.POWER_MILLIAMPERE_HOUR, '815 mAh'],
[963, UniversalYAxisUnit.POWER_JOULE, '963 J'],
[506, UniversalYAxisUnit.POWER_ELECTRON_VOLT, '506 eV'],
[298, UniversalYAxisUnit.POWER_AMPERE, '298 A'],
[654, UniversalYAxisUnit.POWER_KILOAMPERE, '654 kA'],
[187, UniversalYAxisUnit.POWER_MILLIAMPERE, '187 mA'],
[472, UniversalYAxisUnit.POWER_VOLT, '472 V'],
[538, UniversalYAxisUnit.POWER_KILOVOLT, '538 kV'],
[226, UniversalYAxisUnit.POWER_MILLIVOLT, '226 mV'],
[592, UniversalYAxisUnit.POWER_DECIBEL_MILLIWATT, '592 dBm'],
[333, UniversalYAxisUnit.POWER_OHM, '333 Ω'],
[447, UniversalYAxisUnit.POWER_KILOOHM, '447 kΩ'],
[781, UniversalYAxisUnit.POWER_MEGAOHM, '781 MΩ'],
[650, UniversalYAxisUnit.POWER_FARAD, '650 F'],
[512, UniversalYAxisUnit.POWER_MICROFARAD, '512 µF'],
[478, UniversalYAxisUnit.POWER_NANOFARAD, '478 nF'],
[341, UniversalYAxisUnit.POWER_PICOFARAD, '341 pF'],
[129, UniversalYAxisUnit.POWER_FEMTOFARAD, '129 fF'],
[904, UniversalYAxisUnit.POWER_HENRY, '904 H'],
[1000, UniversalYAxisUnit.POWER_HENRY, '1 kH'],
[275, UniversalYAxisUnit.POWER_MILLIHENRY, '275 mH'],
[618, UniversalYAxisUnit.POWER_MICROHENRY, '618 µH'],
[1000, UniversalYAxisUnit.POWER_MICROHENRY, '1 mH'],
[1080, UniversalYAxisUnit.POWER_MICROHENRY, '1.08 mH'],
[459, UniversalYAxisUnit.POWER_LUMENS, '459 Lm'],
[1000, UniversalYAxisUnit.POWER_LUMENS, '1 kLm'],
[1080, UniversalYAxisUnit.POWER_LUMENS, '1.08 kLm'],
])('formats power value %s %s as %s', (value, unit, expected) => {
expect(formatUniversalUnit(value, unit)).toBe(expected);
});
});
describe('Flow', () => {
test.each([
[512, UniversalYAxisUnit.FLOW_GALLONS_PER_MINUTE, '512 gpm'],
[1000, UniversalYAxisUnit.FLOW_GALLONS_PER_MINUTE, '1000 gpm'],
[678, UniversalYAxisUnit.FLOW_CUBIC_METERS_PER_SECOND, '678 cms'],
[1000, UniversalYAxisUnit.FLOW_CUBIC_METERS_PER_SECOND, '1000 cms'],
[245, UniversalYAxisUnit.FLOW_CUBIC_FEET_PER_SECOND, '245 cfs'],
[389, UniversalYAxisUnit.FLOW_CUBIC_FEET_PER_MINUTE, '389 cfm'],
[1000, UniversalYAxisUnit.FLOW_CUBIC_FEET_PER_MINUTE, '1000 cfm'],
[731, UniversalYAxisUnit.FLOW_LITERS_PER_HOUR, '731 L/h'],
[1000, UniversalYAxisUnit.FLOW_LITERS_PER_HOUR, '1000 L/h'],
[864, UniversalYAxisUnit.FLOW_LITERS_PER_MINUTE, '864 L/min'],
[1000, UniversalYAxisUnit.FLOW_LITERS_PER_MINUTE, '1000 L/min'],
[150, UniversalYAxisUnit.FLOW_MILLILITERS_PER_MINUTE, '150 mL/min'],
[1000, UniversalYAxisUnit.FLOW_MILLILITERS_PER_MINUTE, '1000 mL/min'],
[947, UniversalYAxisUnit.FLOW_LUX, '947 lux'],
[1000, UniversalYAxisUnit.FLOW_LUX, '1000 lux'],
])('formats flow value %s %s as %s', (value, unit, expected) => {
expect(formatUniversalUnit(value, unit)).toBe(expected);
});
});
describe('Force', () => {
test.each([
[845, UniversalYAxisUnit.FORCE_NEWTON_METERS, '845 Nm'],
[1000, UniversalYAxisUnit.FORCE_NEWTON_METERS, '1 kNm'],
[1080, UniversalYAxisUnit.FORCE_NEWTON_METERS, '1.08 kNm'],
[268, UniversalYAxisUnit.FORCE_KILONEWTON_METERS, '268 kNm'],
[1000, UniversalYAxisUnit.FORCE_KILONEWTON_METERS, '1 MNm'],
[1080, UniversalYAxisUnit.FORCE_KILONEWTON_METERS, '1.08 MNm'],
[593, UniversalYAxisUnit.FORCE_NEWTONS, '593 N'],
[1000, UniversalYAxisUnit.FORCE_KILONEWTONS, '1 MN'],
[1080, UniversalYAxisUnit.FORCE_KILONEWTONS, '1.08 MN'],
])('formats force value %s %s as %s', (value, unit, expected) => {
expect(formatUniversalUnit(value, unit)).toBe(expected);
});
});
describe('Mass', () => {
test.each([
[120, UniversalYAxisUnit.MASS_MILLIGRAM, '120 mg'],
[120000, UniversalYAxisUnit.MASS_MILLIGRAM, '120 g'],
[987, UniversalYAxisUnit.MASS_GRAM, '987 g'],
[1020, UniversalYAxisUnit.MASS_GRAM, '1.02 kg'],
[456, UniversalYAxisUnit.MASS_POUND, '456 lb'],
[321, UniversalYAxisUnit.MASS_KILOGRAM, '321 kg'],
[654, UniversalYAxisUnit.MASS_METRIC_TON, '654 t'],
])('formats mass value %s %s as %s', (value, unit, expected) => {
expect(formatUniversalUnit(value, unit)).toBe(expected);
});
});
describe('Length', () => {
test.each([
[88, UniversalYAxisUnit.LENGTH_MILLIMETER, '88 mm'],
[100, UniversalYAxisUnit.LENGTH_MILLIMETER, '100 mm'],
[1000, UniversalYAxisUnit.LENGTH_MILLIMETER, '1 m'],
[177, UniversalYAxisUnit.LENGTH_INCH, '177 in'],
[266, UniversalYAxisUnit.LENGTH_FOOT, '266 ft'],
[355, UniversalYAxisUnit.LENGTH_METER, '355 m'],
[355000, UniversalYAxisUnit.LENGTH_METER, '355 km'],
[444, UniversalYAxisUnit.LENGTH_KILOMETER, '444 km'],
[533, UniversalYAxisUnit.LENGTH_MILE, '533 mi'],
])('formats length value %s %s as %s', (value, unit, expected) => {
expect(formatUniversalUnit(value, unit)).toBe(expected);
});
});
describe('Pressure', () => {
test.each([
[45, UniversalYAxisUnit.PRESSURE_MILLIBAR, '45 mbar'],
[1013, UniversalYAxisUnit.PRESSURE_MILLIBAR, '1.01 bar'],
[27, UniversalYAxisUnit.PRESSURE_BAR, '27 bar'],
[62, UniversalYAxisUnit.PRESSURE_KILOBAR, '62 kbar'],
[845, UniversalYAxisUnit.PRESSURE_PASCAL, '845 Pa'],
[540, UniversalYAxisUnit.PRESSURE_HECTOPASCAL, '540 hPa'],
[378, UniversalYAxisUnit.PRESSURE_KILOPASCAL, '378 kPa'],
[29, UniversalYAxisUnit.PRESSURE_INCHES_HG, '29 "Hg'],
[65, UniversalYAxisUnit.PRESSURE_PSI, '65psi'],
])('formats pressure value %s %s as %s', (value, unit, expected) => {
expect(formatUniversalUnit(value, unit)).toBe(expected);
});
});
describe('Radiation', () => {
test.each([
[452, UniversalYAxisUnit.RADIATION_BECQUEREL, '452 Bq'],
[37, UniversalYAxisUnit.RADIATION_CURIE, '37 Ci'],
[128, UniversalYAxisUnit.RADIATION_GRAY, '128 Gy'],
[512, UniversalYAxisUnit.RADIATION_RAD, '512 rad'],
[256, UniversalYAxisUnit.RADIATION_SIEVERT, '256 Sv'],
[640, UniversalYAxisUnit.RADIATION_MILLISIEVERT, '640 mSv'],
[875, UniversalYAxisUnit.RADIATION_MICROSIEVERT, '875 µSv'],
[875000, UniversalYAxisUnit.RADIATION_MICROSIEVERT, '875 mSv'],
[92, UniversalYAxisUnit.RADIATION_REM, '92 rem'],
[715, UniversalYAxisUnit.RADIATION_EXPOSURE_C_PER_KG, '715 C/kg'],
[833, UniversalYAxisUnit.RADIATION_ROENTGEN, '833 R'],
[468, UniversalYAxisUnit.RADIATION_SIEVERT_PER_HOUR, '468 Sv/h'],
[590, UniversalYAxisUnit.RADIATION_MILLISIEVERT_PER_HOUR, '590 mSv/h'],
[712, UniversalYAxisUnit.RADIATION_MICROSIEVERT_PER_HOUR, '712 µSv/h'],
])('formats radiation value %s %s as %s', (value, unit, expected) => {
expect(formatUniversalUnit(value, unit)).toBe(expected);
});
});
describe('Rotation Speed', () => {
test.each([
[345, UniversalYAxisUnit.ROTATION_SPEED_REVOLUTIONS_PER_MINUTE, '345 rpm'],
[789, UniversalYAxisUnit.ROTATION_SPEED_HERTZ, '789 Hz'],
[789000, UniversalYAxisUnit.ROTATION_SPEED_HERTZ, '789 kHz'],
[213, UniversalYAxisUnit.ROTATION_SPEED_RADIANS_PER_SECOND, '213 rad/s'],
[654, UniversalYAxisUnit.ROTATION_SPEED_DEGREES_PER_SECOND, '654 °/s'],
])('formats rotation speed value %s %s as %s', (value, unit, expected) => {
expect(formatUniversalUnit(value, unit)).toBe(expected);
});
});
describe('Temperature', () => {
test.each([
[37, UniversalYAxisUnit.TEMPERATURE_CELSIUS, '37 °C'],
[451, UniversalYAxisUnit.TEMPERATURE_FAHRENHEIT, '451 °F'],
[310, UniversalYAxisUnit.TEMPERATURE_KELVIN, '310 K'],
])('formats temperature value %s %s as %s', (value, unit, expected) => {
expect(formatUniversalUnit(value, unit)).toBe(expected);
});
});
describe('Velocity', () => {
test.each([
[900, UniversalYAxisUnit.VELOCITY_METERS_PER_SECOND, '900 m/s'],
[456, UniversalYAxisUnit.VELOCITY_KILOMETERS_PER_HOUR, '456 km/h'],
[789, UniversalYAxisUnit.VELOCITY_MILES_PER_HOUR, '789 mph'],
[222, UniversalYAxisUnit.VELOCITY_KNOT, '222 kn'],
])('formats velocity value %s %s as %s', (value, unit, expected) => {
expect(formatUniversalUnit(value, unit)).toBe(expected);
});
});
describe('Volume', () => {
test.each([
[1200, UniversalYAxisUnit.VOLUME_MILLILITER, '1.2 L'],
[9000000, UniversalYAxisUnit.VOLUME_MILLILITER, '9 kL'],
[9, UniversalYAxisUnit.VOLUME_LITER, '9 L'],
[9000, UniversalYAxisUnit.VOLUME_LITER, '9 kL'],
[9000000, UniversalYAxisUnit.VOLUME_LITER, '9 ML'],
[9000000000, UniversalYAxisUnit.VOLUME_LITER, '9 GL'],
[9000000000000, UniversalYAxisUnit.VOLUME_LITER, '9 TL'],
[9000000000000000, UniversalYAxisUnit.VOLUME_LITER, '9 PL'],
[9010000000000000000, UniversalYAxisUnit.VOLUME_LITER, '9.01 EL'],
[9020000000000000000000, UniversalYAxisUnit.VOLUME_LITER, '9.02 ZL'],
[9030000000000000000000000, UniversalYAxisUnit.VOLUME_LITER, '9.03 YL'],
[900, UniversalYAxisUnit.VOLUME_CUBIC_METER, '900 m³'],
[
9000000000000000000000000000000,
UniversalYAxisUnit.VOLUME_CUBIC_METER,
'9e+30 m³',
],
[900, UniversalYAxisUnit.VOLUME_NORMAL_CUBIC_METER, '900 Nm³'],
[
9000000000000000000000000000000,
UniversalYAxisUnit.VOLUME_NORMAL_CUBIC_METER,
'9e+30 Nm³',
],
[900, UniversalYAxisUnit.VOLUME_CUBIC_DECIMETER, '900 dm³'],
[
9000000000000000000000000000000,
UniversalYAxisUnit.VOLUME_CUBIC_DECIMETER,
'9e+30 dm³',
],
[900, UniversalYAxisUnit.VOLUME_GALLON, '900 gal'],
[
9000000000000000000000000000000,
UniversalYAxisUnit.VOLUME_GALLON,
'9e+30 gal',
],
])('formats volume value %s %s as %s', (value, unit, expected) => {
expect(formatUniversalUnit(value, unit)).toBe(expected);
});
});
describe('Boolean', () => {
it('formats boolean units', () => {
expect(formatUniversalUnit(1, UniversalYAxisUnit.TRUE_FALSE)).toBe('True');
expect(formatUniversalUnit(1, UniversalYAxisUnit.YES_NO)).toBe('Yes');
expect(formatUniversalUnit(1, UniversalYAxisUnit.ON_OFF)).toBe('On');
});
});
});
describe('Mapping Validator', () => {
it('validates that all units have a mapping', () => {
// Each universal unit should have a mapping to a 1:1 Grafana unit in UniversalUnitToGrafanaUnit or an additional mapping in AdditionalLabelsMappingForGrafanaUnits
const units = Object.values(UniversalYAxisUnit);
expect(
units.every((unit) => {
const hasBaseMapping = unit in UniversalUnitToGrafanaUnit;
const hasAdditionalMapping = unit in AdditionalLabelsMappingForGrafanaUnits;
const hasMapping = hasBaseMapping || hasAdditionalMapping;
if (!hasMapping) {
throw new Error(`Unit ${unit} does not have a mapping`);
}
return hasMapping;
}),
).toBe(true);
});
});

View File

@@ -1,6 +1,8 @@
import { UniversalYAxisUnit } from '../types';
import {
getUniversalNameFromMetricUnit,
mapMetricUnitToUniversalUnit,
mergeCategories,
} from '../utils';
describe('YAxisUnitSelector utils', () => {
@@ -36,4 +38,43 @@ describe('YAxisUnitSelector utils', () => {
expect(getUniversalNameFromMetricUnit('s')).toBe('Seconds (s)');
});
});
describe('mergeCategories', () => {
it('merges categories correctly', () => {
const categories1 = [
{
name: 'Data',
units: [
{ name: 'bytes', id: UniversalYAxisUnit.BYTES },
{ name: 'kilobytes', id: UniversalYAxisUnit.KILOBYTES },
],
},
];
const categories2 = [
{
name: 'Data',
units: [{ name: 'bits', id: UniversalYAxisUnit.BITS }],
},
{
name: 'Time',
units: [{ name: 'seconds', id: UniversalYAxisUnit.SECONDS }],
},
];
const mergedCategories = mergeCategories(categories1, categories2);
expect(mergedCategories).toEqual([
{
name: 'Data',
units: [
{ name: 'bytes', id: UniversalYAxisUnit.BYTES },
{ name: 'kilobytes', id: UniversalYAxisUnit.KILOBYTES },
{ name: 'bits', id: UniversalYAxisUnit.BITS },
],
},
{
name: 'Time',
units: [{ name: 'seconds', id: UniversalYAxisUnit.SECONDS }],
},
]);
});
});
});

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,90 @@
import { formattedValueToString, getValueFormat } from '@grafana/data';
import { PrecisionOption, PrecisionOptionsEnum } from 'components/Graph/types';
import { formatDecimalWithLeadingZeros } from 'components/Graph/utils';
import {
AdditionalLabelsMappingForGrafanaUnits,
CUSTOM_SCALING_FAMILIES,
UniversalUnitToGrafanaUnit,
} from 'components/YAxisUnitSelector/constants';
import { UniversalYAxisUnit } from 'components/YAxisUnitSelector/types';
function scaleValue(
value: number,
unit: UniversalYAxisUnit,
family: UniversalYAxisUnit[],
factor: number,
): { value: number; label: string } {
let idx = family.indexOf(unit);
// If the unit is not in the family, return the unit with the additional label
if (idx === -1) {
return { value, label: AdditionalLabelsMappingForGrafanaUnits[unit] || '' };
}
// Scale the value up or down to the nearest unit in the family
let scaled = value;
// Scale up
while (scaled >= factor && idx < family.length - 1) {
scaled /= factor;
idx += 1;
}
// Scale down
while (scaled < 1 && idx > 0) {
scaled *= factor;
idx -= 1;
}
// Return the scaled value and the label of the nearest unit in the family
return {
value: scaled,
label: AdditionalLabelsMappingForGrafanaUnits[family[idx]] || '',
};
}
export function formatUniversalUnit(
value: number,
unit: UniversalYAxisUnit,
precision: PrecisionOption = PrecisionOptionsEnum.FULL,
decimals: number | undefined = undefined,
): string {
// Check if this unit belongs to a family that needs custom scaling
const family = CUSTOM_SCALING_FAMILIES.find((family) =>
family.units.includes(unit),
);
if (family) {
const scaled = scaleValue(value, unit, family.units, family.scaleFactor);
const formatter = getValueFormat(scaled.label);
const formatted = formatter(scaled.value, decimals);
if (formatted.text && formatted.text.includes('.')) {
formatted.text = formatDecimalWithLeadingZeros(
parseFloat(formatted.text),
precision,
);
}
return `${formatted.text} ${scaled.label}`;
}
// Use Grafana formatting with custom label mappings
const grafanaFormat = UniversalUnitToGrafanaUnit[unit];
if (grafanaFormat) {
const formatter = getValueFormat(grafanaFormat);
const formatted = formatter(value, decimals);
if (formatted.text && formatted.text.includes('.')) {
formatted.text = formatDecimalWithLeadingZeros(
parseFloat(formatted.text),
precision,
);
}
return formattedValueToString(formatted);
}
// Fallback to short format for other units
const formatter = getValueFormat('short');
const formatted = formatter(value, decimals);
if (formatted.text && formatted.text.includes('.')) {
formatted.text = formatDecimalWithLeadingZeros(
parseFloat(formatted.text),
precision,
);
}
return `${formatted.text} ${unit}`;
}

View File

@@ -5,11 +5,11 @@ export interface YAxisUnitSelectorProps {
loading?: boolean;
disabled?: boolean;
'data-testid'?: string;
source: YAxisSource;
}
export enum UniversalYAxisUnit {
// Time
WEEKS = 'wk',
DAYS = 'd',
HOURS = 'h',
MINUTES = 'min',
@@ -17,6 +17,14 @@ export enum UniversalYAxisUnit {
MICROSECONDS = 'us',
MILLISECONDS = 'ms',
NANOSECONDS = 'ns',
DURATION_MS = 'dtdurationms',
DURATION_S = 'dtdurations',
DURATION_HMS = 'dthms',
DURATION_DHMS = 'dtdhms',
TIMETICKS = 'timeticks',
CLOCK_MS = 'clockms',
CLOCK_S = 'clocks',
TIME_HERTZ = 'hertz',
// Data
BYTES = 'By',
@@ -29,6 +37,17 @@ export enum UniversalYAxisUnit {
ZETTABYTES = 'ZBy',
YOTTABYTES = 'YBy',
// Binary (IEC) Data
BYTES_IEC = 'bytes',
KIBIBYTES = 'KiBy',
MEBIBYTES = 'MiBy',
GIBIBYTES = 'GiBy',
TEBIBYTES = 'TiBy',
PEBIBYTES = 'PiBy',
EXBIBYTES = 'EiBy',
ZEBIBYTES = 'ZiBy',
YOBIBYTES = 'YiBy',
// Data Rate
BYTES_SECOND = 'By/s',
KILOBYTES_SECOND = 'kBy/s',
@@ -39,9 +58,21 @@ export enum UniversalYAxisUnit {
EXABYTES_SECOND = 'EBy/s',
ZETTABYTES_SECOND = 'ZBy/s',
YOTTABYTES_SECOND = 'YBy/s',
DATA_RATE_PACKETS_PER_SECOND = 'pps',
// Binary (IEC) Data Rate
KIBIBYTES_SECOND = 'KiBy/s',
MEBIBYTES_SECOND = 'MiBy/s',
GIBIBYTES_SECOND = 'GiBy/s',
TEBIBYTES_SECOND = 'TiBy/s',
PEBIBYTES_SECOND = 'PiBy/s',
EXBIBYTES_SECOND = 'EiBy/s',
ZEBIBYTES_SECOND = 'ZiBy/s',
YOBIBYTES_SECOND = 'YiBy/s',
// Bits
BITS = 'bit',
BITS_IEC = 'bits',
KILOBITS = 'kbit',
MEGABITS = 'Mbit',
GIGABITS = 'Gbit',
@@ -62,6 +93,16 @@ export enum UniversalYAxisUnit {
ZETTABITS_SECOND = 'Zbit/s',
YOTTABITS_SECOND = 'Ybit/s',
// Binary (IEC) Bit Rate
KIBIBITS_SECOND = 'Kibit/s',
MEBIBITS_SECOND = 'Mibit/s',
GIBIBITS_SECOND = 'Gibit/s',
TEBIBITS_SECOND = 'Tibit/s',
PEBIBITS_SECOND = 'Pibit/s',
EXBIBITS_SECOND = 'Eibit/s',
ZEBIBITS_SECOND = 'Zibit/s',
YOBIBITS_SECOND = 'Yibit/s',
// Count
COUNT = '{count}',
COUNT_SECOND = '{count}/s',
@@ -87,7 +128,231 @@ export enum UniversalYAxisUnit {
// Percent
PERCENT = '%',
PERCENT_UNIT = 'percentunit',
// Boolean
TRUE_FALSE = '{bool}',
YES_NO = '{bool_yn}',
ON_OFF = 'bool_on_off',
// None
NONE = '1',
// Hash rate
HASH_RATE_HASHES_PER_SECOND = 'Hs',
HASH_RATE_KILOHASHES_PER_SECOND = 'KHs',
HASH_RATE_MEGAHASHES_PER_SECOND = 'MHs',
HASH_RATE_GIGAHASHES_PER_SECOND = 'GHs',
HASH_RATE_TERAHASHES_PER_SECOND = 'THs',
HASH_RATE_PETAHASHES_PER_SECOND = 'PHs',
HASH_RATE_EXAHASHES_PER_SECOND = 'EHs',
// Miscellaneous
MISC_STRING = 'string',
MISC_SHORT = 'short',
MISC_HUMIDITY = 'humidity',
MISC_DECIBEL = 'dB',
MISC_HEXADECIMAL = 'hex',
MISC_HEXADECIMAL_0X = 'hex0x',
MISC_SCIENTIFIC_NOTATION = 'sci',
MISC_LOCALE_FORMAT = 'locale',
MISC_PIXELS = 'pixel',
// Acceleration
ACCELERATION_METERS_PER_SECOND_SQUARED = 'accMS2',
ACCELERATION_FEET_PER_SECOND_SQUARED = 'accFS2',
ACCELERATION_G_UNIT = 'accG',
// Angular
ANGULAR_DEGREE = 'degree',
ANGULAR_RADIAN = 'radian',
ANGULAR_GRADIAN = 'grad',
ANGULAR_ARC_MINUTE = 'arcmin',
ANGULAR_ARC_SECOND = 'arcsec',
// Area
AREA_SQUARE_METERS = 'areaM2',
AREA_SQUARE_FEET = 'areaF2',
AREA_SQUARE_MILES = 'areaMI2',
// FLOPs
FLOPS_FLOPS = 'flops',
FLOPS_MFLOPS = 'mflops',
FLOPS_GFLOPS = 'gflops',
FLOPS_TFLOPS = 'tflops',
FLOPS_PFLOPS = 'pflops',
FLOPS_EFLOPS = 'eflops',
FLOPS_ZFLOPS = 'zflops',
FLOPS_YFLOPS = 'yflops',
// Concentration
CONCENTRATION_PPM = 'ppm',
CONCENTRATION_PPB = 'conppb',
CONCENTRATION_NG_M3 = 'conngm3',
CONCENTRATION_NG_NORMAL_CUBIC_METER = 'conngNm3',
CONCENTRATION_UG_M3 = 'conμgm3',
CONCENTRATION_UG_NORMAL_CUBIC_METER = 'conμgNm3',
CONCENTRATION_MG_M3 = 'conmgm3',
CONCENTRATION_MG_NORMAL_CUBIC_METER = 'conmgNm3',
CONCENTRATION_G_M3 = 'congm3',
CONCENTRATION_G_NORMAL_CUBIC_METER = 'congNm3',
CONCENTRATION_MG_PER_DL = 'conmgdL',
CONCENTRATION_MMOL_PER_L = 'conmmolL',
// Currency
CURRENCY_USD = 'currencyUSD',
CURRENCY_GBP = 'currencyGBP',
CURRENCY_EUR = 'currencyEUR',
CURRENCY_JPY = 'currencyJPY',
CURRENCY_RUB = 'currencyRUB',
CURRENCY_UAH = 'currencyUAH',
CURRENCY_BRL = 'currencyBRL',
CURRENCY_DKK = 'currencyDKK',
CURRENCY_ISK = 'currencyISK',
CURRENCY_NOK = 'currencyNOK',
CURRENCY_SEK = 'currencySEK',
CURRENCY_CZK = 'currencyCZK',
CURRENCY_CHF = 'currencyCHF',
CURRENCY_PLN = 'currencyPLN',
CURRENCY_BTC = 'currencyBTC',
CURRENCY_MBTC = 'currencymBTC',
CURRENCY_UBTC = 'currencyμBTC',
CURRENCY_ZAR = 'currencyZAR',
CURRENCY_INR = 'currencyINR',
CURRENCY_KRW = 'currencyKRW',
CURRENCY_IDR = 'currencyIDR',
CURRENCY_PHP = 'currencyPHP',
CURRENCY_VND = 'currencyVND',
// Datetime
DATETIME_ISO = 'dateTimeAsIso',
DATETIME_ISO_NO_DATE_IF_TODAY = 'dateTimeAsIsoNoDateIfToday',
DATETIME_US = 'dateTimeAsUS',
DATETIME_US_NO_DATE_IF_TODAY = 'dateTimeAsUSNoDateIfToday',
DATETIME_LOCAL = 'dateTimeAsLocal',
DATETIME_LOCAL_NO_DATE_IF_TODAY = 'dateTimeAsLocalNoDateIfToday',
DATETIME_SYSTEM = 'dateTimeAsSystem',
DATETIME_FROM_NOW = 'dateTimeFromNow',
// Power/Electrical
POWER_WATT = 'watt',
POWER_KILOWATT = 'kwatt',
POWER_MEGAWATT = 'megwatt',
POWER_GIGAWATT = 'gwatt',
POWER_MILLIWATT = 'mwatt',
POWER_WATT_PER_SQUARE_METER = 'Wm2',
POWER_VOLT_AMPERE = 'voltamp',
POWER_KILOVOLT_AMPERE = 'kvoltamp',
POWER_VOLT_AMPERE_REACTIVE = 'voltampreact',
POWER_KILOVOLT_AMPERE_REACTIVE = 'kvoltampreact',
POWER_WATT_HOUR = 'watth',
POWER_WATT_HOUR_PER_KG = 'watthperkg',
POWER_KILOWATT_HOUR = 'kwatth',
POWER_KILOWATT_MINUTE = 'kwattm',
POWER_AMPERE_HOUR = 'amph',
POWER_KILOAMPERE_HOUR = 'kamph',
POWER_MILLIAMPERE_HOUR = 'mamph',
POWER_JOULE = 'joule',
POWER_ELECTRON_VOLT = 'ev',
POWER_AMPERE = 'amp',
POWER_KILOAMPERE = 'kamp',
POWER_MILLIAMPERE = 'mamp',
POWER_VOLT = 'volt',
POWER_KILOVOLT = 'kvolt',
POWER_MILLIVOLT = 'mvolt',
POWER_DECIBEL_MILLIWATT = 'dBm',
POWER_OHM = 'ohm',
POWER_KILOOHM = 'kohm',
POWER_MEGAOHM = 'Mohm',
POWER_FARAD = 'farad',
POWER_MICROFARAD = 'µfarad',
POWER_NANOFARAD = 'nfarad',
POWER_PICOFARAD = 'pfarad',
POWER_FEMTOFARAD = 'ffarad',
POWER_HENRY = 'henry',
POWER_MILLIHENRY = 'mhenry',
POWER_MICROHENRY = 'µhenry',
POWER_LUMENS = 'lumens',
// Flow
FLOW_GALLONS_PER_MINUTE = 'flowgpm',
FLOW_CUBIC_METERS_PER_SECOND = 'flowcms',
FLOW_CUBIC_FEET_PER_SECOND = 'flowcfs',
FLOW_CUBIC_FEET_PER_MINUTE = 'flowcfm',
FLOW_LITERS_PER_HOUR = 'litreh',
FLOW_LITERS_PER_MINUTE = 'flowlpm',
FLOW_MILLILITERS_PER_MINUTE = 'flowmlpm',
FLOW_LUX = 'lux',
// Force
FORCE_NEWTON_METERS = 'forceNm',
FORCE_KILONEWTON_METERS = 'forcekNm',
FORCE_NEWTONS = 'forceN',
FORCE_KILONEWTONS = 'forcekN',
// Mass
MASS_MILLIGRAM = 'massmg',
MASS_GRAM = 'massg',
MASS_POUND = 'masslb',
MASS_KILOGRAM = 'masskg',
MASS_METRIC_TON = 'masst',
// Length
LENGTH_MILLIMETER = 'lengthmm',
LENGTH_INCH = 'lengthin',
LENGTH_FOOT = 'lengthft',
LENGTH_METER = 'lengthm',
LENGTH_KILOMETER = 'lengthkm',
LENGTH_MILE = 'lengthmi',
// Pressure
PRESSURE_MILLIBAR = 'pressurembar',
PRESSURE_BAR = 'pressurebar',
PRESSURE_KILOBAR = 'pressurekbar',
PRESSURE_PASCAL = 'pressurepa',
PRESSURE_HECTOPASCAL = 'pressurehpa',
PRESSURE_KILOPASCAL = 'pressurekpa',
PRESSURE_INCHES_HG = 'pressurehg',
PRESSURE_PSI = 'pressurepsi',
// Radiation
RADIATION_BECQUEREL = 'radbq',
RADIATION_CURIE = 'radci',
RADIATION_GRAY = 'radgy',
RADIATION_RAD = 'radrad',
RADIATION_SIEVERT = 'radsv',
RADIATION_MILLISIEVERT = 'radmsv',
RADIATION_MICROSIEVERT = 'radusv',
RADIATION_REM = 'radrem',
RADIATION_EXPOSURE_C_PER_KG = 'radexpckg',
RADIATION_ROENTGEN = 'radr',
RADIATION_SIEVERT_PER_HOUR = 'radsvh',
RADIATION_MILLISIEVERT_PER_HOUR = 'radmsvh',
RADIATION_MICROSIEVERT_PER_HOUR = 'radusvh',
// Rotation speed
ROTATION_SPEED_REVOLUTIONS_PER_MINUTE = 'rotrpm',
ROTATION_SPEED_HERTZ = 'rothz',
ROTATION_SPEED_RADIANS_PER_SECOND = 'rotrads',
ROTATION_SPEED_DEGREES_PER_SECOND = 'rotdegs',
// Temperature
TEMPERATURE_CELSIUS = 'celsius',
TEMPERATURE_FAHRENHEIT = 'fahrenheit',
TEMPERATURE_KELVIN = 'kelvin',
// Velocity
VELOCITY_METERS_PER_SECOND = 'velocityms',
VELOCITY_KILOMETERS_PER_HOUR = 'velocitykmh',
VELOCITY_MILES_PER_HOUR = 'velocitymph',
VELOCITY_KNOT = 'velocityknot',
// Volume
VOLUME_MILLILITER = 'mlitre',
VOLUME_LITER = 'litre',
VOLUME_CUBIC_METER = 'm3',
VOLUME_NORMAL_CUBIC_METER = 'Nm3',
VOLUME_CUBIC_DECIMETER = 'dm3',
VOLUME_GALLON = 'gallons',
}
export enum YAxisUnit {
@@ -293,6 +558,15 @@ export enum YAxisUnit {
UCUM_PEBIBYTES = 'PiBy',
OPEN_METRICS_PEBIBYTES = 'pebibytes',
UCUM_EXBIBYTES = 'EiBy',
OPEN_METRICS_EXBIBYTES = 'exbibytes',
UCUM_ZEBIBYTES = 'ZiBy',
OPEN_METRICS_ZEBIBYTES = 'zebibytes',
UCUM_YOBIBYTES = 'YiBy',
OPEN_METRICS_YOBIBYTES = 'yobibytes',
UCUM_KIBIBYTES_SECOND = 'KiBy/s',
OPEN_METRICS_KIBIBYTES_SECOND = 'kibibytes_per_second',
@@ -323,6 +597,24 @@ export enum YAxisUnit {
UCUM_PEBIBITS_SECOND = 'Pibit/s',
OPEN_METRICS_PEBIBITS_SECOND = 'pebibits_per_second',
UCUM_EXBIBYTES_SECOND = 'EiBy/s',
OPEN_METRICS_EXBIBYTES_SECOND = 'exbibytes_per_second',
UCUM_EXBIBITS_SECOND = 'Eibit/s',
OPEN_METRICS_EXBIBITS_SECOND = 'exbibits_per_second',
UCUM_ZEBIBYTES_SECOND = 'ZiBy/s',
OPEN_METRICS_ZEBIBYTES_SECOND = 'zebibytes_per_second',
UCUM_ZEBIBITS_SECOND = 'Zibit/s',
OPEN_METRICS_ZEBIBITS_SECOND = 'zebibits_per_second',
UCUM_YOBIBYTES_SECOND = 'YiBy/s',
OPEN_METRICS_YOBIBYTES_SECOND = 'yobibytes_per_second',
UCUM_YOBIBITS_SECOND = 'Yibit/s',
OPEN_METRICS_YOBIBITS_SECOND = 'yobibits_per_second',
UCUM_TRUE_FALSE = '{bool}',
OPEN_METRICS_TRUE_FALSE = 'boolean_true_false',
@@ -364,3 +656,27 @@ export enum YAxisUnit {
OPEN_METRICS_PERCENT_UNIT = 'percentunit',
}
export interface ScaledValue {
value: number;
label: string;
}
export interface UnitFamilyConfig {
units: UniversalYAxisUnit[];
scaleFactor: number;
}
export interface YAxisCategory {
name: string;
units: {
name: string;
id: UniversalYAxisUnit;
}[];
}
export enum YAxisSource {
ALERTS = 'alerts',
DASHBOARDS = 'dashboards',
EXPLORER = 'explorer',
}

View File

@@ -1,5 +1,11 @@
import { UniversalYAxisUnitMappings, Y_AXIS_UNIT_NAMES } from './constants';
import { UniversalYAxisUnit, YAxisUnit } from './types';
import { ADDITIONAL_Y_AXIS_CATEGORIES, BASE_Y_AXIS_CATEGORIES } from './data';
import {
UniversalYAxisUnit,
YAxisCategory,
YAxisSource,
YAxisUnit,
} from './types';
export const mapMetricUnitToUniversalUnit = (
unit: string | undefined,
@@ -9,7 +15,7 @@ export const mapMetricUnitToUniversalUnit = (
}
const universalUnit = Object.values(UniversalYAxisUnit).find(
(u) => UniversalYAxisUnitMappings[u].has(unit as YAxisUnit) || unit === u,
(u) => UniversalYAxisUnitMappings[u]?.has(unit as YAxisUnit) || unit === u,
);
return universalUnit || (unit as UniversalYAxisUnit) || null;
@@ -31,3 +37,44 @@ export const getUniversalNameFromMetricUnit = (
return universalName || unit || '-';
};
export function isUniversalUnit(format: string): boolean {
return Object.values(UniversalYAxisUnit).includes(
format as UniversalYAxisUnit,
);
}
export function mergeCategories(
categories1: YAxisCategory[],
categories2: YAxisCategory[],
): YAxisCategory[] {
const mapOfCategories = new Map<string, YAxisCategory>();
categories1.forEach((category) => {
mapOfCategories.set(category.name, category);
});
categories2.forEach((category) => {
if (mapOfCategories.has(category.name)) {
mapOfCategories.set(category.name, {
name: category.name,
units: [
...(mapOfCategories.get(category.name)?.units ?? []),
...category.units,
],
});
} else {
mapOfCategories.set(category.name, category);
}
});
return Array.from(mapOfCategories.values());
}
export function getYAxisCategories(source: YAxisSource): YAxisCategory[] {
if (source !== YAxisSource.DASHBOARDS) {
return BASE_Y_AXIS_CATEGORIES;
}
return mergeCategories(BASE_Y_AXIS_CATEGORIES, ADDITIONAL_Y_AXIS_CATEGORIES);
}

View File

@@ -1,7 +1,8 @@
import { Button, Flex, Switch, Typography } from 'antd';
import { BaseOptionType, DefaultOptionType, SelectProps } from 'antd/es/select';
import { getInvolvedQueriesInTraceOperator } from 'components/QueryBuilderV2/QueryV2/TraceOperator/utils/utils';
import { Y_AXIS_CATEGORIES } from 'components/YAxisUnitSelector/constants';
import { YAxisSource } from 'components/YAxisUnitSelector/types';
import { getYAxisCategories } from 'components/YAxisUnitSelector/utils';
import ROUTES from 'constants/routes';
import {
AlertThresholdMatchType,
@@ -39,7 +40,8 @@ export function getQueryNames(currentQuery: Query): BaseOptionType[] {
}
export function getCategoryByOptionId(id: string): string | undefined {
return Y_AXIS_CATEGORIES.find((category) =>
const categories = getYAxisCategories(YAxisSource.ALERTS);
return categories.find((category) =>
category.units.some((unit) => unit.id === id),
)?.name;
}
@@ -47,14 +49,15 @@ export function getCategoryByOptionId(id: string): string | undefined {
export function getCategorySelectOptionByName(
name: string,
): DefaultOptionType[] {
const categories = getYAxisCategories(YAxisSource.ALERTS);
return (
Y_AXIS_CATEGORIES.find((category) => category.name === name)?.units.map(
(unit) => ({
categories
.find((category) => category.name === name)
?.units.map((unit) => ({
label: unit.name,
value: unit.id,
'data-testid': `threshold-unit-select-option-${unit.id}`,
}),
) || []
})) || []
);
}

View File

@@ -1,4 +1,5 @@
import YAxisUnitSelector from 'components/YAxisUnitSelector';
import { YAxisSource } from 'components/YAxisUnitSelector/types';
import { PANEL_TYPES } from 'constants/queryBuilder';
import { useCreateAlertState } from 'container/CreateAlertV2/context';
import ChartPreviewComponent from 'container/FormAlertRules/ChartPreview';
@@ -37,6 +38,7 @@ function ChartPreview({ alertDef }: ChartPreviewProps): JSX.Element {
onChange={(value): void => {
setAlertState({ type: 'SET_Y_AXIS_UNIT', payload: value });
}}
source={YAxisSource.ALERTS}
/>
</div>
);

View File

@@ -1,5 +1,5 @@
import { TableProps } from 'antd';
import { PrecisionOption } from 'components/Graph/yAxisConfig';
import { PrecisionOption } from 'components/Graph/types';
import { PANEL_TYPES } from 'constants/queryBuilder';
import { LogsExplorerTableProps } from 'container/LogsExplorerTable/LogsExplorerTable.interfaces';
import {

View File

@@ -6,6 +6,7 @@ import { MetricType } from 'api/metricsExplorer/getMetricsList';
import { UpdateMetricMetadataProps } from 'api/metricsExplorer/updateMetricMetadata';
import { ResizeTable } from 'components/ResizeTable';
import YAxisUnitSelector from 'components/YAxisUnitSelector';
import { YAxisSource } from 'components/YAxisUnitSelector/types';
import { getUniversalNameFromMetricUnit } from 'components/YAxisUnitSelector/utils';
import FieldRenderer from 'container/LogDetailedView/FieldRenderer';
import { DataType } from 'container/LogDetailedView/TableView';
@@ -120,6 +121,7 @@ function Metadata({
setMetricMetadata((prev) => ({ ...prev, unit: value }));
}}
data-testid="unit-select"
source={YAxisSource.EXPLORER}
/>
);
}

View File

@@ -12,10 +12,7 @@ import {
Switch,
Typography,
} from 'antd';
import {
PrecisionOption,
PrecisionOptionsEnum,
} from 'components/Graph/yAxisConfig';
import { PrecisionOption, PrecisionOptionsEnum } from 'components/Graph/types';
import TimePreference from 'components/TimePreferenceDropDown';
import { PANEL_TYPES, PanelDisplay } from 'constants/queryBuilder';
import GraphTypes, {

View File

@@ -4,10 +4,7 @@ import './NewWidget.styles.scss';
import { WarningOutlined } from '@ant-design/icons';
import { Button, Flex, Modal, Space, Typography } from 'antd';
import logEvent from 'api/common/logEvent';
import {
PrecisionOption,
PrecisionOptionsEnum,
} from 'components/Graph/yAxisConfig';
import { PrecisionOption, PrecisionOptionsEnum } from 'components/Graph/types';
import OverlayScrollbar from 'components/OverlayScrollbar/OverlayScrollbar';
import { adjustQueryForV5 } from 'components/QueryBuilderV2/utils';
import { QueryParams } from 'constants/query';

View File

@@ -1,6 +1,6 @@
import { DefaultOptionType } from 'antd/es/select';
import { omitIdFromQuery } from 'components/ExplorerCard/utils';
import { PrecisionOptionsEnum } from 'components/Graph/yAxisConfig';
import { PrecisionOptionsEnum } from 'components/Graph/types';
import {
initialQueryBuilderFormValuesMap,
PANEL_TYPES,

View File

@@ -1,4 +1,5 @@
import { getToolTipValue, PrecisionOption } from 'components/Graph/yAxisConfig';
import { PrecisionOption } from 'components/Graph/types';
import { getToolTipValue } from 'components/Graph/yAxisConfig';
import { DATE_TIME_FORMATS } from 'constants/dateTimeFormats';
import { themeColors } from 'constants/theme';
import dayjs from 'dayjs';

View File

@@ -1,6 +1,7 @@
/* eslint-disable @typescript-eslint/ban-ts-comment */
// @ts-nocheck
import { getToolTipValue, PrecisionOption } from 'components/Graph/yAxisConfig';
import { PrecisionOption } from 'components/Graph/types';
import { getToolTipValue } from 'components/Graph/yAxisConfig';
import { PANEL_TYPES } from 'constants/queryBuilder';
import { uPlotXAxisValuesFormat } from './constants';

View File

@@ -1,4 +1,4 @@
import { PrecisionOption } from 'components/Graph/yAxisConfig';
import { PrecisionOption } from 'components/Graph/types';
import { PANEL_GROUP_TYPES, PANEL_TYPES } from 'constants/queryBuilder';
import { ThresholdProps } from 'container/NewWidget/RightContainer/Threshold/types';
import { timePreferenceType } from 'container/NewWidget/RightContainer/timeItems';