diff --git a/CHANGELOG b/CHANGELOG
index 5caf9c529b..d1de3ddf99 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -15,6 +15,8 @@ v1.4
v1.3.1 (2013-XX-XX)
-------------------
+* issue #540: suppress return of temporary internal variables in AQL
+
* issue #530: ReferenceError: ArangoError is not a constructor
* issue #535: Problem with AQL user functions javascript API
diff --git a/Documentation/Makefile.files b/Documentation/Makefile.files
index dc1feb042a..6e395033f3 100644
--- a/Documentation/Makefile.files
+++ b/Documentation/Makefile.files
@@ -310,7 +310,7 @@ CLEANUP += \
swagger:
python @srcdir@/Documentation/Scripts/generateSwagger.py \
- < @srcdir@/arangod/RestHandler/RestEdgeHandler.cpp > @srcdir@/html/admin/api-docs/edges
+ < @srcdir@/arangod/RestHandler/RestEdgeHandler.cpp > @srcdir@/html/admin/api-docs/edge
python @srcdir@/Documentation/Scripts/generateSwagger.py \
< @srcdir@/arangod/RestHandler/RestDocumentHandler.cpp > @srcdir@/html/admin/api-docs/document
diff --git a/Documentation/Manual/NewFeatures11.md b/Documentation/Manual/NewFeatures11.md
index 27bf661f31..89643a3b31 100644
--- a/Documentation/Manual/NewFeatures11.md
+++ b/Documentation/Manual/NewFeatures11.md
@@ -209,8 +209,7 @@ Server Statistics {#NewFeatures11ServerStatistics}
--------------------------------------------------
ArangoDB 1.1 allows querying the server status via the administration
-front-end (see @ref UserManualWebInterfaceStatistics) or via REST API
-methods.
+front-end or via REST API methods.
The following methods are available:
- `GET /_admin/connection-statistics`: provides connection statistics
diff --git a/Documentation/UserManual/WebInterface.md b/Documentation/UserManual/WebInterface.md
index 506836f142..1b36bd1a86 100644
--- a/Documentation/UserManual/WebInterface.md
+++ b/Documentation/UserManual/WebInterface.md
@@ -7,7 +7,7 @@ ArangoDB's Web-Interface {#UserManualWebInterface}
Accessing the Web-Interface {#UserManualWebInterfaceAccess}
===========================================================
-The web interfaced can be access as
+The web interface can be accessed via the URL
http://localhost:8529
@@ -20,64 +20,55 @@ application instead. In this case use
Collections Tab {#UserManualWebInterfaceCollections}
----------------------------------------------------
-The collection tabs shows an overview about the loaded and unloaded
-collections of the database.
+The *Collections* tab shows an overview of the loaded and unloaded
+collections present in ArangoDB. System collections (i.e. collections
+whose names start with an underscore) are not shown by default.
-@htmlonly @endhtmlonly
-@latexonly\includegraphics[width=12cm]{images/fe-collections.png}@endlatexonly
+The list of collections can be restricted using the search bar, or by
+using the filtering at the top. The filter can also be used to show or
+hide system collections.
-You can load, unloaded, delete, or inspect the collections. Please
-note that you should not delete or change system collections, i. e.,
-collections starting with an underscore.
+Clicking on a collection will show the documents contained in it.
+Clicking the small icon on a collection's badge will bring up a dialog
+that allows loading/unloading, renaming and deleting the collection.
-If you click on the magnifying glass, you will get a list of all documents
-in the collection.
+Please note that you should not change or delete system collections.
-@htmlonly
@endhtmlonly
-@latexonly\includegraphics[width=12cm]{images/fe-documents.png}@endlatexonly
+In the list of documents of a collection, you can click on the *Add document*
+line to add a new document to the collection. The document will be created
+instantly, with a system-defined key. The key and all other attributes of the
+document can be adjusted in the following view.
-Using the pencil you can edit the document.
-Query Tab {#UserManualWebInterfaceQuery}
-----------------------------------------
+AQL Editor Tab {#UserManualWebInterfaceQuery}
+---------------------------------------------
-The query tabs allows you to execute AQL queries.
+The *AQL Editor* tab allow to execute AQL queries.
-@htmlonly
@endhtmlonly
-@latexonly\includegraphics[width=12cm]{images/fe-query.png}@endlatexonly
+Type in a query in the bottom box and execute it by pressing the *Submit* button.
+The query result will be shown in the box at the top.
-Type in a query and execute it.
-Shell Tab {#UserManualWebInterfaceShell}
-----------------------------------------
+JS Shell Tab {#UserManualWebInterfaceShell}
+-------------------------------------------
-The shell tabs give you access to a JavaScript shell connection to the
+The *JS Shell* tab provides access to a JavaScript shell connection to the
database server.
-@htmlonly
@endhtmlonly
-@latexonly\includegraphics[width=12cm]{images/fe-shell.png}@endlatexonly
+Any valid JavaScript code can be executed inside the shell. The code will be
+executed inside your browser. To contact the ArangoDB server, you can use the
+`db` object, for example as follows:
+
+ JSH> db._create("mycollection");
+ JSH> db.mycollection.save({ _key: "test", value: "something" });
-Use the OK button or return to execute a command.
Logs Tab {#UserManualWebInterfaceLogs}
--------------------------------------
-You can browse the log files.
-
-@htmlonly
@endhtmlonly
-@latexonly\includegraphics[width=12cm]{images/fe-logs.png}@endlatexonly
+You can use the *Logs* tab to browse the most recent log entries provided by the
+ArangoDB database server.
Note that the server only keeps a limited number of log entries. For
real log analyses write the logs to disk using syslog or a similar
-mechanism.
-
-Statistics Tab {#UserManualWebInterfaceStatistics}
---------------------------------------------------
-
-Use the statistics tab to display information about the server.
-
-@htmlonly
@endhtmlonly
-@latexonly\includegraphics[width=12cm]{images/fe-statistics.png}@endlatexonly
-
-Initially no statistics will be display. You must use the add button
-to configure what type of information should be displayed.
+mechanism. ArangoDB provides several startup options for this.
diff --git a/Documentation/UserManual/WebInterfaceTOC.md b/Documentation/UserManual/WebInterfaceTOC.md
index 4a29ec7410..a17c13ad43 100644
--- a/Documentation/UserManual/WebInterfaceTOC.md
+++ b/Documentation/UserManual/WebInterfaceTOC.md
@@ -6,4 +6,3 @@ TOC {#UserManualWebInterfaceTOC}
- @ref UserManualWebInterfaceQuery
- @ref UserManualWebInterfaceShell
- @ref UserManualWebInterfaceLogs
- - @ref UserManualWebInterfaceStatistics
diff --git a/arangod/Ahuacatl/ahuacatl-codegen.c b/arangod/Ahuacatl/ahuacatl-codegen.c
index 9ae2d7a5a6..a86c242f74 100644
--- a/arangod/Ahuacatl/ahuacatl-codegen.c
+++ b/arangod/Ahuacatl/ahuacatl-codegen.c
@@ -668,7 +668,7 @@ static void InitArray (TRI_aql_codegen_js_t* const generator,
static void EnterSymbol (TRI_aql_codegen_js_t* const generator,
const char* const name,
const TRI_aql_codegen_register_t registerIndex) {
- TRI_aql_codegen_scope_t* scope = CurrentScope(generator);
+ TRI_aql_codegen_scope_t* scope = CurrentScope(generator);
TRI_aql_codegen_variable_t* variable = CreateVariable(name, registerIndex);
if (variable == NULL) {
@@ -890,7 +890,8 @@ static void CloseLoops (TRI_aql_codegen_js_t* const generator) {
////////////////////////////////////////////////////////////////////////////////
static TRI_vector_string_t StoreSymbols (TRI_aql_codegen_js_t* const generator,
- const TRI_aql_codegen_register_t rowRegister) {
+ const TRI_aql_codegen_register_t rowRegister,
+ bool suppressTemporaries) {
TRI_vector_string_t variableNames;
size_t i = generator->_scopes._length;
@@ -907,7 +908,12 @@ static TRI_vector_string_t StoreSymbols (TRI_aql_codegen_js_t* const generator,
TRI_aql_codegen_variable_t* variable = (TRI_aql_codegen_variable_t*) peek->_variables._table[j];
char* copy;
- if (! variable) {
+ if (variable == NULL) {
+ continue;
+ }
+
+ if (suppressTemporaries && *variable->_name == '_') {
+ // don't emit temporary variables
continue;
}
@@ -957,6 +963,7 @@ static void RestoreSymbols (TRI_aql_codegen_js_t* const generator,
// iterate over all variables passed
n = variableNames->_length;
+
for (i = 0; i < n; ++i) {
// create a new register for each variable
TRI_aql_codegen_register_t registerIndex = IncRegister(generator);
@@ -2001,7 +2008,7 @@ static void ProcessSort (TRI_aql_codegen_js_t* const generator,
InitArray(generator, rowRegister);
// save symbols
- variableNames = StoreSymbols(generator, rowRegister);
+ variableNames = StoreSymbols(generator, rowRegister, false);
// result.push(row)
ScopeOutputRegister(generator, scope->_resultRegister);
@@ -2050,13 +2057,17 @@ static void ProcessCollect (TRI_aql_codegen_js_t* const generator,
TRI_aql_node_t* list;
size_t i, n;
+#if AQL_VERBOSE
+ ScopeOutput(generator, "\n/* collect start */\n");
+#endif
+
// var row = { };
InitArray(generator, rowRegister);
// we are not interested in the variable names here, but
// StoreSymbols also generates code to save the current state in
// a rowRegister, and we need that
- variableNames = StoreSymbols(generator, rowRegister);
+ variableNames = StoreSymbols(generator, rowRegister, true);
TRI_DestroyVectorString(&variableNames);
// result.push(row)
@@ -2133,6 +2144,10 @@ static void ProcessCollect (TRI_aql_codegen_js_t* const generator,
EnterSymbol(generator, TRI_AQL_NODE_STRING(nameNode), intoRegister);
}
+
+#if AQL_VERBOSE
+ ScopeOutput(generator, "\n/* collect end */\n");
+#endif
}
////////////////////////////////////////////////////////////////////////////////
@@ -2152,7 +2167,7 @@ static void ProcessLimit (TRI_aql_codegen_js_t* const generator,
InitArray(generator, rowRegister);
// save symbols
- variableNames = StoreSymbols(generator, rowRegister);
+ variableNames = StoreSymbols(generator, rowRegister, false);
// result.push(row)
ScopeOutputRegister(generator, scope->_resultRegister);
diff --git a/arangod/RestHandler/RestDocumentHandler.cpp b/arangod/RestHandler/RestDocumentHandler.cpp
index 409b0dad78..d4b3eac785 100644
--- a/arangod/RestHandler/RestDocumentHandler.cpp
+++ b/arangod/RestHandler/RestDocumentHandler.cpp
@@ -510,7 +510,7 @@ bool RestDocumentHandler::readDocument () {
///
/// Use a document handle:
///
-/// @EXAMPLE_ARANGOSH_RUN{RestReadDocument}
+/// @EXAMPLE_ARANGOSH_RUN{RestDocumentHandlerReadDocument}
/// var cn = "products";
/// db._drop(cn);
/// db._create(cn);
@@ -527,7 +527,7 @@ bool RestDocumentHandler::readDocument () {
///
/// Use a document handle and an etag:
///
-/// @EXAMPLE_ARANGOSH_RUN{RestReadDocumentIfNoneMatch}
+/// @EXAMPLE_ARANGOSH_RUN{RestDocumentHandlerReadDocumentIfNoneMatch}
/// var cn = "products";
/// db._drop(cn);
/// db._create(cn);
@@ -545,7 +545,7 @@ bool RestDocumentHandler::readDocument () {
///
/// Unknown document handle:
///
-/// @EXAMPLE_ARANGOSH_RUN{RestReadDocumentUnknownHandle}
+/// @EXAMPLE_ARANGOSH_RUN{RestDocumentHandlerReadDocumentUnknownHandle}
/// var url = "/_api/document/products/unknownhandle";
///
/// var response = logCurlRequest('GET', url);
@@ -666,7 +666,7 @@ bool RestDocumentHandler::readSingleDocument (bool generateBody) {
///
/// Returns a collection.
///
-/// @EXAMPLE_ARANGOSH_RUN{RestReadDocumentAll}
+/// @EXAMPLE_ARANGOSH_RUN{RestDocumentHandlerReadDocumentAll}
/// var cn = "products";
/// db._drop(cn);
/// db._create(cn);
@@ -685,7 +685,7 @@ bool RestDocumentHandler::readSingleDocument (bool generateBody) {
///
/// Collection does not exist.
///
-/// @EXAMPLE_ARANGOSH_RUN{RestReadDocumentAllCollectionDoesNotExist}
+/// @EXAMPLE_ARANGOSH_RUN{RestDocumentHandlerReadDocumentAllCollectionDoesNotExist}
/// var cn = "doesnotexist";
/// db._drop(cn);
/// var url = "/_api/document/?collection=" + cn;
@@ -811,7 +811,7 @@ bool RestDocumentHandler::readAllDocuments () {
///
/// @EXAMPLES
///
-/// @EXAMPLE_ARANGOSH_RUN{RestReadDocumentHead}
+/// @EXAMPLE_ARANGOSH_RUN{RestDocumentHandlerReadDocumentHead}
/// var cn = "products";
/// db._drop(cn);
/// db._create(cn);
@@ -962,7 +962,7 @@ bool RestDocumentHandler::checkDocument () {
///
/// Using document handle:
///
-/// @EXAMPLE_ARANGOSH_RUN{RestUpdateDocument}
+/// @EXAMPLE_ARANGOSH_RUN{RestDocumentHandlerUpdateDocument}
/// var cn = "products";
/// db._drop(cn);
/// db._create(cn);
@@ -979,7 +979,7 @@ bool RestDocumentHandler::checkDocument () {
///
/// Unknown document handle:
///
-/// @EXAMPLE_ARANGOSH_RUN{RestUpdateDocumentUnknownHandle}
+/// @EXAMPLE_ARANGOSH_RUN{RestDocumentHandlerUpdateDocumentUnknownHandle}
/// var cn = "products";
/// db._drop(cn);
/// db._create(cn);
@@ -997,7 +997,7 @@ bool RestDocumentHandler::checkDocument () {
///
/// Produce a revision conflict:
///
-/// @EXAMPLE_ARANGOSH_RUN{RestUpdateDocumentIfMatchOther}
+/// @EXAMPLE_ARANGOSH_RUN{RestDocumentHandlerUpdateDocumentIfMatchOther}
/// var cn = "products";
/// db._drop(cn);
/// db._create(cn);
@@ -1016,7 +1016,7 @@ bool RestDocumentHandler::checkDocument () {
///
/// Last write wins:
///
-/// @EXAMPLE_ARANGOSH_RUN{RestUpdateDocumentIfMatchOtherLastWriteWins}
+/// @EXAMPLE_ARANGOSH_RUN{RestDocumentHandlerUpdateDocumentIfMatchOtherLastWriteWins}
/// var cn = "products";
/// db._drop(cn);
/// db._create(cn);
@@ -1034,7 +1034,7 @@ bool RestDocumentHandler::checkDocument () {
///
/// Alternative to header field:
///
-/// @EXAMPLE_ARANGOSH_RUN{RestUpdateDocumentRevOther}
+/// @EXAMPLE_ARANGOSH_RUN{RestDocumentHandlerUpdateDocumentRevOther}
/// var cn = "products";
/// db._drop(cn);
/// db._create(cn);
@@ -1151,7 +1151,7 @@ bool RestDocumentHandler::replaceDocument () {
///
/// patches an existing document with new content.
///
-/// @EXAMPLE_ARANGOSH_RUN{RestPatchDocument}
+/// @EXAMPLE_ARANGOSH_RUN{RestDocumentHandlerPatchDocument}
/// var cn = "products";
/// db._drop(cn);
/// db._create(cn);
@@ -1392,7 +1392,7 @@ bool RestDocumentHandler::modifyDocument (bool isPatch) {
///
/// Using document handle:
///
-/// @EXAMPLE_ARANGOSH_RUN{RestDocumentHandlerDELETEDocument}
+/// @EXAMPLE_ARANGOSH_RUN{RestDocumentHandlerDeleteDocument}
/// var cn = "products";
/// db._drop(cn);
/// db._create(cn, { waitForSync: true });
diff --git a/arangod/RestHandler/RestEdgeHandler.cpp b/arangod/RestHandler/RestEdgeHandler.cpp
index e6cab8be4a..8fd712fc4b 100644
--- a/arangod/RestHandler/RestEdgeHandler.cpp
+++ b/arangod/RestHandler/RestEdgeHandler.cpp
@@ -75,30 +75,63 @@ RestEdgeHandler::RestEdgeHandler (HttpRequest* request, TRI_vocbase_t* vocbase)
///
/// @RESTHEADER{POST /_api/edge,creates an edge}
///
-/// @REST{POST /_api/edge?collection=`collection-name`&from=`from-handle`&to=`to-handle`}
+/// @RESTQUERYPARAMETERS
///
-/// Creates a new edge in the collection identified by `collection-name`.
+/// @RESTQUERYPARAM{collection,string,required}
+/// Creates a new edge in the collection identified by `collection` name.
+///
+/// @RESTQUERYPARAM{from,string,required}
+/// The document handle of the start point must be passed in `from` handle.
+///
+/// @RESTQUERYPARAM{to,string,required}
+/// The document handle of the end point must be passed in `to` handle.
+///
+/// @RESTBODYPARAM{edge-document,json,required}
/// A JSON representation of the edge document must be passed as the body of
/// the POST request. This JSON object may contain the edge's document key in
/// the `_key` attribute if needed.
-/// The document handle of the start point must be passed in `from-handle`.
-/// The document handle of the end point must be passed in `to-handle`.
///
-/// `from-handle` and `to-handle` are immutable once the edge has been
+/// @RESTDESCRIPTION
+/// `from` handle and `to` handle are immutable once the edge has been
/// created.
///
/// In all other respects the method works like `POST /document`, see
/// @ref RestDocument for details.
///
+/// @RESTRETURNCODES
+///
+/// @RESTRETURNCODE{202}
+/// is returned if the edge was created successfully.
+///
+/// @RESTRETURNCODE{404}
+/// is returned if the edge collection was not found.
+///
/// @EXAMPLES
///
-/// Create an edge:
+/// Create an edge and reads it back:
///
-/// @verbinclude rest-edge-create-edge
+/// @EXAMPLE_ARANGOSH_RUN{RestEdgeCreateEdge}
+/// db._drop("edges");
+/// db._drop("vertices");
+/// var Graph = require("org/arangodb/graph").Graph;
+/// var g = new Graph("graph", "vertices", "edges");
+/// g.addVertex(1);
+/// g.addVertex(2);
+/// var url = "/_api/edge/?collection=edges&from=vertices/1&to=vertices/2";
+///
+/// var response = logCurlRequest("POST", url, { "name": "Emil" });
+///
+/// assert(response.code === 202);
///
-/// Read an edge:
+/// logJsonResponse(response);
+/// var body = response.body.replace(/\\/g, '');
+/// var edge_id = JSON.parse(body)._id;
+/// var response2 = logCurlRequest("GET", "/_api/edge/" + edge_id);
+///
+/// assert(response2.code === 200);
///
-/// @verbinclude rest-edge-read-edge
+/// logJsonResponse(response2);
+/// @END_EXAMPLE_ARANGOSH_RUN
////////////////////////////////////////////////////////////////////////////////
bool RestEdgeHandler::createDocument () {
diff --git a/html/admin/api-docs.json b/html/admin/api-docs.json
index cbfd2c3cd1..05abc74afd 100644
--- a/html/admin/api-docs.json
+++ b/html/admin/api-docs.json
@@ -1,5 +1,5 @@
{
- "apiVersion":"1.3",
+ "apiVersion":"1.4",
"swaggerVersion":"1.1",
"apis":[ {
"path": "api-docs/document",
@@ -9,6 +9,10 @@
"path": "api-docs/edges",
"description": "Interface für Edges"
},
+ {
+ "path": "api-docs/edge",
+ "description": "Interface für Edge"
+ },
{
"path": "api-docs/collection",
"description": "Interface for Collections"
diff --git a/html/admin/css/footerView.css b/html/admin/css/footerView.css
index 131a119937..68dd6d7bff 100644
--- a/html/admin/css/footerView.css
+++ b/html/admin/css/footerView.css
@@ -1,10 +1,11 @@
.footer {
+ position: fixed;
background: url("../img/footer_hd_bg.png") repeat-x scroll left 10px #4A4A4A;
font-size: 14px;
text-align: center;
left: 0;
right: 0;
- margin-top:500px;
+ bottom: 0px;
}
.footerExtra {
diff --git a/html/admin/css/graphView.css b/html/admin/css/graphView.css
index 0d2e22b324..be29b16aa0 100644
--- a/html/admin/css/graphView.css
+++ b/html/admin/css/graphView.css
@@ -22,11 +22,27 @@
background-color: rgb(56, 52, 52);
}
-.searchByAttribute {
+.searchByAttribute, .searchEqualsLabel {
margin-top: 3px;
- margin-right: 10px;
+ margin-right: 6px;
+}
+
+svg.graphViewer text {
+ font: 11px Arial;
+ pointer-events: none;
+ stroke: #000;
+}
+
+.capitalize {
+ text-transform:capitalize;
}
svg.graphViewer {
border-style: groove;
+}
+
+div.mousepointer {
+ position: absolute;
+ margin: 0;
+ padding: 5px;
}
\ No newline at end of file
diff --git a/html/admin/js/graphViewer/graph/JSONAdapter.js b/html/admin/js/graphViewer/graph/JSONAdapter.js
index cfa894b226..950a440706 100644
--- a/html/admin/js/graphViewer/graph/JSONAdapter.js
+++ b/html/admin/js/graphViewer/graph/JSONAdapter.js
@@ -162,6 +162,10 @@ function JSONAdapter(jsonPath, nodes, edges, width, height) {
};
+ self.setChildLimit = function (limit) {
+
+ };
+
self.expandCommunity = function (commNode, callback) {
};
diff --git a/html/admin/js/graphViewer/graph/arangoAdapter.js b/html/admin/js/graphViewer/graph/arangoAdapter.js
index f256b667df..343ca6d061 100644
--- a/html/admin/js/graphViewer/graph/arangoAdapter.js
+++ b/html/admin/js/graphViewer/graph/arangoAdapter.js
@@ -53,13 +53,16 @@ function ArangoAdapter(nodes, edges, config) {
api = {},
queries = {},
cachedCommunities = {},
+ joinedInCommunities = {},
nodeCollection,
edgeCollection,
limit,
+ childLimit,
reducer,
arangodb,
width,
height,
+ direction,
setWidth = function(w) {
initialX.range = w / 2;
@@ -93,12 +96,22 @@ function ArangoAdapter(nodes, edges, config) {
if (config.height !== undefined) {
setHeight(config.height);
}
+ if (config.undirected !== undefined) {
+ if (config.undirected === true) {
+ direction = "any";
+ } else {
+ direction = "outbound";
+ }
+ } else {
+ direction = "outbound";
+ }
},
findNode = function(id) {
- var res = $.grep(nodes, function(e){
- return e._id === id;
- });
+ var intId = joinedInCommunities[id] || id,
+ res = $.grep(nodes, function(e){
+ return e._id === intId;
+ });
if (res.length === 0) {
return false;
}
@@ -145,7 +158,8 @@ function ArangoAdapter(nodes, edges, config) {
_data: data,
_id: data._id
},
- e = findEdge(edge._id);
+ e = findEdge(edge._id),
+ edgeToPush;
if (e) {
return e;
}
@@ -160,8 +174,32 @@ function ArangoAdapter(nodes, edges, config) {
edge.source = source;
edge.target = target;
edges.push(edge);
- source._outboundCounter++;
- target._inboundCounter++;
+
+
+ if (cachedCommunities[source._id] !== undefined) {
+ edgeToPush = {};
+ edgeToPush.type = "s";
+ edgeToPush.id = edge._id;
+ edgeToPush.source = $.grep(cachedCommunities[source._id].nodes, function(e){
+ return e._id === data._from;
+ })[0];
+ edgeToPush.source._outboundCounter++;
+ cachedCommunities[source._id].edges.push(edgeToPush);
+ } else {
+ source._outboundCounter++;
+ }
+ if (cachedCommunities[target._id] !== undefined) {
+ edgeToPush = {};
+ edgeToPush.type = "t";
+ edgeToPush.id = edge._id;
+ edgeToPush.target = $.grep(cachedCommunities[target._id].nodes, function(e){
+ return e._id === data._to;
+ })[0];
+ edgeToPush.target._inboundCounter++;
+ cachedCommunities[target._id].edges.push(edgeToPush);
+ } else {
+ target._inboundCounter++;
+ }
return edge;
},
@@ -275,6 +313,9 @@ function ArangoAdapter(nodes, edges, config) {
if (query !== queries.connectedEdges) {
bindVars["@nodes"] = nodeCollection;
}
+ if (query !== queries.childrenCentrality) {
+ bindVars.dir = direction;
+ }
bindVars["@edges"] = edgeCollection;
var data = {
query: query,
@@ -317,8 +358,10 @@ function ArangoAdapter(nodes, edges, config) {
cachedCommunities[commId] = {};
cachedCommunities[commId].nodes = nodesToRemove;
cachedCommunities[commId].edges = [];
+
combineCommunityEdges(nodesToRemove, commNode);
_.each(nodesToRemove, function(n) {
+ joinedInCommunities[n._id] = commId;
removeNode(n);
});
nodes.push(commNode);
@@ -335,6 +378,7 @@ function ArangoAdapter(nodes, edges, config) {
collapseCommunity(com);
}
_.each(nodesToAdd, function(n) {
+ delete joinedInCommunities[n._id];
nodes.push(n);
});
_.each(edgesToChange, function(e) {
@@ -358,23 +402,38 @@ function ArangoAdapter(nodes, edges, config) {
parseResultOfTraversal = function (result, callback) {
result = result[0];
+ var inserted = {},
+ n = insertNode(result[0].vertex),
+ com, buckets;
_.each(result, function(visited) {
var node = insertNode(visited.vertex),
- path = visited.path;
+ path = visited.path;
+ inserted[node._id] = node;
_.each(path.vertices, function(connectedNode) {
- insertNode(connectedNode);
+ var ins = insertNode(connectedNode);
+ inserted[ins._id] = ins;
});
_.each(path.edges, function(edge) {
insertEdge(edge);
});
- });
+ });
+ delete inserted[n._id];
+ if (_.size(inserted) > childLimit) {
+ buckets = reducer.bucketNodes(_.values(inserted), childLimit);
+ _.each(buckets, function(b) {
+ if (b.length > 1) {
+ var ids = _.map(b, function(n) {
+ return n._id;
+ });
+ collapseCommunity(ids);
+ }
+ });
+ }
+ if (limit < nodes.length) {
+ com = reducer.getCommunity(limit, n);
+ collapseCommunity(com);
+ }
if (callback) {
- var n = insertNode(result[0].vertex),
- com;
- if (limit < nodes.length) {
- com = reducer.getCommunity(limit, n);
- collapseCommunity(com);
- }
callback(n);
}
},
@@ -421,7 +480,7 @@ function ArangoAdapter(nodes, edges, config) {
_.each(res, self.deleteEdge);
});
};
-
+
parseConfig(config);
api.base = arangodb.lastIndexOf("http://", 0) === 0
@@ -447,7 +506,7 @@ function ArangoAdapter(nodes, edges, config) {
+ "@@nodes, "
+ "@@edges, "
+ "@id, "
- + "\"outbound\", {"
+ + "@dir, {"
+ "strategy: \"depthfirst\","
+ "maxDepth: 1,"
+ "paths: true"
@@ -460,7 +519,7 @@ function ArangoAdapter(nodes, edges, config) {
+ "@@nodes, "
+ "@@edges, "
+ "n._id, "
- + "\"outbound\", {"
+ + "@dir, {"
+ "strategy: \"depthfirst\","
+ "maxDepth: 1,"
+ "paths: true"
@@ -478,8 +537,9 @@ function ArangoAdapter(nodes, edges, config) {
+ " || e._from == @id"
+ " RETURN e";
- reducer = new NodeReducer(nodes, edges);
+ childLimit = Number.POSITIVE_INFINITY;
+ reducer = new NodeReducer(nodes, edges);
self.oldLoadNodeFromTreeById = function(nodeId, callback) {
sendQuery(queries.nodeById, {
@@ -639,9 +699,16 @@ function ArangoAdapter(nodes, edges, config) {
});
};
- self.changeTo = function (nodesCol, edgesCol ) {
+ self.changeTo = function (nodesCol, edgesCol, dir) {
nodeCollection = nodesCol;
edgeCollection = edgesCol;
+ if (dir !== undefined) {
+ if (dir === true) {
+ direction = "any";
+ } else {
+ direction = "outbound";
+ }
+ }
api.node = api.base + "document?collection=" + nodeCollection;
api.edge = api.base + "edge?collection=" + edgeCollection;
};
@@ -657,6 +724,10 @@ function ArangoAdapter(nodes, edges, config) {
}
};
+ self.setChildLimit = function (pLimit) {
+ childLimit = pLimit;
+ };
+
self.expandCommunity = function (commNode, callback) {
expandCommunity(commNode);
if (callback !== undefined) {
@@ -664,4 +735,34 @@ function ArangoAdapter(nodes, edges, config) {
}
};
+ self.getCollections = function(callback) {
+ if (callback && callback.length >= 2) {
+ $.ajax({
+ cache: false,
+ type: "GET",
+ url: api.collection,
+ contentType: "application/json",
+ dataType: "json",
+ processData: false,
+ success: function(data) {
+ var cols = data.collections,
+ docs = [],
+ edgeCols = [];
+ _.each(cols, function(c) {
+ if (!c.name.match(/^_/)) {
+ if (c.type === 3) {
+ edgeCols.push(c.name);
+ } else if (c.type === 2){
+ docs.push(c.name);
+ }
+ }
+ });
+ callback(docs, edgeCols);
+ },
+ error: function(data) {
+ throw data.statusText;
+ }
+ });
+ }
+ };
}
\ No newline at end of file
diff --git a/html/admin/js/graphViewer/graph/edgeShaper.js b/html/admin/js/graphViewer/graph/edgeShaper.js
index e7b6f4f31d..1bd0a48fd6 100644
--- a/html/admin/js/graphViewer/graph/edgeShaper.js
+++ b/html/admin/js/graphViewer/graph/edgeShaper.js
@@ -50,7 +50,8 @@ function EdgeShaper(parent, flags, idfunc) {
edges = [],
toplevelSVG,
visibleLabels = true,
-
+ followEdge = {},
+ followEdgeG,
idFunction = function(d) {
return d.source._id + "-" + d.target._id;
},
@@ -70,7 +71,9 @@ function EdgeShaper(parent, flags, idfunc) {
dblclick: noop,
mousedown: noop,
mouseup: noop,
- mousemove: noop
+ mousemove: noop,
+ mouseout: noop,
+ mouseover: noop
};
addUpdate = noop;
},
@@ -317,6 +320,8 @@ function EdgeShaper(parent, flags, idfunc) {
idFunction = idfunc;
}
+ followEdgeG = toplevelSVG.append("g");
+
/////////////////////////////////////////////////////////
/// Public functions
@@ -349,6 +354,24 @@ function EdgeShaper(parent, flags, idfunc) {
}
shapeEdges();
};
+
+ self.addAnEdgeFollowingTheCursor = function(x, y) {
+ followEdge = followEdgeG.append("line");
+ followEdge.attr("stroke", "black")
+ .attr("id", "connectionLine")
+ .attr("x1", x)
+ .attr("y1", y)
+ .attr("x2", x)
+ .attr("y2", y);
+ return function(x, y) {
+ followEdge.attr("x2", x).attr("y2", y);
+ };
+ };
+
+ self.removeCursorFollowingEdge = function() {
+ followEdge.remove();
+ followEdge = {};
+ };
}
EdgeShaper.shapes = Object.freeze({
diff --git a/html/admin/js/graphViewer/graph/eventDispatcher.js b/html/admin/js/graphViewer/graph/eventDispatcher.js
index cc473b816f..818320008d 100644
--- a/html/admin/js/graphViewer/graph/eventDispatcher.js
+++ b/html/admin/js/graphViewer/graph/eventDispatcher.js
@@ -1,5 +1,5 @@
/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true */
-/*global _*/
+/*global _, $, window*/
/*global EventLibrary*/
////////////////////////////////////////////////////////////////////////////////
/// @brief Graph functionality
@@ -32,6 +32,9 @@ function EventDispatcher(nodeShaper, edgeShaper, config) {
var eventlib,
expandConfig,
+ svgBase,
+ svgTemp,
+ svgObj,
self = this,
parseNodeEditorConfig = function(config) {
if (config.shaper === undefined) {
@@ -77,11 +80,14 @@ function EventDispatcher(nodeShaper, edgeShaper, config) {
self.events.STARTCREATEEDGE = function(callback) {
return function(node) {
+ var e = d3.event || window.event;
edgeStart = node;
didInsert = false;
if (callback !== undefined) {
- callback();
+ callback(node, e);
}
+ // Necessary to omit dragging of the graph
+ e.stopPropagation();
};
};
@@ -118,6 +124,20 @@ function EventDispatcher(nodeShaper, edgeShaper, config) {
};
};
}
+ },
+
+ bindSVGEvents = function() {
+ svgObj = svgObj || $("svg");
+ _.each(svgBase, function(fs, ev) {
+ svgObj.bind(ev, function(trigger) {
+ _.each(fs, function(f) {
+ f(trigger);
+ });
+ if (!! svgTemp[ev]) {
+ svgTemp[ev](trigger);
+ }
+ });
+ });
};
if (nodeShaper === undefined) {
@@ -130,6 +150,17 @@ function EventDispatcher(nodeShaper, edgeShaper, config) {
eventlib = new EventLibrary();
+ svgBase = {
+ click: [],
+ dblclick: [],
+ mousedown: [],
+ mouseup: [],
+ mousemove: [],
+ mouseout: [],
+ mouseover: []
+ };
+ svgTemp = {};
+
self.events = {};
if (config !== undefined) {
@@ -171,6 +202,10 @@ function EventDispatcher(nodeShaper, edgeShaper, config) {
actions: actions
});
break;
+ case "svg":
+ svgTemp[event] = func;
+ bindSVGEvents();
+ break;
default:
if (object.bind !== undefined) {
object.unbind(event);
@@ -196,11 +231,28 @@ function EventDispatcher(nodeShaper, edgeShaper, config) {
actions: actions
});
break;
+ case "svg":
+ svgTemp = {};
+ _.each(actions, function(fs, ev) {
+ if (ev !== "reset") {
+ svgTemp[ev] = fs;
+ }
+ });
+ bindSVGEvents();
+ break;
default:
throw "Sorry cannot rebind to object. Please give either "
- + "\"nodes\" or \"edges\"";
+ + "\"nodes\", \"edges\" or \"svg\"";
}
};
+
+ self.fixSVG = function(event, action) {
+ if (svgBase[event] === undefined) {
+ throw "Sorry unkown event";
+ }
+ svgBase[event].push(action);
+ bindSVGEvents();
+ };
/*
self.unbind = function () {
throw "Not implemented";
diff --git a/html/admin/js/graphViewer/graph/forceLayouter.js b/html/admin/js/graphViewer/graph/forceLayouter.js
index 787dc27778..34fa266339 100644
--- a/html/admin/js/graphViewer/graph/forceLayouter.js
+++ b/html/admin/js/graphViewer/graph/forceLayouter.js
@@ -47,9 +47,9 @@ function ForceLayouter(config) {
"use strict";
var self = this,
force = d3.layout.force(),
- distance = config.distance || 80,
- gravity = config.gravity || 0.08,
- charge = config.charge || -240,
+ distance = config.distance || 240, // 80
+ gravity = config.gravity || 0.01, // 0.08
+ charge = config.charge || -1000, // -240
onUpdate = config.onUpdate || function () {},
width = config.width || 940,
height = config.height || 640,
diff --git a/html/admin/js/graphViewer/graph/nodeReducer.js b/html/admin/js/graphViewer/graph/nodeReducer.js
index 334d3767cd..2ec7fc6983 100644
--- a/html/admin/js/graphViewer/graph/nodeReducer.js
+++ b/html/admin/js/graphViewer/graph/nodeReducer.js
@@ -265,9 +265,34 @@ function NodeReducer(nodes, edges) {
joinCommunities(l.sID, l.lID, coms, heap, l.val);
updateValues(l, dQ, a, heap);
return true;
+ },
+
+ addNode = function(bucket, node) {
+ bucket.push(node);
+
+ },
+
+ getSimilarityValue = function(bucket, node) {
+ if (bucket.length === 0) {
+ return 1;
+ }
+ var comp = bucket[0],
+ props = _.union(_.keys(comp), _.keys(node)),
+ countMatch = 0,
+ propCount = 0;
+ _.each(props, function(key) {
+ if (comp[key] !== undefined && node[key]!== undefined) {
+ countMatch++;
+ if (comp[key] === node[key]) {
+ countMatch += 4;
+ }
+ }
+ });
+ propCount = props.length * 5;
+ propCount++;
+ countMatch++;
+ return countMatch / propCount;
};
-
-
self.getCommunity = function(limit, focus) {
var dQ = {},
@@ -305,4 +330,34 @@ function NodeReducer(nodes, edges) {
}
return res[0];
};
+
+ self.bucketNodes = function(toSort, numBuckets) {
+ var res = [],
+ threshold = 0.5;
+ if (toSort.length <= numBuckets) {
+ res = _.map(toSort, function(n) {
+ return [n];
+ });
+ return res;
+ }
+ _.each(toSort, function(n) {
+ var i, shortest, sLength;
+ shortest = 0;
+ sLength = Number.POSITIVE_INFINITY;
+ for (i = 0; i < numBuckets; i++) {
+ res[i] = res[i] || [];
+ if (getSimilarityValue(res[i], n) > threshold) {
+ addNode(res[i], n);
+ return;
+ }
+ if (sLength > res[i].length) {
+ shortest = i;
+ sLength = res[i].length;
+ }
+ }
+ addNode(res[shortest], n);
+ });
+ return res;
+ };
+
}
diff --git a/html/admin/js/graphViewer/graph/nodeShaper.js b/html/admin/js/graphViewer/graph/nodeShaper.js
index d60e7cd1cd..369b188e34 100644
--- a/html/admin/js/graphViewer/graph/nodeShaper.js
+++ b/html/admin/js/graphViewer/graph/nodeShaper.js
@@ -62,7 +62,7 @@
*/
function NodeShaper(parent, flags, idfunc) {
"use strict";
-
+
var self = this,
communityRegEx = /^\*community/,
nodes = [],
@@ -114,7 +114,9 @@ function NodeShaper(parent, flags, idfunc) {
drag: noop,
mousedown: noop,
mouseup: noop,
- mousemove: noop
+ mousemove: noop,
+ mouseout: noop,
+ mouseover: noop
};
addUpdate = noop;
},
@@ -227,12 +229,14 @@ function NodeShaper(parent, flags, idfunc) {
addLabel = function (node) {
node.append("text") // Append a label for the node
.attr("text-anchor", "middle") // Define text-anchor
+ .attr("stroke", "black") // Foce a black color20*75)
.text(label);
};
} else {
addLabel = function (node) {
node.append("text") // Append a label for the node
.attr("text-anchor", "middle") // Define text-anchor
+ .attr("stroke", "black") // Foce a black color20*75)
.text(function(d) {
return d._data[label] !== undefined ? d._data[label] : "";
});
diff --git a/html/admin/js/graphViewer/graph/zoomManager.js b/html/admin/js/graphViewer/graph/zoomManager.js
index 09a66fc933..4e2b32851d 100644
--- a/html/admin/js/graphViewer/graph/zoomManager.js
+++ b/html/admin/js/graphViewer/graph/zoomManager.js
@@ -105,7 +105,7 @@ function ZoomManager(width, height, svg, g, nodeShaper, edgeShaper, config, limi
var fontMax = conf.maxFont || 16,
fontMin = conf.minFont || 6,
rMax = conf.maxRadius || 25,
- rMin = conf.minRadius || 1;
+ rMin = conf.minRadius || 4;
baseDist = conf.focusZoom || 1;
baseDRadius = conf.focusRadius || 100;
diff --git a/html/admin/js/graphViewer/graphViewer.js b/html/admin/js/graphViewer/graphViewer.js
index 75cc74e204..38d525ba65 100644
--- a/html/admin/js/graphViewer/graphViewer.js
+++ b/html/admin/js/graphViewer/graphViewer.js
@@ -1,6 +1,6 @@
/*jslint indent: 2, nomen: true, maxlen: 100, white: true plusplus: true */
/*global _*/
-/*global EventDispatcher, ArangoAdapter, JSONAdapter */
+/*global ArangoAdapter, JSONAdapter */
/*global ForceLayouter, EdgeShaper, NodeShaper, ZoomManager */
////////////////////////////////////////////////////////////////////////////////
/// @brief Graph functionality
@@ -56,7 +56,6 @@ function GraphViewer(svg, width, height, adapterConfig, config) {
edgeContainer,
zoomManager,
fixedSize,
- dispatcher,
edges = [],
nodes = [],
@@ -101,7 +100,6 @@ function GraphViewer(svg, width, height, adapterConfig, config) {
nsConf = config.nodeShaper || {},
idFunc = nsConf.idfunc || undefined,
zConf = config.zoom || false;
-
parseLayouterConfig(config.layouter);
edgeContainer = graphContainer.append("g");
self.edgeShaper = new EdgeShaper(edgeContainer, esConf);
@@ -113,13 +111,14 @@ function GraphViewer(svg, width, height, adapterConfig, config) {
switch (adapterConfig.type.toLowerCase()) {
case "arango":
- adapterConfig.width = width;
- adapterConfig.height = height;
+ adapterConfig.width = width;
+ adapterConfig.height = height;
self.adapter = new ArangoAdapter(
nodes,
edges,
adapterConfig
);
+ self.adapter.setChildLimit(5);
break;
case "json":
self.adapter = new JSONAdapter(
diff --git a/html/admin/js/graphViewer/jasmine_test/helper/eventHelper.js b/html/admin/js/graphViewer/jasmine_test/helper/eventHelper.js
index 53ff15f9fc..d91e78431b 100644
--- a/html/admin/js/graphViewer/jasmine_test/helper/eventHelper.js
+++ b/html/admin/js/graphViewer/jasmine_test/helper/eventHelper.js
@@ -33,6 +33,14 @@ var helper = helper || {};
(function eventHelper() {
"use strict";
+ helper.simulateMouseMoveEvent = function(objectId, x, y) {
+ var evt = document.createEvent("MouseEvents"),
+ testee = document.getElementById(objectId);
+ evt.initMouseEvent("mousemove", true, true, window,
+ 0, 0, 0, x, y, false, false, false, false, 0, null);
+ testee.dispatchEvent(evt);
+ };
+
helper.simulateDragEvent = function (objectId) {
helper.simulateMouseEvent("mousedown", objectId);
var e1 = document.createEvent("MouseEvents"),
diff --git a/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js b/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js
index 63926e00c3..f182904938 100644
--- a/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js
+++ b/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js
@@ -286,6 +286,7 @@
apibase = host + "/_api/",
apiCursor = apibase + 'cursor';
self.fakeReducerRequest = function() {};
+ self.fakeReducerBucketRequest = function() {};
spyOn(window, "NodeReducer").andCallFake(function(v, e) {
return {
getCommunity: function(limit, focus) {
@@ -293,6 +294,9 @@
return self.fakeReducerRequest(limit, focus);
}
return self.fakeReducerRequest(limit);
+ },
+ bucketNodes: function(toSort, numBuckets) {
+ return self.fakeReducerBucketRequest(toSort, numBuckets);
}
};
});
@@ -306,26 +310,40 @@
height: 40
}
);
- traversalQuery = function(id, nods, edgs) {
+ traversalQuery = function(id, nods, edgs, undirected) {
+ var dir;
+ if (undirected === true) {
+ dir = "any";
+ } else {
+ dir = "outbound";
+ }
return JSON.stringify({
- query: "RETURN TRAVERSAL(@@nodes, @@edges, @id, \"outbound\","
+ query: "RETURN TRAVERSAL(@@nodes, @@edges, @id, @dir,"
+ " {strategy: \"depthfirst\",maxDepth: 1,paths: true})",
bindVars: {
id: id,
"@nodes": nods,
+ dir: dir,
"@edges": edgs
}
});
};
- filterQuery = function(v, nods, edgs) {
+ filterQuery = function(v, nods, edgs, undirected) {
+ var dir;
+ if (undirected === true) {
+ dir = "any";
+ } else {
+ dir = "outbound";
+ }
return JSON.stringify({
query: "FOR n IN @@nodes FILTER n.id == @value"
- + " RETURN TRAVERSAL(@@nodes, @@edges, n._id, \"outbound\","
+ + " RETURN TRAVERSAL(@@nodes, @@edges, n._id, @dir,"
+ " {strategy: \"depthfirst\",maxDepth: 1,paths: true})",
bindVars: {
value: v,
"@nodes": nods,
- "@edges": edgs
+ dir: dir,
+ "@edges": edgs
}
});
};
@@ -424,9 +442,45 @@
};
};
});
-
+
+ it('should offer lists of available collections', function() {
+ var collections = [],
+ sys1 = {id: "1", name: "_sys1", status: 3, type: 2},
+ sys2 = {id: "2", name: "_sys2", status: 2, type: 2},
+ doc1 = {id: "3", name: "doc1", status: 3, type: 2},
+ doc2 = {id: "4", name: "doc2", status: 2, type: 2},
+ doc3 = {id: "5", name: "doc3", status: 3, type: 2},
+ edge1 = {id: "6", name: "edge1", status: 3, type: 3},
+ edge2 = {id: "7", name: "edge2", status: 2, type: 3};
+
+ collections.push(sys1);
+ collections.push(sys2);
+ collections.push(doc1);
+ collections.push(doc2);
+ collections.push(doc3);
+ collections.push(edge1);
+ collections.push(edge2);
+
+ spyOn($, "ajax").andCallFake(function(request) {
+ request.success({collections: collections});
+ });
+
+ adapter.getCollections(function(docs, edge) {
+ expect(docs).toContain("doc1");
+ expect(docs).toContain("doc2");
+ expect(docs).toContain("doc3");
+
+ expect(docs.length).toEqual(3);
+
+ expect(edge).toContain("edge1");
+ expect(edge).toContain("edge2");
+
+ expect(edge.length).toEqual(2);
+ });
+ });
+
it('should be able to load a tree node from '
- + 'ArangoDB by internal _id attribute', function() {
+ + 'ArangoDB by internal _id attribute', function() {
var c0, c1, c2, c3, c4;
@@ -466,8 +520,14 @@
});
});
+ it('should map loadNode to loadByID', function() {
+ spyOn(adapter, "loadNodeFromTreeById");
+ adapter.loadNode("a", "b");
+ expect(adapter.loadNodeFromTreeById).toHaveBeenCalledWith("a", "b");
+ });
+
it('should be able to load a tree node from ArangoDB'
- + ' by internal attribute and value', function() {
+ + ' by internal attribute and value', function() {
var c0, c1, c2, c3, c4;
@@ -649,6 +709,170 @@
});
+ it('should be able to switch to different collections and change to directed', function() {
+
+ runs(function() {
+
+ spyOn($, "ajax");
+
+ adapter.changeTo(altNodesCollection, altEdgesCollection, false);
+
+ adapter.loadNode("42");
+
+ expect($.ajax).toHaveBeenCalledWith(
+ requests.cursor(traversalQuery("42", altNodesCollection, altEdgesCollection, false))
+ );
+
+ });
+ });
+
+ it('should be able to switch to different collections'
+ + ' and change to undirected', function() {
+
+ runs(function() {
+
+ spyOn($, "ajax");
+
+ adapter.changeTo(altNodesCollection, altEdgesCollection, true);
+
+ adapter.loadNode("42");
+
+ expect($.ajax).toHaveBeenCalledWith(
+ requests.cursor(traversalQuery("42", altNodesCollection, altEdgesCollection, true))
+ );
+
+ });
+ });
+
+ it('should add at most the upper bound of children in one step', function() {
+ var inNodeCol, callNodes;
+
+ runs(function() {
+ var addNNodes = function(n) {
+ var i = 0,
+ res = [];
+ for (i = 0; i < n; i++) {
+ res.push(insertNode(nodesCollection, i));
+ }
+ return res;
+ },
+ connectToAllButSelf = function(source, ns) {
+ _.each(ns, function(target) {
+ if (source !== target) {
+ insertEdge(edgesCollection, source, target);
+ }
+ });
+ };
+
+ inNodeCol = addNNodes(21);
+ connectToAllButSelf(inNodeCol[0], inNodeCol);
+ adapter.setChildLimit(5);
+
+ spyOn($, "ajax").andCallFake(function(request) {
+ var vars = JSON.parse(request.data).bindVars;
+ if (vars !== undefined) {
+ request.success({result: loadGraph(vars)});
+ }
+ });
+ spyOn(this, "fakeReducerBucketRequest").andCallFake(function(ns) {
+ var i = 0,
+ res = [],
+ pos;
+ callNodes = ns;
+ for (i = 0; i < 5; i++) {
+ pos = i*4;
+ res.push(ns.slice(pos, pos + 4));
+ }
+ return res;
+ });
+
+ callbackCheck = false;
+ adapter.loadNodeFromTreeById(inNodeCol[0], checkCallbackFunction);
+
+ });
+
+ waitsFor(function() {
+ return callbackCheck;
+ });
+
+ runs(function() {
+ var callNodesIds = _.map(callNodes, function(n) {
+ return n._id;
+ });
+ expect(this.fakeReducerBucketRequest).toHaveBeenCalledWith(
+ jasmine.any(Array),
+ 5
+ );
+ expect(callNodesIds).toEqual(inNodeCol.slice(1));
+ expect(nodes.length).toEqual(6);
+ expect(getCommunityNodes().length).toEqual(5);
+ });
+
+ });
+
+ it('should not replace single nodes by communities', function() {
+ var inNodeCol, callNodes;
+
+ runs(function() {
+ var addNNodes = function(n) {
+ var i = 0,
+ res = [];
+ for (i = 0; i < n; i++) {
+ res.push(insertNode(nodesCollection, i));
+ }
+ return res;
+ },
+ connectToAllButSelf = function(source, ns) {
+ _.each(ns, function(target) {
+ if (source !== target) {
+ insertEdge(edgesCollection, source, target);
+ }
+ });
+ };
+
+ inNodeCol = addNNodes(7);
+ connectToAllButSelf(inNodeCol[0], inNodeCol);
+ adapter.setChildLimit(5);
+
+ spyOn($, "ajax").andCallFake(function(request) {
+ var vars = JSON.parse(request.data).bindVars;
+ if (vars !== undefined) {
+ request.success({result: loadGraph(vars)});
+ }
+ });
+ spyOn(this, "fakeReducerBucketRequest").andCallFake(function(ns) {
+ var i = 0,
+ res = [],
+ pos;
+ for (i = 0; i < 4; i++) {
+ res.push([ns[i]]);
+ }
+ res.push([ns[4], ns[5]]);
+ return res;
+ });
+
+ callbackCheck = false;
+ adapter.loadNodeFromTreeById(inNodeCol[0], checkCallbackFunction);
+
+ });
+
+ waitsFor(function() {
+ return callbackCheck;
+ });
+
+ runs(function() {
+ var callNodesIds = _.map(callNodes, function(n) {
+ return n._id;
+ });
+ expect(this.fakeReducerBucketRequest).toHaveBeenCalledWith(
+ jasmine.any(Array),
+ 5
+ );
+ expect(nodes.length).toEqual(6);
+ expect(getCommunityNodes().length).toEqual(1);
+ });
+
+ });
describe('that has already loaded one graph', function() {
var c0, c1, c2, c3, c4, c5, c6, c7,
@@ -971,6 +1195,167 @@
});
+ describe('expanding after a while', function() {
+
+ it('should connect edges of internal nodes accordingly', function() {
+
+ var commNode, called, counterCallback,
+ v0, v1, v2, v3, v4,
+ e0_1, e0_2, e1_3, e1_4, e2_3, e2_4;
+
+ runs(function() {
+ var v = "vertices",
+ e = "edges";
+ nodes.length = 0;
+ edges.length = 0;
+ v0 = insertNode(v, 0);
+ v1 = insertNode(v, 1);
+ v2 = insertNode(v, 2);
+ v3 = insertNode(v, 3);
+ v4 = insertNode(v, 4);
+ e0_1 = insertEdge(e, v0, v1);
+ e0_2 = insertEdge(e, v0, v2);
+ e1_3 = insertEdge(e, v1, v3);
+ e1_4 = insertEdge(e, v1, v4);
+ e2_3 = insertEdge(e, v2, v3);
+ e2_4 = insertEdge(e, v2, v4);
+ called = 0;
+ counterCallback = function() {
+ called++;
+ };
+ spyOn(this, "fakeReducerRequest").andCallFake(function() {
+ return [v1, v3, v4];
+ });
+ adapter.setNodeLimit(3);
+
+ adapter.changeTo(v, e);
+ adapter.loadNode(v0, counterCallback);
+ adapter.loadNode(v1, counterCallback);
+
+ });
+
+ waitsFor(function() {
+ return called === 2;
+ });
+
+ runs(function() {
+ adapter.loadNode(v2, counterCallback);
+ commNode = getCommunityNodes()[0];
+ });
+
+ waitsFor(function() {
+ return called === 3;
+ });
+
+ runs(function() {
+ var commId = commNode._id;
+ // Check start condition
+ existNodes([commId, v0, v2]);
+ expect(nodes.length).toEqual(3);
+
+ existEdge(v0, v2);
+ existEdge(v0, commId);
+ existEdge(v2, commId);
+ expect(edges.length).toEqual(4);
+
+ adapter.setNodeLimit(20);
+ adapter.expandCommunity(commNode, counterCallback);
+ });
+
+ waitsFor(function() {
+ return called === 4;
+ });
+
+ runs(function() {
+ existNodes([v0, v1, v2, v3, v4]);
+ expect(nodes.length).toEqual(5);
+
+ existEdge(v0, v1);
+ existEdge(v0, v2);
+ existEdge(v1, v3);
+ existEdge(v1, v4);
+ existEdge(v2, v3);
+ existEdge(v2, v4);
+ expect(edges.length).toEqual(6);
+
+ });
+ });
+
+ it('set inbound and outboundcounter correctly', function() {
+
+ var commNode, called, counterCallback,
+ v0, v1, v2, v3, v4,
+ e0_1, e0_2, e1_3, e1_4, e2_3, e2_4;
+
+ runs(function() {
+ var v = "vertices",
+ e = "edges";
+ nodes.length = 0;
+ edges.length = 0;
+ v0 = insertNode(v, 0);
+ v1 = insertNode(v, 1);
+ v2 = insertNode(v, 2);
+ v3 = insertNode(v, 3);
+ v4 = insertNode(v, 4);
+ e0_1 = insertEdge(e, v0, v1);
+ e0_2 = insertEdge(e, v0, v2);
+ e1_3 = insertEdge(e, v1, v3);
+ e1_4 = insertEdge(e, v1, v4);
+ e2_3 = insertEdge(e, v2, v3);
+ e2_4 = insertEdge(e, v2, v4);
+ called = 0;
+ counterCallback = function() {
+ called++;
+ };
+ spyOn(this, "fakeReducerRequest").andCallFake(function() {
+ return [v1, v3, v4];
+ });
+ adapter.setNodeLimit(3);
+
+ adapter.changeTo(v, e);
+ adapter.loadNode(v0, counterCallback);
+ adapter.loadNode(v1, counterCallback);
+
+ });
+
+ waitsFor(function() {
+ return called === 2;
+ });
+
+ runs(function() {
+ adapter.loadNode(v2, counterCallback);
+ commNode = getCommunityNodes()[0];
+ });
+
+ waitsFor(function() {
+ return called === 3;
+ });
+
+ runs(function() {
+ adapter.setNodeLimit(20);
+ adapter.expandCommunity(commNode, counterCallback);
+ });
+
+ waitsFor(function() {
+ return called === 4;
+ });
+
+ runs(function() {
+ var checkNodeWithInAndOut = function(id, inbound, outbound) {
+ var n = nodeWithID(id);
+ expect(n._outboundCounter).toEqual(outbound);
+ expect(n._inboundCounter).toEqual(inbound);
+ };
+ checkNodeWithInAndOut(v0, 0, 2);
+ checkNodeWithInAndOut(v1, 1, 2);
+ checkNodeWithInAndOut(v2, 1, 2);
+ checkNodeWithInAndOut(v3, 2, 0);
+ checkNodeWithInAndOut(v4, 2, 0);
+ });
+ });
+
+ });
+
describe('that displays a community node already', function() {
var firstCommId,
@@ -996,7 +1381,7 @@
});
});
- it('should expand a community if enough space is available', function() {
+ it('should expand a community if enough space is available', function() {
runs(function() {
adapter.setNodeLimit(10);
callbackCheck = false;
@@ -1019,7 +1404,7 @@
});
it('should expand a community and join another '
- + 'one if not enough space is available', function() {
+ + 'one if not enough space is available', function() {
runs(function() {
fakeResult = [c1, c7];
callbackCheck = false;
@@ -1079,6 +1464,26 @@
});
});
+ it('should connect edges to internal nodes', function() {
+
+ runs(function() {
+ insertEdge(edgesCollection, c3, c0);
+
+ adapter.setNodeLimit(20);
+ callbackCheck = false;
+ adapter.loadNode(c3, checkCallbackFunction);
+ });
+
+ waitsFor(function() {
+ return callbackCheck;
+ });
+
+ runs(function() {
+ existEdge(c3, firstCommId);
+ });
+
+ });
+
});
});
diff --git a/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterUISpec.js b/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterUISpec.js
index 206283ac69..9da406b57c 100644
--- a/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterUISpec.js
+++ b/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterUISpec.js
@@ -43,13 +43,17 @@
beforeEach(function () {
adapter = {
- changeTo: function(){}
+ changeTo: function(){},
+ getCollections: function(cb) {
+ cb(["nodes", "newNodes"], ["edges", "newEdges"]);
+ }
};
list = document.createElement("ul");
document.body.appendChild(list);
- list.id = "control_list";
+ list.id = "control_adapter_list";
adapterUI = new ArangoAdapterControls(list, adapter);
spyOn(adapter, 'changeTo');
+ spyOn(adapter, "getCollections").andCallThrough();
this.addMatchers({
toBeTag: function(name) {
var el = this.actual;
@@ -88,34 +92,119 @@
runs(function() {
adapterUI.addControlChangeCollections();
- expect($("#control_list #control_collections").length).toEqual(1);
- expect($("#control_list #control_collections")[0]).toConformToListCSS();
+ expect($("#control_adapter_list #control_adapter_collections").length).toEqual(1);
+ expect($("#control_adapter_list #control_adapter_collections")[0]).toConformToListCSS();
- helper.simulateMouseEvent("click", "control_collections");
+ helper.simulateMouseEvent("click", "control_adapter_collections");
- expect($("#control_collections_modal").length).toEqual(1);
+ expect($("#control_adapter_collections_modal").length).toEqual(1);
- $("#control_collections_nodecollection").attr("value", "newNodes");
- $("#control_collections_edgecollection").attr("value", "newEdges");
+ $("#control_adapter_collections_nodecollection").attr("value", "newNodes");
+ $("#control_adapter_collections_edgecollection").attr("value", "newEdges");
- helper.simulateMouseEvent("click", "control_collections_submit");
+ helper.simulateMouseEvent("click", "control_adapter_collections_submit");
expect(adapter.changeTo).toHaveBeenCalledWith(
"newNodes",
- "newEdges"
+ "newEdges",
+ false
);
});
waitsFor(function() {
- return $("#control_collections_modal").length === 0;
+ return $("#control_adapter_collections_modal").length === 0;
}, 2000, "The modal dialog should disappear.");
});
+ it('should change collections and traversal direction to directed', function() {
+ runs(function() {
+ adapterUI.addControlChangeCollections();
+ helper.simulateMouseEvent("click", "control_adapter_collections");
+
+ $("#control_adapter_collections_nodecollection").attr("value", "newNodes");
+ $("#control_adapter_collections_edgecollection").attr("value", "newEdges");
+ $("#control_adapter_collections_undirected").attr("checked", false);
+
+ helper.simulateMouseEvent("click", "control_adapter_collections_submit");
+
+ expect(adapter.changeTo).toHaveBeenCalledWith(
+ "newNodes",
+ "newEdges",
+ false
+ );
+
+ });
+
+ waitsFor(function() {
+ return $("#control_adapter_collections_modal").length === 0;
+ }, 2000, "The modal dialog should disappear.");
+
+ });
+
+ it('should change collections and traversal direction to undirected', function() {
+ runs(function() {
+ adapterUI.addControlChangeCollections();
+ helper.simulateMouseEvent("click", "control_adapter_collections");
+ $("#control_adapter_collections_nodecollection").attr("value", "newNodes");
+ $("#control_adapter_collections_edgecollection").attr("value", "newEdges");
+ $("#control_adapter_collections_undirected").attr("checked", true);
+
+ helper.simulateMouseEvent("click", "control_adapter_collections_submit");
+
+ expect(adapter.changeTo).toHaveBeenCalledWith(
+ "newNodes",
+ "newEdges",
+ true
+ );
+
+ });
+
+ waitsFor(function() {
+ return $("#control_adapter_collections_modal").length === 0;
+ }, 2000, "The modal dialog should disappear.");
+
+ });
+
+ it('should offer the available collections as lists', function() {
+ runs(function() {
+ adapterUI.addControlChangeCollections();
+
+ helper.simulateMouseEvent("click", "control_adapter_collections");
+ var docList = document.getElementById("control_adapter_collections_nodecollection"),
+ edgeList = document.getElementById("control_adapter_collections_edgecollection"),
+ docCollectionOptions = docList.children,
+ edgeCollectionOptions = edgeList.children;
+
+ expect(adapter.getCollections).toHaveBeenCalled();
+
+ expect(docList).toBeTag("select");
+ expect(docCollectionOptions.length).toEqual(2);
+ expect(docCollectionOptions[0]).toBeTag("option");
+ expect(docCollectionOptions[1]).toBeTag("option");
+ expect(docCollectionOptions[0].value).toEqual("nodes");
+ expect(docCollectionOptions[1].value).toEqual("newNodes");
+
+
+ expect(edgeList).toBeTag("select");
+ expect(edgeCollectionOptions.length).toEqual(2);
+ expect(edgeCollectionOptions[0]).toBeTag("option");
+ expect(edgeCollectionOptions[1]).toBeTag("option");
+ expect(edgeCollectionOptions[0].value).toEqual("edges");
+ expect(edgeCollectionOptions[1].value).toEqual("newEdges");
+
+ helper.simulateMouseEvent("click", "control_adapter_collections_submit");
+ });
+
+ waitsFor(function() {
+ return $("#control_adapter_collections_modal").length === 0;
+ }, 2000, "The modal dialog should disappear.");
+ });
+
it('should be able to add all controls to the list', function() {
adapterUI.addAll();
- expect($("#control_list #control_collections").length).toEqual(1);
+ expect($("#control_adapter_list #control_adapter_collections").length).toEqual(1);
});
});
}());
\ No newline at end of file
diff --git a/html/admin/js/graphViewer/jasmine_test/specAdapter/interfaceSpec.js b/html/admin/js/graphViewer/jasmine_test/specAdapter/interfaceSpec.js
index 485dd09d1b..299302a30f 100644
--- a/html/admin/js/graphViewer/jasmine_test/specAdapter/interfaceSpec.js
+++ b/html/admin/js/graphViewer/jasmine_test/specAdapter/interfaceSpec.js
@@ -67,7 +67,9 @@ var describeInterface = function (testee) {
expect(testee).toHaveFunction("deleteNode", 2);
expect(testee).toHaveFunction("patchNode", 3);
expect(testee).toHaveFunction("setNodeLimit", 2);
+ expect(testee).toHaveFunction("setChildLimit", 1);
expect(testee).toHaveFunction("expandCommunity", 2);
+
});
};
diff --git a/html/admin/js/graphViewer/jasmine_test/specEdgeShaper/edgeShaperSpec.js b/html/admin/js/graphViewer/jasmine_test/specEdgeShaper/edgeShaperSpec.js
index e058f8e6be..2b01b81aec 100644
--- a/html/admin/js/graphViewer/jasmine_test/specEdgeShaper/edgeShaperSpec.js
+++ b/html/admin/js/graphViewer/jasmine_test/specEdgeShaper/edgeShaperSpec.js
@@ -42,6 +42,7 @@
beforeEach(function () {
svg = document.createElement("svg");
+ svg.id = "svg";
document.body.appendChild(svg);
});
@@ -274,6 +275,55 @@
expect($("#1-5 line").attr("x2")).toEqual("28.284271247461902");
});
+ it('should be able to draw an edge that follows the cursor', function() {
+ var line,
+ jqLine,
+ cursorX,
+ cursorY,
+ nodeX = 15,
+ nodeY = 20,
+ shaper = new EdgeShaper(d3.select("svg")),
+ moveCB = shaper.addAnEdgeFollowingTheCursor(nodeX, nodeY);
+
+ cursorX = 20;
+ cursorY = 30;
+ moveCB(cursorX, cursorY);
+
+ expect($("#connectionLine").length).toEqual(1);
+
+ jqLine = $("#connectionLine");
+ line = document.getElementById("connectionLine");
+ expect(line.tagName.toLowerCase()).toEqual("line");
+ expect(jqLine.attr("x1")).toEqual(String(nodeX));
+ expect(jqLine.attr("y1")).toEqual(String(nodeY));
+
+ expect(jqLine.attr("x2")).toEqual(String(cursorX));
+ expect(jqLine.attr("y2")).toEqual(String(cursorY));
+
+ cursorX = 45;
+ cursorY = 12;
+ moveCB(cursorX, cursorY);
+ expect(jqLine.attr("x2")).toEqual(String(cursorX));
+ expect(jqLine.attr("y2")).toEqual(String(cursorY));
+ });
+
+ it('should be able to remove the cursor-following edge on demand', function() {
+ var line,
+ cursorX,
+ cursorY,
+ nodeX = 15,
+ nodeY = 20,
+ shaper = new EdgeShaper(d3.select("svg")),
+ moveCB;
+
+ moveCB = shaper.addAnEdgeFollowingTheCursor(nodeX, nodeY);
+ cursorX = 20;
+ cursorY = 30;
+ moveCB(cursorX, cursorY);
+ shaper.removeCursorFollowingEdge();
+ expect($("#connectionLine").length).toEqual(0);
+ });
+
describe('testing for colours', function() {
it('should have a default colouring of no colour flag is given', function() {
diff --git a/html/admin/js/graphViewer/jasmine_test/specEdgeShaper/edgeShaperUISpec.js b/html/admin/js/graphViewer/jasmine_test/specEdgeShaper/edgeShaperUISpec.js
index 3508071a69..f1ac9f8598 100644
--- a/html/admin/js/graphViewer/jasmine_test/specEdgeShaper/edgeShaperUISpec.js
+++ b/html/admin/js/graphViewer/jasmine_test/specEdgeShaper/edgeShaperUISpec.js
@@ -47,7 +47,7 @@
shaper = new EdgeShaper(d3.select("svg"));
list = document.createElement("ul");
document.body.appendChild(list);
- list.id = "control_list";
+ list.id = "control_edge_list";
shaperUI = new EdgeShaperControls(list, shaper);
spyOn(shaper, 'changeTo');
this.addMatchers({
@@ -94,10 +94,10 @@
runs(function() {
shaperUI.addControlOpticShapeNone();
- expect($("#control_list #control_none").length).toEqual(1);
- expect($("#control_list #control_none")[0]).toConformToListCSS();
+ expect($("#control_edge_list #control_edge_none").length).toEqual(1);
+ expect($("#control_edge_list #control_edge_none")[0]).toConformToListCSS();
- helper.simulateMouseEvent("click", "control_none");
+ helper.simulateMouseEvent("click", "control_edge_none");
expect(shaper.changeTo).toHaveBeenCalledWith({
shape: {
@@ -111,10 +111,10 @@
runs(function() {
shaperUI.addControlOpticShapeArrow();
- expect($("#control_list #control_arrow").length).toEqual(1);
- expect($("#control_list #control_arrow")[0]).toConformToListCSS();
+ expect($("#control_edge_list #control_edge_arrow").length).toEqual(1);
+ expect($("#control_edge_list #control_edge_arrow")[0]).toConformToListCSS();
- helper.simulateMouseEvent("click", "control_arrow");
+ helper.simulateMouseEvent("click", "control_edge_arrow");
expect(shaper.changeTo).toHaveBeenCalledWith({
shape: {
@@ -129,12 +129,12 @@
runs(function() {
shaperUI.addControlOpticLabel();
- expect($("#control_list #control_label").length).toEqual(1);
- expect($("#control_list #control_label")[0]).toConformToListCSS();
+ expect($("#control_edge_list #control_edge_label").length).toEqual(1);
+ expect($("#control_edge_list #control_edge_label")[0]).toConformToListCSS();
- helper.simulateMouseEvent("click", "control_label");
- $("#control_label_key").attr("value", "theAnswer");
- helper.simulateMouseEvent("click", "control_label_submit");
+ helper.simulateMouseEvent("click", "control_edge_label");
+ $("#control_edge_label_key").attr("value", "theAnswer");
+ helper.simulateMouseEvent("click", "control_edge_label_submit");
expect(shaper.changeTo).toHaveBeenCalledWith({
label: "theAnswer"
@@ -142,7 +142,7 @@
});
waitsFor(function() {
- return $("#control_label_modal").length === 0;
+ return $("#control_edge_label_modal").length === 0;
}, 2000, "The modal dialog should disappear.");
});
@@ -151,12 +151,12 @@
runs(function() {
shaperUI.addControlOpticSingleColour();
- expect($("#control_list #control_singlecolour").length).toEqual(1);
- expect($("#control_list #control_singlecolour")[0]).toConformToListCSS();
+ expect($("#control_edge_list #control_edge_singlecolour").length).toEqual(1);
+ expect($("#control_edge_list #control_edge_singlecolour")[0]).toConformToListCSS();
- helper.simulateMouseEvent("click", "control_singlecolour");
- $("#control_singlecolour_stroke").attr("value", "#123456");
- helper.simulateMouseEvent("click", "control_singlecolour_submit");
+ helper.simulateMouseEvent("click", "control_edge_singlecolour");
+ $("#control_edge_singlecolour_stroke").attr("value", "#123456");
+ helper.simulateMouseEvent("click", "control_edge_singlecolour_submit");
expect(shaper.changeTo).toHaveBeenCalledWith({
color: {
@@ -167,7 +167,7 @@
});
waitsFor(function() {
- return $("#control_singlecolour_modal").length === 0;
+ return $("#control_edge_singlecolour_modal").length === 0;
}, 2000, "The modal dialog should disappear.");
});
@@ -176,12 +176,12 @@
runs(function() {
shaperUI.addControlOpticAttributeColour();
- expect($("#control_list #control_attributecolour").length).toEqual(1);
- expect($("#control_list #control_attributecolour")[0]).toConformToListCSS();
+ expect($("#control_edge_list #control_edge_attributecolour").length).toEqual(1);
+ expect($("#control_edge_list #control_edge_attributecolour")[0]).toConformToListCSS();
- helper.simulateMouseEvent("click", "control_attributecolour");
- $("#control_attributecolour_key").attr("value", "label");
- helper.simulateMouseEvent("click", "control_attributecolour_submit");
+ helper.simulateMouseEvent("click", "control_edge_attributecolour");
+ $("#control_edge_attributecolour_key").attr("value", "label");
+ helper.simulateMouseEvent("click", "control_edge_attributecolour_submit");
expect(shaper.changeTo).toHaveBeenCalledWith({
color: {
@@ -192,7 +192,7 @@
});
waitsFor(function() {
- return $("#control_attributecolour_modal").length === 0;
+ return $("#control_edge_attributecolour_modal").length === 0;
}, 2000, "The modal dialog should disappear.");
});
@@ -201,13 +201,13 @@
runs(function() {
shaperUI.addControlOpticGradientColour();
- expect($("#control_list #control_gradientcolour").length).toEqual(1);
- expect($("#control_list #control_gradientcolour")[0]).toConformToListCSS();
+ expect($("#control_edge_list #control_edge_gradientcolour").length).toEqual(1);
+ expect($("#control_edge_list #control_edge_gradientcolour")[0]).toConformToListCSS();
- helper.simulateMouseEvent("click", "control_gradientcolour");
- $("#control_gradientcolour_source").attr("value", "#123456");
- $("#control_gradientcolour_target").attr("value", "#654321");
- helper.simulateMouseEvent("click", "control_gradientcolour_submit");
+ helper.simulateMouseEvent("click", "control_edge_gradientcolour");
+ $("#control_edge_gradientcolour_source").attr("value", "#123456");
+ $("#control_edge_gradientcolour_target").attr("value", "#654321");
+ helper.simulateMouseEvent("click", "control_edge_gradientcolour_submit");
expect(shaper.changeTo).toHaveBeenCalledWith({
color: {
@@ -219,7 +219,7 @@
});
waitsFor(function() {
- return $("#control_gradientcolour_modal").length === 0;
+ return $("#control_edge_gradientcolour_modal").length === 0;
}, 2000, "The modal dialog should disappear.");
});
@@ -227,12 +227,12 @@
it('should be able to add all optic controls to the list', function () {
shaperUI.addAllOptics();
- expect($("#control_list #control_none").length).toEqual(1);
- expect($("#control_list #control_arrow").length).toEqual(1);
- expect($("#control_list #control_label").length).toEqual(1);
- expect($("#control_list #control_singlecolour").length).toEqual(1);
- expect($("#control_list #control_attributecolour").length).toEqual(1);
- expect($("#control_list #control_gradientcolour").length).toEqual(1);
+ expect($("#control_edge_list #control_edge_none").length).toEqual(1);
+ expect($("#control_edge_list #control_edge_arrow").length).toEqual(1);
+ expect($("#control_edge_list #control_edge_label").length).toEqual(1);
+ expect($("#control_edge_list #control_edge_singlecolour").length).toEqual(1);
+ expect($("#control_edge_list #control_edge_attributecolour").length).toEqual(1);
+ expect($("#control_edge_list #control_edge_gradientcolour").length).toEqual(1);
});
@@ -244,12 +244,12 @@
it('should be able to add all controls to the list', function () {
shaperUI.addAll();
- expect($("#control_list #control_none").length).toEqual(1);
- expect($("#control_list #control_arrow").length).toEqual(1);
- expect($("#control_list #control_label").length).toEqual(1);
- expect($("#control_list #control_singlecolour").length).toEqual(1);
- expect($("#control_list #control_attributecolour").length).toEqual(1);
- expect($("#control_list #control_gradientcolour").length).toEqual(1);
+ expect($("#control_edge_list #control_edge_none").length).toEqual(1);
+ expect($("#control_edge_list #control_edge_arrow").length).toEqual(1);
+ expect($("#control_edge_list #control_edge_label").length).toEqual(1);
+ expect($("#control_edge_list #control_edge_singlecolour").length).toEqual(1);
+ expect($("#control_edge_list #control_edge_attributecolour").length).toEqual(1);
+ expect($("#control_edge_list #control_edge_gradientcolour").length).toEqual(1);
});
});
diff --git a/html/admin/js/graphViewer/jasmine_test/specEvents/eventDispatcherSpec.js b/html/admin/js/graphViewer/jasmine_test/specEvents/eventDispatcherSpec.js
index ac7bd7ee46..3d9a6d0b25 100644
--- a/html/admin/js/graphViewer/jasmine_test/specEvents/eventDispatcherSpec.js
+++ b/html/admin/js/graphViewer/jasmine_test/specEvents/eventDispatcherSpec.js
@@ -759,6 +759,147 @@
});
});
+ });
+
+ describe('checking binding to SVG', function() {
+
+ it('should be able to permanently bind many functions to events', function() {
+ var functions = {
+ a: function() {},
+ b: function() {},
+ c: function() {},
+ d: function() {}
+ };
+ spyOn(functions, "a");
+ spyOn(functions, "b");
+ spyOn(functions, "c");
+ spyOn(functions, "d");
+
+ dispatcher.fixSVG("click", functions.a);
+ dispatcher.fixSVG("click", functions.b);
+ dispatcher.fixSVG("click", functions.c);
+ dispatcher.fixSVG("click", functions.d);
+
+ helper.simulateMouseEvent("click", "svg");
+
+ expect(functions.a).wasCalled();
+ expect(functions.b).wasCalled();
+ expect(functions.c).wasCalled();
+ expect(functions.d).wasCalled();
+ });
+
+ it('should be able to bind temporary functions to events', function() {
+ var functions = {
+ a: function() {}
+ };
+ spyOn(functions, "a");
+
+ dispatcher.bind("svg", "click", functions.a);
+
+ helper.simulateMouseEvent("click", "svg");
+
+ expect(functions.a).wasCalled();
+ });
+
+ it('should be able to overwrite temporary functions on events', function() {
+ var functions = {
+ a: function() {},
+ b: function() {}
+ };
+ spyOn(functions, "a");
+ spyOn(functions, "b");
+
+ dispatcher.bind("svg", "click", functions.a);
+
+ dispatcher.bind("svg", "click", functions.b);
+
+ helper.simulateMouseEvent("click", "svg");
+
+ expect(functions.b).wasCalled();
+ expect(functions.a).wasNotCalled();
+ });
+
+ it('should not overwrite permanent functions', function() {
+ var functions = {
+ a: function() {},
+ b: function() {}
+ };
+ spyOn(functions, "a");
+ spyOn(functions, "b");
+
+ dispatcher.fixSVG("click", functions.a);
+
+ dispatcher.bind("svg", "click", functions.b);
+
+ helper.simulateMouseEvent("click", "svg");
+
+ expect(functions.b).wasCalled();
+ expect(functions.a).wasCalled();
+ });
+
+ it('binding a permanent function should not effect temporary function', function() {
+ var functions = {
+ a: function() {},
+ b: function() {}
+ };
+ spyOn(functions, "a");
+ spyOn(functions, "b");
+
+ dispatcher.bind("svg", "click", functions.b);
+ dispatcher.fixSVG("click", functions.a);
+
+ helper.simulateMouseEvent("click", "svg");
+
+ expect(functions.b).wasCalled();
+ expect(functions.a).wasCalled();
+ });
+
+ it('should be able to bind only the given events and'
+ + ' unbind other temporary events', function() {
+ var functions = {
+ a: function() {},
+ b: function() {},
+ c: function() {},
+ d: function() {}
+ };
+ spyOn(functions, "a");
+ spyOn(functions, "b");
+ spyOn(functions, "c");
+ spyOn(functions, "d");
+
+ dispatcher.bind("svg", "mouseup", functions.a);
+ dispatcher.bind("svg", "mousedown", functions.b);
+ dispatcher.bind("svg", "click", functions.c);
+ dispatcher.rebind("svg", {click: functions.d});
+
+ helper.simulateMouseEvent("click", "svg");
+ helper.simulateMouseEvent("mouseup", "svg");
+ helper.simulateMouseEvent("mousedown", "svg");
+
+ expect(functions.a).wasNotCalled();
+ expect(functions.b).wasNotCalled();
+ expect(functions.c).wasNotCalled();
+ expect(functions.d).wasCalled();
+ });
+
+ it('should not remove permanent events on rebind', function() {
+ var functions = {
+ a: function() {},
+ b: function() {}
+ };
+ spyOn(functions, "a");
+ spyOn(functions, "b");
+
+ dispatcher.fixSVG("mousemove", functions.a);
+ dispatcher.rebind("svg", {click: functions.b});
+
+ helper.simulateMouseEvent("mousemove", "svg");
+ helper.simulateMouseEvent("click", "svg");
+
+ expect(functions.a).wasCalled();
+ expect(functions.b).wasCalled();
+ });
+
});
describe('checking rebinding of events', function() {
@@ -843,6 +984,8 @@
});
});
+
+
});
});
diff --git a/html/admin/js/graphViewer/jasmine_test/specEvents/eventDispatcherUISpec.js b/html/admin/js/graphViewer/jasmine_test/specEvents/eventDispatcherUISpec.js
index e641dccb45..f10ad66e0d 100644
--- a/html/admin/js/graphViewer/jasmine_test/specEvents/eventDispatcherUISpec.js
+++ b/html/admin/js/graphViewer/jasmine_test/specEvents/eventDispatcherUISpec.js
@@ -42,6 +42,7 @@
var svg, dispatcher, dispatcherUI, list,
nodeShaper, edgeShaper, layouter,
nodes, edges, adapter,
+ mousePointerbox,
addSpies = function() {
spyOn(layouter, "drag");
@@ -60,17 +61,21 @@
beforeEach(function () {
nodes = [{
_id: 1,
- _rev: 1,
- _key: 1,
+ x: 3,
+ y: 4,
_data: {
_id: 1,
+ _rev: 1,
+ _key: 1,
name: "Alice"
}
},{
_id: 2,
- _rev: 2,
- _key: 2,
+ x: 1,
+ y: 2,
_data: {
+ _rev: 2,
+ _key: 2,
_id: 2
}
}];
@@ -121,16 +126,26 @@
};
svg = document.createElement("svg");
+ svg.id = "svg";
document.body.appendChild(svg);
nodeShaper = new NodeShaper(d3.select("svg"));
edgeShaper = new EdgeShaper(d3.select("svg"));
list = document.createElement("ul");
document.body.appendChild(list);
- list.id = "control_list";
+ list.id = "control_event_list";
+
+ mousePointerbox = document.createElement("svg");
+ mousePointerbox.id = "mousepointer";
+ mousePointerbox.className = "mousepointer";
+
+ document.body.appendChild(mousePointerbox);
+
nodeShaper.drawNodes(nodes);
edgeShaper.drawEdges(edges);
- dispatcherUI = new EventDispatcherControls(list, nodeShaper, edgeShaper, completeConfig);
+ dispatcherUI = new EventDispatcherControls(
+ list, mousePointerbox, nodeShaper, edgeShaper, completeConfig
+ );
spyOn(nodeShaper, "changeTo").andCallThrough();
spyOn(edgeShaper, "changeTo").andCallThrough();
@@ -174,6 +189,7 @@
expect(list).toConformToToolbox();
document.body.removeChild(list);
document.body.removeChild(svg);
+ document.body.removeChild(mousePointerbox);
});
it('should throw errors if not setup correctly', function() {
@@ -182,9 +198,12 @@
}).toThrow("A list element has to be given.");
expect(function() {
var e = new EventDispatcherControls(list);
+ }).toThrow("The cursor decoration box has to be given.");
+ expect(function() {
+ var e = new EventDispatcherControls(list, mousePointerbox);
}).toThrow("The NodeShaper has to be given.");
expect(function() {
- var e = new EventDispatcherControls(list, nodeShaper);
+ var e = new EventDispatcherControls(list, mousePointerbox, nodeShaper);
}).toThrow("The EdgeShaper has to be given.");
});
@@ -192,9 +211,9 @@
runs(function() {
dispatcherUI.addControlDrag();
- expect($("#control_list #control_drag").length).toEqual(1);
+ expect($("#control_event_list #control_event_drag").length).toEqual(1);
- helper.simulateMouseEvent("click", "control_drag");
+ helper.simulateMouseEvent("click", "control_event_drag");
expect(nodeShaper.changeTo).toHaveBeenCalledWith({
actions: {
@@ -209,6 +228,8 @@
}
});
+ expect(mousePointerbox.className).toEqual("mousepointer icon-move");
+
helper.simulateDragEvent("1");
expect(layouter.drag).toHaveBeenCalled();
@@ -220,9 +241,9 @@
runs(function() {
dispatcherUI.addControlEdit();
- expect($("#control_list #control_edit").length).toEqual(1);
+ expect($("#control_event_list #control_event_edit").length).toEqual(1);
- helper.simulateMouseEvent("click", "control_edit");
+ helper.simulateMouseEvent("click", "control_event_edit");
expect(nodeShaper.changeTo).toHaveBeenCalledWith({
actions: {
@@ -238,39 +259,38 @@
}
});
+ expect(mousePointerbox.className).toEqual("mousepointer icon-pencil");
+
helper.simulateMouseEvent("click", "1");
- expect($("#control_node_edit_modal").length).toEqual(1);
+ expect($("#control_event_node_edit_modal").length).toEqual(1);
- $("#control_node_edit_name_value").val("Bob");
+ $("#control_event_node_edit_name_value").val("Bob");
- helper.simulateMouseEvent("click", "control_node_edit_submit");
+ helper.simulateMouseEvent("click", "control_event_node_edit_submit");
expect(adapter.patchNode).toHaveBeenCalledWith(
nodes[0],
- { _id: "1",
+ {
name: "Bob"
},
jasmine.any(Function));
});
waitsFor(function() {
- return $("#control_node_edit_modal").length === 0;
+ return $("#control_event_node_edit_modal").length === 0;
}, 2000, "The modal dialog should disappear.");
runs(function() {
helper.simulateMouseEvent("click", "1-2");
- expect($("#control_edge_edit_modal").length).toEqual(1);
+ expect($("#control_event_edge_edit_modal").length).toEqual(1);
- $("#control_edge_edit_label_value").val("newLabel");
- helper.simulateMouseEvent("click", "control_edge_edit_submit");
+ $("#control_event_edge_edit_label_value").val("newLabel");
+ helper.simulateMouseEvent("click", "control_event_edge_edit_submit");
expect(adapter.patchEdge).toHaveBeenCalledWith(
edges[0],
{
- _id: "12",
- _rev: "12",
- _key: "12",
_from: "1",
_to: "2",
label: "newLabel"
@@ -279,7 +299,7 @@
});
waitsFor(function() {
- return $("#control_edge_edit_modal").length === 0;
+ return $("#control_event_edge_edit_modal").length === 0;
}, 2000, "The modal dialog should disappear.");
});
@@ -288,9 +308,9 @@
runs(function() {
dispatcherUI.addControlExpand();
- expect($("#control_list #control_expand").length).toEqual(1);
+ expect($("#control_event_list #control_event_expand").length).toEqual(1);
- helper.simulateMouseEvent("click", "control_expand");
+ helper.simulateMouseEvent("click", "control_event_expand");
expect(nodeShaper.changeTo).toHaveBeenCalledWith({
actions: {
@@ -305,6 +325,8 @@
}
});
+ expect(mousePointerbox.className).toEqual("mousepointer icon-plus");
+
helper.simulateMouseEvent("click", "1");
expect(adapter.loadNode).toHaveBeenCalledWith(nodes[0]._id, jasmine.any(Function));
@@ -316,9 +338,9 @@
runs(function() {
dispatcherUI.addControlDelete();
- expect($("#control_list #control_delete").length).toEqual(1);
+ expect($("#control_event_list #control_event_delete").length).toEqual(1);
- helper.simulateMouseEvent("click", "control_delete");
+ helper.simulateMouseEvent("click", "control_event_delete");
expect(edgeShaper.changeTo).toHaveBeenCalledWith({
actions: {
@@ -334,6 +356,8 @@
}
});
+ expect(mousePointerbox.className).toEqual("mousepointer icon-trash");
+
helper.simulateMouseEvent("click", "1");
expect(adapter.deleteNode).toHaveBeenCalledWith(
@@ -351,48 +375,104 @@
});
});
- it('should be able to add a connect control to the list', function() {
- runs(function() {
+ describe('the connect control', function() {
+
+ it('should be added to the list', function() {
+ runs(function() {
+ dispatcherUI.addControlConnect();
+
+ expect($("#control_event_list #control_event_connect").length).toEqual(1);
+
+ helper.simulateMouseEvent("click", "control_event_connect");
+
+ expect(nodeShaper.changeTo).toHaveBeenCalledWith({
+ actions: {
+ reset: true,
+ mousedown: jasmine.any(Function),
+ mouseup: jasmine.any(Function)
+ }
+ });
+
+ expect(edgeShaper.changeTo).toHaveBeenCalledWith({
+ actions: {
+ reset: true
+ }
+ });
+
+ expect(mousePointerbox.className).toEqual("mousepointer icon-resize-horizontal");
+
+ helper.simulateMouseEvent("mousedown", "2");
+
+ helper.simulateMouseEvent("mouseup", "1");
+
+ expect(adapter.createEdge).toHaveBeenCalledWith(
+ {source: nodes[1], target: nodes[0]},
+ jasmine.any(Function)
+ );
+
+ });
+ });
+
+ it('should draw a line from startNode following the cursor', function() {
+ var line,
+ cursorX,
+ cursorY;
+
+ spyOn(edgeShaper, "addAnEdgeFollowingTheCursor");
+
dispatcherUI.addControlConnect();
-
- expect($("#control_list #control_connect").length).toEqual(1);
-
- helper.simulateMouseEvent("click", "control_connect");
-
- expect(nodeShaper.changeTo).toHaveBeenCalledWith({
- actions: {
- reset: true,
- mousedown: jasmine.any(Function),
- mouseup: jasmine.any(Function)
- }
- });
-
- expect(edgeShaper.changeTo).toHaveBeenCalledWith({
- actions: {
- reset: true
- }
- });
-
+ helper.simulateMouseEvent("click", "control_event_connect");
helper.simulateMouseEvent("mousedown", "2");
- helper.simulateMouseEvent("mouseup", "1");
-
- expect(adapter.createEdge).toHaveBeenCalledWith(
- {source: nodes[1], target: nodes[0]},
- jasmine.any(Function)
+ expect(edgeShaper.addAnEdgeFollowingTheCursor).toHaveBeenCalledWith(
+ 0, 0
);
+ });
+
+ it('the cursor-line should follow the cursor on mousemove over svg', function() {
+ dispatcherUI.addControlConnect();
+ helper.simulateMouseEvent("click", "control_event_connect");
+ helper.simulateMouseEvent("mousedown", "2");
- });
+ helper.simulateMouseMoveEvent("svg", 40, 50);
+
+ var line = $("#connectionLine");
+ expect(line.attr("x1")).toEqual(String(nodes[1].x));
+ expect(line.attr("y1")).toEqual(String(nodes[1].y));
+ expect(line.attr("x2")).toEqual("40");
+ expect(line.attr("y2")).toEqual("50");
+ });
+
+ it('the cursor-line should disappear on mouseup on svg', function() {
+ spyOn(edgeShaper, "removeCursorFollowingEdge");
+ dispatcherUI.addControlConnect();
+ helper.simulateMouseEvent("click", "control_event_connect");
+ helper.simulateMouseEvent("mousedown", "2");
+ helper.simulateMouseEvent("mouseup", "1-2");
+ expect(edgeShaper.removeCursorFollowingEdge).toHaveBeenCalled();
+ });
+
+ it('the cursor-line should disappear on mouseup on svg', function() {
+ spyOn(edgeShaper, "removeCursorFollowingEdge");
+ dispatcherUI.addControlConnect();
+ helper.simulateMouseEvent("click", "control_event_connect");
+ helper.simulateMouseEvent("mousedown", "2");
+ helper.simulateMouseEvent("mouseup", "1");
+ expect(edgeShaper.removeCursorFollowingEdge).toHaveBeenCalled();
+ });
+
});
+
+
it('should be able to add all controls to the list', function () {
dispatcherUI.addAll();
- expect($("#control_list #control_drag").length).toEqual(1);
- expect($("#control_list #control_edit").length).toEqual(1);
- expect($("#control_list #control_expand").length).toEqual(1);
- expect($("#control_list #control_delete").length).toEqual(1);
- expect($("#control_list #control_connect").length).toEqual(1);
+ expect($("#control_event_list #control_event_drag").length).toEqual(1);
+ expect($("#control_event_list #control_event_edit").length).toEqual(1);
+ expect($("#control_event_list #control_event_expand").length).toEqual(1);
+ expect($("#control_event_list #control_event_delete").length).toEqual(1);
+ expect($("#control_event_list #control_event_connect").length).toEqual(1);
});
});
diff --git a/html/admin/js/graphViewer/jasmine_test/specEvents/eventLibrarySpec.js b/html/admin/js/graphViewer/jasmine_test/specEvents/eventLibrarySpec.js
index a87de74c62..6a39dc7b7e 100644
--- a/html/admin/js/graphViewer/jasmine_test/specEvents/eventLibrarySpec.js
+++ b/html/admin/js/graphViewer/jasmine_test/specEvents/eventLibrarySpec.js
@@ -209,21 +209,127 @@
expect(c2._outboundCounter).toEqual(1);
});
- it('should expand a community node properly', function() {
- var comm = {
- _id: "*community_1"
- };
- nodes.push(comm);
+ describe('with community nodes', function() {
- spyOn(adapterDummy, "expandCommunity");
+ it('should expand a community node properly', function() {
+ var comm = {
+ _id: "*community_1"
+ };
+ nodes.push(comm);
- testee = eventLib.Expand(config);
- testee(comm);
+ spyOn(adapterDummy, "expandCommunity");
+
+ testee = eventLib.Expand(config);
+ testee(comm);
+
+ expect(adapterDummy.expandCommunity).toHaveBeenCalledWith(comm, jasmine.any(Function));
+ });
+
+ it('should remove a community if last pointer to it is collapsed', function() {
+
+ runs(function() {
+ var c0 = {
+ _id: 0,
+ _outboundCounter: 1,
+ _inboundCounter: 0
+ },
+ c1 = {
+ _id: 1,
+ _expanded: true,
+ _outboundCounter: 1,
+ _inboundCounter: 1
+ },
+ comm = {
+ _id: "*community_1",
+ _outboundCounter: 1,
+ _inboundCounter: 1
+ },
+ c2 = {
+ _id: 1,
+ _outboundCounter: 0,
+ _inboundCounter: 1
+ },
+ e0 = {
+ source: c0,
+ target: c1
+ },
+ e1 = {
+ source: c1,
+ target: comm
+ },
+ e2 = {
+ source: comm,
+ target: c2
+ };
+ nodes.push(c0);
+ nodes.push(c1);
+ nodes.push(comm);
+ nodes.push(c2);
+ edges.push(e0);
+ edges.push(e1);
+ edges.push(e2);
+
+ testee = eventLib.Expand(config);
+ testee(c1);
+
+ expect(nodes).toEqual([c0, c1]);
+ expect(edges).toEqual([e0]);
+ });
+
+ });
+
+ it('should not remove a community if a pointer to it still exists', function() {
+
+ runs(function() {
+ var c0 = {
+ _id: 0,
+ _outboundCounter: 2,
+ _inboundCounter: 0
+ },
+ c1 = {
+ _id: 1,
+ _expanded: true,
+ _outboundCounter: 1,
+ _inboundCounter: 1
+ },
+ comm = {
+ _id: "*community_1",
+ _outboundCounter: 0,
+ _inboundCounter: 2
+ },
+ e0 = {
+ source: c0,
+ target: c1
+ },
+ e1 = {
+ source: c0,
+ target: comm
+ },
+ e2 = {
+ source: c1,
+ target: comm
+ };
+ nodes.push(c0);
+ nodes.push(c1);
+ nodes.push(comm);
+ edges.push(e0);
+ edges.push(e1);
+ edges.push(e2);
+
+ testee = eventLib.Expand(config);
+ testee(c1);
+
+ expect(nodes).toEqual([c0, c1, comm]);
+ expect(edges).toEqual([e0, e1]);
+ });
+
+ });
- expect(adapterDummy.expandCommunity).toHaveBeenCalledWith(comm, jasmine.any(Function));
});
+
+
describe('setup process', function() {
var testConfig = {};
diff --git a/html/admin/js/graphViewer/jasmine_test/specForceLayouter/forceLayouterSpec.js b/html/admin/js/graphViewer/jasmine_test/specForceLayouter/forceLayouterSpec.js
index ad9882b29d..57cf900cb9 100644
--- a/html/admin/js/graphViewer/jasmine_test/specForceLayouter/forceLayouterSpec.js
+++ b/html/admin/js/graphViewer/jasmine_test/specForceLayouter/forceLayouterSpec.js
@@ -154,7 +154,7 @@
+ " should be close to Node " + n2.id
+ " but distance is " + distance;
};
- threshold = threshold || 100;
+ threshold = threshold || 150;
return Math.abs(distance) < threshold;
},
@@ -241,7 +241,7 @@
});
it('should position not linked nodes close to each other', function() {
- runs(function() {
+ runs(function() {
nodes = createNodeList(4);
standardConfig.nodes = nodes;
edgeShaper = {"updateEdges": function(){}};
@@ -391,10 +391,16 @@
var tmp = new ForceLayouter(config);
+ /*
expect(mock.size).wasCalledWith([940, 640]);
- expect(mock.linkDistance).wasCalledWith(80);
+ expect(mock.linkDistance).wasCalledWith(240);
expect(mock.gravity).wasCalledWith(0.08);
expect(mock.charge).wasCalledWith(-240);
+ */
+ expect(mock.size).wasCalledWith([940, 640]);
+ expect(mock.linkDistance).wasCalledWith(240);
+ expect(mock.gravity).wasCalledWith(0.01);
+ expect(mock.charge).wasCalledWith(-1000);
});
it('should be able to switch the distance', function() {
diff --git a/html/admin/js/graphViewer/jasmine_test/specForceLayouter/forceLayouterUISpec.js b/html/admin/js/graphViewer/jasmine_test/specForceLayouter/forceLayouterUISpec.js
index 8b7b22deeb..f846ce1998 100644
--- a/html/admin/js/graphViewer/jasmine_test/specForceLayouter/forceLayouterUISpec.js
+++ b/html/admin/js/graphViewer/jasmine_test/specForceLayouter/forceLayouterUISpec.js
@@ -49,7 +49,7 @@
layouter = new ForceLayouter(config);
list = document.createElement("ul");
document.body.appendChild(list);
- list.id = "control_list";
+ list.id = "control_layout_list";
layouterUI = new LayouterControls(list, layouter);
spyOn(layouter, 'changeTo');
this.addMatchers({
@@ -90,15 +90,15 @@
runs(function() {
layouterUI.addControlGravity();
- expect($("#control_list #control_gravity").length).toEqual(1);
- expect($("#control_list #control_gravity")[0]).toConformToListCSS();
+ expect($("#control_layout_list #control_layout_gravity").length).toEqual(1);
+ expect($("#control_layout_list #control_layout_gravity")[0]).toConformToListCSS();
- helper.simulateMouseEvent("click", "control_gravity");
+ helper.simulateMouseEvent("click", "control_layout_gravity");
- expect($("#control_gravity_modal").length).toEqual(1);
+ expect($("#control_layout_gravity_modal").length).toEqual(1);
- $("#control_gravity_value").attr("value", 42);
- helper.simulateMouseEvent("click", "control_gravity_submit");
+ $("#control_layout_gravity_value").attr("value", 42);
+ helper.simulateMouseEvent("click", "control_layout_gravity_submit");
expect(layouter.changeTo).toHaveBeenCalledWith({
gravity: "42"
@@ -107,7 +107,7 @@
});
waitsFor(function() {
- return $("#control_gravity_modal").length === 0;
+ return $("#control_layout_gravity_modal").length === 0;
}, 2000, "The modal dialog should disappear.");
});
@@ -115,15 +115,15 @@
runs(function() {
layouterUI.addControlDistance();
- expect($("#control_list #control_distance").length).toEqual(1);
- expect($("#control_list #control_distance")[0]).toConformToListCSS();
+ expect($("#control_layout_list #control_layout_distance").length).toEqual(1);
+ expect($("#control_layout_list #control_layout_distance")[0]).toConformToListCSS();
- helper.simulateMouseEvent("click", "control_distance");
+ helper.simulateMouseEvent("click", "control_layout_distance");
- expect($("#control_distance_modal").length).toEqual(1);
+ expect($("#control_layout_distance_modal").length).toEqual(1);
- $("#control_distance_value").attr("value", 42);
- helper.simulateMouseEvent("click", "control_distance_submit");
+ $("#control_layout_distance_value").attr("value", 42);
+ helper.simulateMouseEvent("click", "control_layout_distance_submit");
expect(layouter.changeTo).toHaveBeenCalledWith({
distance: "42"
@@ -132,7 +132,7 @@
});
waitsFor(function() {
- return $("#control_distance_modal").length === 0;
+ return $("#control_layout_distance_modal").length === 0;
}, 2000, "The modal dialog should disappear.");
});
@@ -140,15 +140,15 @@
runs(function() {
layouterUI.addControlCharge();
- expect($("#control_list #control_charge").length).toEqual(1);
- expect($("#control_list #control_charge")[0]).toConformToListCSS();
+ expect($("#control_layout_list #control_layout_charge").length).toEqual(1);
+ expect($("#control_layout_list #control_layout_charge")[0]).toConformToListCSS();
- helper.simulateMouseEvent("click", "control_charge");
+ helper.simulateMouseEvent("click", "control_layout_charge");
- expect($("#control_charge_modal").length).toEqual(1);
+ expect($("#control_layout_charge_modal").length).toEqual(1);
- $("#control_charge_value").attr("value", 42);
- helper.simulateMouseEvent("click", "control_charge_submit");
+ $("#control_layout_charge_value").attr("value", 42);
+ helper.simulateMouseEvent("click", "control_layout_charge_submit");
expect(layouter.changeTo).toHaveBeenCalledWith({
charge: "42"
@@ -157,16 +157,16 @@
});
waitsFor(function() {
- return $("#control_charge_modal").length === 0;
+ return $("#control_layout_charge_modal").length === 0;
}, 2000, "The modal dialog should disappear.");
});
it('should be able to add all controls to the list', function () {
layouterUI.addAll();
- expect($("#control_list #control_gravity").length).toEqual(1);
- expect($("#control_list #control_distance").length).toEqual(1);
- expect($("#control_list #control_charge").length).toEqual(1);
+ expect($("#control_layout_list #control_layout_gravity").length).toEqual(1);
+ expect($("#control_layout_list #control_layout_distance").length).toEqual(1);
+ expect($("#control_layout_list #control_layout_charge").length).toEqual(1);
});
});
diff --git a/html/admin/js/graphViewer/jasmine_test/specGraphViewer/graphViewerUISpec.js b/html/admin/js/graphViewer/jasmine_test/specGraphViewer/graphViewerUISpec.js
index 08dab1b591..fbb3eae4d3 100644
--- a/html/admin/js/graphViewer/jasmine_test/specGraphViewer/graphViewerUISpec.js
+++ b/html/admin/js/graphViewer/jasmine_test/specGraphViewer/graphViewerUISpec.js
@@ -57,6 +57,9 @@
value: value
};
};
+ r.getCollections = function(callback) {
+ callback(["nodes"], ["edges"]);
+ };
return r;
};
//Mock for ZoomManager
@@ -190,17 +193,41 @@
});
it('should contain the objects from eventDispatcher', function() {
- expect($(toolboxSelector + " #control_drag").length).toEqual(1);
- expect($(toolboxSelector + " #control_edit").length).toEqual(1);
- expect($(toolboxSelector + " #control_expand").length).toEqual(1);
- expect($(toolboxSelector + " #control_delete").length).toEqual(1);
- expect($(toolboxSelector + " #control_connect").length).toEqual(1);
+ expect($(toolboxSelector + " #control_event_drag").length).toEqual(1);
+ expect($(toolboxSelector + " #control_event_edit").length).toEqual(1);
+ expect($(toolboxSelector + " #control_event_expand").length).toEqual(1);
+ expect($(toolboxSelector + " #control_event_delete").length).toEqual(1);
+ expect($(toolboxSelector + " #control_event_connect").length).toEqual(1);
});
it('should have the correct layout', function() {
expect($(toolboxSelector)[0]).toConformToToolboxLayout();
});
+ it('should create the additional mouse-icon box', function() {
+ var pointerBox = $("#contentDiv #mousepointer");
+ expect(pointerBox.length).toEqual(1);
+ expect(pointerBox[0]).toBeTag("div");
+ expect(pointerBox[0]).toBeOfClass("mousepointer");
+ });
+
+ it('should position the mouse-icon box next to the mouse pointer', function() {
+ var x = 40,
+ y = 50,
+ pointerBox = $("#contentDiv #mousepointer");
+
+ helper.simulateMouseMoveEvent("graphViewerSVG", x, y);
+ expect(pointerBox.offset().left).toEqual(x + 7);
+ expect(pointerBox.offset().top).toEqual(y + 12);
+
+ x = 66;
+ y = 33;
+
+ helper.simulateMouseMoveEvent("graphViewerSVG", x, y);
+ expect(pointerBox.offset().left).toEqual(x + 7);
+ expect(pointerBox.offset().top).toEqual(y + 12);
+ });
+
});
describe('checking the menubar', function() {
@@ -263,12 +290,14 @@
expect($(menuSelector + " #control_gradientcolour").length).toEqual(1);
});
*/
+ /*
it('should contain a menu for the adapter', function() {
var menuSelector = "#contentDiv #menubar #adaptermenu";
expect($(menuSelector).length).toEqual(1);
expect($(menuSelector)[0]).toBeADropdownMenu();
expect($(menuSelector + " #control_collections").length).toEqual(1);
});
+ */
/*
it('should contain a menu for the layouter', function() {
var menuSelector = "#contentDiv #menubar #layoutermenu";
@@ -280,6 +309,15 @@
});
*/
+ it('should contain a general configure menu', function() {
+ var menuSelector = "#contentDiv #menubar #configuremenu";
+ expect($(menuSelector).length).toEqual(1);
+ expect($(menuSelector)[0]).toBeADropdownMenu();
+ expect($("> button", menuSelector).text()).toEqual("Configure ");
+ expect($(menuSelector + " #control_adapter_collections").length).toEqual(1);
+ expect($(menuSelector + " #control_node_label").length).toEqual(1);
+ });
+
it('should have the same layout as the web interface', function() {
var header = div.children[0],
transHeader = header.firstChild,
@@ -296,8 +334,10 @@
expect(searchField.id).toEqual("transparentPlaceholder");
expect(searchField.className).toEqual("pull-left");
expect(searchField.children[0].id).toEqual("attribute");
- expect(searchField.children[1].id).toEqual("value");
- expect(searchField.children[2].id).toEqual("loadnode");
+ expect(searchField.children[1]).toBeTag("span");
+ expect(searchField.children[1].textContent).toEqual("==");
+ expect(searchField.children[2].id).toEqual("value");
+ expect(searchField.children[3].id).toEqual("loadnode");
});
});
@@ -444,7 +484,7 @@
runs (function() {
$("#contentDiv #menubar #value").attr("value", "0");
helper.simulateMouseEvent("click", "loadnode");
- helper.simulateMouseEvent("click", "control_expand");
+ helper.simulateMouseEvent("click", "control_event_expand");
});
waits(waittime);
diff --git a/html/admin/js/graphViewer/jasmine_test/specNodeReducer/nodeReducerSpec.js b/html/admin/js/graphViewer/jasmine_test/specNodeReducer/nodeReducerSpec.js
index 384b37d18e..6438df2efa 100644
--- a/html/admin/js/graphViewer/jasmine_test/specNodeReducer/nodeReducerSpec.js
+++ b/html/admin/js/graphViewer/jasmine_test/specNodeReducer/nodeReducerSpec.js
@@ -98,6 +98,12 @@
expect(reducer.getCommunity.length).toEqual(2);
});
+ it('should offer a function for bucket sort of nodes', function() {
+ expect(reducer.bucketNodes).toBeDefined();
+ expect(reducer.bucketNodes).toEqual(jasmine.any(Function));
+ expect(reducer.bucketNodes.length).toEqual(2);
+ });
+
});
describe('checking community identification', function() {
@@ -154,6 +160,146 @@
});
+ describe('checking bucket sort of nodes', function() {
+ var allNodes, buckets;
+
+ beforeEach(function() {
+ allNodes = [];
+
+ this.addMatchers({
+ toContainAll: function(objs) {
+ var bucket = this.actual,
+ passed = true;
+ _.each(bucket, function(n) {
+ var i;
+ for (i = 0; i < objs.length; i++) {
+ if (objs[i] === n) {
+ return;
+ }
+ }
+ passed = false;
+ });
+ this.message = function() {
+ return JSON.stringify(bucket)
+ + " should contain all of "
+ + JSON.stringify(objs);
+ };
+ return passed;
+ }
+ });
+ });
+
+ it('should not bucket anything if #nodes <= #buckets', function() {
+ buckets = 5;
+ allNodes.push({a: 1});
+ allNodes.push({a: 1});
+ allNodes.push({a: 1});
+ allNodes.push({a: 1});
+ allNodes.push({a: 1});
+ var res = reducer.bucketNodes(allNodes, buckets);
+ expect(res.length).toEqual(5);
+ expect(res[0].length).toEqual(1);
+ expect(res[1].length).toEqual(1);
+ expect(res[2].length).toEqual(1);
+ expect(res[3].length).toEqual(1);
+ expect(res[4].length).toEqual(1);
+ });
+
+ it('should create at most the given amount of buckets', function() {
+ buckets = 3;
+ allNodes.push({a: 1});
+ allNodes.push({b: 2});
+ allNodes.push({c: 3});
+ allNodes.push({d: 4});
+ allNodes.push({e: 5});
+ allNodes.push({f: 6});
+
+ var res = reducer.bucketNodes(allNodes, buckets);
+ expect(res.length).toEqual(3);
+ });
+
+ it('should uniformly distribute dissimilar nodes', function() {
+ buckets = 3;
+ allNodes.push({a: 1});
+ allNodes.push({b: 2});
+ allNodes.push({c: 3});
+ allNodes.push({d: 4});
+ allNodes.push({e: 5});
+ allNodes.push({f: 6});
+ allNodes.push({g: 7});
+ allNodes.push({h: 8});
+ allNodes.push({i: 9});
+
+ var res = reducer.bucketNodes(allNodes, buckets);
+ expect(res[0].length).toEqual(3);
+ expect(res[1].length).toEqual(3);
+ expect(res[2].length).toEqual(3);
+ });
+
+ it('should bucket clearly similar nodes together', function() {
+ buckets = 3;
+ var a1, a2 ,a3,
+ b1, b2, b3,
+ c1, c2, c3,
+ resArray,
+ res1,
+ res2,
+ res3;
+
+ a1 = {a: 1};
+ a2 = {a: 1};
+ a3 = {a: 1};
+
+ b1 = {b: 2};
+ b2 = {b: 2};
+ b3 = {b: 2};
+
+ c1 = {c: 3};
+ c2 = {c: 3};
+ c3 = {c: 3};
+
+ allNodes.push(a1);
+ allNodes.push(a2);
+ allNodes.push(a3);
+ allNodes.push(b1);
+ allNodes.push(b2);
+ allNodes.push(b3);
+ allNodes.push(c1);
+ allNodes.push(c2);
+ allNodes.push(c3);
+
+ resArray = reducer.bucketNodes(allNodes, buckets);
+ res1 = resArray[0];
+ res2 = resArray[1];
+ res3 = resArray[2];
+
+ if (res1[0].a !== undefined) {
+ expect(res1).toContainAll([a1, a2, a3]);
+ } else if (res2[0].a !== undefined) {
+ expect(res2).toContainAll([a1, a2, a3]);
+ } else {
+ expect(res3).toContainAll([a1, a2, a3]);
+ }
+
+ if (res1[0].b !== undefined) {
+ expect(res1).toContainAll([b1, b2, b3]);
+ } else if (res2[0].b !== undefined) {
+ expect(res2).toContainAll([b1, b2, b3]);
+ } else {
+ expect(res3).toContainAll([b1, b2, b3]);
+ }
+
+ if (res1[0].c !== undefined) {
+ expect(res1).toContainAll([c1, c2, c3]);
+ } else if (res2[0].c !== undefined) {
+ expect(res2).toContainAll([c1, c2, c3]);
+ } else {
+ expect(res3).toContainAll([c1, c2, c3]);
+ }
+ });
+
+ });
+
});
});
}());
\ No newline at end of file
diff --git a/html/admin/js/graphViewer/jasmine_test/specNodeShaper/nodeShaperUISpec.js b/html/admin/js/graphViewer/jasmine_test/specNodeShaper/nodeShaperUISpec.js
index ddd1d29d42..1aa40a9600 100644
--- a/html/admin/js/graphViewer/jasmine_test/specNodeShaper/nodeShaperUISpec.js
+++ b/html/admin/js/graphViewer/jasmine_test/specNodeShaper/nodeShaperUISpec.js
@@ -47,7 +47,7 @@
shaper = new NodeShaper(d3.select("svg"));
list = document.createElement("ul");
document.body.appendChild(list);
- list.id = "control_list";
+ list.id = "control_node_list";
shaperUI = new NodeShaperControls(list, shaper);
spyOn(shaper, 'changeTo');
this.addMatchers({
@@ -94,10 +94,10 @@
runs(function() {
shaperUI.addControlOpticShapeNone();
- expect($("#control_list #control_none").length).toEqual(1);
- expect($("#control_list #control_none")[0]).toConformToListCSS();
+ expect($("#control_node_list #control_node_none").length).toEqual(1);
+ expect($("#control_node_list #control_node_none")[0]).toConformToListCSS();
- helper.simulateMouseEvent("click", "control_none");
+ helper.simulateMouseEvent("click", "control_node_none");
expect(shaper.changeTo).toHaveBeenCalledWith({
shape: {
@@ -111,14 +111,14 @@
runs(function() {
shaperUI.addControlOpticShapeCircle();
- expect($("#control_list #control_circle").length).toEqual(1);
- expect($("#control_list #control_circle")[0]).toConformToListCSS();
+ expect($("#control_node_list #control_node_circle").length).toEqual(1);
+ expect($("#control_node_list #control_node_circle")[0]).toConformToListCSS();
- helper.simulateMouseEvent("click", "control_circle");
- expect($("#control_circle_modal").length).toEqual(1);
+ helper.simulateMouseEvent("click", "control_node_circle");
+ expect($("#control_node_circle_modal").length).toEqual(1);
- $("#control_circle_radius").attr("value", 42);
- helper.simulateMouseEvent("click", "control_circle_submit");
+ $("#control_node_circle_radius").attr("value", 42);
+ helper.simulateMouseEvent("click", "control_node_circle_submit");
expect(shaper.changeTo).toHaveBeenCalledWith({
shape: {
@@ -129,7 +129,7 @@
});
waitsFor(function() {
- return $("#control_circle_modal").length === 0;
+ return $("#control_node_circle_modal").length === 0;
}, 2000, "The modal dialog should disappear.");
});
@@ -138,13 +138,13 @@
runs(function() {
shaperUI.addControlOpticShapeRect();
- expect($("#control_list #control_rect").length).toEqual(1);
- expect($("#control_list #control_rect")[0]).toConformToListCSS();
+ expect($("#control_node_list #control_node_rect").length).toEqual(1);
+ expect($("#control_node_list #control_node_rect")[0]).toConformToListCSS();
- helper.simulateMouseEvent("click", "control_rect");
- $("#control_rect_width").attr("value", 42);
- $("#control_rect_height").attr("value", 12);
- helper.simulateMouseEvent("click", "control_rect_submit");
+ helper.simulateMouseEvent("click", "control_node_rect");
+ $("#control_node_rect_width").attr("value", 42);
+ $("#control_node_rect_height").attr("value", 12);
+ helper.simulateMouseEvent("click", "control_node_rect_submit");
expect(shaper.changeTo).toHaveBeenCalledWith({
shape: {
@@ -156,7 +156,7 @@
});
waitsFor(function() {
- return $("#control_rect_modal").length === 0;
+ return $("#control_node_rect_modal").length === 0;
}, 2000, "The modal dialog should disappear.");
});
@@ -165,12 +165,12 @@
runs(function() {
shaperUI.addControlOpticLabel();
- expect($("#control_list #control_label").length).toEqual(1);
- expect($("#control_list #control_label")[0]).toConformToListCSS();
+ expect($("#control_node_list #control_node_label").length).toEqual(1);
+ expect($("#control_node_list #control_node_label")[0]).toConformToListCSS();
- helper.simulateMouseEvent("click", "control_label");
- $("#control_label_key").attr("value", "theAnswer");
- helper.simulateMouseEvent("click", "control_label_submit");
+ helper.simulateMouseEvent("click", "control_node_label");
+ $("#control_node_label_key").attr("value", "theAnswer");
+ helper.simulateMouseEvent("click", "control_node_label_submit");
expect(shaper.changeTo).toHaveBeenCalledWith({
label: "theAnswer"
@@ -178,7 +178,7 @@
});
waitsFor(function() {
- return $("#control_label_modal").length === 0;
+ return $("#control_node_label_modal").length === 0;
}, 2000, "The modal dialog should disappear.");
});
@@ -187,13 +187,13 @@
runs(function() {
shaperUI.addControlOpticSingleColour();
- expect($("#control_list #control_singlecolour").length).toEqual(1);
- expect($("#control_list #control_singlecolour")[0]).toConformToListCSS();
+ expect($("#control_node_list #control_node_singlecolour").length).toEqual(1);
+ expect($("#control_node_list #control_node_singlecolour")[0]).toConformToListCSS();
- helper.simulateMouseEvent("click", "control_singlecolour");
- $("#control_singlecolour_fill").attr("value", "#123456");
- $("#control_singlecolour_stroke").attr("value", "#654321");
- helper.simulateMouseEvent("click", "control_singlecolour_submit");
+ helper.simulateMouseEvent("click", "control_node_singlecolour");
+ $("#control_node_singlecolour_fill").attr("value", "#123456");
+ $("#control_node_singlecolour_stroke").attr("value", "#654321");
+ helper.simulateMouseEvent("click", "control_node_singlecolour_submit");
expect(shaper.changeTo).toHaveBeenCalledWith({
color: {
@@ -205,7 +205,7 @@
});
waitsFor(function() {
- return $("#control_singlecolour_modal").length === 0;
+ return $("#control_node_singlecolour_modal").length === 0;
}, 2000, "The modal dialog should disappear.");
});
@@ -214,12 +214,12 @@
runs(function() {
shaperUI.addControlOpticAttributeColour();
- expect($("#control_list #control_attributecolour").length).toEqual(1);
- expect($("#control_list #control_attributecolour")[0]).toConformToListCSS();
+ expect($("#control_node_list #control_node_attributecolour").length).toEqual(1);
+ expect($("#control_node_list #control_node_attributecolour")[0]).toConformToListCSS();
- helper.simulateMouseEvent("click", "control_attributecolour");
- $("#control_attributecolour_key").attr("value", "label");
- helper.simulateMouseEvent("click", "control_attributecolour_submit");
+ helper.simulateMouseEvent("click", "control_node_attributecolour");
+ $("#control_node_attributecolour_key").attr("value", "label");
+ helper.simulateMouseEvent("click", "control_node_attributecolour_submit");
expect(shaper.changeTo).toHaveBeenCalledWith({
color: {
@@ -230,7 +230,7 @@
});
waitsFor(function() {
- return $("#control_attributecolour_modal").length === 0;
+ return $("#control_node_attributecolour_modal").length === 0;
}, 2000, "The modal dialog should disappear.");
});
@@ -239,13 +239,13 @@
runs(function() {
shaperUI.addControlOpticExpandColour();
- expect($("#control_list #control_expandcolour").length).toEqual(1);
- expect($("#control_list #control_expandcolour")[0]).toConformToListCSS();
+ expect($("#control_node_list #control_node_expandcolour").length).toEqual(1);
+ expect($("#control_node_list #control_node_expandcolour")[0]).toConformToListCSS();
- helper.simulateMouseEvent("click", "control_expandcolour");
- $("#control_expandcolour_expanded").attr("value", "#123456");
- $("#control_expandcolour_collapsed").attr("value", "#654321");
- helper.simulateMouseEvent("click", "control_expandcolour_submit");
+ helper.simulateMouseEvent("click", "control_node_expandcolour");
+ $("#control_node_expandcolour_expanded").attr("value", "#123456");
+ $("#control_node_expandcolour_collapsed").attr("value", "#654321");
+ helper.simulateMouseEvent("click", "control_node_expandcolour_submit");
expect(shaper.changeTo).toHaveBeenCalledWith({
color: {
@@ -257,7 +257,7 @@
});
waitsFor(function() {
- return $("#control_expandcolour_modal").length === 0;
+ return $("#control_node_expandcolour_modal").length === 0;
}, 2000, "The modal dialog should disappear.");
});
@@ -266,13 +266,13 @@
it('should be able to add all optic controls to the list', function () {
shaperUI.addAllOptics();
- expect($("#control_list #control_none").length).toEqual(1);
- expect($("#control_list #control_circle").length).toEqual(1);
- expect($("#control_list #control_rect").length).toEqual(1);
- expect($("#control_list #control_label").length).toEqual(1);
- expect($("#control_list #control_singlecolour").length).toEqual(1);
- expect($("#control_list #control_attributecolour").length).toEqual(1);
- expect($("#control_list #control_expandcolour").length).toEqual(1);
+ expect($("#control_node_list #control_node_none").length).toEqual(1);
+ expect($("#control_node_list #control_node_circle").length).toEqual(1);
+ expect($("#control_node_list #control_node_rect").length).toEqual(1);
+ expect($("#control_node_list #control_node_label").length).toEqual(1);
+ expect($("#control_node_list #control_node_singlecolour").length).toEqual(1);
+ expect($("#control_node_list #control_node_attributecolour").length).toEqual(1);
+ expect($("#control_node_list #control_node_expandcolour").length).toEqual(1);
});
it('should be able to add all action controls to the list', function () {
@@ -283,13 +283,13 @@
it('should be able to add all controls to the list', function () {
shaperUI.addAll();
- expect($("#control_list #control_none").length).toEqual(1);
- expect($("#control_list #control_circle").length).toEqual(1);
- expect($("#control_list #control_rect").length).toEqual(1);
- expect($("#control_list #control_label").length).toEqual(1);
- expect($("#control_list #control_singlecolour").length).toEqual(1);
- expect($("#control_list #control_attributecolour").length).toEqual(1);
- expect($("#control_list #control_expandcolour").length).toEqual(1);
+ expect($("#control_node_list #control_node_none").length).toEqual(1);
+ expect($("#control_node_list #control_node_circle").length).toEqual(1);
+ expect($("#control_node_list #control_node_rect").length).toEqual(1);
+ expect($("#control_node_list #control_node_label").length).toEqual(1);
+ expect($("#control_node_list #control_node_singlecolour").length).toEqual(1);
+ expect($("#control_node_list #control_node_attributecolour").length).toEqual(1);
+ expect($("#control_node_list #control_node_expandcolour").length).toEqual(1);
});
});
diff --git a/html/admin/js/graphViewer/jasmine_test/specZoomManager/zoomManagerSpec.js b/html/admin/js/graphViewer/jasmine_test/specZoomManager/zoomManagerSpec.js
index ce6e66df24..85ca0acd12 100644
--- a/html/admin/js/graphViewer/jasmine_test/specZoomManager/zoomManagerSpec.js
+++ b/html/admin/js/graphViewer/jasmine_test/specZoomManager/zoomManagerSpec.js
@@ -214,7 +214,7 @@
fontMax = 16;
fontMin = 6;
radMax = 25;
- radMin = 1;
+ radMin = 4;
distRBase = 100;
minScale = radMin / radMax;
toggleScale = fontMin / fontMax;
diff --git a/html/admin/js/graphViewer/ui/arangoAdapterControls.js b/html/admin/js/graphViewer/ui/arangoAdapterControls.js
index 8d16e1fafb..4be485c9bd 100644
--- a/html/admin/js/graphViewer/ui/arangoAdapterControls.js
+++ b/html/admin/js/graphViewer/ui/arangoAdapterControls.js
@@ -41,23 +41,32 @@ function ArangoAdapterControls(list, adapter) {
baseClass = "adapter";
this.addControlChangeCollections = function() {
- var prefix = "control_collections",
- idprefix = prefix + "_";
- uiComponentsHelper.createButton(baseClass, list, "Collections", prefix, function() {
- modalDialogHelper.createModalDialog("Switch Collections",
- idprefix, [{
- type: "text",
- id: "nodecollection"
- },{
- type: "text",
- id: "edgecollection"
- }], function () {
- var nodes = $("#" + idprefix + "nodecollection").attr("value"),
- edges = $("#" + idprefix + "edgecollection").attr("value");
- adapter.changeTo(nodes, edges);
- }
- );
+ var prefix = "control_adapter_collections",
+ idprefix = prefix + "_";
+ adapter.getCollections(function(nodeCols, edgeCols) {
+ uiComponentsHelper.createButton(baseClass, list, "Collections", prefix, function() {
+ modalDialogHelper.createModalDialog("Switch Collections",
+ idprefix, [{
+ type: "list",
+ id: "nodecollection",
+ objects: nodeCols
+ },{
+ type: "list",
+ id: "edgecollection",
+ objects: edgeCols
+ },{
+ type: "checkbox",
+ id: "undirected"
+ }], function () {
+ var nodes = $("#" + idprefix + "nodecollection").attr("value"),
+ edges = $("#" + idprefix + "edgecollection").attr("value"),
+ undirected = !!$("#" + idprefix + "undirected").attr("checked");
+ adapter.changeTo(nodes, edges, undirected);
+ }
+ );
+ });
});
+
};
this.addAll = function() {
diff --git a/html/admin/js/graphViewer/ui/edgeShaperControls.js b/html/admin/js/graphViewer/ui/edgeShaperControls.js
index 185e7f5228..6df9be8843 100644
--- a/html/admin/js/graphViewer/ui/edgeShaperControls.js
+++ b/html/admin/js/graphViewer/ui/edgeShaperControls.js
@@ -41,7 +41,7 @@ function EdgeShaperControls(list, shaper) {
baseClass = "graph";
this.addControlOpticShapeNone = function() {
- var prefix = "control_none",
+ var prefix = "control_edge_none",
idprefix = prefix + "_";
uiComponentsHelper.createButton(baseClass, list, "None", prefix, function() {
shaper.changeTo({
@@ -53,7 +53,7 @@ function EdgeShaperControls(list, shaper) {
};
this.addControlOpticShapeArrow = function() {
- var prefix = "control_arrow",
+ var prefix = "control_edge_arrow",
idprefix = prefix + "_";
uiComponentsHelper.createButton(baseClass, list, "Arrow", prefix, function() {
shaper.changeTo({
@@ -67,7 +67,7 @@ function EdgeShaperControls(list, shaper) {
this.addControlOpticLabel = function() {
- var prefix = "control_label",
+ var prefix = "control_edge_label",
idprefix = prefix + "_";
uiComponentsHelper.createButton(baseClass, list, "Label", prefix, function() {
modalDialogHelper.createModalDialog("Switch Label Attribute",
@@ -88,7 +88,7 @@ function EdgeShaperControls(list, shaper) {
this.addControlOpticSingleColour = function() {
- var prefix = "control_singlecolour",
+ var prefix = "control_edge_singlecolour",
idprefix = prefix + "_";
uiComponentsHelper.createButton(baseClass, list, "Single Colour", prefix, function() {
modalDialogHelper.createModalDialog("Switch to Colour",
@@ -109,7 +109,7 @@ function EdgeShaperControls(list, shaper) {
};
this.addControlOpticAttributeColour = function() {
- var prefix = "control_attributecolour",
+ var prefix = "control_edge_attributecolour",
idprefix = prefix + "_";
uiComponentsHelper.createButton(baseClass, list, "Colour by Attribute", prefix, function() {
modalDialogHelper.createModalDialog("Display colour by attribute",
@@ -130,7 +130,7 @@ function EdgeShaperControls(list, shaper) {
};
this.addControlOpticGradientColour = function() {
- var prefix = "control_gradientcolour",
+ var prefix = "control_edge_gradientcolour",
idprefix = prefix + "_";
uiComponentsHelper.createButton(baseClass, list, "Gradient Colour", prefix, function() {
modalDialogHelper.createModalDialog("Change colours for gradient",
diff --git a/html/admin/js/graphViewer/ui/eventDispatcherControls.js b/html/admin/js/graphViewer/ui/eventDispatcherControls.js
index 3bd299abdb..a272432ed8 100644
--- a/html/admin/js/graphViewer/ui/eventDispatcherControls.js
+++ b/html/admin/js/graphViewer/ui/eventDispatcherControls.js
@@ -1,6 +1,6 @@
/*jslint indent: 2, nomen: true, maxlen: 100, white: true plusplus: true */
/*global $, _, d3*/
-/*global document*/
+/*global document, window*/
/*global modalDialogHelper, uiComponentsHelper */
/*global EventDispatcher, EventLibrary*/
////////////////////////////////////////////////////////////////////////////////
@@ -29,12 +29,15 @@
/// @author Michael Hackstein
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
-function EventDispatcherControls(list, nodeShaper, edgeShaper, dispatcherConfig) {
+function EventDispatcherControls(list, cursorIconBox, nodeShaper, edgeShaper, dispatcherConfig) {
"use strict";
if (list === undefined) {
throw "A list element has to be given.";
}
+ if (cursorIconBox === undefined) {
+ throw "The cursor decoration box has to be given.";
+ }
if (nodeShaper === undefined) {
throw "The NodeShaper has to be given.";
}
@@ -53,6 +56,10 @@ function EventDispatcherControls(list, nodeShaper, edgeShaper, dispatcherConfig)
eventlib = new EventLibrary(),
dispatcher = new EventDispatcher(nodeShaper, edgeShaper, dispatcherConfig),
+ setCursorIcon = function(icon) {
+ cursorIconBox.className = "mousepointer icon-" + icon;
+ },
+
appendToList = function(button) {
if (firstButton) {
currentListGroup = document.createElement("div");
@@ -72,14 +79,14 @@ function EventDispatcherControls(list, nodeShaper, edgeShaper, dispatcherConfig)
baseClass,
list,
title,
- "control_" + title,
+ "control_event_" + title,
callback
);
},
createIcon = function(icon, title, callback) {
var btn = uiComponentsHelper.createIconButton(
icon,
- "control_" + title,
+ "control_event_" + title,
callback
);
appendToList(btn);
@@ -89,33 +96,72 @@ function EventDispatcherControls(list, nodeShaper, edgeShaper, dispatcherConfig)
},
rebindEdges = function(actions) {
dispatcher.rebind("edges", actions);
+ },
+ rebindSVG = function(actions) {
+ dispatcher.rebind("svg", actions);
+ },
+
+ getCursorPosition = function (ev) {
+ var e = ev || window.event,
+ res = {};
+ res.x = e.clientX;
+ res.y = e.clientY;
+ res.x += document.body.scrollLeft;
+ res.y += document.body.scrollTop;
+ return res;
+ },
+
+ getCursorPositionInSVG = function (ev) {
+ var pos = getCursorPosition(ev);
+ pos.x -= $('svg').offset().left;
+ pos.y -= $('svg').offset().top;
+ return pos;
+ },
+
+ moveCursorBox = function(ev) {
+ var pos = getCursorPosition(ev);
+ pos.x += 7;
+ pos.y += 12;
+ cursorIconBox.style.position = "absolute";
+ cursorIconBox.style.left = pos.x + 'px';
+ cursorIconBox.style.top = pos.y + 'px';
};
+ dispatcher.fixSVG("mousemove", moveCursorBox);
+ dispatcher.fixSVG("mouseout", function() {
+ cursorIconBox.style.display = "none";
+ });
+ dispatcher.fixSVG("mouseover", function() {
+ cursorIconBox.style.display = "block";
+ });
+
this.addControlDrag = function() {
- var prefix = "control_drag",
+ var prefix = "control_event_drag",
idprefix = prefix + "_",
+ icon = "move",
callback = function() {
+ setCursorIcon(icon);
rebindNodes( {
drag: dispatcher.events.DRAG
});
rebindEdges();
-
-
+ rebindSVG();
};
- createIcon("move", "drag", callback);
+ createIcon(icon, "drag", callback);
};
this.addControlEdit = function() {
- var prefix = "control_edit",
+ var prefix = "control_event_edit",
idprefix = prefix + "_",
+ icon = "pencil",
nodeCallback = function(n) {
modalDialogHelper.createModalEditDialog(
"Edit Node " + n._id,
- "control_node_edit_",
+ "control_event_node_edit_",
n._data,
function(newData) {
dispatcher.events.PATCHNODE(n, newData, function() {
- $("#control_node_edit_modal").modal('hide');
+ $("#control_event_node_edit_modal").modal('hide');
})();
}
);
@@ -123,59 +169,83 @@ function EventDispatcherControls(list, nodeShaper, edgeShaper, dispatcherConfig)
edgeCallback = function(e) {
modalDialogHelper.createModalEditDialog(
"Edit Edge " + e._data._from + "->" + e._data._to,
- "control_edge_edit_",
+ "control_event_edge_edit_",
e._data,
function(newData) {
dispatcher.events.PATCHEDGE(e, newData, function() {
- $("#control_edge_edit_modal").modal('hide');
+ $("#control_event_edge_edit_modal").modal('hide');
})();
}
);
},
callback = function() {
+ setCursorIcon(icon);
rebindNodes({click: nodeCallback});
rebindEdges({click: edgeCallback});
+ rebindSVG();
};
- createIcon("pencil", "edit", callback);
+ createIcon(icon, "edit", callback);
};
this.addControlExpand = function() {
- var prefix = "control_expand",
+ var prefix = "control_event_expand",
idprefix = prefix + "_",
+ icon = "plus",
callback = function() {
+ setCursorIcon(icon);
rebindNodes({click: dispatcher.events.EXPAND});
rebindEdges();
+ rebindSVG();
};
- createIcon("plus", "expand", callback);
+ createIcon(icon, "expand", callback);
};
this.addControlDelete = function() {
- var prefix = "control_delete",
+ var prefix = "control_event_delete",
idprefix = prefix + "_",
+ icon = "trash",
callback = function() {
+ setCursorIcon(icon);
rebindNodes({click: dispatcher.events.DELETENODE(function() {
})});
rebindEdges({click: dispatcher.events.DELETEEDGE(function() {
})});
+ rebindSVG();
};
- createIcon("trash", "delete", callback);
+ createIcon(icon, "delete", callback);
};
this.addControlConnect = function() {
- var prefix = "control_connect",
+ var prefix = "control_event_connect",
idprefix = prefix + "_",
+ icon = "resize-horizontal",
callback = function() {
-
+ setCursorIcon(icon);
rebindNodes({
- mousedown: dispatcher.events.STARTCREATEEDGE(),
+ mousedown: dispatcher.events.STARTCREATEEDGE(function(startNode, ev) {
+ var pos = getCursorPositionInSVG(ev);
+ var moveCB = edgeShaper.addAnEdgeFollowingTheCursor(pos.x, pos.y);
+ dispatcher.bind("svg", "mousemove", function(ev) {
+ var pos = getCursorPositionInSVG(ev);
+ moveCB(pos.x, pos.y);
+ });
+ }),
mouseup: dispatcher.events.FINISHCREATEEDGE(function(edge){
+ edgeShaper.removeCursorFollowingEdge();
+ dispatcher.bind("svg", "mousemove", function(){});
})
});
rebindEdges();
+ rebindSVG({
+ mouseup: function() {
+ dispatcher.events.CANCELCREATEEDGE();
+ edgeShaper.removeCursorFollowingEdge();
+ }
+ });
};
- createIcon("resize-horizontal", "connect", callback);
+ createIcon(icon, "connect", callback);
};
diff --git a/html/admin/js/graphViewer/ui/graphViewerUI.js b/html/admin/js/graphViewer/ui/graphViewerUI.js
index b1329b7f73..18f5c37a1f 100644
--- a/html/admin/js/graphViewer/ui/graphViewerUI.js
+++ b/html/admin/js/graphViewer/ui/graphViewerUI.js
@@ -2,7 +2,7 @@
/*global document, $, _ */
/*global EventDispatcherControls, NodeShaperControls, EdgeShaperControls */
/*global LayouterControls, ArangoAdapterControls*/
-/*global GraphViewer, d3*/
+/*global GraphViewer, d3, window*/
////////////////////////////////////////////////////////////////////////////////
/// @brief Graph functionality
///
@@ -30,7 +30,7 @@
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
-function GraphViewerUI(container, adapterConfig, optWidth, optHeight) {
+function GraphViewerUI(container, adapterConfig, optWidth, optHeight, viewerConfig) {
"use strict";
if (container === undefined) {
@@ -48,7 +48,9 @@ function GraphViewerUI(container, adapterConfig, optWidth, optHeight) {
height = optHeight || container.offsetHeight,
menubar = document.createElement("ul"),
background = document.createElement("div"),
- svg,
+ mousePointerBox = document.createElement("div"),
+ svg,
+
makeBootstrapDropdown = function (div, id, title) {
var btn, caret, list;
div.className = "btn-group";
@@ -69,6 +71,7 @@ function GraphViewerUI(container, adapterConfig, optWidth, optHeight) {
createSVG = function () {
return d3.select("#" + container.id + " #background")
.append("svg")
+ .attr("id", "graphViewerSVG")
.attr("width",width)
.attr("height",height)
.attr("class", "pull-right graphViewer")
@@ -78,13 +81,17 @@ function GraphViewerUI(container, adapterConfig, optWidth, optHeight) {
var toolbox = document.createElement("div"),
dispatcherUI = new EventDispatcherControls(
toolbox,
+ mousePointerBox,
graphViewer.nodeShaper,
graphViewer.edgeShaper,
graphViewer.dispatcherConfig
);
toolbox.id = "toolbox";
toolbox.className = "btn-group btn-group-vertical pull-left toolbox";
+ mousePointerBox.id = "mousepointer";
+ mousePointerBox.className = "mousepointer";
background.appendChild(toolbox);
+ background.appendChild(mousePointerBox);
dispatcherUI.addAll();
},
createMenu = function() {
@@ -94,6 +101,14 @@ function GraphViewerUI(container, adapterConfig, optWidth, optHeight) {
searchValueField = document.createElement("input"),
searchStart = document.createElement("img"),
buttons = document.createElement("div"),
+ equalsField = document.createElement("span"),
+ configureDropDown = document.createElement("div"),
+ configureList = makeBootstrapDropdown(
+ configureDropDown,
+ "configuredropdown",
+ "Configure"
+ ),
+
/*
nodeShaperDropDown = document.createElement("div"),
nodeShaperList = makeBootstrapDropdown(
@@ -107,14 +122,12 @@ function GraphViewerUI(container, adapterConfig, optWidth, optHeight) {
"edgeshaperdropdown",
"Edges"
),
- */
adapterDropDown = document.createElement("div"),
adapterList = makeBootstrapDropdown(
adapterDropDown,
"adapterdropdown",
"Connection"
),
- /*
layouterDropDown = document.createElement("div"),
layouterList = makeBootstrapDropdown(
layouterDropDown,
@@ -133,11 +146,21 @@ function GraphViewerUI(container, adapterConfig, optWidth, optHeight) {
layouterList,
graphViewer.layouter
),
- */
adapterUI = new ArangoAdapterControls(
adapterList,
graphViewer.adapter
),
+ */
+
+ nodeShaperUI = new NodeShaperControls(
+ configureList,
+ graphViewer.nodeShaper
+ ),
+ adapterUI = new ArangoAdapterControls(
+ configureList,
+ graphViewer.adapter
+ ),
+
searchFunction = function() {
if (searchAttrField.value === ""
|| searchAttrField.value === undefined) {
@@ -175,13 +198,18 @@ function GraphViewerUI(container, adapterConfig, optWidth, optHeight) {
searchStart.height = 16;
searchStart.src = "img/enter_icon.png";
+ equalsField.className = "searchEqualsLabel";
+ equalsField.appendChild(document.createTextNode("=="));
+
+
/*
nodeShaperDropDown.id = "nodeshapermenu";
edgeShaperDropDown.id = "edgeshapermenu";
layouterDropDown.id = "layoutermenu";
- */
-
adapterDropDown.id = "adaptermenu";
+ */
+ configureDropDown.id = "configuremenu";
+
searchStart.onclick = searchFunction;
$(searchValueField).keypress(function(e) {
@@ -195,34 +223,36 @@ function GraphViewerUI(container, adapterConfig, optWidth, optHeight) {
menubar.appendChild(transparentHeader);
transparentHeader.appendChild(searchDiv);
searchDiv.appendChild(searchAttrField);
+ searchDiv.appendChild(equalsField);
searchDiv.appendChild(searchValueField);
searchDiv.appendChild(searchStart);
transparentHeader.appendChild(buttons);
+
+ buttons.appendChild(configureDropDown);
+
+ adapterUI.addControlChangeCollections();
+ nodeShaperUI.addControlOpticLabel();
+
/*
buttons.appendChild(nodeShaperDropDown);
buttons.appendChild(edgeShaperDropDown);
buttons.appendChild(layouterDropDown);
- */
buttons.appendChild(adapterDropDown);
- /*
- transparentHeader.appendChild(nodeShaperDropDown);
- transparentHeader.appendChild(edgeShaperDropDown);
- transparentHeader.appendChild(adapterDropDown);
- transparentHeader.appendChild(layouterDropDown);
- */
- /*
+
nodeShaperUI.addAll();
edgeShaperUI.addAll();
layouterUI.addAll();
- */
adapterUI.addAll();
+ */
};
container.appendChild(menubar);
container.appendChild(background);
background.className = "thumbnails";
background.id = "background";
svg = createSVG();
- graphViewer = new GraphViewer(svg, width, height, adapterConfig, {zoom: true});
+ viewerConfig = viewerConfig || {};
+ viewerConfig.zoom = true;
+ graphViewer = new GraphViewer(svg, width, height, adapterConfig, viewerConfig);
createToolbox();
createMenu();
diff --git a/html/admin/js/graphViewer/ui/layouterControls.js b/html/admin/js/graphViewer/ui/layouterControls.js
index cbd22cf4fa..88e4272af8 100644
--- a/html/admin/js/graphViewer/ui/layouterControls.js
+++ b/html/admin/js/graphViewer/ui/layouterControls.js
@@ -41,7 +41,7 @@ function LayouterControls(list, layouter) {
baseClass = "layout";
this.addControlGravity = function() {
- var prefix = "control_gravity",
+ var prefix = "control_layout_gravity",
idprefix = prefix + "_";
uiComponentsHelper.createButton(baseClass, list, "Gravity", prefix, function() {
modalDialogHelper.createModalDialog("Switch Gravity Strength",
@@ -59,7 +59,7 @@ function LayouterControls(list, layouter) {
};
this.addControlCharge = function() {
- var prefix = "control_charge",
+ var prefix = "control_layout_charge",
idprefix = prefix + "_";
uiComponentsHelper.createButton(baseClass, list, "Charge", prefix, function() {
modalDialogHelper.createModalDialog("Switch Charge Strength",
@@ -77,7 +77,7 @@ function LayouterControls(list, layouter) {
};
this.addControlDistance = function() {
- var prefix = "control_distance",
+ var prefix = "control_layout_distance",
idprefix = prefix + "_";
uiComponentsHelper.createButton(baseClass, list, "Distance", prefix, function() {
modalDialogHelper.createModalDialog("Switch Distance Strength",
diff --git a/html/admin/js/graphViewer/ui/modalDialogHelper.js b/html/admin/js/graphViewer/ui/modalDialogHelper.js
index 909698ed91..4989a2e351 100644
--- a/html/admin/js/graphViewer/ui/modalDialogHelper.js
+++ b/html/admin/js/graphViewer/ui/modalDialogHelper.js
@@ -57,7 +57,7 @@ var modalDialogHelper = modalDialogHelper || {};
document.body.removeChild(div);
};
- headerDiv.className = "modal_header";
+ headerDiv.className = "modal-header";
buttonDismiss.className = "close";
buttonDismiss.dataDismiss = "modal";
@@ -66,11 +66,11 @@ var modalDialogHelper = modalDialogHelper || {};
header.appendChild(document.createTextNode(title));
- bodyDiv.className = "modal_body";
+ bodyDiv.className = "modal-body";
bodyTable.id = idprefix + "table";
- footerDiv.className = "modal_footer";
+ footerDiv.className = "modal-footer";
buttonCancel.id = idprefix + "cancel";
buttonCancel.className = "btn btn-danger pull-left";
@@ -132,6 +132,25 @@ var modalDialogHelper = modalDialogHelper || {};
input.id = idprefix + o.id;
contentTh.appendChild(input);
break;
+ case "checkbox":
+ input = document.createElement("input");
+ input.type = "checkbox";
+ input.id = idprefix + o.id;
+ contentTh.appendChild(input);
+ break;
+ case "list":
+ input = document.createElement("select");
+ input.id = idprefix + o.id;
+ contentTh.appendChild(input);
+ _.each(o.objects, function(entry) {
+ var option = document.createElement("option");
+ option.value = entry;
+ option.appendChild(
+ document.createTextNode(entry)
+ );
+ input.appendChild(option);
+ });
+ break;
default:
//Sorry unknown
table.removeChild(tr);
diff --git a/html/admin/js/graphViewer/ui/nodeShaperControls.js b/html/admin/js/graphViewer/ui/nodeShaperControls.js
index d0d942354c..75431aa981 100644
--- a/html/admin/js/graphViewer/ui/nodeShaperControls.js
+++ b/html/admin/js/graphViewer/ui/nodeShaperControls.js
@@ -41,7 +41,7 @@ function NodeShaperControls(list, shaper) {
baseClass = "graph";
this.addControlOpticShapeNone = function() {
- uiComponentsHelper.createButton(baseClass, list, "None", "control_none", function() {
+ uiComponentsHelper.createButton(baseClass, list, "None", "control_node_none", function() {
shaper.changeTo({
shape: {
type: NodeShaper.shapes.NONE
@@ -51,7 +51,7 @@ function NodeShaperControls(list, shaper) {
};
this.addControlOpticShapeCircle = function() {
- var prefix = "control_circle",
+ var prefix = "control_node_circle",
idprefix = prefix + "_";
uiComponentsHelper.createButton(baseClass, list, "Circle", prefix, function() {
modalDialogHelper.createModalDialog("Switch to Circle",
@@ -72,11 +72,11 @@ function NodeShaperControls(list, shaper) {
};
this.addControlOpticShapeRect = function() {
- var prefix = "control_rect",
+ var prefix = "control_node_rect",
idprefix = prefix + "_";
uiComponentsHelper.createButton(baseClass, list, "Rectangle", prefix, function() {
modalDialogHelper.createModalDialog("Switch to Rectangle",
- "control_rect_", [{
+ "control_node_rect_", [{
type: "text",
id: "width"
},{
@@ -98,7 +98,7 @@ function NodeShaperControls(list, shaper) {
};
this.addControlOpticLabel = function() {
- var prefix = "control_label",
+ var prefix = "control_node_label",
idprefix = prefix + "_";
uiComponentsHelper.createButton(baseClass, list, "Label", prefix, function() {
modalDialogHelper.createModalDialog("Switch Label Attribute",
@@ -120,7 +120,7 @@ function NodeShaperControls(list, shaper) {
//////////////////////////////////////////////////////////////////
this.addControlOpticSingleColour = function() {
- var prefix = "control_singlecolour",
+ var prefix = "control_node_singlecolour",
idprefix = prefix + "_";
uiComponentsHelper.createButton(baseClass, list, "Single Colour", prefix, function() {
modalDialogHelper.createModalDialog("Switch to Colour",
@@ -146,7 +146,7 @@ function NodeShaperControls(list, shaper) {
};
this.addControlOpticAttributeColour = function() {
- var prefix = "control_attributecolour",
+ var prefix = "control_node_attributecolour",
idprefix = prefix + "_";
uiComponentsHelper.createButton(baseClass, list, "Colour by Attribute", prefix, function() {
modalDialogHelper.createModalDialog("Display colour by attribute",
@@ -167,7 +167,7 @@ function NodeShaperControls(list, shaper) {
};
this.addControlOpticExpandColour = function() {
- var prefix = "control_expandcolour",
+ var prefix = "control_node_expandcolour",
idprefix = prefix + "_";
uiComponentsHelper.createButton(baseClass, list, "Expansion Colour", prefix, function() {
modalDialogHelper.createModalDialog("Display colours for expansion",
diff --git a/html/admin/js/models/arangoCollection.js b/html/admin/js/models/arangoCollection.js
index 5db44790fb..8dfe067fc3 100644
--- a/html/admin/js/models/arangoCollection.js
+++ b/html/admin/js/models/arangoCollection.js
@@ -1,8 +1,9 @@
-/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true */
-/*global window, Backbone*/
+/*jslint indent: 2, nomen: true, maxlen: 120, vars: true, white: true, plusplus: true, nonpropdel: true, continue: true, regexp: true */
+/*global require, window, Backbone */
window.arangoCollection = Backbone.Model.extend({
initialize: function () {
+ 'use strict';
},
urlRoot: "/_api/collection",
diff --git a/html/admin/js/models/arangoDocument.js b/html/admin/js/models/arangoDocument.js
index c7ff150028..1d77d01c24 100644
--- a/html/admin/js/models/arangoDocument.js
+++ b/html/admin/js/models/arangoDocument.js
@@ -1,8 +1,9 @@
-/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true */
-/*global window, Backbone*/
+/*jslint indent: 2, nomen: true, maxlen: 120, vars: true, white: true, plusplus: true, nonpropdel: true, continue: true, regexp: true */
+/*global require, window, Backbone */
window.arangoDocument = Backbone.Model.extend({
initialize: function () {
+ 'use strict';
},
urlRoot: "/_api/document",
defaults: {
diff --git a/html/admin/js/models/arangoLog.js b/html/admin/js/models/arangoLog.js
index 5b465af7fb..549780a5b7 100644
--- a/html/admin/js/models/arangoLog.js
+++ b/html/admin/js/models/arangoLog.js
@@ -1,8 +1,9 @@
-/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true */
-/*global window, Backbone*/
+/*jslint indent: 2, nomen: true, maxlen: 120, vars: true, white: true, plusplus: true, nonpropdel: true, continue: true, regexp: true */
+/*global require, window, Backbone */
window.arangoLog = Backbone.Model.extend({
initialize: function () {
+ 'use strict';
},
urlRoot: "/_admin/log",
defaults: {
diff --git a/html/admin/js/models/arangoStatistics.js b/html/admin/js/models/arangoStatistics.js
index 774f36913f..b639223092 100644
--- a/html/admin/js/models/arangoStatistics.js
+++ b/html/admin/js/models/arangoStatistics.js
@@ -1,10 +1,12 @@
-/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true */
-/*global window, Backbone*/
+/*jslint indent: 2, nomen: true, maxlen: 120, vars: true, white: true, plusplus: true, nonpropdel: true, continue: true, regexp: true */
+/*global require, window, Backbone */
window.Statistics = Backbone.Model.extend({
defaults: {
},
url: function() {
+ 'use strict';
+
return "../statistics";
}
});
diff --git a/html/admin/js/models/arangoStatisticsDescription.js b/html/admin/js/models/arangoStatisticsDescription.js
index c5d4fecec1..7099ecbda7 100644
--- a/html/admin/js/models/arangoStatisticsDescription.js
+++ b/html/admin/js/models/arangoStatisticsDescription.js
@@ -1,5 +1,5 @@
-/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true */
-/*global window, Backbone*/
+/*jslint indent: 2, nomen: true, maxlen: 120, vars: true, white: true, plusplus: true, nonpropdel: true, continue: true, regexp: true */
+/*global require, window, Backbone */
window.StatisticsDescription = Backbone.Model.extend({
defaults: {
@@ -7,6 +7,8 @@ window.StatisticsDescription = Backbone.Model.extend({
"groups" : ""
},
url: function() {
+ 'use strict';
+
return "../statistics-description";
}
});
diff --git a/html/admin/js/models/foxx.js b/html/admin/js/models/foxx.js
index ddd9aaa7d9..4ab5af127b 100644
--- a/html/admin/js/models/foxx.js
+++ b/html/admin/js/models/foxx.js
@@ -1,3 +1,6 @@
+/*jslint indent: 2, nomen: true, maxlen: 120, vars: true, white: true, plusplus: true, nonpropdel: true, continue: true, regexp: true */
+/*global require, window, Backbone */
+
window.Foxx = Backbone.Model.extend({
defaults: {
"title": "",
@@ -8,6 +11,8 @@ window.Foxx = Backbone.Model.extend({
},
url: function() {
+ 'use strict';
+
if (this.get("_key")) {
return "../aardvark/foxxes/" + this.get("_key");
}
@@ -15,6 +20,8 @@ window.Foxx = Backbone.Model.extend({
},
isNew: function() {
+ 'use strict';
+
return false;
}
diff --git a/html/admin/js/templates/documentsView.ejs b/html/admin/js/templates/documentsView.ejs
index 6a913b81fe..1b4505ac34 100644
--- a/html/admin/js/templates/documentsView.ejs
+++ b/html/admin/js/templates/documentsView.ejs
@@ -35,7 +35,7 @@
Theres no way back…
diff --git a/html/admin/js/templates/graphView.ejs b/html/admin/js/templates/graphView.ejs index d6a3a77669..117433b683 100644 --- a/html/admin/js/templates/graphView.ejs +++ b/html/admin/js/templates/graphView.ejs @@ -1,22 +1,54 @@ -