mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-14 16:05:58 +08:00
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:
parent
b5be770a03
commit
3ab4f71aa1
@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -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>
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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 (
|
||||||
<>
|
<>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user