Skip to content

Commit

Permalink
Add tooltip when hovering Critical Path (#1871)
Browse files Browse the repository at this point in the history
## Which problem is this PR solving?
- Related to #1582 

## Description of the changes
-  Added Tooltip which is visible on hovering the critical path

@yurishkuro

---------

Signed-off-by: GLVS Kiriti <glvskiriti2003369@gmail.com>
Signed-off-by: GLVSKiriti <116095646+GLVSKiriti@users.noreply.github.com>
Co-authored-by: Yuri Shkuro <yurishkuro@users.noreply.github.com>
  • Loading branch information
GLVSKiriti and yurishkuro committed Oct 22, 2023
1 parent 3df53f4 commit c44ab81
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,32 @@ limitations under the License.
top: 45%;
height: 11%;
z-index: 2;
overflow: hidden;
}

.SpanBar--criticalPath::before {
content: '';
position: absolute;
top: 0;
width: 10%;
height: 100%;
visibility: hidden;
background-color: white;
border: 1px solid white;
}

.SpanBar--criticalPath:hover::before {
visibility: visible;
animation: runOnce 2s forwards;
}

@keyframes runOnce {
0% {
left: 0;
}
100% {
left: 100%;
}
}

.SpanBar--label {
Expand Down Expand Up @@ -85,6 +111,8 @@ limitations under the License.

.SpanBar--logMarker:hover {
background-color: #000;
transform: scale(1.2);
transition: transform 0.3s ease;
}

.SpanBar--logMarker::before,
Expand All @@ -94,7 +122,7 @@ limitations under the License.
top: 0;
bottom: 0;
right: 0;
border: 1px solid transparent;
border: 3px solid transparent;
}

.SpanBar--logMarker::after {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// limitations under the License.

import React, { useState } from 'react';
import { Popover } from 'antd';
import { Popover, Tooltip } from 'antd';
import _groupBy from 'lodash/groupBy';

import AccordianLogs from './SpanDetail/AccordianLogs';
Expand Down Expand Up @@ -124,7 +124,7 @@ function SpanBar(props: TCommonProps) {
<div
data-testid="SpanBar--logMarker"
className="SpanBar--logMarker"
style={{ left: positionKey }}
style={{ left: positionKey, zIndex: 3 }}
/>
</Popover>
))}
Expand All @@ -146,16 +146,25 @@ function SpanBar(props: TCommonProps) {
const criticalPathViewEnd = critcalPathViewBounds.end;
const key = `${each.spanId}-${index}`;
return (
<div
key={key}
data-testid="SpanBar--criticalPath"
className="SpanBar--criticalPath"
style={{
background: 'black',
left: toPercentInDecimal(criticalPathViewStart),
width: toPercentInDecimal(criticalPathViewEnd - criticalPathViewStart),
}}
/>
<Tooltip
placement="top"
title={
<div>
A segment on the <em>critical path</em> of the overall trace/request/workflow.
</div>
}
>
<div
key={key}
data-testid="SpanBar--criticalPath"
className="SpanBar--criticalPath"
style={{
background: 'black',
left: toPercentInDecimal(criticalPathViewStart),
width: toPercentInDecimal(criticalPathViewEnd - criticalPathViewStart),
}}
/>
</Tooltip>
);
})}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
// limitations under the License.
import React from 'react';
import { shallow, mount } from 'enzyme';
import { render, screen } from '@testing-library/react';

import ListView from './ListView';
import SpanBarRow from './SpanBarRow';
Expand All @@ -25,6 +26,8 @@ import updateUiFindSpy from '../../../utils/update-ui-find';
import * as linkPatterns from '../../../model/link-patterns';
import memoizedTraceCriticalPath from '../CriticalPath/index';

import criticalPathTest from '../CriticalPath/testCases/test2';

jest.mock('./SpanTreeOffset');
jest.mock('../../../utils/update-ui-find');

Expand Down Expand Up @@ -326,6 +329,26 @@ describe('<VirtualizedTraceViewImpl>', () => {
).toBe(true);
});

