Skip to content

Commit

Permalink
Configuration from the UI (#22)
Browse files Browse the repository at this point in the history
* Allow server configuration inside the UI

* correct configuration settings and change page layout

* update search explanation
  • Loading branch information
bricaud authored Apr 16, 2018
1 parent 8aa6947 commit b70b941
Show file tree
Hide file tree
Showing 7 changed files with 283 additions and 218 deletions.
28 changes: 17 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@ Graphexp is a lightweight web interface to explore and display a graph stored in

Graphexp is under the Apache 2.0 license.

![graphexp](https://github.com/bricaud/graphexp/blob/master/images/graphexp2.png "Graph exploration")
![graphexp](https://github.com/bricaud/graphexp/blob/master/images/graphexp2018.png "Graph exploration")


## Configuration

To use Graph Explorer, you need a [Gremlin server](http://tinkerpop.apache.org/) running with REST or websocket protocol and a *recent* web browser to display the visualization.
On your web browser, just access the file `graphexp.html`.

If the access to the Gremlin server is not `localhost:8182`, the address can be configured in `graphConf.js`. Use this latter file to configure the communication protocol `REST` (default) or `websocket`. Depending on the version of your Gremlin server you also need to configure the `COMMUNICATION_METHOD`, `GraphSON1` for Gremlin server version 3.2.x or `GraphSON3` for versions 3.3.x.
Next step, configure the server settings on the bottom of the page. The default Gremlin server address is `localhost:8182`. You will have to specify the communication protocol `websocket` or `REST` and the gremlin server version. Graphexp is not able to handle secure connections yet and a contribution on this topic would be welcome.

Graphexp now works with Amazon Neptune thanks to a pull request of [jwalton922](https://github.com/jwalton922). With this database, set `SINGLE_COMMANDS_AND_NO_VARS = true` in `graphConf.js`.
Graphexp works with Amazon Neptune thanks to a pull request of [jwalton922](https://github.com/jwalton922). With this database, set `SINGLE_COMMANDS_AND_NO_VARS = true` in the file `graphConf.js`.

![graphexpzoom](https://github.com/bricaud/graphexp/blob/master/images/graphexpzoom.png "Exploration of the Tinkerpop modern graph")

Expand Down Expand Up @@ -50,26 +50,26 @@ docker run -p 8182:8182 -it --name gremlin-server-websocket bricaud/gremlin-serv
You may also try out a Graphexp demo on [joov's Github repository](https://github.com/joov/gremlin-demo). It uses Docker compose and can work on Windows.

### Graphexp guidelines
To display a node, type in a property name and value, then click on the search button. The input is case-sensitive.
Leaving a blank value will display a part of the graph limited to the first 50 nodes found (with their connections).
The node and edge properties can be automatically retrieved using the `get graph info` button. Pushing this button will also display some graph properties on the left side of the page. If it is not the case, check your configuration, it means Graphexp can not query the graphDB.

To get some first visualization of your graph, you may click on the `Search` button, without filling any box. Graphexp will then send a query to the graph DB, asking for the first 50 nodes and their edges.

The node and edge properties can be automatically retrieved using the `get graph info` button. Pushing this button will also display some graph properties on the left side of the page. If it is not the case, check your configuration, it means Graphexp can not query the graphDB.

When a node of the visualization is clicked, it will become 'active' with a circle surrounding it and its information will be displayed on the right side of the page. Moreover, this action will trigger the display of its neighbors.
Clicking on an edge will show its properties (without highlighting the edge).

When appearing for the first time the nodes will be positioned following a force layout. Drag and drop can be used to pin them in a particular position. Once dragged the nodes will stay at their position. Drag and drop is allowed only for the nodes on the active layer (most recent layer) with no connection with nodes in other layers. See "Visualization concepts" section for more information on the layers.

### Querying the graphDB
In the top bar, you can search the graphDB to display particular nodes.
In the top bar, you can search the graphDB to display a particular node or group of nodes.

* The box `Enter a label` allows you to display all the nodes with a particular label.
* The box `Enter a field`, in combination with the `Enter a keyword/value` box, allows to find nodes with a particular keyword or value in their properties (fields are node properties). The `Type of search` allows for a perfect (equals) or partial match (Contains). *Note that the 'contains' option will only work with Janusgraph*.
* The box `Node label` allows to filter nodes with a particular label during the search.
* The box `Node property`, in combination with the `Property value` box, allows to find nodes with a particular keyword or value in their properties. The `Type of search` allows for a perfect (equals) or partial match (Contains). *Note that the 'contains' option will only work with Janusgraph*.
* The box `Traverse by edge` acts directly in the interactive visualization. If an edge label is entered in the box, clicking on a node will only display its neighbors connected with that type of edge label.
* The `Results limit` is here to avoid overwhelming the visualization. It fixes the maximal le number of nodes to display per query.
* If `Freeze exploration` is ticked, the graph displayed will stay the same even if nodes are clicked on. It is useful when you just need to display the node properties.
* `Number of layers` is explained below in the "Visualization concepts" section.
* `Number of layers` is explained below in the "Visualization concept" section.

Note that the input is case-sensitive.

## Visualization concept

Expand All @@ -94,6 +94,12 @@ The program uses:
* the D3.js library to visualize a graph in an interactive manner, [API Reference](https://github.com/d3/d3/blob/master/API.md),
* an ajax request (with Jquery) that query the graph database (Gremlin Tinkerpop via REST).


## Contributing
Contribution as pull requests are very welcome.
If you want to contribute, you may have a look at the [issues](https://github.com/bricaud/graphexp/issues). You can also submit a pull request with a new feature. When contributing, keep in mind that graphexp must stays simple. The idea is to have a simple tool for a quick (and efficient) graph exploration.


## Tutorial with the tree of life
Once your gremlin server is up and running (from the [Docker repository](https://hub.docker.com/r/bricaud/gremlin-server-with-demo-graph/)), click on the `get graph info` button. Information should appear on the left side of the page, like on the following image.
![graphexptol1](https://github.com/bricaud/graphexp/blob/master/images/graphexptol1.png "Graph exploration Tree of life")
Expand Down
16 changes: 13 additions & 3 deletions css/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ a:focus { color: black; }
a:hover { color: green; }
a:active { color: red; }

input[type="number"] {
width:50px;
}

/* -----------------------
Layout styles
------------------------*/
Expand Down Expand Up @@ -101,13 +105,19 @@ Layout styles
grid-template-rows: auto 15%;
}

.nav.inputs_container {
.nav.inputs_container_top {
grid-row: 1 / 2;
display: grid;
grid-template-columns: auto auto auto auto auto;
grid-auto-flow: row;
}

.nav.inputs_container_bottom {
grid-row: 1 / 2;
display: grid;
grid-template-columns: auto auto auto auto;
grid-auto-flow: row;
}
.nav.input_unit_container {
padding: 5px;
align-self: center;
Expand All @@ -118,9 +128,9 @@ Layout styles
}

.nav.controls {
grid-row: 2 / 3;
grid-row: 1 / span 3;
justify-self: center;
padding-top: 5px;
align-self: center;
}

.content
Expand Down
55 changes: 43 additions & 12 deletions graphexp.html
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,18 @@ <h1 class="header-heading">Graph Explorer v 0.6</h1>
</div>
-->
<div class="nav-bar">
<div class="nav container" id="nav_bar">
<div class="nav inputs_container">
<div class="nav container" id="search_bar">
<div class="nav inputs_container_top">
<div class="nav input_unit_container">
<label for="label_field">Enter a label:</label>
<label for="label_field">Node label:</label>
<input name="label_field" id="label_field" value="" />
</div>
<div class="nav input_unit_container">
<label for="search_field">Enter a field: </label>
<label for="search_field">Node property:</label>
<input name="search_field" id="search_field" value="" />
</div>
<div class="nav input_unit_container">
<label class="nav input_label" for="search_value">Enter a Keyword/value: </label>
<label class="nav input_label" for="search_value">Property value:</label>
<input name="search_value" id="search_value" value="" />
</div>
<div class="nav input_unit_container">
Expand All @@ -72,14 +72,21 @@ <h1 class="header-heading">Graph Explorer v 0.6</h1>
</div>
<div class="nav input_unit_container">
<label for="limit_field">Results limit:</label>
<input name="limit_field" id="limit_field" value="50" min="1" max="1000" type="number" />
<input name="limit_field" id="limit_field" value="50" min="1" max="1000" type="number"/>
</div>
</div>
<div class="nav controls">
<button name="search query" onclick="search_query();">Search</button>
</div>
</div>
<div class="nav container" id="graph_bar">
<div class="nav inputs_container_bottom">
<div class="nav input_unit_container">
<label class="nav input_label" for="edge_filter">Traverse by edge: </label>
<label class="nav input_label" for="edge_filter">Traverse by edge:</label>
<input name="edge_filter" id="edge_filter" value="" />
</div>
<div class="nav input_unit_container">
<label class="nav input_label" for="nbLayers">Nb of layers </label>
<label class="nav input_label" for="nbLayers">Nb of layers</label>
<input type="number" id="nbLayers" min="1" max="128" onclick="set_nb_layers()">
</div>
<div class="nav input_unit_container">
Expand All @@ -92,7 +99,6 @@ <h1 class="header-heading">Graph Explorer v 0.6</h1>
</div>
</div>
<div class="nav controls">
<button name="search query" onclick="search_query();">Search</button>
<button name="clear" onclick="graph_viz.clear();">Clear</button>
</div>
</div>
Expand Down Expand Up @@ -124,6 +130,30 @@ <h1 class="header-heading">Graph Explorer v 0.6</h1>
</div>
<div class="footer">
<div class="container">
<div class="nav inputs_container_top">
<div class="nav input_unit_container">
<label class="nav input_label" for="server_address">Server Address:</label>
<input name="server_address" id="server_address" value="localhost" />
</div>
<div class="nav input_unit_container">
<label class="nav input_label" for="server_port">Server port:</label>
<input name="server_port" id="server_port" type="number" value="8182"/>
</div>
<div class="nav input_unit_container">
<label for="server_protocol">Protocol:</label>
<select name="server_protocol" id="server_protocol">
<option value="websocket">websocket</option>
<option value="REST">REST</option>
</select>
</div>
<div class="nav input_unit_container">
<label for="communication_method">Gremlin version:</label>
<select name="communication_method" id="communication_method">
<option value="GraphSON3">3.3.*</option>
<option value="GraphSON2">3.2.*</option>
</select>
</div>
</div>
<a href="http://www.github.com/bricaud/graphexp">Graph Explorer V 0.7</a>
</div>
</div>
Expand Down Expand Up @@ -214,7 +244,7 @@ <h1 class="header-heading">Graph Explorer v 0.6</h1>

function colorize(selection){
var value = selection.value;
console.log(value);
console.log('Color by '+value);
graphShapes.colorize(value);

}
Expand Down Expand Up @@ -276,16 +306,17 @@ <h1 class="header-heading">Graph Explorer v 0.6</h1>


function get_prop_value(d,prop_name,item){
//let COMMUNICATION_METHOD = $('#communication_method').val();
if (prop_name in d.properties){
if (item=='nodes'){
if (COMMUNICATION_METHOD == 'GraphSON3') {
if ('summary' in d.properties[prop_name]) {
return d.properties[prop_name]['summary'];
} else if (COMMUNICATION_METHOD == 'GraphSON1') {
return d.properties[prop_name][0].value;
}
}
else if (item=='edges'){
console.log(d.properties[prop_name])
//console.log(d.properties[prop_name])
return d.properties[prop_name];
}
}
Expand Down
Binary file added images/graphexp2018.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 3 additions & 11 deletions scripts/graphConf.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,14 @@

// configuration for the graph database access
const HOST = "localhost";
const PORT = "8182";

// for implementations like Neptune where only single commands are allowed per request
// For implementations like Neptune where only single commands are allowed per request
// set to true
const SINGLE_COMMANDS_AND_NO_VARS = false;


// The communication protocol with the server can be "REST" or "websocket"
const COMMUNICATION_PROTOCOL = "REST";
//const COMMUNICATION_PROTOCOL = "websocket";
// Time out for the REST protocol. Increase it if the graphDB is slow.
const REST_TIMEOUT = 2000
// TODO: configuration for the secure server

// The communication method can be GraphSON 1.0 (used by Gremlin 3.2)
// or GraphSON 3.0 (used by Gremlin 3.3)
const COMMUNICATION_METHOD = "GraphSON1";
//const COMMUNICATION_METHOD = "GraphSON3";

// Graph configuration
const default_nb_of_layers = 3;
Expand Down
2 changes: 1 addition & 1 deletion scripts/graphShapes.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ var graphShapes = (function(){
return color_palette(node_code_color(d.label));
}
else if (typeof d.properties[colored_prop] !=="undefined"){
if (COMMUNICATION_METHOD == 'GraphSON3'){
if ('summary' in d.properties[colored_prop]){
return color_palette(node_code_color(d.properties[colored_prop]['summary']));
}else {
return color_palette(node_code_color(d.properties[colored_prop][0].value));
Expand Down
Loading

0 comments on commit b70b941

Please sign in to comment.