enhancement(FE): span time unit normalisation (#1021)

* feat: relevant span time unit on trace detail page

* fix: remove time unit on hover on flame graph
This commit is contained in:
Pranshu Chittora 2022-04-29 14:33:57 +05:30 committed by GitHub
parent b5be770a03
commit 3ab4f71aa1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 34 additions and 25 deletions

View File

@ -1,7 +1,4 @@
import { import { convertTimeToRelevantUnit } from 'container/TraceDetail/utils';
IIntervalUnit,
resolveTimeFromInterval,
} from 'container/TraceDetail/utils';
import useThemeMode from 'hooks/useThemeMode'; import useThemeMode from 'hooks/useThemeMode';
import React from 'react'; import React from 'react';
import { toFixed } from 'utils/toFixed'; import { toFixed } from 'utils/toFixed';
@ -13,12 +10,12 @@ interface SpanLengthProps {
leftOffset: string; leftOffset: string;
bgColor: string; bgColor: string;
inMsCount: number; inMsCount: number;
intervalUnit: IIntervalUnit;
} }
function SpanLength(props: SpanLengthProps): JSX.Element { function SpanLength(props: SpanLengthProps): JSX.Element {
const { width, leftOffset, bgColor, intervalUnit, inMsCount } = props; const { width, leftOffset, bgColor, inMsCount } = props;
const { isDarkMode } = useThemeMode(); const { isDarkMode } = useThemeMode();
const { time, timeUnitName } = convertTimeToRelevantUnit(inMsCount);
return ( return (
<SpanWrapper> <SpanWrapper>
<SpanLine <SpanLine
@ -34,9 +31,9 @@ function SpanLength(props: SpanLengthProps): JSX.Element {
width={width} width={width}
/> />
<SpanText isDarkMode={isDarkMode} leftOffset={leftOffset}>{`${toFixed( <SpanText isDarkMode={isDarkMode} leftOffset={leftOffset}>{`${toFixed(
resolveTimeFromInterval(inMsCount, intervalUnit), time,
2, 2,
)} ${intervalUnit.name}`}</SpanText> )} ${timeUnitName}`}</SpanText>
</SpanWrapper> </SpanWrapper>
); );
} }

View File

@ -153,7 +153,6 @@ function Trace(props: TraceProps): JSX.Element {
width={width.toString()} width={width.toString()}
bgColor={serviceColour} bgColor={serviceColour}
inMsCount={inMsCount / 1e6} inMsCount={inMsCount / 1e6}
intervalUnit={intervalUnit}
/> />
</Col> </Col>
</CardContainer> </CardContainer>

View File

@ -37,11 +37,10 @@ function Timeline({
}); });
let intervalUnit = INTERVAL_UNITS[0]; let intervalUnit = INTERVAL_UNITS[0];
for (let idx = 0; idx < INTERVAL_UNITS.length; idx += 1) { for (let idx = INTERVAL_UNITS.length - 1; idx >= 0; idx -= 1) {
const standardInterval = INTERVAL_UNITS[idx]; const standardInterval = INTERVAL_UNITS[idx];
if (baseSpread * standardInterval.multiplier < 1) { if (baseSpread * standardInterval.multiplier >= 1) {
const index = idx; intervalUnit = INTERVAL_UNITS[idx];
if (index > 1) intervalUnit = INTERVAL_UNITS[index - 1];
break; break;
} }
} }

View File

