Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move filter to query param and highlight filter matches on graphs #310

Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
bdc0220
Add a TraceGraph view (#273) (#276)
copa2 Dec 18, 2018
4112482
Revisions for search and trace detail embed mode (#286)
tiffon Dec 20, 2018
2baf075
Unfocus unit test (#298)
tiffon Dec 20, 2018
d90d042
Add a Button to Reset Viewing Layer Zoom (#215) (#290)
everett980 Jan 3, 2019
29b340d
Add a copy icon to entries in KeyValuesTable (#204) (#292)
everett980 Jan 4, 2019
e0f34e4
Add popover and prevent submit if duration params are invalid (#244) …
everett980 Jan 4, 2019
bf70c14
Add indent guides to trace timeline view (#172) (#297)
everett980 Jan 4, 2019
07c7f4f
Add ability to search for nodes in TraceDiffGraph and TraceGraph (#307)
everett980 Jan 7, 2019
1953db5
Style GraphSearch, Debounce query param updating
everett980 Jan 8, 2019
e918deb
Use hex instead of html colors, remove commented code
everett980 Jan 8, 2019
181562c
Handle falsy graphSearch value in state, improve typing
everett980 Jan 8, 2019
edf4805
Move GraphSearch and use as utility
everett980 Jan 8, 2019
d1e05d6
Add tests for GraphSearch
everett980 Jan 8, 2019
6ea7d6a
Update create-react-app to 2.1.2 (#302)
tiffon Jan 9, 2019
5fa907b
Add tests for consuming GraphSearch, Add tests for filter-spans
everett980 Jan 9, 2019
0122fd7
Improve spy variable name
everett980 Jan 9, 2019
f08a609
Ability to open additional menu links in same tab (Resolves #275) (#278)
zablvit Jan 9, 2019
8e2df85
Revive the changelog (#300)
tiffon Jan 12, 2019
7ea05f4
Add SpanID support to filter-spans, Consolidate textFilter & GraphSearch
everett980 Jan 15, 2019
2bf1b43
Unify uiFind name, fix refs, improve types, remove commented code
everett980 Jan 15, 2019
353d69c
Add tests to new & tested files, merge common/GraphSearch into user
everett980 Jan 15, 2019
99b7a6c
Update exisitng test files
everett980 Jan 16, 2019
10b5194
Polish filter-spans
everett980 Jan 16, 2019
dd9f14c
Merge branch 'jaegertracingmaster' into issue-307-add-node-search-to-…
everett980 Jan 16, 2019
0c5b591
Use uppercase types, remove constructor for initial state
everett980 Jan 16, 2019
50db264
Update enzyme, Re-enable and add TracePage/index.test.js tests
everett980 Jan 25, 2019
9a7e0c1
Merge branch 'jaegertracingmaster' into issue-307-add-node-search-to-…
everett980 Jan 25, 2019
ef880c7
Merge branch 'issue-307-add-node-search-to-tracegraph-and-tracediffgr…
everett980 Jan 25, 2019
e531d6e
Add tests to TraceDiff/
everett980 Feb 6, 2019
fe420c6
Treat all span relationships equally, make ui-find-match css more obv…
everett980 Feb 7, 2019
a5178e0
Fix node/edge layering, simplify ui-find-match css
everett980 Feb 7, 2019
66f080d
Change diffNode ui match color, scale ui match outline size
everett980 Feb 15, 2019
9dc1a4e
Calculate box-shadow size on nodesContainer not drawNode
everett980 Feb 20, 2019
f685d47
Fix color attributes to preserve node text color
everett980 Feb 21, 2019
b6b40c0
Rename UIFind to UiFind, Update TraceDiffFind
everett980 Feb 21, 2019
acd3e66
Finish DiffGraph find css, Render 0 count suffix
everett980 Feb 25, 2019
2434056
merge master and update test
everett980 Feb 25, 2019
51337fb
Fix git case insensitivity issue
everett980 Feb 26, 2019
4313988
Merge branch 'issue-307-add-node-search-to-tracegraph-and-tracediffgr…
everett980 Feb 26, 2019
1f5421d
Merge updated graph find, maintain increased test coverage
everett980 Feb 26, 2019
69a576a
Remove redundant find, Fix TraceGraph suffix, Fix flow complaint, WIP
everett980 Mar 1, 2019
259cd13
Clean up WIP commit
everett980 Mar 5, 2019
15c51d5
Clean up CSS, Track only TracePage, Fix span-ancestor-ids logic
everett980 Mar 5, 2019
a1f5e59
Ensure scroll to bottom scrolls to last visible span
everett980 Mar 5, 2019
aa3f2e5
Move addToUiFind logic to VirtualizedTraceView
everett980 Mar 5, 2019
df9bafd
Merge branch 'master' into issue-307-add-node-search-to-tracegraph-an…
everett980 Mar 5, 2019
7422720
Merge branch 'issue-307-add-node-search-to-tracegraph-and-tracediffgr…
everett980 Mar 6, 2019
c5034fa
Process FOLLOWS_FROM spans in TraceView (#335)
rubenvp8510 Mar 7, 2019
95026f9
Move graph utils to new file, Clean up span-ancestor-id loop
everett980 Mar 7, 2019
c3d4d14
fix merge again
everett980 Mar 8, 2019
bf3386f
Merge branch 'issue-307-add-node-search-to-tracegraph-and-tracediffgr…
everett980 Mar 8, 2019
b4afe2d
Update tests after merge
everett980 Mar 8, 2019
de6571f
Merge pull request #1 from everett980/issue-239-fix-TracePageHeader-t…
everett980 Mar 8, 2019
5386868
Clean up and DRY out tests, Change trackFilter to function
everett980 Mar 11, 2019
5971072
Merge branch 'jaegertracingmaster' into issue-307-add-node-search-to-…
everett980 Mar 11, 2019
c5f40c8
Fix yarn.lock urls
everett980 Mar 11, 2019
8a4b0fb
Fix yarn.lock change %2f back to /
everett980 Mar 11, 2019
d3965dc
Merge branch 'master' into issue-307-add-node-search-to-tracegraph-an…
tiffon Mar 12, 2019
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 @@ -47,6 +47,37 @@ limitations under the License.
stroke-width: 0.7;
}

/* Find within diff */
.TraceDiffGraph--uiFind {
border: solid 1px #a9a9a9;
border-radius: 21px;
bottom: 20px;
cursor: auto;
display: flex;
padding: 5px;
position: absolute;
right: 20px;
z-index: 1;
}

.TraceDiffGraph--uiFind--input {
width: 300px;
transition: ease 1s;
margin: 0px 3px;
}

.TraceDiffGraph--uiFind:not(:hover) > .TraceDiffGraph--uiFind--input:not(:focus) {
border: none;
padding: 0px;
width: 0;
margin: 0px;
}

.TraceDiffGraph--uiFind--icon {
cursor: pointer;
font-size: 32px;
}
everett980 marked this conversation as resolved.
Show resolved Hide resolved

tiffon marked this conversation as resolved.
Show resolved Hide resolved
/* DAG minimap */

.TraceDiffGraph--miniMap {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@
// limitations under the License.

import * as React from 'react';
import { Icon, Input } from 'antd';
import { DirectedGraph, LayoutManager } from '@jaegertracing/plexus';

import drawNode from './drawNode';
import ErrorMessage from '../../common/ErrorMessage';
import LoadingIndicator from '../../common/LoadingIndicator';
import UIFindInput from '../../common/UIFindInput';
everett980 marked this conversation as resolved.
Show resolved Hide resolved
import { fetchedState } from '../../../constants';
import convPlexus from '../../../model/trace-dag/convPlexus';
import TraceDag from '../../../model/trace-dag/TraceDag';
Expand All @@ -42,23 +44,33 @@ function setOnEdgesContainer(state: Object) {
}
const { k } = zoomTransform;
const opacity = 0.1 + k * 0.9;
return { style: { opacity } };
return { style: { opacity, zIndex: 1 } };
everett980 marked this conversation as resolved.
Show resolved Hide resolved
}

function setOnNodesContainer() {
return { style: { zIndex: -1 } };
}

export default class TraceDiffGraph extends React.PureComponent<Props> {
props: Props;
_uiFindInputRef: { current: Input | null };

layoutManager: LayoutManager;

constructor(props: Props) {
super(props);
this.layoutManager = new LayoutManager({ useDotEdges: true, splines: 'polyline' });
this._uiFindInputRef = React.createRef();
}

componentWillUnmount() {
this.layoutManager.stopAndRelease();
}

handleIconClick = () => {
everett980 marked this conversation as resolved.
Show resolved Hide resolved
if (this._uiFindInputRef.current) this._uiFindInputRef.current.focus();
};

render() {
const { a, b } = this.props;
if (!a || !b) {
Expand Down Expand Up @@ -109,9 +121,17 @@ export default class TraceDiffGraph extends React.PureComponent<Props> {
getNodeLabel={drawNode}
setOnRoot={classNameIsSmall}
setOnEdgesContainer={setOnEdgesContainer}
setOnNodesContainer={setOnNodesContainer}
edges={edges}
vertices={vertices}
/>
<div className="TraceDiffGraph--uiFind">
<UIFindInput
forwardedRef={this._uiFindInputRef}
inputProps={{ className: 'TraceDiffGraph--uiFind--input' }}
/>
<Icon className="TraceDiffGraph--uiFind--icon" onClick={this.handleIconClick} type="search" />
</div>
</div>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,13 @@ limitations under the License.
color: #fff;
}

.DiffNode.is-ui-find-match {
everett980 marked this conversation as resolved.
Show resolved Hide resolved
outline-style: solid;
outline-color: #050;
outline-width: 2px;
box-shadow: 0 0 4px 8px #0d0;
}

.DiffNode--metricCell {
padding: 0.3rem 0.5rem;
background: rgba(255, 255, 255, 0.3);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,24 @@
import * as React from 'react';
import { Popover } from 'antd';
import cx from 'classnames';
import _get from 'lodash/get';
import _map from 'lodash/map';
import _memoize from 'lodash/memoize';
import { connect } from 'react-redux';

import CopyIcon from '../../common/CopyIcon';
import { extractUIFindFromState } from '../../common/UIFindInput';
import filterSpans from '../../../utils/filter-spans';

import type { PVertex } from '../../../model/trace-dag/types';
import type { PVertex, DenseSpan } from '../../../model/trace-dag/types';

import './drawNode.css';

type Props = {
a: number,
b: number,
uiFind: string,
members: DenseSpan[],
operation: string,
service: string,
};
Expand All @@ -36,9 +44,18 @@ const max = Math.max;

class DiffNode extends React.PureComponent<Props> {
props: Props;
filterSpans: typeof filterSpans;
static defaultProps = {
uiFind: '',
};

constructor(props: Props) {
super(props);
this.filterSpans = _memoize(filterSpans);
}

render() {
const { a, b, operation, service } = this.props;
const { a, b, uiFind, operation, service } = this.props;
const isSame = a === b;
const className = cx({
'is-same': isSame,
Expand All @@ -47,6 +64,7 @@ class DiffNode extends React.PureComponent<Props> {
'is-added': a === 0,
'is-less': a > b && b > 0,
'is-removed': b === 0,
'is-ui-find-match': _get(this.filterSpans(uiFind, _map(this.props.members, 'span')), 'size'),
});
const chgSign = a < b ? '+' : '-';
const table = (
Expand Down Expand Up @@ -88,7 +106,9 @@ class DiffNode extends React.PureComponent<Props> {
}
}

const ConnectedDiffNode = connect(extractUIFindFromState)(DiffNode);

export default function drawNode<T>(vertex: PVertex<T>) {
const { data, operation, service } = vertex.data;
return <DiffNode {...data} operation={operation} service={service} />;
const { data, members, operation, service } = vertex.data;
return <ConnectedDiffNode {...data} members={members} operation={operation} service={service} />;
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,20 @@ limitations under the License.
cursor: pointer;
white-space: nowrap;
border-collapse: separate;
border-radius: 2px;
}

.OpNode td,
.OpNode th {
border: none;
}

.OpNode.is-ui-find-match {
outline-style: solid;
outline-color: #050;
outline-width: 2px;
box-shadow: 0 0 4px 8px #0d0;
}

.OpMode--mode-service {
background: #bbb;
}
Expand Down
47 changes: 42 additions & 5 deletions packages/jaeger-ui/src/components/TracePage/TraceGraph/OpNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,18 @@

import * as React from 'react';
import { Popover } from 'antd';
import cx from 'classnames';
import _get from 'lodash/get';
import _map from 'lodash/map';
import _memoize from 'lodash/memoize';
import { connect } from 'react-redux';

import CopyIcon from '../../common/CopyIcon';
import { extractUIFindFromState } from '../../common/UIFindInput';
import colorGenerator from '../../../utils/color-generator';
import filterSpans from '../../../utils/filter-spans';

import type { PVertex } from '../../../model/trace-dag/types';
import type { PVertex, DenseSpan } from '../../../model/trace-dag/types';

import './OpNode.css';

Expand All @@ -34,6 +41,8 @@ type Props = {
operation: string,
service: string,
mode: string,
uiFind: string,
members: DenseSpan[],
};

export const MODE_SERVICE = 'service';
Expand Down Expand Up @@ -65,9 +74,29 @@ export function round2(percent: number) {

export default class OpNode extends React.PureComponent<Props> {
props: Props;
filterSpans: typeof filterSpans;
static defaultProps = {
uiFind: '',
};

constructor(props: Props) {
super(props);
this.filterSpans = _memoize(filterSpans);
}

render() {
const { count, errors, time, percent, selfTime, percentSelfTime, operation, service, mode } = this.props;
const {
count,
errors,
time,
percent,
selfTime,
percentSelfTime,
operation,
service,
mode,
uiFind,
} = this.props;

// Spans over 20 % time are full red - we have probably to reconsider better approach
let backgroundColor;
Expand All @@ -83,8 +112,12 @@ export default class OpNode extends React.PureComponent<Props> {
.join();
}

const className = cx('OpNode', `OpNode--mode-${mode}`, {
'is-ui-find-match': _get(this.filterSpans(uiFind, _map(this.props.members, 'span')), 'size'),
});

const table = (
<table className={`OpNode OpNode--mode-${mode}`} cellSpacing="0">
<table className={className} cellSpacing="0">
<tbody
style={{
background: `rgba(${backgroundColor})`,
Expand Down Expand Up @@ -125,9 +158,13 @@ export default class OpNode extends React.PureComponent<Props> {
}
}

const ConnectedOpNode = connect(extractUIFindFromState)(OpNode);

export function getNodeDrawer(mode: string) {
return function drawNode<T>(vertex: PVertex<T>) {
const { data, operation, service } = vertex.data;
return <OpNode {...data} mode={mode} operation={operation} service={service} />;
const { data, members, operation, service } = vertex.data;
return (
<ConnectedOpNode {...data} members={members} mode={mode} operation={operation} service={service} />
);
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,13 @@

import React from 'react';
import { shallow } from 'enzyme';
import _map from 'lodash/map';

import OpNode, { getNodeDrawer, MODE_SERVICE, MODE_TIME, MODE_SELFTIME } from './OpNode';
import CopyIcon from '../../common/CopyIcon';
import filterSpansMock from '../../../utils/filter-spans';

jest.mock('../../../utils/filter-spans');

describe('<OpNode>', () => {
let wrapper;
Expand All @@ -28,23 +32,25 @@ describe('<OpNode>', () => {
props = {
count: 5,
errors: 0,
time: 200000,
uiFind: 'uiFind',
members: [{ span: { spanID: 'memberSpanID0' } }, { span: { spanID: 'memberSpanID1' } }],
operation: 'op1',
percent: 7.89,
selfTime: 180000,
percentSelfTime: 90,
operation: 'op1',
selfTime: 180000,
service: 'service1',
time: 200000,
};
wrapper = shallow(<OpNode {...props} mode={mode} />);
});

it('it does not explode', () => {
it('does not explode', () => {
expect(wrapper).toBeDefined();
expect(wrapper.find('.OpNode').length).toBe(1);
expect(wrapper.find('.OpNode--mode-service').length).toBe(1);
});

it('it renders OpNode', () => {
it('renders OpNode', () => {
expect(wrapper.find('.OpNode--count').text()).toBe('5 / 0');
expect(wrapper.find('.OpNode--time').text()).toBe('200 ms (7.89 %)');
expect(wrapper.find('.OpNode--avg').text()).toBe('40 ms');
Expand All @@ -58,7 +64,7 @@ describe('<OpNode>', () => {
).toBe('service1');
});

it('it switches mode', () => {
it('switches mode', () => {
mode = MODE_SERVICE;
wrapper = shallow(<OpNode {...props} mode={mode} />);
expect(wrapper.find('.OpNode--mode-service').length).toBe(1);
Expand All @@ -78,6 +84,15 @@ describe('<OpNode>', () => {
expect(wrapper.find('.OpNode--mode-selftime').length).toBe(1);
});

it('updates class when it matches search', () => {
const uiFind = 'newUIFindToTriggerRender';
expect(wrapper.find('.is-ui-find-match').length).toBe(0);
filterSpansMock.mockReturnValue({ size: 1 });
wrapper.setProps({ uiFind });
expect(wrapper.find('.is-ui-find-match').length).toBe(1);
expect(filterSpansMock).toHaveBeenLastCalledWith(uiFind, _map(props.members, 'span'));
});

it('renders a copy icon', () => {
const copyIcon = wrapper.find(CopyIcon);
expect(copyIcon.length).toBe(1);
Expand All @@ -86,7 +101,7 @@ describe('<OpNode>', () => {
});

describe('getNodeDrawer()', () => {
it('it creates OpNode', () => {
it('creates OpNode', () => {
const vertex = {
data: {
service: 'service1',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ function setOnEdgesContainer(state: Object) {
return { style: { opacity } };
}

function setOnNodesContainer() {
return { style: { zIndex: -1 } };
}

const HELP_CONTENT = (
<div className="TraceGraph--help-content">
{HELP_TABLE}
Expand Down Expand Up @@ -267,6 +271,7 @@ export default class TraceGraph extends React.PureComponent<Props, State> {
setOnRoot={classNameIsSmall}
setOnEdgePath={setOnEdgePath}
setOnEdgesContainer={setOnEdgesContainer}
setOnNodesContainer={setOnNodesContainer}
edges={ev.edges}
vertices={ev.vertices}
/>
Expand Down
Loading