Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,20 @@ function useCytoscape(options: cytoscape.CytoscapeOptions) {
return [ref, cy] as [React.MutableRefObject<any>, cytoscape.Core | undefined];
}

function rotatePoint(
{ x, y }: { x: number; y: number },
degreesRotated: number
) {
const radiansPerDegree = Math.PI / 180;
const θ = radiansPerDegree * degreesRotated;
const cosθ = Math.cos(θ);
const sinθ = Math.sin(θ);
return {
x: x * cosθ - y * sinθ,
y: x * sinθ + y * cosθ
};
}

function getLayoutOptions(
selectedRoots: string[],
height: number,
Expand All @@ -71,10 +85,11 @@ function getLayoutOptions(
animate: true,
animationEasing: animationOptions.easing,
animationDuration: animationOptions.duration,
// Rotate nodes from top -> bottom to display left -> right
// @ts-ignore
transform: (node: any, { x, y }: cytoscape.Position) => ({ x: y, y: -x }),
// swap width/height of boundingBox to compensation for the rotation
// Rotate nodes counter-clockwise to transform layout from top→bottom to left→right.
// The extra 5° achieves the effect of separating overlapping taxi-styled edges.
transform: (node: any, pos: cytoscape.Position) => rotatePoint(pos, -95),
// swap width/height of boundingBox to compensate for the rotation
boundingBox: { x1: 0, y1: 0, w: height, h: width }
};
}
Expand Down Expand Up @@ -109,20 +124,31 @@ export function Cytoscape({
// is required and can trigger rendering when changed.
const divStyle = { ...style, height };

const dataHandler = useCallback<cytoscape.EventHandler>(
event => {
const resetConnectedEdgeStyle = useCallback(
(node?: cytoscape.NodeSingular) => {
if (cy) {
cy.edges().removeClass('highlight');

if (serviceName) {
const focusedNode = cy.getElementById(serviceName);
focusedNode.connectedEdges().addClass('highlight');
if (node) {
node.connectedEdges().addClass('highlight');
}
}
},
[cy]
);

// Add the "primary" class to the node if its id matches the serviceName.
if (cy.nodes().length > 0 && serviceName) {
cy.nodes().removeClass('primary');
cy.getElementById(serviceName).addClass('primary');
const dataHandler = useCallback<cytoscape.EventHandler>(
event => {
if (cy) {
if (serviceName) {
resetConnectedEdgeStyle(cy.getElementById(serviceName));
// Add the "primary" class to the node if its id matches the serviceName.
if (cy.nodes().length > 0) {
cy.nodes().removeClass('primary');
cy.getElementById(serviceName).addClass('primary');
}
} else {
resetConnectedEdgeStyle();
}
if (event.cy.elements().length > 0) {
const selectedRoots = selectRoots(event.cy);
Expand All @@ -141,7 +167,7 @@ export function Cytoscape({
}
}
},
[cy, serviceName, height, width]
[cy, resetConnectedEdgeStyle, serviceName, height, width]
);

// Trigger a custom "data" event when data changes
Expand All @@ -162,12 +188,20 @@ export function Cytoscape({
event.target.removeClass('hover');
event.target.connectedEdges().removeClass('nodeHover');
};
const selectHandler: cytoscape.EventHandler = event => {
resetConnectedEdgeStyle(event.target);
};
const unselectHandler: cytoscape.EventHandler = event => {
resetConnectedEdgeStyle();
};

if (cy) {
cy.on('data', dataHandler);
cy.ready(dataHandler);
cy.on('mouseover', 'edge, node', mouseoverHandler);
cy.on('mouseout', 'edge, node', mouseoutHandler);
cy.on('select', 'node', selectHandler);
cy.on('unselect', 'node', unselectHandler);
}

return () => {
Expand All @@ -181,7 +215,7 @@ export function Cytoscape({
cy.removeListener('mouseout', 'edge, node', mouseoutHandler);
}
};
}, [cy, dataHandler, serviceName]);
}, [cy, dataHandler, resetConnectedEdgeStyle, serviceName]);

return (
<CytoscapeContext.Provider value={cy}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,15 +121,18 @@ const style: cytoscape.Stylesheet[] = [
{
selector: 'edge.nodeHover',
style: {
width: 4,
width: 2,
// @ts-ignore
'z-index': zIndexEdgeHover
'z-index': zIndexEdgeHover,
'line-color': theme.euiColorDarkShade,
'source-arrow-color': theme.euiColorDarkShade,
'target-arrow-color': theme.euiColorDarkShade
}
},
{
selector: 'node.hover',
style: {
'border-width': 4
'border-width': 2
}
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export function KueryBar() {
const disabled = /\/service-map$/.test(location.pathname);
const disabledPlaceholder = i18n.translate(
'xpack.apm.kueryBar.disabledPlaceholder',
{ defaultMessage: 'Search is not available for service maps' }
{ defaultMessage: 'Search is not available for service map' }
);

async function onChange(inputValue: string, selectionStart: number) {
Expand Down