Skip to content

Commit

Permalink
[APM] Only add decimals for numbers below 10 (#69334) (#69374)
Browse files Browse the repository at this point in the history
  • Loading branch information
sorenlouv authored Jun 17, 2020
1 parent 6fb8c92 commit 5c68ca6
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 79 deletions.
6 changes: 3 additions & 3 deletions x-pack/plugins/apm/e2e/cypress/integration/snapshots.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
module.exports = {
APM: {
'Transaction duration charts': {
'1': '350.0 ms',
'2': '175.0 ms',
'3': '0.0 ms',
'1': '350 ms',
'2': '175 ms',
'3': '0 ms',
},
},
__version: '4.5.0',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ describe('ServiceOverview -> List', () => {
expect(renderedColumns[0]).toMatchSnapshot();
expect(renderedColumns.slice(2)).toEqual([
'python',
'91.5 ms',
'92 ms',
'86.9 tpm',
'12.6 err.',
]);
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import d3 from 'd3';
import { HistogramInner } from '../index';
import response from './response.json';
import {
asDecimal,
getDurationFormatter,
asInteger,
} from '../../../../../utils/formatters';
import { toJson } from '../../../../../utils/testHelpers';
import { getFormattedBuckets } from '../../../../app/TransactionDetails/Distribution/index';
Expand All @@ -33,8 +33,8 @@ describe('Histogram', () => {
transactionId="myTransactionId"
onClick={onClick}
formatX={(time) => timeFormatter(time).formatted}
formatYShort={(t) => `${asDecimal(t)} occ.`}
formatYLong={(t) => `${asDecimal(t)} occurrences`}
formatYShort={(t) => `${asInteger(t)} occ.`}
formatYLong={(t) => `${asInteger(t)} occurrences`}
tooltipHeader={(bucket) => {
const xFormatted = timeFormatter(bucket.x);
const x0Formatted = timeFormatter(bucket.x0);
Expand Down Expand Up @@ -78,9 +78,9 @@ describe('Histogram', () => {
const tooltips = wrapper.find('Tooltip');

expect(tooltips.length).toBe(1);
expect(tooltips.prop('header')).toBe('811.1 - 926.9 ms');
expect(tooltips.prop('header')).toBe('811 - 927 ms');
expect(tooltips.prop('tooltipPoints')).toEqual([
{ value: '49.0 occurrences' },
{ value: '49 occurrences' },
]);
expect(tooltips.prop('x')).toEqual(869010);
expect(tooltips.prop('y')).toEqual(27.5);
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ describe('ErrorMarker', () => {
act(() => {
fireEvent.click(component.getByTestId('popover'));
});
expectTextsInDocument(component, ['10.0 ms']);
expectTextsInDocument(component, ['10 ms']);
return component;
}
function getKueryDecoded(url: string) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ describe('duration formatters', () => {
expect(asDuration(1)).toEqual('1 μs');
expect(asDuration(toMicroseconds(1, 'milliseconds'))).toEqual('1,000 μs');
expect(asDuration(toMicroseconds(1000, 'milliseconds'))).toEqual(
'1,000.0 ms'
'1,000 ms'
);
expect(asDuration(toMicroseconds(10000, 'milliseconds'))).toEqual(
'10,000.0 ms'
'10,000 ms'
);
expect(asDuration(toMicroseconds(20, 'seconds'))).toEqual('20.0 s');
expect(asDuration(toMicroseconds(10, 'minutes'))).toEqual('10.0 min');
expect(asDuration(toMicroseconds(1, 'hours'))).toEqual('60.0 min');
expect(asDuration(toMicroseconds(20, 'seconds'))).toEqual('20 s');
expect(asDuration(toMicroseconds(10, 'minutes'))).toEqual('10 min');
expect(asDuration(toMicroseconds(1, 'hours'))).toEqual('60 min');
expect(asDuration(toMicroseconds(1.5, 'hours'))).toEqual('1.5 h');
});

Expand All @@ -41,7 +41,7 @@ describe('duration formatters', () => {

describe('asMilliseconds', () => {
it('converts to formatted decimal milliseconds', () => {
expect(asMillisecondDuration(0)).toEqual('0.0 ms');
expect(asMillisecondDuration(0)).toEqual('0 ms');
});
});
});
119 changes: 71 additions & 48 deletions x-pack/plugins/apm/public/utils/formatters/duration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,6 @@ interface FormatterOptions {

type DurationTimeUnit = TimeUnit | 'microseconds';

interface DurationUnit {
[unit: string]: {
label: string;
convert: (value: number) => string;
};
}

interface ConvertedDuration {
value: string;
unit?: string;
Expand All @@ -38,42 +31,69 @@ export type TimeFormatter = (

type TimeFormatterBuilder = (max: number) => TimeFormatter;

const durationUnit: DurationUnit = {
hours: {
label: i18n.translate('xpack.apm.formatters.hoursTimeUnitLabel', {
defaultMessage: 'h',
}),
convert: (value: number) =>
asDecimal(moment.duration(value / 1000).asHours()),
},
minutes: {
label: i18n.translate('xpack.apm.formatters.minutesTimeUnitLabel', {
defaultMessage: 'min',
}),
convert: (value: number) =>
asDecimal(moment.duration(value / 1000).asMinutes()),
},
seconds: {
label: i18n.translate('xpack.apm.formatters.secondsTimeUnitLabel', {
defaultMessage: 's',
}),
convert: (value: number) =>
asDecimal(moment.duration(value / 1000).asSeconds()),
},
milliseconds: {
label: i18n.translate('xpack.apm.formatters.millisTimeUnitLabel', {
defaultMessage: 'ms',
}),
convert: (value: number) =>
asDecimal(moment.duration(value / 1000).asMilliseconds()),
},
microseconds: {
label: i18n.translate('xpack.apm.formatters.microsTimeUnitLabel', {
defaultMessage: 'μs',
}),
convert: (value: number) => asInteger(value),
},
};
function asDecimalOrInteger(value: number) {
// exact 0 or above 10 should not have decimal
if (value === 0 || value >= 10) {
return asInteger(value);
}
return asDecimal(value);
}

function getUnitLabelAndConvertedValue(
unitKey: DurationTimeUnit,
value: number
) {
switch (unitKey) {
case 'hours': {
return {
unitLabel: i18n.translate('xpack.apm.formatters.hoursTimeUnitLabel', {
defaultMessage: 'h',
}),
convertedValue: asDecimalOrInteger(
moment.duration(value / 1000).asHours()
),
};
}
case 'minutes': {
return {
unitLabel: i18n.translate('xpack.apm.formatters.minutesTimeUnitLabel', {
defaultMessage: 'min',
}),
convertedValue: asDecimalOrInteger(
moment.duration(value / 1000).asMinutes()
),
};
}
case 'seconds': {
return {
unitLabel: i18n.translate('xpack.apm.formatters.secondsTimeUnitLabel', {
defaultMessage: 's',
}),
convertedValue: asDecimalOrInteger(
moment.duration(value / 1000).asSeconds()
),
};
}
case 'milliseconds': {
return {
unitLabel: i18n.translate('xpack.apm.formatters.millisTimeUnitLabel', {
defaultMessage: 'ms',
}),
convertedValue: asDecimalOrInteger(
moment.duration(value / 1000).asMilliseconds()
),
};
}
case 'microseconds': {
return {
unitLabel: i18n.translate('xpack.apm.formatters.microsTimeUnitLabel', {
defaultMessage: 'μs',
}),
convertedValue: asInteger(value),
};
}
}
}

/**
* Converts a microseconds value into the unit defined.
Expand All @@ -87,16 +107,19 @@ function convertTo({
microseconds: Maybe<number>;
defaultValue?: string;
}): ConvertedDuration {
const duration = durationUnit[unit];
if (!duration || microseconds == null) {
if (microseconds == null) {
return { value: defaultValue, formatted: defaultValue };
}

const convertedValue = duration.convert(microseconds);
const { convertedValue, unitLabel } = getUnitLabelAndConvertedValue(
unit,
microseconds
);

return {
value: convertedValue,
unit: duration.label,
formatted: `${convertedValue} ${duration.label}`,
unit: unitLabel,
formatted: `${convertedValue} ${unitLabel}`,
};
}

Expand Down

0 comments on commit 5c68ca6

Please sign in to comment.