it('renders Critical Path segments when row is not collapsed', () => {
wrapper.setProps({
trace: criticalPathTest.trace,
criticalPath: criticalPathTest.criticalPathSections,
});
render(instance.renderRow('some-key', {}, 0, {}));
expect(screen.getAllByTestId('SpanBar--criticalPath').length).toBe(2);
});

it('renders Critical Path segments are merged if consecutive when row is collapased', () => {
const childrenHiddenIDs = new Set([criticalPathTest.trace.spans[0].spanID]);
wrapper.setProps({
childrenHiddenIDs,
trace: criticalPathTest.trace,
criticalPath: criticalPathTest.criticalPathSections,
});
render(instance.renderRow('some-key', {}, 0, {}));
expect(screen.getAllByTestId('SpanBar--criticalPath').length).toBe(1);
});

it('renders a SpanBarRow with a RPC span if the row is collapsed and a client span', () => {
const clientTags = [{ key: 'span.kind', value: 'client' }, ...trace.spans[0].tags];
const serverTags = [{ key: 'span.kind', value: 'server' }, ...trace.spans[1].tags];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,41 @@ function getCssClasses(currentViewRange: [number, number]) {
});
}

function mergeChildrenCriticalPath(
trace: Trace,
spanID: string,
criticalPath: criticalPathSection[]
): criticalPathSection[] {
// Define an array to store the IDs of the span and its descendants (if the span is collapsed)
const allRequiredSpanIds = [spanID];

// If the span is collapsed, recursively find all of its descendants.
const findAllDescendants = (currentChildSpanIds: string[]) => {
currentChildSpanIds.forEach(eachId => {
const currentChildSpan = trace.spans.find(a => a.spanID === eachId)!;
if (currentChildSpan.hasChildren) {
allRequiredSpanIds.push(...currentChildSpan.childSpanIds);
findAllDescendants(currentChildSpan.childSpanIds);
}
});
};
findAllDescendants(allRequiredSpanIds);

const criticalPathSections: criticalPathSection[] = [];
criticalPath.forEach(each => {
if (allRequiredSpanIds.includes(each.spanId)) {
if (criticalPathSections.length !== 0 && each.section_end === criticalPathSections[0].section_start) {
// Merge Critical Paths if they are consecutive
criticalPathSections[0].section_start = each.section_start;
} else {
criticalPathSections.unshift({ ...each });
}
}
});

return criticalPathSections;
}

const memoizedGenerateRowStates = memoizeOne(generateRowStatesFromTrace);
const memoizedViewBoundsFunc = memoizeOne(createViewedBoundsFunc, _isEqual);
const memoizedGetCssClasses = memoizeOne(getCssClasses, _isEqual);
Expand Down Expand Up @@ -358,24 +393,9 @@ export class VirtualizedTraceViewImpl extends React.Component<VirtualizedTraceVi
const isDetailExpanded = detailStates.has(spanID);
const isMatchingFilter = findMatchesIDs ? findMatchesIDs.has(spanID) : false;
const showErrorIcon = isErrorSpan(span) || (isCollapsed && spanContainsErredSpan(trace.spans, spanIndex));
const criticalPathSections = criticalPath?.filter(each => {
if (isCollapsed) {
const allChildSpanIds = [spanID, ...childSpanIds];
// This function called recursively to find all descendants of a span
const findAllDescendants = (currentChildSpanIds: string[]) => {
currentChildSpanIds.forEach(eachId => {
const currentChildSpan = trace.spans.find(a => a.spanID === eachId)!;
if (currentChildSpan.hasChildren) {
allChildSpanIds.push(...currentChildSpan.childSpanIds);
findAllDescendants(currentChildSpan.childSpanIds);
}
});
};
findAllDescendants(childSpanIds);
return allChildSpanIds.includes(each.spanId);
}
return each.spanId === spanID;
});
const criticalPathSections = isCollapsed
? mergeChildrenCriticalPath(trace, spanID, criticalPath)
: criticalPath.filter(each => each.spanId === spanID);
// Check for direct child "server" span if the span is a "client" span.
let rpc = null;
if (isCollapsed) {
Expand Down

0 comments on commit c44ab81

Please sign in to comment.