mirror of https://gitee.com/bigwinds/arangodb
GraphViewer: The CommunityNode now offers function to remove nodes and edges, as well as a function to remove all outbound at once
This commit is contained in:
parent
f8ca0ef0f9
commit
d29ec0d9a9
|
@ -44,6 +44,7 @@ function CommunityNode(initial) {
|
||||||
internal = {},
|
internal = {},
|
||||||
inbound = {},
|
inbound = {},
|
||||||
outbound = {},
|
outbound = {},
|
||||||
|
outReferences = {},
|
||||||
////////////////////////////////////
|
////////////////////////////////////
|
||||||
// Private functions //
|
// Private functions //
|
||||||
////////////////////////////////////
|
////////////////////////////////////
|
||||||
|
@ -73,6 +74,66 @@ function CommunityNode(initial) {
|
||||||
self._size++;
|
self._size++;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
removeNode = function(n) {
|
||||||
|
var id = n._id || n;
|
||||||
|
delete nodes[id];
|
||||||
|
self._size--;
|
||||||
|
},
|
||||||
|
|
||||||
|
removeInboundEdge = function(e) {
|
||||||
|
var id;
|
||||||
|
if (!_.has(e, "_id")) {
|
||||||
|
id = e;
|
||||||
|
e = internal[id] || inbound[id];
|
||||||
|
} else {
|
||||||
|
id = e._id;
|
||||||
|
}
|
||||||
|
e.target = e._target;
|
||||||
|
delete e._target;
|
||||||
|
if (internal[id]) {
|
||||||
|
delete internal[id];
|
||||||
|
self._outboundCounter++;
|
||||||
|
outbound[id] = e;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
delete inbound[id];
|
||||||
|
self._inboundCounter++;
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
|
||||||
|
removeOutboundEdge = function(e) {
|
||||||
|
var id;
|
||||||
|
if (!_.has(e, "_id")) {
|
||||||
|
id = e;
|
||||||
|
e = internal[id] || outbound[id];
|
||||||
|
} else {
|
||||||
|
id = e._id;
|
||||||
|
}
|
||||||
|
e.source = e._source;
|
||||||
|
delete e._source;
|
||||||
|
delete outReferences[e.source._id][id];
|
||||||
|
if (internal[id]) {
|
||||||
|
delete internal[id];
|
||||||
|
self._inboundCounter++;
|
||||||
|
inbound[id] = e;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
delete outbound[id];
|
||||||
|
self._outboundCounter++;
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
|
||||||
|
removeOutboundEdgesFromNode = function(n) {
|
||||||
|
var id = n._id || n,
|
||||||
|
res = [];
|
||||||
|
_.each(outReferences[id], function(e) {
|
||||||
|
removeOutboundEdge(e);
|
||||||
|
res.push(e);
|
||||||
|
});
|
||||||
|
delete outReferences[id];
|
||||||
|
return res;
|
||||||
|
},
|
||||||
|
|
||||||
insertInboundEdge = function(e) {
|
insertInboundEdge = function(e) {
|
||||||
e._target = e.target;
|
e._target = e.target;
|
||||||
e.target = self;
|
e.target = self;
|
||||||
|
@ -88,8 +149,11 @@ function CommunityNode(initial) {
|
||||||
},
|
},
|
||||||
|
|
||||||
insertOutboundEdge = function(e) {
|
insertOutboundEdge = function(e) {
|
||||||
|
var sId = e.source._id;
|
||||||
e._source = e.source;
|
e._source = e.source;
|
||||||
e.source = self;
|
e.source = self;
|
||||||
|
outReferences[sId] = outReferences[sId] || {};
|
||||||
|
outReferences[sId][e._id] = e;
|
||||||
if (inbound[e._id]) {
|
if (inbound[e._id]) {
|
||||||
delete inbound[e._id];
|
delete inbound[e._id];
|
||||||
self._inboundCounter--;
|
self._inboundCounter--;
|
||||||
|
@ -146,8 +210,16 @@ function CommunityNode(initial) {
|
||||||
this.hasNode = hasNode;
|
this.hasNode = hasNode;
|
||||||
this.getNodes = getNodes;
|
this.getNodes = getNodes;
|
||||||
this.getNode = getNode;
|
this.getNode = getNode;
|
||||||
|
|
||||||
this.insertNode = insertNode;
|
this.insertNode = insertNode;
|
||||||
this.insertInboundEdge = insertInboundEdge;
|
this.insertInboundEdge = insertInboundEdge;
|
||||||
this.insertOutboundEdge = insertOutboundEdge;
|
this.insertOutboundEdge = insertOutboundEdge;
|
||||||
|
|
||||||
|
this.removeNode = removeNode;
|
||||||
|
this.removeInboundEdge = removeInboundEdge;
|
||||||
|
this.removeOutboundEdge = removeOutboundEdge;
|
||||||
|
|
||||||
|
this.removeOutboundEdgesFromNode = removeOutboundEdgesFromNode;
|
||||||
|
|
||||||
this.dissolve = dissolve;
|
this.dissolve = dissolve;
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,6 +95,22 @@
|
||||||
expect(testee).toHaveFunction("insertOutboundEdge", 1);
|
expect(testee).toHaveFunction("insertOutboundEdge", 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should offer a function to remove in incomming edge', function() {
|
||||||
|
expect(testee).toHaveFunction("removeInboundEdge", 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should offer a function to remove in outgoing edge', function() {
|
||||||
|
expect(testee).toHaveFunction("removeOutboundEdge", 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should offer a function to remove a node', function() {
|
||||||
|
expect(testee).toHaveFunction("removeNode", 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should offer a function to remove and return all outgoing edges of a node', function() {
|
||||||
|
expect(testee).toHaveFunction("removeOutboundEdgesFromNode", 1);
|
||||||
|
});
|
||||||
|
|
||||||
it('should offer a function to dissolve the community', function() {
|
it('should offer a function to dissolve the community', function() {
|
||||||
expect(testee).toHaveFunction("dissolve", 0);
|
expect(testee).toHaveFunction("dissolve", 0);
|
||||||
});
|
});
|
||||||
|
@ -180,6 +196,46 @@
|
||||||
expect(c.getNode("nofoxx")).toBeUndefined();
|
expect(c.getNode("nofoxx")).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should be able to remove a node', function() {
|
||||||
|
var c = new CommunityNode(nodes.slice(3, 5)),
|
||||||
|
n = {
|
||||||
|
_id: "foxx",
|
||||||
|
_inboundCounter: 0,
|
||||||
|
_outboundCounter: 0,
|
||||||
|
position: {
|
||||||
|
x: 1,
|
||||||
|
y: 1,
|
||||||
|
z: 1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
expect(c._size).toEqual(2);
|
||||||
|
c.insertNode(n);
|
||||||
|
expect(c._size).toEqual(3);
|
||||||
|
c.removeNode(n);
|
||||||
|
expect(c._size).toEqual(2);
|
||||||
|
expect(c.getNodes()).toEqual(nodes.slice(3, 5));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be able to remove a node by id', function() {
|
||||||
|
var c = new CommunityNode(nodes.slice(3, 5)),
|
||||||
|
n = {
|
||||||
|
_id: "foxx",
|
||||||
|
_inboundCounter: 0,
|
||||||
|
_outboundCounter: 0,
|
||||||
|
position: {
|
||||||
|
x: 1,
|
||||||
|
y: 1,
|
||||||
|
z: 1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
expect(c._size).toEqual(2);
|
||||||
|
c.insertNode(n);
|
||||||
|
expect(c._size).toEqual(3);
|
||||||
|
c.removeNode("foxx");
|
||||||
|
expect(c._size).toEqual(2);
|
||||||
|
expect(c.getNodes()).toEqual(nodes.slice(3, 5));
|
||||||
|
});
|
||||||
|
|
||||||
it('should initially contain the required attributes for shaping', function() {
|
it('should initially contain the required attributes for shaping', function() {
|
||||||
var x = 42,
|
var x = 42,
|
||||||
y = 23,
|
y = 23,
|
||||||
|
@ -263,7 +319,241 @@
|
||||||
expect(c.insertOutboundEdge(e2)).toBeFalsy();
|
expect(c.insertOutboundEdge(e2)).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to resolve the community', function() {
|
it('should be possible to remove an inbound edge', function() {
|
||||||
|
var c = new CommunityNode(),
|
||||||
|
e = {
|
||||||
|
_id: "1-2",
|
||||||
|
_data: {
|
||||||
|
_from: "1",
|
||||||
|
_to: "2"
|
||||||
|
},
|
||||||
|
source: nodes[1],
|
||||||
|
target: nodes[2]
|
||||||
|
};
|
||||||
|
c.insertInboundEdge(e);
|
||||||
|
|
||||||
|
expect(c.dissolve().edges).toEqual({
|
||||||
|
inbound: [e],
|
||||||
|
outbound: [],
|
||||||
|
both: []
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(e.target).toEqual(c);
|
||||||
|
expect(e._target).toEqual(nodes[2]);
|
||||||
|
|
||||||
|
c.removeInboundEdge(e);
|
||||||
|
|
||||||
|
expect(e.target).toEqual(nodes[2]);
|
||||||
|
|
||||||
|
|
||||||
|
expect(c.dissolve().edges).toEqual({
|
||||||
|
inbound: [],
|
||||||
|
outbound: [],
|
||||||
|
both: []
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be possible to remove an inbound edge by its id', function() {
|
||||||
|
var c = new CommunityNode(),
|
||||||
|
e = {
|
||||||
|
_id: "1-2",
|
||||||
|
_data: {
|
||||||
|
_from: "1",
|
||||||
|
_to: "2"
|
||||||
|
},
|
||||||
|
source: nodes[1],
|
||||||
|
target: nodes[2]
|
||||||
|
};
|
||||||
|
c.insertInboundEdge(e);
|
||||||
|
|
||||||
|
expect(c.dissolve().edges).toEqual({
|
||||||
|
inbound: [e],
|
||||||
|
outbound: [],
|
||||||
|
both: []
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(e.target).toEqual(c);
|
||||||
|
|
||||||
|
c.removeInboundEdge("1-2");
|
||||||
|
|
||||||
|
expect(e.target).toEqual(nodes[2]);
|
||||||
|
|
||||||
|
expect(c.dissolve().edges).toEqual({
|
||||||
|
inbound: [],
|
||||||
|
outbound: [],
|
||||||
|
both: []
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be possible to remove the inbound value of an internal edge', function() {
|
||||||
|
var c = new CommunityNode(),
|
||||||
|
e = {
|
||||||
|
_id: "1-2",
|
||||||
|
_data: {
|
||||||
|
_from: "1",
|
||||||
|
_to: "2"
|
||||||
|
},
|
||||||
|
source: nodes[1],
|
||||||
|
target: nodes[2]
|
||||||
|
};
|
||||||
|
c.insertInboundEdge(e);
|
||||||
|
c.insertOutboundEdge(e);
|
||||||
|
expect(c.dissolve().edges).toEqual({
|
||||||
|
inbound: [],
|
||||||
|
outbound: [],
|
||||||
|
both: [e]
|
||||||
|
});
|
||||||
|
|
||||||
|
c.removeInboundEdge(e);
|
||||||
|
|
||||||
|
expect(c.dissolve().edges).toEqual({
|
||||||
|
inbound: [],
|
||||||
|
outbound: [e],
|
||||||
|
both: []
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('should be possible to remove an outbound edge', function() {
|
||||||
|
var c = new CommunityNode(),
|
||||||
|
e = {
|
||||||
|
_id: "1-2",
|
||||||
|
_data: {
|
||||||
|
_from: "1",
|
||||||
|
_to: "2"
|
||||||
|
},
|
||||||
|
source: nodes[1],
|
||||||
|
target: nodes[2]
|
||||||
|
};
|
||||||
|
c.insertOutboundEdge(e);
|
||||||
|
|
||||||
|
expect(c.dissolve().edges).toEqual({
|
||||||
|
inbound: [],
|
||||||
|
outbound: [e],
|
||||||
|
both: []
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(e.source).toEqual(c);
|
||||||
|
|
||||||
|
c.removeOutboundEdge(e);
|
||||||
|
|
||||||
|
expect(e.source).toEqual(nodes[1]);
|
||||||
|
|
||||||
|
expect(c.dissolve().edges).toEqual({
|
||||||
|
inbound: [],
|
||||||
|
outbound: [],
|
||||||
|
both: []
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be possible to remove an outbound edge by its id', function() {
|
||||||
|
var c = new CommunityNode(),
|
||||||
|
e = {
|
||||||
|
_id: "1-2",
|
||||||
|
_data: {
|
||||||
|
_from: "1",
|
||||||
|
_to: "2"
|
||||||
|
},
|
||||||
|
source: nodes[1],
|
||||||
|
target: nodes[2]
|
||||||
|
};
|
||||||
|
c.insertOutboundEdge(e);
|
||||||
|
|
||||||
|
expect(c.dissolve().edges).toEqual({
|
||||||
|
inbound: [],
|
||||||
|
outbound: [e],
|
||||||
|
both: []
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(e.source).toEqual(c);
|
||||||
|
|
||||||
|
c.removeOutboundEdge("1-2");
|
||||||
|
|
||||||
|
expect(e.source).toEqual(nodes[1]);
|
||||||
|
|
||||||
|
|
||||||
|
expect(c.dissolve().edges).toEqual({
|
||||||
|
inbound: [],
|
||||||
|
outbound: [],
|
||||||
|
both: []
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be possible to remove the outbound value of an internal edge', function() {
|
||||||
|
var c = new CommunityNode(),
|
||||||
|
e = {
|
||||||
|
_id: "1-2",
|
||||||
|
_data: {
|
||||||
|
_from: "1",
|
||||||
|
_to: "2"
|
||||||
|
},
|
||||||
|
source: nodes[1],
|
||||||
|
target: nodes[2]
|
||||||
|
};
|
||||||
|
c.insertInboundEdge(e);
|
||||||
|
c.insertOutboundEdge(e);
|
||||||
|
expect(c.dissolve().edges).toEqual({
|
||||||
|
inbound: [],
|
||||||
|
outbound: [],
|
||||||
|
both: [e]
|
||||||
|
});
|
||||||
|
|
||||||
|
c.removeOutboundEdge(e);
|
||||||
|
|
||||||
|
expect(c.dissolve().edges).toEqual({
|
||||||
|
inbound: [e],
|
||||||
|
outbound: [],
|
||||||
|
both: []
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be possible to return and remove all outbound edges for a node', function() {
|
||||||
|
var c = new CommunityNode([nodes[0], nodes[1]]),
|
||||||
|
e01 = {
|
||||||
|
_id: "0-1",
|
||||||
|
_data: {
|
||||||
|
_from: "0",
|
||||||
|
_to: "1"
|
||||||
|
},
|
||||||
|
source: nodes[0],
|
||||||
|
target: nodes[1]
|
||||||
|
},
|
||||||
|
e02 = {
|
||||||
|
_id: "0-2",
|
||||||
|
_data: {
|
||||||
|
_from: "0",
|
||||||
|
_to: "2"
|
||||||
|
},
|
||||||
|
source: nodes[0],
|
||||||
|
target: nodes[2]
|
||||||
|
},
|
||||||
|
e12 = {
|
||||||
|
_id: "1-2",
|
||||||
|
_data: {
|
||||||
|
_from: "1",
|
||||||
|
_to: "2"
|
||||||
|
},
|
||||||
|
source: nodes[1],
|
||||||
|
target: nodes[2]
|
||||||
|
};
|
||||||
|
|
||||||
|
c.insertOutboundEdge(e01);
|
||||||
|
c.insertOutboundEdge(e02);
|
||||||
|
c.insertOutboundEdge(e12);
|
||||||
|
c.insertInboundEdge(e01);
|
||||||
|
|
||||||
|
expect(c.removeOutboundEdgesFromNode(nodes[0])).toEqual(
|
||||||
|
[e01, e02]
|
||||||
|
);
|
||||||
|
expect(c.dissolve().edges).toEqual({
|
||||||
|
inbound: [e01],
|
||||||
|
outbound: [e12],
|
||||||
|
both: []
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be able to dissolve the community', function() {
|
||||||
var c = new CommunityNode(nodes.slice(3, 13)),
|
var c = new CommunityNode(nodes.slice(3, 13)),
|
||||||
e1 = {
|
e1 = {
|
||||||
_id: "3-4",
|
_id: "3-4",
|
||||||
|
|
Loading…
Reference in New Issue