Skip to content

Commit

Permalink
Remove all client-side map munging (#60701)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
smith authored Mar 20, 2020
1 parent 3a39602 commit b5f460f
Show file tree
Hide file tree
Showing 25 changed files with 1,110 additions and 266 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { EuiBetaBadge } from '@elastic/eui';
import theme from '@elastic/eui/dist/eui_theme_light.json';
import { i18n } from '@kbn/i18n';
import React from 'react';
import styled from 'styled-components';

const BetaBadgeContainer = styled.div`
right: ${theme.gutterTypes.gutterMedium};
position: absolute;
top: ${theme.gutterTypes.gutterSmall};
z-index: 1; /* The element containing the cytoscape canvas has z-index = 0. */
`;

export function BetaBadge() {
return (
<BetaBadgeContainer>
<EuiBetaBadge
label={i18n.translate('xpack.apm.serviceMap.betaBadge', {
defaultMessage: 'Beta'
})}
tooltipContent={i18n.translate(
'xpack.apm.serviceMap.betaTooltipMessage',
{
defaultMessage:
'This feature is currently in beta. If you encounter any bugs or have feedback, please open an issue or visit our discussion forum.'
}
)}
/>
</BetaBadgeContainer>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@ import { storiesOf } from '@storybook/react';
import cytoscape from 'cytoscape';
import React from 'react';
import { Cytoscape } from './Cytoscape';
import { getCytoscapeElements } from './get_cytoscape_elements';
import serviceMapResponse from './cytoscape-layout-test-response.json';
import { iconForNode } from './icons';

const elementsFromResponses = getCytoscapeElements(serviceMapResponse, '');
const elementsFromResponses = serviceMapResponse.elements;

storiesOf('app/ServiceMap/Cytoscape', module).add(
'example',
Expand All @@ -22,25 +21,22 @@ storiesOf('app/ServiceMap/Cytoscape', module).add(
{
data: {
id: 'opbeans-python',
label: 'opbeans-python',
agentName: 'python',
type: 'service'
'service.name': 'opbeans-python',
'agent.name': 'python'
}
},
{
data: {
id: 'opbeans-node',
label: 'opbeans-node',
agentName: 'nodejs',
type: 'service'
'service.name': 'opbeans-node',
'agent.name': 'nodejs'
}
},
{
data: {
id: 'opbeans-ruby',
label: 'opbeans-ruby',
agentName: 'ruby',
type: 'service'
'service.name': 'opbeans-ruby',
'agent.name': 'ruby'
}
},
{ data: { source: 'opbeans-python', target: 'opbeans-node' } },
Expand Down Expand Up @@ -78,74 +74,74 @@ storiesOf('app/ServiceMap/Cytoscape', module)
() => {
const cy = cytoscape();
const elements = [
{ data: { id: 'default', label: 'default', type: undefined } },
{ data: { id: 'cache', label: 'cache', type: 'cache' } },
{ data: { id: 'database', label: 'database', type: 'database' } },
{ data: { id: 'external', label: 'external', type: 'external' } },
{ data: { id: 'messaging', label: 'messaging', type: 'messaging' } },
{ data: { id: 'default' } },
{ data: { id: 'cache', label: 'cache', 'span.type': 'cache' } },
{ data: { id: 'database', label: 'database', 'span.type': 'db' } },
{
data: { id: 'external', label: 'external', 'span.type': 'external' }
},
{
data: {
id: 'messaging',
label: 'messaging',
'span.type': 'messaging'
}
},

{
data: {
id: 'dotnet',
label: 'dotnet service',
type: 'service',
agentName: 'dotnet'
'service.name': 'dotnet service',
'agent.name': 'dotnet'
}
},
{
data: {
id: 'go',
label: 'go service',
type: 'service',
agentName: 'go'
'service.name': 'go service',
'agent.name': 'go'
}
},
{
data: {
id: 'java',
label: 'java service',
type: 'service',
agentName: 'java'
'service.name': 'java service',
'agent.name': 'java'
}
},
{
data: {
id: 'js-base',
label: 'js-base service',
type: 'service',
agentName: 'js-base'
'service.name': 'js-base service',
'agent.name': 'js-base'
}
},
{
data: {
id: 'nodejs',
label: 'nodejs service',
type: 'service',
agentName: 'nodejs'
'service.name': 'nodejs service',
'agent.name': 'nodejs'
}
},
{
data: {
id: 'php',
label: 'php service',
type: 'service',
agentName: 'php'
'service.name': 'php service',
'agent.name': 'php'
}
},
{
data: {
id: 'python',
label: 'python service',
type: 'service',
agentName: 'python'
'service.name': 'python service',
'agent.name': 'python'
}
},
{
data: {
id: 'ruby',
label: 'ruby service',
type: 'service',
agentName: 'ruby'
'service.name': 'ruby service',
'agent.name': 'ruby'
}
}
];
Expand All @@ -158,8 +154,8 @@ storiesOf('app/ServiceMap/Cytoscape', module)
<EuiCard
description={
<pre>
agentName: {node.data('agentName') || 'undefined'}, type:{' '}
{node.data('type') || 'undefined'}
agent.name: {node.data('agent.name') || 'undefined'},
span.type: {node.data('span.type') || 'undefined'}
</pre>
}
icon={
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,22 @@
* you may not use this file except in compliance with the Elastic License.
*/

import cytoscape from 'cytoscape';
import React, {
createContext,
CSSProperties,
useState,
useRef,
useEffect,
ReactNode,
createContext,
useCallback
useCallback,
useEffect,
useRef,
useState
} from 'react';
import cytoscape from 'cytoscape';
import { isRumAgentName } from '../../../../../../../plugins/apm/common/agent_name';
import { AGENT_NAME } from '../../../../../../../plugins/apm/common/elasticsearch_fieldnames';
import {
animationOptions,
cytoscapeOptions,
nodeHeight,
animationOptions
nodeHeight
} from './cytoscapeOptions';

export const CytoscapeContext = createContext<cytoscape.Core | undefined>(
Expand Down Expand Up @@ -81,7 +82,7 @@ function getLayoutOptions(
function selectRoots(cy: cytoscape.Core): string[] {
const nodes = cy.nodes();
const roots = nodes.roots();
const rumNodes = nodes.filter(node => isRumAgentName(node.data('agentName')));
const rumNodes = nodes.filter(node => isRumAgentName(node.data(AGENT_NAME)));
return rumNodes.union(roots).map(node => node.id());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
} from '@elastic/eui';
import cytoscape from 'cytoscape';
import React from 'react';
import { SERVICE_FRAMEWORK_NAME } from '../../../../../../../../plugins/apm/common/elasticsearch_fieldnames';
import { Buttons } from './Buttons';
import { Info } from './Info';
import { ServiceMetricFetcher } from './ServiceMetricFetcher';
Expand All @@ -33,7 +34,7 @@ export function Contents({
onFocusClick,
selectedNodeServiceName
}: ContentsProps) {
const frameworkName = selectedNodeData.frameworkName;
const frameworkName = selectedNodeData[SERVICE_FRAMEWORK_NAME];
return (
<EuiFlexGroup
direction="column"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ import { i18n } from '@kbn/i18n';
import cytoscape from 'cytoscape';
import React from 'react';
import styled from 'styled-components';
import {
SPAN_SUBTYPE,
SPAN_TYPE
} from '../../../../../../../../plugins/apm/common/elasticsearch_fieldnames';

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

export function Info({ type, subtype }: InfoProps) {
export function Info(data: InfoProps) {
// For nodes with span.type "db", convert it to "database".
// Otherwise leave it as-is.
const type = data[SPAN_TYPE] === 'db' ? 'database' : data[SPAN_TYPE];

// Externals should not have a subtype so make it undefined if the type is external.
const subtype = data[SPAN_TYPE] !== 'external' && data[SPAN_SUBTYPE];

const listItems = [
{
title: i18n.translate('xpack.apm.serviceMap.typePopoverMetric', {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import React, {
useRef,
useState
} from 'react';
import { SERVICE_NAME } from '../../../../../../../../plugins/apm/common/elasticsearch_fieldnames';
import { CytoscapeContext } from '../Cytoscape';
import { Contents } from './Contents';

Expand All @@ -36,7 +37,7 @@ export function Popover({ focusedServiceName }: PopoverProps) {
const renderedWidth = selectedNode?.renderedWidth() ?? 0;
const { x, y } = selectedNode?.renderedPosition() ?? { x: -10000, y: -10000 };
const isOpen = !!selectedNode;
const isService = selectedNode?.data('type') === 'service';
const isService = selectedNode?.data(SERVICE_NAME) !== undefined;
const triggerStyle: CSSProperties = {
background: 'transparent',
height: renderedHeight,
Expand Down
Loading

0 comments on commit b5f460f

Please sign in to comment.