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

Directed graph layout and presentation #212

Merged
merged 27 commits into from
Jun 25, 2018
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
c9b2a3d
Prep the repo for separately developed components
tiffon Apr 19, 2018
910f614
WIP - Very rough graph layout functionality
tiffon Apr 26, 2018
fbc521a
Graph layout functionality is in solid shape
tiffon May 2, 2018
a124623
Merge branch 'master' into directed-graph
tiffon May 2, 2018
a67f5a9
Fix minor misc issues with plexus layout
tiffon May 2, 2018
28fdf8b
Merge branch 'master' into use-lerna
tiffon May 2, 2018
d3279d5
Fix uberinternal yarn.lock issues
tiffon May 2, 2018
2b5ba78
Fix uberinternal yarn.lock issues
tiffon May 2, 2018
6da2283
Upgrade react to 16.3.2
tiffon May 3, 2018
ec59e7f
Merge branch 'use-lerna' into directed-graph
tiffon May 3, 2018
c92a8b4
Upgrade flow to 0.71.0
tiffon May 3, 2018
3fbea78
Very rough React graph component
tiffon May 6, 2018
b59540f
Enable custom props for graph elements
tiffon May 6, 2018
b39903d
The graph refreshes when it gets new data
tiffon May 6, 2018
f046b3c
Make the jaeger-ui package private
tiffon May 9, 2018
61d70dd
Misc cleanup for plexus package.json
tiffon May 9, 2018
3558e70
Fix issues with plexus package.json
tiffon May 9, 2018
86038f9
Don't output a CSS file for plexus
tiffon May 10, 2018
d7b1ec0
Increase plexus node spacing for neato layouts
tiffon May 10, 2018
b1fc63b
Update plexus to 0.0.1-dev.2
tiffon May 11, 2018
83c1406
Merge branch 'master' into directed-graph-component
tiffon May 11, 2018
d251d6b
Adding new issue and pull request template (#219)
PikBot Jun 16, 2018
ddf250c
plexus readme, remove `LayoutManager.dispose()`
tiffon Jun 24, 2018
d1f3610
Merge branch 'master' into directed-graph-component
tiffon Jun 24, 2018
4c6c121
remove unecessary package
tiffon Jun 24, 2018
d4118f3
Add more complex graphs to plexus demo
tiffon Jun 24, 2018
60ef268
Start the worker ID at 0
tiffon Jun 25, 2018
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
3 changes: 2 additions & 1 deletion .flowconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
.*/node_modules/redux-form/.*
.*/node_modules/react-motion/.*
.*/node_modules/draft-js/.*
.*/node_modules/nwb/.*

[include]

Expand All @@ -12,4 +13,4 @@
[options]

[version]
0.64.0
0.71.0
18 changes: 18 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!--
We appreciate your contribution to the Jaeger project! 👋🎉
Before creating a pull request, please make sure:
- Your PR is solving one problem
- You have read the guide for contributing
- See https://github.com/jaegertracing/jaeger/blob/master/CONTRIBUTING_GUIDELINES.md
- You signed all your commits (otherwise we won't be able to merge the PR)
- See https://github.com/jaegertracing/jaeger/blob/master/CONTRIBUTING_GUIDELINES.md#sign-your-work
- You added unit tests for the new functionality
- You mention in the PR description which issue it is addressing, e.g. "Resolves #123"
-->

## Which problem is this PR solving?
-

## Short description of the changes
-
47 changes: 18 additions & 29 deletions .github/issue_template.md
Original file line number Diff line number Diff line change
@@ -1,39 +1,28 @@
<!--
If you are reporting a new issue, please make sure that we do not have any
duplicates already open. You can ensure this by searching the issue list for
this repository. If there is a duplicate, please close your issue and add a
comment to the existing issue instead.

If you suspect your issue is a bug, please edit your issue description to
include the BUG REPORT INFORMATION shown below. If you fail to provide this
information within 7 days, we cannot debug your issue and will close it. We
will, however, reopen it if you later provide the information.

---------------------------------------------------
BUG REPORT INFORMATION
---------------------------------------------------
Use the commands below to provide key information from your environment:
You do NOT have to include this information if this is a FEATURE REQUEST
Welcome to the Jaeger project! 👋🎉

- Please search for existing issues to avoid creating duplicate bugs/feature requests.
- Please be respectful and considerate of others when commenting on issues.
- Please provide as much information as possible so we all understand the issue.
- If you only have a question, you may get a faster response by asking in
- our chat room https://gitter.im/jaegertracing/Lobby, or
- the forum https://groups.google.com/d/forum/jaeger-tracing
(but please don't double post)
-->

**Description**
## Requirement - what kind of business use case are you trying to solve?

<!--
Briefly describe the problem you are having in a few paragraphs.
-->

**Steps to reproduce the issue:**
1.
2.
3.

**Describe the results you received:**
<!-- required section -->

## Problem - what in Jaeger blocks you from solving the requirement?

**Describe the results you expected:**
<!-- required section -->
<!-- If possible, describe the impact of the problem. -->

## Proposal - what do you suggest to solve the problem or improve the existing situation?

**Additional information you deem important (e.g. issue happens only occasionally):**
<!-- It's ok if you don't have one. -->

## Any open questions to address

**Additional environment details (Browser, etc.):**
<!-- Questions that should be answered before proceeding with implementation. -->
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ coverage
npm-debug.log
.vscode
yarn-error.log
*.ignore.*
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"private": true,
"license": "Apache-2.0",
"devDependencies": {
"babel-eslint": "^7.2.3",
"eslint": "^4.5.0",
Expand All @@ -10,6 +11,7 @@
"eslint-plugin-import": "^2.7.0",
"eslint-plugin-jsx-a11y": "^6.0.2",
"eslint-plugin-react": "^7.2.1",
"flow-bin": "^0.71.0",
"glow": "^1.2.2",
"husky": "^0.14.3",
"lerna": "^2.10.2",
Expand All @@ -26,7 +28,7 @@
"lint": "npm run eslint && npm run prettier && npm run flow && npm run check-license",
"precommit": "lint-staged",
"prettier":
"prettier --write '{.,scripts}/*.{js,json,md}' 'packages/*/src/**/*.{css,js,json,md}' 'packages/*/*.{css,js,json,md}'",
"prettier --write '{.,scripts}/*.{js,json,md}' 'packages/*/{src,demo/src}/**/*.{css,js,json,md}' 'packages/*/*.{css,js,json,md}'",
"test": "lerna run test"
},
"prettier": {
Expand Down
7 changes: 4 additions & 3 deletions packages/jaeger-ui/package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
{
"private": true,
"name": "jaeger-ui",
"version": "0.0.1",
"main": "src/index.js",
"license": "MIT",
"license": "Apache-2.0",
"proxy": {
"/api": {
"target": "http://localhost:16686",
Expand Down Expand Up @@ -51,9 +52,9 @@
"prop-types": "^15.5.10",
"query-string": "^5.0.0",
"raven-js": "^3.22.1",
"react": "^16.3.0",
"react": "^16.3.2",
"react-dimensions": "^1.3.0",
"react-dom": "^16.3.0",
"react-dom": "^16.3.2",
"react-ga": "^2.4.1",
"react-helmet": "^5.1.3",
"react-icons": "^2.2.7",
Expand Down
10 changes: 6 additions & 4 deletions packages/jaeger-ui/src/components/App/TopNav.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,16 @@ export default function TopNav(props: TopNavProps) {
return (
<div>
<Menu theme="dark" mode="horizontal" selectable={false} className="ub-right" selectedKeys={[activeKey]}>
{menuItems.map(item => {
if (item.items) {
{menuItems.map(m => {
if (m.items != null) {
const group = ((m: any): ConfigMenuGroup);
return (
<Menu.Item key={item.label}>
<CustomNavDropdown key={item.label} {...item} />
<Menu.Item key={group.label}>
<CustomNavDropdown key={group.label} {...group} />
</Menu.Item>
);
}
const item = ((m: any): ConfigMenuItem);
return (
<Menu.Item key={item.label}>
<a href={item.url} target="_blank" rel="noopener noreferrer">
Expand Down
4 changes: 4 additions & 0 deletions packages/plexus/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
demo/dist
es
lib
umd
13 changes: 13 additions & 0 deletions packages/plexus/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# plexus

plexus is a React component for rendering directed graphs.

## Why?

To support directed graphs in Jaeger-UI, we surveyed the JavaScript libraries and utilities available for rendering directed graphs. The landscape is impressive, but we concluded the venerable [GraphViz](https://graphviz.gitlab.io/) ([alt](https://www.graphviz.org/)) is the right tool for us.

GraphViz is awesome, but the output formats don't fit our needs. We've elected to use GraphViz to generate the layouts (node positioning, edge routing) and React for rendering.

## viz.js

The excellent [viz.js](https://github.com/mdaines/viz.js) is used, in a WebWorker, to generate GraphViz as plain-text output which is then parsed and provided to a React component which does the rendering.
84 changes: 84 additions & 0 deletions packages/plexus/demo/src/data-small.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Copyright (c) 2017 Uber Technologies, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import * as React from 'react';

export const varied = {
vertices: [
{ key: 'string key 0', data: { value: new Date(), message: 'vertex w a string key that has spaces' } },
{
key: 1,
label: 'Key is the number 1Key is the number 1Key',
data: { err: new Error(9), message: 'vertex with a number key and a string label' },
},
{ key: '2', label: <h3>OMG an H3</h3>, data: { message: 'label is an H3 React element' } },
{
key: 33,
label: 'Key is the number 1Key is the number 1Key',
data: { value: /abc/, message: 'data contains a RegExp and the node lacks a label' },
},
],
edges: [
{ from: 'string key 0', to: 1, label: 'The Great Edge Label', data: 'Edge with a string label' },
{
from: 'string key 0',
to: '2',
label: <strong>Drop it like its hot</strong>,
data: 'edge with a React.Node label',
},
{ from: '1', to: '2', data: 'edge sans label' },
{ from: '2', to: 33, isBidirectional: true, data: 'A bidirection edge' },
],
};

export const colored = {
vertices: [
{ key: 'string key 0', data: 'red' },
{
key: 1,
label: 'Key is the number 1',
data: 'blue',
},
{ key: '2', label: <h3>OMG an H3</h3>, data: 'green' },
{ key: 33, data: 'teal' },
],
edges: [
{ from: 'string key 0', to: 1, label: 'The Great Edge Label', data: '#c00' },
{
from: 'string key 0',
to: '2',
label: <strong>Drop it like its hot</strong>,
data: '#0c0',
},
{ from: '1', to: '2', data: '#00c' },
{ from: '2', to: 33, isBidirectional: true, data: '#c0c' },
],
};

export function getColorNodeLabel(vertex) {
let { label } = vertex;
label = label == null ? String(vertex.key) : label;
if (typeof label !== 'string' && !React.isValidElement(label)) {
label = String(label);
}
return <span style={{ color: vertex.data }}>{label}</span>;
}

export function setOnColorNode(vertex) {
const style = { border: `1px solid ${vertex.data}` };
return { style };
}
export function setOnColorEdge(edge) {
return { stroke: edge.data };
}
3 changes: 3 additions & 0 deletions packages/plexus/demo/src/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
html {
font-family: Arial, Helvetica, sans-serif;
}
70 changes: 70 additions & 0 deletions packages/plexus/demo/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright (c) 2017 Uber Technologies, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import * as React from 'react';
// eslint-disable-next-line import/no-extraneous-dependencies
import { render } from 'react-dom';

// import large from './data-large.ignore';
import { varied, colored, getColorNodeLabel, setOnColorEdge, setOnColorNode } from './data-small';
import { DirectedGraph, LayoutManager } from '../../src';

import './index.css';

const addAnAttr = () => ({ 'data-rando': Math.random() });

class Demo extends React.Component {
state = {
data: colored,
colorData: true,
};

constructor(props) {
super(props);
this.layoutManager = new LayoutManager();
}

handleClick = () => {
const { colorData } = this.state;
this.setState({
colorData: !colorData,
data: colorData ? varied : colored,
});
};

render() {
const { data, colorData } = this.state;
return (
<div>
<h1>
<a href="#" onClick={this.handleClick}>
plexus Demo
</a>
</h1>
<DirectedGraph
layoutManager={this.layoutManager}
getNodeLabel={colorData ? getColorNodeLabel : null}
setOnEdgePath={colorData ? setOnColorEdge : null}
setOnNode={colorData ? setOnColorNode : null}
setOnEdgesContainer={addAnAttr}
setOnNodesContainer={addAnAttr}
setOnRoot={addAnAttr}
{...data}
/>
</div>
);
}
}

render(<Demo />, document.querySelector('#demo'));
Loading