[APM] Service map - fixes layout issues for maps with no rum services (#62887)
* Closes #62878 in Service Maps by improving the selection algorithm for root nodes * Fixes some latent centering issues when navigating in the service map. * Removes unused imports * Added layoutstopDelayTimeout to cleanup step
This commit is contained in:
parent
d4f2bd744d
commit
184f59447b
|
@ -14,8 +14,6 @@ import React, {
|
|||
useState
|
||||
} from 'react';
|
||||
import { debounce } from 'lodash';
|
||||
import { isRumAgentName } from '../../../../../../../plugins/apm/common/agent_name';
|
||||
import { AGENT_NAME } from '../../../../../../../plugins/apm/common/elasticsearch_fieldnames';
|
||||
import {
|
||||
animationOptions,
|
||||
cytoscapeOptions,
|
||||
|
@ -96,10 +94,15 @@ function getLayoutOptions(
|
|||
}
|
||||
|
||||
function selectRoots(cy: cytoscape.Core): string[] {
|
||||
const nodes = cy.nodes();
|
||||
const roots = nodes.roots();
|
||||
const rumNodes = nodes.filter(node => isRumAgentName(node.data(AGENT_NAME)));
|
||||
return rumNodes.union(roots).map(node => node.id());
|
||||
const bfs = cy.elements().bfs({
|
||||
roots: cy.elements().leaves()
|
||||
});
|
||||
const furthestNodeFromLeaves = bfs.path.last();
|
||||
return cy
|
||||
.elements()
|
||||
.roots()
|
||||
.union(furthestNodeFromLeaves)
|
||||
.map(el => el.id());
|
||||
}
|
||||
|
||||
export function Cytoscape({
|
||||
|
@ -168,15 +171,26 @@ export function Cytoscape({
|
|||
layout.run();
|
||||
}
|
||||
};
|
||||
let layoutstopDelayTimeout: NodeJS.Timeout;
|
||||
const layoutstopHandler: cytoscape.EventHandler = event => {
|
||||
event.cy.animate({
|
||||
...animationOptions,
|
||||
center: {
|
||||
eles: serviceName
|
||||
? event.cy.getElementById(serviceName)
|
||||
: event.cy.collection()
|
||||
// This 0ms timer is necessary to prevent a race condition
|
||||
// between the layout finishing rendering and viewport centering
|
||||
layoutstopDelayTimeout = setTimeout(() => {
|
||||
if (serviceName) {
|
||||
event.cy.animate({
|
||||
...animationOptions,
|
||||
fit: {
|
||||
eles: event.cy.elements(),
|
||||
padding: nodeHeight
|
||||
},
|
||||
center: {
|
||||
eles: event.cy.getElementById(serviceName)
|
||||
}
|
||||
});
|
||||
} else {
|
||||
event.cy.fit(undefined, nodeHeight);
|
||||
}
|
||||
});
|
||||
}, 0);
|
||||
};
|
||||
// debounce hover tracking so it doesn't spam telemetry with redundant events
|
||||
const trackNodeEdgeHover = debounce(
|
||||
|
@ -231,6 +245,7 @@ export function Cytoscape({
|
|||
cy.removeListener('select', 'node', selectHandler);
|
||||
cy.removeListener('unselect', 'node', unselectHandler);
|
||||
}
|
||||
clearTimeout(layoutstopDelayTimeout);
|
||||
};
|
||||
}, [cy, height, serviceName, trackApmEvent, width]);
|
||||
|
||||
|
|
Loading…
Reference in a new issue