Skip to content

Commit b5f460f

Browse files
authored
Remove all client-side map munging (#60701)
Remove the getCytoscapeElements function. On the server: * Replace `source` with `sourceData`, `destination` with `targetData`, `source.id` with `source`, and `destination.id` with `target`. * Return a single array as an `elements` property instead of `nodes` and `connections` * Map all of the items data to be inside of a `data` object * Replace SERVICE_AGENT_NAME with AGENT_NAME * Add some missing constants On the client: * Remove getCytoscapeElements * Move all presentation-specific data transformation to use the original attributes in the place where they're needed * Remove `href` since it wasn't being used * Move BetaBadge to its own file * Move cytoscapeDivStyle to cytoscapeOptions * Fix storybook to work with new data formats
1 parent 3a39602 commit b5f460f

File tree

25 files changed

+1110
-266
lines changed

25 files changed

+1110
-266
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
import { EuiBetaBadge } from '@elastic/eui';
8+
import theme from '@elastic/eui/dist/eui_theme_light.json';
9+
import { i18n } from '@kbn/i18n';
10+
import React from 'react';
11+
import styled from 'styled-components';
12+
13+
const BetaBadgeContainer = styled.div`
14+
right: ${theme.gutterTypes.gutterMedium};
15+
position: absolute;
16+
top: ${theme.gutterTypes.gutterSmall};
17+
z-index: 1; /* The element containing the cytoscape canvas has z-index = 0. */
18+
`;
19+
20+
export function BetaBadge() {
21+
return (
22+
<BetaBadgeContainer>
23+
<EuiBetaBadge
24+
label={i18n.translate('xpack.apm.serviceMap.betaBadge', {
25+
defaultMessage: 'Beta'
26+
})}
27+
tooltipContent={i18n.translate(
28+
'xpack.apm.serviceMap.betaTooltipMessage',
29+
{
30+
defaultMessage:
31+
'This feature is currently in beta. If you encounter any bugs or have feedback, please open an issue or visit our discussion forum.'
32+
}
33+
)}
34+
/>
35+
</BetaBadgeContainer>
36+
);
37+
}

x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Cytoscape.stories.tsx

Lines changed: 38 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,10 @@ import { storiesOf } from '@storybook/react';
99
import cytoscape from 'cytoscape';
1010
import React from 'react';
1111
import { Cytoscape } from './Cytoscape';
12-
import { getCytoscapeElements } from './get_cytoscape_elements';
1312
import serviceMapResponse from './cytoscape-layout-test-response.json';
1413
import { iconForNode } from './icons';
1514

16-
const elementsFromResponses = getCytoscapeElements(serviceMapResponse, '');
15+
const elementsFromResponses = serviceMapResponse.elements;
1716

1817
storiesOf('app/ServiceMap/Cytoscape', module).add(
1918
'example',
@@ -22,25 +21,22 @@ storiesOf('app/ServiceMap/Cytoscape', module).add(
2221
{
2322
data: {
2423
id: 'opbeans-python',
25-
label: 'opbeans-python',
26-
agentName: 'python',
27-
type: 'service'
24+
'service.name': 'opbeans-python',
25+
'agent.name': 'python'
2826
}
2927
},
3028
{
3129
data: {
3230
id: 'opbeans-node',
33-
label: 'opbeans-node',
34-
agentName: 'nodejs',
35-
type: 'service'
31+
'service.name': 'opbeans-node',
32+
'agent.name': 'nodejs'
3633
}
3734
},
3835
{
3936
data: {
4037
id: 'opbeans-ruby',
41-
label: 'opbeans-ruby',
42-
agentName: 'ruby',
43-
type: 'service'
38+
'service.name': 'opbeans-ruby',
39+
'agent.name': 'ruby'
4440
}
4541
},
4642
{ data: { source: 'opbeans-python', target: 'opbeans-node' } },
@@ -78,74 +74,74 @@ storiesOf('app/ServiceMap/Cytoscape', module)
7874
() => {
7975
const cy = cytoscape();
8076
const elements = [
81-
{ data: { id: 'default', label: 'default', type: undefined } },
82-
{ data: { id: 'cache', label: 'cache', type: 'cache' } },
83-
{ data: { id: 'database', label: 'database', type: 'database' } },
84-
{ data: { id: 'external', label: 'external', type: 'external' } },
85-
{ data: { id: 'messaging', label: 'messaging', type: 'messaging' } },
77+
{ data: { id: 'default' } },
78+
{ data: { id: 'cache', label: 'cache', 'span.type': 'cache' } },
79+
{ data: { id: 'database', label: 'database', 'span.type': 'db' } },
80+
{
81+
data: { id: 'external', label: 'external', 'span.type': 'external' }
82+
},
83+
{
84+
data: {
85+
id: 'messaging',
86+
label: 'messaging',
87+
'span.type': 'messaging'
88+
}
89+
},
8690

8791
{
8892
data: {
8993
id: 'dotnet',
90-
label: 'dotnet service',
91-
type: 'service',
92-
agentName: 'dotnet'
94+
'service.name': 'dotnet service',
95+
'agent.name': 'dotnet'
9396
}
9497
},
9598
{
9699
data: {
97100
id: 'go',
98-
label: 'go service',
99-
type: 'service',
100-
agentName: 'go'
101+
'service.name': 'go service',
102+
'agent.name': 'go'
101103
}
102104
},
103105
{
104106
data: {
105107
id: 'java',
106-
label: 'java service',
107-
type: 'service',
108-
agentName: 'java'
108+
'service.name': 'java service',
109+
'agent.name': 'java'
109110
}
110111
},
111112
{
112113
data: {
113114
id: 'js-base',
114-
label: 'js-base service',
115-
type: 'service',
116-
agentName: 'js-base'
115+
'service.name': 'js-base service',
116+
'agent.name': 'js-base'
117117
}
118118
},
119119
{
120120
data: {
121121
id: 'nodejs',
122-
label: 'nodejs service',
123-
type: 'service',
124-
agentName: 'nodejs'
122+
'service.name': 'nodejs service',
123+
'agent.name': 'nodejs'
125124
}
126125
},
127126
{
128127
data: {
129128
id: 'php',
130-
label: 'php service',
131-
type: 'service',
132-
agentName: 'php'
129+
'service.name': 'php service',
130+
'agent.name': 'php'
133131
}
134132
},
135133
{
136134
data: {
137135
id: 'python',
138-
label: 'python service',
139-
type: 'service',
140-
agentName: 'python'
136+
'service.name': 'python service',
137+
'agent.name': 'python'
141138
}
142139
},
143140
{
144141
data: {
145142
id: 'ruby',
146-
label: 'ruby service',
147-
type: 'service',
148-
agentName: 'ruby'
143+
'service.name': 'ruby service',
144+
'agent.name': 'ruby'
149145
}
150146
}
151147
];
@@ -158,8 +154,8 @@ storiesOf('app/ServiceMap/Cytoscape', module)
158154
<EuiCard
159155
description={
160156
<pre>
161-
agentName: {node.data('agentName') || 'undefined'}, type:{' '}
162-
{node.data('type') || 'undefined'}
157+
agent.name: {node.data('agent.name') || 'undefined'},
158+
span.type: {node.data('span.type') || 'undefined'}
163159
</pre>
164160
}
165161
icon={

x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Cytoscape.tsx

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,22 @@
44
* you may not use this file except in compliance with the Elastic License.
55
*/
66

7+
import cytoscape from 'cytoscape';
78
import React, {
9+
createContext,
810
CSSProperties,
9-
useState,
10-
useRef,
11-
useEffect,
1211
ReactNode,
13-
createContext,
14-
useCallback
12+
useCallback,
13+
useEffect,
14+
useRef,
15+
useState
1516
} from 'react';
16-
import cytoscape from 'cytoscape';
1717
import { isRumAgentName } from '../../../../../../../plugins/apm/common/agent_name';
18+
import { AGENT_NAME } from '../../../../../../../plugins/apm/common/elasticsearch_fieldnames';
1819
import {
20+
animationOptions,
1921
cytoscapeOptions,
20-
nodeHeight,
21-
animationOptions
22+
nodeHeight
2223
} from './cytoscapeOptions';
2324

2425
export const CytoscapeContext = createContext<cytoscape.Core | undefined>(
@@ -81,7 +82,7 @@ function getLayoutOptions(
8182
function selectRoots(cy: cytoscape.Core): string[] {
8283
const nodes = cy.nodes();
8384
const roots = nodes.roots();
84-
const rumNodes = nodes.filter(node => isRumAgentName(node.data('agentName')));
85+
const rumNodes = nodes.filter(node => isRumAgentName(node.data(AGENT_NAME)));
8586
return rumNodes.union(roots).map(node => node.id());
8687
}
8788

x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Popover/Contents.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
} from '@elastic/eui';
1313
import cytoscape from 'cytoscape';
1414
import React from 'react';
15+
import { SERVICE_FRAMEWORK_NAME } from '../../../../../../../../plugins/apm/common/elasticsearch_fieldnames';
1516
import { Buttons } from './Buttons';
1617
import { Info } from './Info';
1718
import { ServiceMetricFetcher } from './ServiceMetricFetcher';
@@ -33,7 +34,7 @@ export function Contents({
3334
onFocusClick,
3435
selectedNodeServiceName
3536
}: ContentsProps) {
36-
const frameworkName = selectedNodeData.frameworkName;
37+
const frameworkName = selectedNodeData[SERVICE_FRAMEWORK_NAME];
3738
return (
3839
<EuiFlexGroup
3940
direction="column"

x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Popover/Info.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ import { i18n } from '@kbn/i18n';
99
import cytoscape from 'cytoscape';
1010
import React from 'react';
1111
import styled from 'styled-components';
12+
import {
13+
SPAN_SUBTYPE,
14+
SPAN_TYPE
15+
} from '../../../../../../../../plugins/apm/common/elasticsearch_fieldnames';
1216

1317
const ItemRow = styled.div`
1418
line-height: 2;
@@ -25,7 +29,14 @@ interface InfoProps extends cytoscape.NodeDataDefinition {
2529
subtype?: string;
2630
}
2731

28-
export function Info({ type, subtype }: InfoProps) {
32+
export function Info(data: InfoProps) {
33+
// For nodes with span.type "db", convert it to "database".
34+
// Otherwise leave it as-is.
35+
const type = data[SPAN_TYPE] === 'db' ? 'database' : data[SPAN_TYPE];
36+
37+
// Externals should not have a subtype so make it undefined if the type is external.
38+
const subtype = data[SPAN_TYPE] !== 'external' && data[SPAN_SUBTYPE];
39+
2940
const listItems = [
3041
{
3142
title: i18n.translate('xpack.apm.serviceMap.typePopoverMetric', {

x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Popover/index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import React, {
1414
useRef,
1515
useState
1616
} from 'react';
17+
import { SERVICE_NAME } from '../../../../../../../../plugins/apm/common/elasticsearch_fieldnames';
1718
import { CytoscapeContext } from '../Cytoscape';
1819
import { Contents } from './Contents';
1920

@@ -36,7 +37,7 @@ export function Popover({ focusedServiceName }: PopoverProps) {
3637
const renderedWidth = selectedNode?.renderedWidth() ?? 0;
3738
const { x, y } = selectedNode?.renderedPosition() ?? { x: -10000, y: -10000 };
3839
const isOpen = !!selectedNode;
39-
const isService = selectedNode?.data('type') === 'service';
40+
const isService = selectedNode?.data(SERVICE_NAME) !== undefined;
4041
const triggerStyle: CSSProperties = {
4142
background: 'transparent',
4243
height: renderedHeight,

0 commit comments

Comments
 (0)