mirror of https://gitee.com/bigwinds/arangodb
merging
This commit is contained in:
commit
ed932e153f
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 <img src="images/fe-collections.png" alt="ArangoDB Front-End">@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 <img src="images/fe-documents.png" alt="ArangoDB Front-End">@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 <img src="images/fe-query.png" alt="ArangoDB Front-End">@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 <img src="images/fe-shell.png" alt="ArangoDB Front-End">@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 <img src="images/fe-logs.png" alt="ArangoDB Front-End">@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 <img src="images/fe-statistics.png" alt="ArangoDB Front-End">@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.
|
||||
|
|
|
@ -6,4 +6,3 @@ TOC {#UserManualWebInterfaceTOC}
|
|||
- @ref UserManualWebInterfaceQuery
|
||||
- @ref UserManualWebInterfaceShell
|
||||
- @ref UserManualWebInterfaceLogs
|
||||
- @ref UserManualWebInterfaceStatistics
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 });
|
||||
|
|
|
@ -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 () {
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -162,6 +162,10 @@ function JSONAdapter(jsonPath, nodes, edges, width, height) {
|
|||
|
||||
};
|
||||
|
||||
self.setChildLimit = function (limit) {
|
||||
|
||||
};
|
||||
|
||||
self.expandCommunity = function (commNode, callback) {
|
||||
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
|
@ -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({
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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] : "";
|
||||
});
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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"),
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
}());
|
|
@ -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);
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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 @@
|
|||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -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 = {};
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
}());
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -214,7 +214,7 @@
|
|||
fontMax = 16;
|
||||
fontMin = 6;
|
||||
radMax = 25;
|
||||
radMin = 1;
|
||||
radMin = 4;
|
||||
distRBase = 100;
|
||||
minScale = radMin / radMax;
|
||||
toggleScale = fontMin / fontMax;
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
<p>Theres no way back…</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button id="confirmDeleteBtn" class="btn btn-danger" style="float:right">Delete</button>
|
||||
<button id="confirmDeleteBtn" class="btn btn-danger" style="float:right" disabled="true">Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,22 +1,54 @@
|
|||
<form action="javascript:void(0);" autocomplete="on" class="form-horizontal" id="creationDialog">
|
||||
<fieldset>
|
||||
<legend>Please give the collections</legend>
|
||||
<div class="control-group">
|
||||
<label for="nodeCollection" class="control-label">Node Collection</label>
|
||||
<div class="controls">
|
||||
<input id="nodeCollection" type="text" name="nodeCollection" placeholder="Node Collection" maxlength="75" class="input-xlarge" value="Classes">
|
||||
<div class="thumbnails" id="background">
|
||||
<form action="javascript:void(0);" autocomplete="on" class="form-horizontal" id="creationDialog">
|
||||
<fieldset>
|
||||
<legend>Configuration</legend>
|
||||
<div class="control-group">
|
||||
<label for="nodeCollection" class="control-label">Node Collection</label>
|
||||
<div class="controls">
|
||||
<input id="nodeCollection" type="text" name="nodeCollection" placeholder="Node Collection" maxlength="75" class="input-xlarge" value="Classes">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label for="edgeCollection" class="control-label">Edge Collection</label>
|
||||
<div class="controls">
|
||||
<input id="edgeCollection" type="text" name="edgeCollection" placeholder="Edge Collection" maxlength="75" class="input-xlarge" value="Connections">
|
||||
<div class="control-group">
|
||||
<label for="edgeCollection" class="control-label">Edge Collection</label>
|
||||
<div class="controls">
|
||||
<input id="edgeCollection" type="text" name="edgeCollection" placeholder="Edge Collection" maxlength="75" class="input-xlarge" value="Connections">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<button type="submit" class="btn btn-primary" id="createViewer" >Start</button>
|
||||
|
||||
<div class="accordion" id="advancedGraphOptions">
|
||||
|
||||
<div class="accordion-group">
|
||||
<div class="accordion-heading">
|
||||
<a class="accordion-toggle" data-toggle="collapse" data-parent="#advancedGraphOptions" href="#advancedOptions">
|
||||
Advanced
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div id="advancedOptions" class="accordion-body collapse out">
|
||||
<div class="accordion-inner">
|
||||
<div class="control-group">
|
||||
<label for="undirected" class="control-label">Undirected Graph</label>
|
||||
<div class="controls">
|
||||
<input id="undirected" type="checkbox" name="undirected" class="input-xlarge">
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label for="nodeLabel" class="control-label">Node Label</label>
|
||||
<div class="controls">
|
||||
<input id="nodeLabel" type="text" name="nodeLabel" placeholder="Node Label" maxlength="75" class="input-xlarge">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
|
||||
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<button type="submit" class="btn btn-primary" id="createViewer" >Start</button>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
|
@ -29,7 +29,16 @@ var documentsView = Backbone.View.extend({
|
|||
"click #documents_next" : "nextDocuments",
|
||||
"click #confirmDeleteBtn" : "confirmDelete",
|
||||
"keyup .modal-body" : "listenKey",
|
||||
"click .key" : "nop"
|
||||
"click .key" : "nop",
|
||||
"keyup" : "returnPressedHandler"
|
||||
},
|
||||
|
||||
returnPressedHandler: function(event) {
|
||||
if (event.keyCode === 13) {
|
||||
if (!!$("#confirmDeleteBtn").attr("disabled") === false) {
|
||||
this.confirmDelete();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
nop: function(event) {
|
||||
|
@ -128,11 +137,12 @@ var documentsView = Backbone.View.extend({
|
|||
var thiselement = a.currentTarget.parentElement;
|
||||
this.idelement = $(thiselement).prev().prev();
|
||||
this.alreadyClicked = true;
|
||||
|
||||
$("#confirmDeleteBtn").attr("disabled", false);
|
||||
$('#docDeleteModal').modal('show');
|
||||
|
||||
},
|
||||
confirmDelete: function () {
|
||||
$("#confirmDeleteBtn").attr("disabled", true);
|
||||
this.reallyDelete();
|
||||
},
|
||||
reallyDelete: function () {
|
||||
|
@ -152,7 +162,7 @@ var documentsView = Backbone.View.extend({
|
|||
deleted = true;
|
||||
}
|
||||
else if (result === false) {
|
||||
arangoHelper.arangoError('Document error');
|
||||
arangoHelper.arangoError('Could not delete document');
|
||||
}
|
||||
}
|
||||
else if (this.type === 'edge') {
|
||||
|
|
|
@ -14,20 +14,35 @@ window.graphView = Backbone.View.extend({
|
|||
|
||||
createViewer: function() {
|
||||
var ecol,
|
||||
ncol,
|
||||
aaconfig;
|
||||
ncol,
|
||||
aaconfig,
|
||||
undirected,
|
||||
label,
|
||||
config;
|
||||
|
||||
|
||||
ecol = $("#edgeCollection").val();
|
||||
ncol = $("#nodeCollection").val();
|
||||
undirected = !!$("#undirected").attr("checked");
|
||||
label = $("#nodeLabel").val();
|
||||
|
||||
ecol = $("#edgeCollection")[0].value;
|
||||
ncol = $("#nodeCollection")[0].value;
|
||||
|
||||
aaconfig = {
|
||||
type: "arango",
|
||||
nodeCollection: ncol,
|
||||
edgeCollection: ecol
|
||||
edgeCollection: ecol,
|
||||
undirected: undirected
|
||||
};
|
||||
|
||||
if (label !== undefined && label !== "") {
|
||||
config = {
|
||||
nodeShaper: {
|
||||
label: label
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$("#creationDialog").remove();
|
||||
ui = new GraphViewerUI(document.getElementById("content"), aaconfig, 940, 680);
|
||||
$("#background").remove();
|
||||
ui = new GraphViewerUI(document.getElementById("content"), aaconfig, 940, 680, config);
|
||||
},
|
||||
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ JAVASCRIPT_JSLINT = \
|
|||
`find @srcdir@/js/common/modules/org -name "*.js"` \
|
||||
`find @srcdir@/js/client/modules -name "*.js"` \
|
||||
`find @srcdir@/js/server/modules -name "*.js"` \
|
||||
`find @srcdir@/html/admin/js/models -name "*.js"` \
|
||||
\
|
||||
@srcdir@/js/client/client.js \
|
||||
@srcdir@/js/server/server.js \
|
||||
|
|
|
@ -241,7 +241,7 @@ actions.defineHttp({
|
|||
}
|
||||
}
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err);
|
||||
actions.resultException(req, res, err, undefined, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -235,7 +235,7 @@ function post_api_collection (req, res) {
|
|||
actions.resultOk(req, res, actions.HTTP_OK, result, headers);
|
||||
}
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err);
|
||||
actions.resultException(req, res, err, undefined, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -668,7 +668,7 @@ function put_api_collection_load (req, res, collection) {
|
|||
actions.resultOk(req, res, actions.HTTP_OK, result);
|
||||
}
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err);
|
||||
actions.resultException(req, res, err, undefined, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -720,7 +720,7 @@ function put_api_collection_unload (req, res, collection) {
|
|||
actions.resultOk(req, res, actions.HTTP_OK, result);
|
||||
}
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err);
|
||||
actions.resultException(req, res, err, undefined, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -750,7 +750,7 @@ function put_api_collection_truncate (req, res, collection) {
|
|||
actions.resultOk(req, res, actions.HTTP_OK, result);
|
||||
}
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err);
|
||||
actions.resultException(req, res, err, undefined, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -812,7 +812,7 @@ function put_api_collection_properties (req, res, collection) {
|
|||
actions.resultOk(req, res, actions.HTTP_OK, result);
|
||||
}
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err);
|
||||
actions.resultException(req, res, err, undefined, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -870,7 +870,7 @@ function put_api_collection_rename (req, res, collection) {
|
|||
actions.resultOk(req, res, actions.HTTP_OK, result);
|
||||
}
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err);
|
||||
actions.resultException(req, res, err, undefined, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -979,7 +979,7 @@ function delete_api_collection (req, res) {
|
|||
actions.resultOk(req, res, actions.HTTP_OK, result);
|
||||
}
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err);
|
||||
actions.resultException(req, res, err, undefined, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1012,7 +1012,7 @@ actions.defineHttp({
|
|||
}
|
||||
}
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err);
|
||||
actions.resultException(req, res, err, undefined, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -137,7 +137,7 @@ var QUERY = internal.AQL_QUERY;
|
|||
///
|
||||
/// Executes a query and extract the result in a single go:
|
||||
///
|
||||
/// @EXAMPLE_ARANGOSH_RUN{RestCreateCursorForLimitReturnSingle}
|
||||
/// @EXAMPLE_ARANGOSH_RUN{RestCursorCreateCursorForLimitReturnSingle}
|
||||
/// var cn = "products";
|
||||
/// db._drop(cn);
|
||||
/// db._create(cn);
|
||||
|
@ -157,7 +157,7 @@ var QUERY = internal.AQL_QUERY;
|
|||
///
|
||||
/// Executes a query and extract part of the result:
|
||||
///
|
||||
/// @EXAMPLE_ARANGOSH_RUN{RestCreateCursorForLimitReturn}
|
||||
/// @EXAMPLE_ARANGOSH_RUN{RestCursorCreateCursorForLimitReturn}
|
||||
/// var cn = "products";
|
||||
/// db._drop(cn);
|
||||
/// db._create(cn);
|
||||
|
@ -182,7 +182,7 @@ var QUERY = internal.AQL_QUERY;
|
|||
///
|
||||
/// Missing body:
|
||||
///
|
||||
/// @EXAMPLE_ARANGOSH_RUN{RestCreateCursorMissingBody}
|
||||
/// @EXAMPLE_ARANGOSH_RUN{RestCursorCreateCursorMissingBody}
|
||||
/// var url = "/_api/cursor";
|
||||
///
|
||||
/// var response = logCurlRequest('POST', url, '');
|
||||
|
@ -194,7 +194,7 @@ var QUERY = internal.AQL_QUERY;
|
|||
///
|
||||
/// Unknown collection:
|
||||
///
|
||||
/// @EXAMPLE_ARANGOSH_RUN{RestCreateCursorUnknownCollection}
|
||||
/// @EXAMPLE_ARANGOSH_RUN{RestCursorCreateCursorUnknownCollection}
|
||||
/// var url = "/_api/cursor";
|
||||
/// var body = '{ "query" : "FOR u IN unknowncoll LIMIT 2 RETURN u", "count" : true, "batchSize" : 2 }';
|
||||
///
|
||||
|
@ -235,7 +235,7 @@ function POST_api_cursor(req, res) {
|
|||
|
||||
// error occurred
|
||||
if (cursor instanceof Error) {
|
||||
actions.resultException(req, res, cursor);
|
||||
actions.resultException(req, res, cursor, undefined, false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -285,11 +285,27 @@ function POST_api_cursor(req, res) {
|
|||
///
|
||||
/// Missing identifier
|
||||
///
|
||||
/// @verbinclude api-cursor-missing-cursor-identifier
|
||||
/// @EXAMPLE_ARANGOSH_RUN{RestCursorMissingCursorIdentifier}
|
||||
/// var url = "/_api/cursor";
|
||||
///
|
||||
/// var response = logCurlRequest('PUT', url, '');
|
||||
///
|
||||
/// assert(response.code === 400);
|
||||
///
|
||||
/// logJsonResponse(response);
|
||||
/// @END_EXAMPLE_ARANGOSH_RUN
|
||||
///
|
||||
/// Unknown identifier
|
||||
///
|
||||
/// @verbinclude api-cursor-invalid-cursor-identifier
|
||||
/// @EXAMPLE_ARANGOSH_RUN{RestCursorInvalidCursorIdentifier}
|
||||
/// var url = "/_api/cursor/123123";
|
||||
///
|
||||
/// var response = logCurlRequest('PUT', url, '');
|
||||
///
|
||||
/// assert(response.code === 400);
|
||||
///
|
||||
/// logJsonResponse(response);
|
||||
/// @END_EXAMPLE_ARANGOSH_RUN
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function PUT_api_cursor (req, res) {
|
||||
|
@ -404,7 +420,7 @@ actions.defineHttp({
|
|||
}
|
||||
}
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err);
|
||||
actions.resultException(req, res, err, undefined, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -131,7 +131,7 @@ actions.defineHttp({
|
|||
}
|
||||
}
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err);
|
||||
actions.resultException(req, res, err, undefined, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -137,7 +137,7 @@ function POST_api_explain (req, res) {
|
|||
var result = EXPLAIN(json.query, json.bindVars);
|
||||
|
||||
if (result instanceof Error) {
|
||||
actions.resultException(req, res, result);
|
||||
actions.resultException(req, res, result, undefined, false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -169,7 +169,7 @@ actions.defineHttp({
|
|||
}
|
||||
}
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err);
|
||||
actions.resultException(req, res, err, undefined, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1770,7 +1770,7 @@ function post_graph_vertex_edges (req, res, g) {
|
|||
|
||||
// error occurred
|
||||
if (cursor instanceof Error) {
|
||||
actions.resultException(req, res, cursor);
|
||||
actions.resultException(req, res, cursor, undefined, false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2039,7 +2039,7 @@ actions.defineHttp({
|
|||
}
|
||||
}
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err);
|
||||
actions.resultException(req, res, err, undefined, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -890,7 +890,7 @@ actions.defineHttp({
|
|||
}
|
||||
}
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err);
|
||||
actions.resultException(req, res, err, undefined, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -126,7 +126,7 @@ actions.defineHttp({
|
|||
}
|
||||
}
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err);
|
||||
actions.resultException(req, res, err, undefined, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -115,7 +115,7 @@ actions.defineHttp({
|
|||
}
|
||||
}
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err);
|
||||
actions.resultException(req, res, err, undefined, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -193,7 +193,7 @@ actions.defineHttp({
|
|||
}
|
||||
}
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err);
|
||||
actions.resultException(req, res, err, undefined, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -312,7 +312,7 @@ actions.defineHttp({
|
|||
}
|
||||
}
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err);
|
||||
actions.resultException(req, res, err, undefined, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -430,7 +430,7 @@ actions.defineHttp({
|
|||
}
|
||||
}
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err);
|
||||
actions.resultException(req, res, err, undefined, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -522,7 +522,7 @@ actions.defineHttp({
|
|||
}
|
||||
}
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err);
|
||||
actions.resultException(req, res, err, undefined, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -611,7 +611,7 @@ actions.defineHttp({
|
|||
}
|
||||
}
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err);
|
||||
actions.resultException(req, res, err, undefined, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -688,7 +688,7 @@ actions.defineHttp({
|
|||
}
|
||||
}
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err);
|
||||
actions.resultException(req, res, err, undefined, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -734,7 +734,7 @@ actions.defineHttp({
|
|||
}
|
||||
}
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err);
|
||||
actions.resultException(req, res, err, undefined, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -828,7 +828,7 @@ actions.defineHttp({
|
|||
}
|
||||
}
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err);
|
||||
actions.resultException(req, res, err, undefined, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -904,7 +904,7 @@ actions.defineHttp({
|
|||
}
|
||||
}
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err);
|
||||
actions.resultException(req, res, err, undefined, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -990,7 +990,7 @@ actions.defineHttp({
|
|||
}
|
||||
}
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err);
|
||||
actions.resultException(req, res, err, undefined, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -1083,7 +1083,7 @@ actions.defineHttp({
|
|||
}
|
||||
}
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err);
|
||||
actions.resultException(req, res, err, undefined, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -141,7 +141,7 @@ actions.defineHttp({
|
|||
}
|
||||
}
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err);
|
||||
actions.resultException(req, res, err, undefined, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -335,7 +335,7 @@ actions.defineHttp({
|
|||
///
|
||||
/// @EXAMPLES
|
||||
///
|
||||
/// @EXAMPLE_ARANGOSH_RUN{AdminStatistics1}
|
||||
/// @EXAMPLE_ARANGOSH_RUN{RestAdminStatistics1}
|
||||
/// var url = "/_admin/statistics";
|
||||
/// var response = logCurlRequest('GET', url);
|
||||
///
|
||||
|
@ -362,7 +362,7 @@ actions.defineHttp({
|
|||
actions.resultOk(req, res, actions.HTTP_OK, result);
|
||||
}
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err);
|
||||
actions.resultException(req, res, err, undefined, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -402,7 +402,7 @@ actions.defineHttp({
|
|||
///
|
||||
/// @EXAMPLES
|
||||
///
|
||||
/// @EXAMPLE_ARANGOSH_RUN{AdminStatisticsDescription1}
|
||||
/// @EXAMPLE_ARANGOSH_RUN{RestAdminStatisticsDescription1}
|
||||
/// var url = "/_admin/statistics-description";
|
||||
/// var response = logCurlRequest('GET', url);
|
||||
///
|
||||
|
@ -611,7 +611,7 @@ actions.defineHttp({
|
|||
actions.resultOk(req, res, actions.HTTP_OK, result);
|
||||
}
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err);
|
||||
actions.resultException(req, res, err, undefined, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -456,7 +456,7 @@ actions.defineHttp({
|
|||
}
|
||||
}
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err);
|
||||
actions.resultException(req, res, err, undefined, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -341,7 +341,7 @@ actions.defineHttp({
|
|||
}
|
||||
}
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err);
|
||||
actions.resultException(req, res, err, undefined, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -428,7 +428,7 @@ actions.defineHttp({
|
|||
}
|
||||
}
|
||||
catch (err) {
|
||||
actions.resultException(req, res, err);
|
||||
actions.resultException(req, res, err, undefined, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1198,7 +1198,7 @@ function resultError (req, res, httpReturnCode, errorNum, errorMessage, headers,
|
|||
|
||||
res.body = JSON.stringify(result);
|
||||
|
||||
if (headers !== undefined) {
|
||||
if (headers !== undefined && headers !== null) {
|
||||
res.headers = headers;
|
||||
}
|
||||
}
|
||||
|
@ -1806,36 +1806,42 @@ function indexNotFound (req, res, collection, index, headers) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief generates an error for an exception
|
||||
///
|
||||
/// @FUN{actions.resultException(@FA{req}, @FA{res}, @FA{err}, @FA{headers})}
|
||||
/// @FUN{actions.resultException(@FA{req}, @FA{res}, @FA{err}, @FA{headers}, @FA{verbose})}
|
||||
///
|
||||
/// The function generates an error response.
|
||||
/// The function generates an error response. If @FA{verbose} is set to
|
||||
/// @LIT{true} or not specified (the default), then the error stack trace will
|
||||
/// be included in the error message if available.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function resultException (req, res, err, headers) {
|
||||
function resultException (req, res, err, headers, verbose) {
|
||||
'use strict';
|
||||
|
||||
var code;
|
||||
var msg;
|
||||
var num;
|
||||
|
||||
if (verbose || verbose === undefined) {
|
||||
msg = String(err.stack || err);
|
||||
}
|
||||
else {
|
||||
msg = String(err);
|
||||
}
|
||||
|
||||
if (err instanceof internal.ArangoError) {
|
||||
num = err.errorNum;
|
||||
msg = err.errorMessage;
|
||||
code = exports.HTTP_BAD;
|
||||
|
||||
if (num === 0) {
|
||||
num = arangodb.ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
if (msg === "") {
|
||||
msg = String(err.stack || err);
|
||||
if (err.errorMessage !== "" && ! verbose) {
|
||||
msg = err.errorMessage;
|
||||
}
|
||||
else {
|
||||
msg += ": " + String(err.stack || err);
|
||||
}
|
||||
|
||||
|
||||
switch (num) {
|
||||
case arangodb.ERROR_INTERNAL:
|
||||
case arangodb.ERROR_OUT_OF_MEMORY:
|
||||
code = exports.HTTP_SERVER_ERROR;
|
||||
break;
|
||||
|
||||
|
@ -1844,23 +1850,17 @@ function resultException (req, res, err, headers) {
|
|||
code = exports.HTTP_CONFLICT;
|
||||
break;
|
||||
}
|
||||
|
||||
resultError(req, res, code, num, msg, headers);
|
||||
}
|
||||
else if (err instanceof TypeError) {
|
||||
num = arangodb.ERROR_TYPE_ERROR;
|
||||
code = exports.HTTP_BAD;
|
||||
msg = String(err.stack || err);
|
||||
|
||||
resultError(req, res, code, num, msg, headers);
|
||||
}
|
||||
|
||||
else {
|
||||
resultError(req, res,
|
||||
exports.HTTP_SERVER_ERROR, arangodb.ERROR_HTTP_SERVER_ERROR,
|
||||
String(err.stack || err),
|
||||
headers);
|
||||
num = arangodb.ERROR_HTTP_SERVER_ERROR;
|
||||
code = exports.HTTP_SERVER_ERROR;
|
||||
}
|
||||
|
||||
resultError(req, res, code, num, msg, headers);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -761,6 +761,11 @@ exports.developmentRoutes = function () {
|
|||
var prefix = doc.collectionPrefix;
|
||||
|
||||
var app = module.createApp(appId);
|
||||
|
||||
if (app === null) {
|
||||
throw new Error("cannot find application '" + appId + "'");
|
||||
}
|
||||
|
||||
var r = routingAalApp(app, mount, prefix);
|
||||
|
||||
routes.push(r);
|
||||
|
|
|
@ -343,6 +343,63 @@ function ahuacatlQueryVariablesTestSuite () {
|
|||
|
||||
var actual = getQueryResults(query);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief collect and return (should omit any temporary variables)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testTemporaryVariables1 : function () {
|
||||
var data = [
|
||||
{ name: "baz" },
|
||||
{ name: "bar" }
|
||||
];
|
||||
var expected = [
|
||||
{ "criteria" : "bar", "g" : [ { "y" : { "test" : "test", "name" : "bar" } } ] },
|
||||
{ "criteria" : "baz", "g" : [ { "y" : { "test" : "test", "name" : "baz" } } ] }
|
||||
];
|
||||
|
||||
var query = "FOR y IN (FOR x IN " + JSON.stringify(data) + " LET object = (FOR a IN [ '1', '2' ] RETURN a) RETURN { test: \"test\", name: x.name }) COLLECT criteria = y.name INTO g LIMIT 10 RETURN { criteria: criteria, g: g }";
|
||||
|
||||
var actual = getQueryResults("LET result = (" + query + ") LIMIT 10 RETURN result");
|
||||
assertEqual([ expected ], actual);
|
||||
|
||||
actual = getQueryResults(query);
|
||||
assertEqual(expected, actual);
|
||||
|
||||
// omit creating sub-objects
|
||||
query = "FOR y IN (FOR x IN " + JSON.stringify(data) + " RETURN { test: \"test\", name: x.name }) COLLECT criteria = y.name INTO g LIMIT 10 RETURN { criteria: criteria, g: g }";
|
||||
|
||||
actual = getQueryResults("LET result = (" + query + ") LIMIT 10 RETURN result");
|
||||
assertEqual([ expected ], actual);
|
||||
|
||||
actual = getQueryResults(query);
|
||||
assertEqual(expected, actual);
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief collect and return (should omit any temporary variables)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testTemporaryVariables2 : function () {
|
||||
var data = [
|
||||
{ name: "baz", _id: "id1" },
|
||||
{ name: "bar", _id: "id2" },
|
||||
{ name: "foo", _id: "id3" }
|
||||
];
|
||||
var expected = [
|
||||
{ "criteria" : "yid3", "g" : [ { "y" : { "x" : { "name" : "foo", "_id" : "id3" } } } ] },
|
||||
{ "criteria" : "yid2", "g" : [ { "y" : { "x" : { "name" : "bar", "_id" : "id2" } } } ] },
|
||||
{ "criteria" : "yid1", "g" : [ { "y" : { "x" : { "name" : "baz", "_id" : "id1" } } } ] }
|
||||
];
|
||||
|
||||
var query = "FOR y IN (FOR x IN " + JSON.stringify(data) + " RETURN { x: x }) COLLECT criteria = CONCAT(\"y\", y.x._id) INTO g SORT MAX(g[*].y.x._id) DESC LIMIT 10 RETURN { criteria: criteria, g: g }";
|
||||
|
||||
var actual = getQueryResults("LET result = (" + query + ") LIMIT 10 RETURN result");
|
||||
assertEqual([ expected ], actual);
|
||||
|
||||
actual = getQueryResults(query);
|
||||
assertEqual(expected, actual);
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -24,7 +24,13 @@
|
|||
#ifdef _Z_OF
|
||||
#undef OF
|
||||
#define OF _Z_OF
|
||||
#else
|
||||
#ifndef OF
|
||||
#define _Z_OF(args) args
|
||||
#define OF _Z_OF
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))
|
||||
|
||||
|
|
Loading…
Reference in New Issue