@ -13,8 +13,9 @@ export const filterSpansByString = (
return JSON.stringify(spanWithoutChildren).includes(searchString); return JSON.stringify(spanWithoutChildren).includes(searchString);
}); });
type TTimeUnitName = 'ms' | 's' | 'm';
export interface IIntervalUnit { export interface IIntervalUnit {
name: 'ms' | 's' | 'm'; name: TTimeUnitName;
multiplier: number; multiplier: number;
} }
export const INTERVAL_UNITS: IIntervalUnit[] = [ export const INTERVAL_UNITS: IIntervalUnit[] = [
@ -39,6 +40,28 @@ export const resolveTimeFromInterval = (
return intervalTime * intervalUnit.multiplier; return intervalTime * intervalUnit.multiplier;
}; };
export const convertTimeToRelevantUnit = (
intervalTime: number,
): { time: number; timeUnitName: TTimeUnitName } => {
let relevantTime = {
time: intervalTime,
timeUnitName: INTERVAL_UNITS[0].name,
};
for (let idx = INTERVAL_UNITS.length - 1; idx >= 0; idx -= 1) {
const intervalUnit = INTERVAL_UNITS[idx];
const convertedTimeForInterval = intervalTime * intervalUnit.multiplier;
if (convertedTimeForInterval >= 1) {
relevantTime = {
time: convertedTimeForInterval,
timeUnitName: intervalUnit.name,
};
break;
}
}
return relevantTime;
};
export const getSortedData = (treeData: ITraceTree): undefined | ITraceTree => { export const getSortedData = (treeData: ITraceTree): undefined | ITraceTree => {
const traverse = (treeNode: ITraceTree, level = 0): void => { const traverse = (treeNode: ITraceTree, level = 0): void => {
if (!treeNode) { if (!treeNode) {

View File

@ -1,14 +1,9 @@
/* eslint-disable react/no-unstable-nested-components */ /* eslint-disable react/no-unstable-nested-components */
import Color from 'color'; import Color from 'color';
import { ITraceMetaData } from 'container/GantChart'; import { ITraceMetaData } from 'container/GantChart';
import {
IIntervalUnit,
resolveTimeFromInterval,
} from 'container/TraceDetail/utils';
import useThemeMode from 'hooks/useThemeMode'; import useThemeMode from 'hooks/useThemeMode';
import React, { useLayoutEffect, useMemo, useState } from 'react'; import React, { useLayoutEffect, useMemo, useState } from 'react';
import { ITraceTree } from 'types/api/trace/getTraceItem'; import { ITraceTree } from 'types/api/trace/getTraceItem';
import { toFixed } from 'utils/toFixed';
import { import {
SpanItemContainer, SpanItemContainer,
@ -98,14 +93,13 @@ function TraceFlameGraph(props: {
onSpanSelect: SpanItemProps['onSpanSelect']; onSpanSelect: SpanItemProps['onSpanSelect'];
hoveredSpanId: string; hoveredSpanId: string;
selectedSpanId: string; selectedSpanId: string;
intervalUnit: IIntervalUnit;
}): JSX.Element { }): JSX.Element {
const { treeData, traceMetaData, onSpanHover } = props; const { treeData, traceMetaData, onSpanHover } = props;
if (!treeData || treeData.id === 'empty' || !traceMetaData) { if (!treeData || treeData.id === 'empty' || !traceMetaData) {
return <div />; return <div />;
} }
const { intervalUnit, onSpanSelect, hoveredSpanId, selectedSpanId } = props; const { onSpanSelect, hoveredSpanId, selectedSpanId } = props;
const { globalStart, spread, levels } = traceMetaData; const { globalStart, spread, levels } = traceMetaData;
function RenderSpanRecursive({ function RenderSpanRecursive({
@ -131,10 +125,7 @@ function TraceFlameGraph(props: {
const leftOffset = ((spanData.startTime - globalStart) * 100) / spread; const leftOffset = ((spanData.startTime - globalStart) * 100) / spread;
const width = ((spanData.value / 1e6) * 100) / spread; const width = ((spanData.value / 1e6) * 100) / spread;
const toolTipText = `${spanData.name}\n${toFixed( const toolTipText = `${spanData.name}`;
resolveTimeFromInterval(spanData.value / 1e6, intervalUnit),
2,
)} ${intervalUnit.name}`;
return ( return (
<> <>