1
0
Fork 0

GraphViewer: Slightly changed interface of ArangoAdapter. It now defaults to the domains.host if none is given

This commit is contained in:
Michael Hackstein 2013-04-16 14:15:21 +02:00
parent 77344be842
commit 04ae758746
4 changed files with 887 additions and 785 deletions

View File

@ -1,5 +1,5 @@
/*jslint indent: 2, nomen: true, maxlen: 100, white: true plusplus: true */ /*jslint indent: 2, nomen: true, maxlen: 100, white: true plusplus: true */
/*global $, d3, _, console*/ /*global $, d3, _, console, document*/
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief Graph functionality /// @brief Graph functionality
/// ///
@ -27,227 +27,285 @@
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany /// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
function ArangoAdapter(arangodb, nodes, edges, nodeCollection, edgeCollection, width, height) { //function ArangoAdapter(arangodb, nodes, edges, nodeCollection, edgeCollection, width, height) {
function ArangoAdapter(nodes, edges, config) {
"use strict"; "use strict";
if (nodes === undefined) {
throw "The nodes have to be given.";
}
if (edges === undefined) {
throw "The edges have to be given.";
}
if (config === undefined) {
throw "A configuration with node- and edgeCollection has to be given.";
}
if (config.nodeCollection === undefined) {
throw "The nodeCollection has to be given.";
}
if (config.edgeCollection === undefined) {
throw "The edgeCollection has to be given.";
}
var self = this, var self = this,
initialX = {}, initialX = {},
initialY = {}, initialY = {},
api = {}, api = {},
queries = {}, queries = {},
nodeCollection,
findNode = function(id) { edgeCollection,
var res = $.grep(nodes, function(e){ arangodb,
return e._id === id; width,
}); height,
if (res.length === 0) {
return false;
}
if (res.length === 1) {
return res[0];
}
throw "Too many nodes with the same ID, should never happen";
},
findEdge = function(id) {
var res = $.grep(edges, function(e){
return e._id === id;
});
if (res.length === 0) {
return false;
}
if (res.length === 1) {
return res[0];
}
throw "Too many nodes with the same ID, should never happen";
},
insertNode = function(data) {
var node = {
_data: data,
_id: data._id
},
n = findNode(node._id);
if (n) {
return n;
}
initialY.getStart(); setWidth = function(w) {
node.x = initialX.getStart(); initialX.range = width / 2;
node.y = initialY.getStart(); initialX.start = width / 4;
nodes.push(node); initialX.getStart = function () {
node._outboundCounter = 0; return this.start + Math.random() * this.range;
node._inboundCounter = 0; };
return node; },
},
setHeight = function(h) {
initialY.range = height / 2;
initialY.start = height / 4;
initialY.getStart = function () {
return this.start + Math.random() * this.range;
};
},
parseConfig = function(config) {
initialX.getStart = function() {return 0;};
initialY.getStart = function() {return 0;};
nodeCollection = config.nodeCollection;
edgeCollection = config.edgeCollection;
if (config.host === undefined) {
arangodb = "http://" + document.location.host;
} else {
arangodb = config.host;
}
if (config.width !== undefined) {
setWidth(config.width);
}
if (config.height !== undefined) {
setHeight(config.height);
}
},
insertEdge = function(data) { findNode = function(id) {
var source, var res = $.grep(nodes, function(e){
target, return e._id === id;
edge = { });
if (res.length === 0) {
return false;
}
if (res.length === 1) {
return res[0];
}
throw "Too many nodes with the same ID, should never happen";
},
findEdge = function(id) {
var res = $.grep(edges, function(e){
return e._id === id;
});
if (res.length === 0) {
return false;
}
if (res.length === 1) {
return res[0];
}
throw "Too many nodes with the same ID, should never happen";
},
insertNode = function(data) {
var node = {
_data: data, _data: data,
_id: data._id _id: data._id
}, },
e = findEdge(edge._id); n = findNode(node._id);
if (e) { if (n) {
return e; return n;
}
source = findNode(data._from);
target = findNode(data._to);
if (!source) {
throw "Unable to insert Edge, source node not existing " + edge._from;
}
if (!target) {
throw "Unable to insert Edge, target node not existing " + edge._to;
}
edge.source = source;
edge.target = target;
edges.push(edge);
source._outboundCounter++;
target._inboundCounter++;
return edge;
},
removeNode = function (node) {
var i;
for ( i = 0; i < nodes.length; i++ ) {
if ( nodes[i] === node ) {
nodes.splice( i, 1 );
return;
} }
}
}, initialY.getStart();
node.x = initialX.getStart();
node.y = initialY.getStart();
nodes.push(node);
node._outboundCounter = 0;
node._inboundCounter = 0;
return node;
},
removeEdgesForNode = function (node) { insertEdge = function(data) {
var i; var source,
for ( i = 0; i < edges.length; i++ ) { target,
if (edges[i].source === node) { edge = {
node._outboundCounter--; _data: data,
edges[i].target._inboundCounter--; _id: data._id
edges.splice( i, 1 ); },
i--; e = findEdge(edge._id);
} else if (edges[i].target === node) { if (e) {
node._inboundCounter--; return e;
edges[i].source._outboundCounter--;
edges.splice( i, 1 );
i--;
} }
} source = findNode(data._from);
}, target = findNode(data._to);
if (!source) {
throw "Unable to insert Edge, source node not existing " + edge._from;
}
if (!target) {
throw "Unable to insert Edge, target node not existing " + edge._to;
}
edge.source = source;
edge.target = target;
edges.push(edge);
source._outboundCounter++;
target._inboundCounter++;
return edge;
},
// Helper function to easily remove all outbound edges for one node removeNode = function (node) {
removeOutboundEdgesFromNode = function ( node ) { var i;
if (node._outboundCounter > 0) { for ( i = 0; i < nodes.length; i++ ) {
var removed = [], if ( nodes[i] === node ) {
i; nodes.splice( i, 1 );
return;
}
}
},
removeEdgesForNode = function (node) {
var i;
for ( i = 0; i < edges.length; i++ ) { for ( i = 0; i < edges.length; i++ ) {
if ( edges[i].source === node ) { if (edges[i].source === node) {
removed.push(edges[i]);
node._outboundCounter--; node._outboundCounter--;
edges[i].target._inboundCounter--; edges[i].target._inboundCounter--;
edges.splice( i, 1 ); edges.splice( i, 1 );
if (node._outboundCounter === 0) { i--;
break; } else if (edges[i].target === node) {
} node._inboundCounter--;
edges[i].source._outboundCounter--;
edges.splice( i, 1 );
i--; i--;
} }
} }
return removed; },
}
},
// Helper function to easily remove all outbound edges for one node
sendQuery = function(query, bindVars, onSuccess) { removeOutboundEdgesFromNode = function ( node ) {
if (query !== queries.connectedEdges) { if (node._outboundCounter > 0) {
bindVars["@nodes"] = nodeCollection; var removed = [],
} i;
bindVars["@edges"] = edgeCollection; for ( i = 0; i < edges.length; i++ ) {
var data = { if ( edges[i].source === node ) {
query: query, removed.push(edges[i]);
bindVars: bindVars node._outboundCounter--;
}; edges[i].target._inboundCounter--;
$.ajax({ edges.splice( i, 1 );
type: "POST", if (node._outboundCounter === 0) {
url: api.cursor, break;
data: JSON.stringify(data), }
contentType: "application/json", i--;
dataType: "json", }
processData: false,
success: function(data) {
onSuccess(data.result);
},
error: function(data) {
try {
console.log(data.statusText);
throw "[" + data.errorNum + "] " + data.errorMessage;
}
catch (e) {
console.log(e);
throw "Undefined ERROR";
} }
return removed;
} }
}); },
},
parseResultOfTraversal = function (result, callback) {
result = result[0];
_.each(result, function(visited) {
var node = insertNode(visited.vertex),
path = visited.path;
_.each(path.vertices, function(connectedNode) {
insertNode(connectedNode);
});
_.each(path.edges, function(edge) {
insertEdge(edge);
});
});
if (callback) {
callback(result[0].vertex);
}
},
parseResultOfQuery = function (result, callback) { sendQuery = function(query, bindVars, onSuccess) {
_.each(result, function (node) { if (query !== queries.connectedEdges) {
var n = findNode(node._id); bindVars["@nodes"] = nodeCollection;
if (!n) {
insertNode(node);
n = node;
} else {
n.children = node.children;
} }
self.requestCentralityChildren(node._id, function(c) { bindVars["@edges"] = edgeCollection;
n._centrality = c; var data = {
}); query: query,
_.each(n.children, function(id) { bindVars: bindVars
var check = findNode(id), };
newnode; $.ajax({
if (check) { type: "POST",
insertEdge(n, check); url: api.cursor,
self.requestCentralityChildren(id, function(c) { data: JSON.stringify(data),
n._centrality = c; contentType: "application/json",
}); dataType: "json",
} else { processData: false,
newnode = {_id: id}; success: function(data) {
insertNode(newnode); onSuccess(data.result);
insertEdge(n, newnode); },
self.requestCentralityChildren(id, function(c) { error: function(data) {
newnode._centrality = c; try {
}); console.log(data.statusText);
throw "[" + data.errorNum + "] " + data.errorMessage;
}
catch (e) {
console.log(e);
throw "Undefined ERROR";
}
} }
}); });
},
parseResultOfTraversal = function (result, callback) {
result = result[0];
_.each(result, function(visited) {
var node = insertNode(visited.vertex),
path = visited.path;
_.each(path.vertices, function(connectedNode) {
insertNode(connectedNode);
});
_.each(path.edges, function(edge) {
insertEdge(edge);
});
});
if (callback) { if (callback) {
callback(n); callback(result[0].vertex);
} }
}); },
},
permanentlyRemoveEdgesOfNode = function (nodeId) { parseResultOfQuery = function (result, callback) {
sendQuery(queries.connectedEdges, { _.each(result, function (node) {
id: nodeId var n = findNode(node._id);
}, function(res) { if (!n) {
_.each(res, self.deleteEdge); insertNode(node);
}); n = node;
}; } else {
n.children = node.children;
}
self.requestCentralityChildren(node._id, function(c) {
n._centrality = c;
});
_.each(n.children, function(id) {
var check = findNode(id),
newnode;
if (check) {
insertEdge(n, check);
self.requestCentralityChildren(id, function(c) {
n._centrality = c;
});
} else {
newnode = {_id: id};
insertNode(newnode);
insertEdge(n, newnode);
self.requestCentralityChildren(id, function(c) {
newnode._centrality = c;
});
}
});
if (callback) {
callback(n);
}
});
},
permanentlyRemoveEdgesOfNode = function (nodeId) {
sendQuery(queries.connectedEdges, {
id: nodeId
}, function(res) {
_.each(res, self.deleteEdge);
});
};
parseConfig(config);
api.base = arangodb.lastIndexOf("http://", 0) === 0 api.base = arangodb.lastIndexOf("http://", 0) === 0
? arangodb + "/_api/" ? arangodb + "/_api/"
@ -303,18 +361,6 @@ function ArangoAdapter(arangodb, nodes, edges, nodeCollection, edgeCollection, w
+ " || e._from == @id" + " || e._from == @id"
+ " RETURN e"; + " RETURN e";
initialX.range = width / 2;
initialX.start = width / 4;
initialX.getStart = function () {
return this.start + Math.random() * this.range;
};
initialY.range = height / 2;
initialY.start = height / 4;
initialY.getStart = function () {
return this.start + Math.random() * this.range;
};
self.oldLoadNodeFromTreeById = function(nodeId, callback) { self.oldLoadNodeFromTreeById = function(nodeId, callback) {
sendQuery(queries.nodeById, { sendQuery(queries.nodeById, {
id: nodeId id: nodeId

View File

@ -97,14 +97,12 @@ function GraphViewer(svg, width, height,
switch (adapterConfig.type.toLowerCase()) { switch (adapterConfig.type.toLowerCase()) {
case "arango": case "arango":
adapterConfig.width = width;
adapterConfig.height = height;
self.adapter = new ArangoAdapter( self.adapter = new ArangoAdapter(
adapterConfig.host,
nodes, nodes,
edges, edges,
adapterConfig.nodeCollection, adapterConfig
adapterConfig.edgeCollection,
width,
height
); );
break; break;
case "json": case "json":

View File

@ -38,7 +38,7 @@
describe("Graph Viewer", function() { describe("Graph Viewer", function() {
"use strict"; "use strict";
var viewer, var viewer,
waittime = 100, waittime = 200,
svg, svg,
docSVG; docSVG;