diff --git a/html/admin/js/graphViewer/graph/abstractAdapter.js b/html/admin/js/graphViewer/graph/abstractAdapter.js
index ae0daec5b2..1386466e38 100644
--- a/html/admin/js/graphViewer/graph/abstractAdapter.js
+++ b/html/admin/js/graphViewer/graph/abstractAdapter.js
@@ -620,6 +620,7 @@ function AbstractAdapter(nodes, edges, descendant, config) {
expandNode = function(n, startCallback) {
if (n._isCommunity) {
+ console.log("Adapter Explore!");
self.expandCommunity(n, startCallback);
} else {
n._expanded = true;
diff --git a/html/admin/js/graphViewer/graph/communityNode.js b/html/admin/js/graphViewer/graph/communityNode.js
index a90b9abe9c..d07f19a27f 100644
--- a/html/admin/js/graphViewer/graph/communityNode.js
+++ b/html/admin/js/graphViewer/graph/communityNode.js
@@ -309,12 +309,12 @@ function CommunityNode(parent, initial) {
shapeFunc(g);
},
- addCollapsedShape = function(g, shapeFunc, colourMapper) {
- g.attr("stroke", colourMapper.getForegroundCommunityColour());
- shapeFunc(g, 9);
- shapeFunc(g, 6);
- shapeFunc(g, 3);
- shapeFunc(g);
+ addColour = function (g, colourFunc) {
+ colourFunc(g);
+ },
+
+ addEvents = function (g, eventsFunc) {
+ eventsFunc(g);
},
addCollapsedLabel = function(g, colourMapper) {
@@ -342,7 +342,24 @@ function CommunityNode(parent, initial) {
.text(self._size);
},
- addNodeShapes = function(g, shapeFunc, colourMapper) {
+ addCollapsedShape = function(g, shapeFunc, colourFunc, start, colourMapper) {
+ var inner = g.append("g");
+ inner.attr("stroke", colourMapper.getForegroundCommunityColour());
+ shapeFunc(inner, 9);
+ shapeFunc(inner, 6);
+ shapeFunc(inner, 3);
+ shapeFunc(inner);
+ colourFunc(inner);
+ inner.on("click", function() {
+ self.expand();
+ start();
+ });
+ addCollapsedLabel(inner, colourMapper);
+ },
+
+
+
+ addNodeShapes = function(g, shapeFunc, colourFunc, eventsFunc, start, colourMapper) {
var interior = g.selectAll(".node")
.data(nodeArray, function(d) {
return d._id;
@@ -357,9 +374,11 @@ function CommunityNode(parent, initial) {
interior.exit().remove();
interior.selectAll("* > *").remove();
addShape(interior, shapeFunc, colourMapper);
+ addColour(interior, colourFunc);
+ addEvents(interior, eventsFunc);
},
- addBoundingBox = function(g) {
+ addBoundingBox = function(g, start) {
bBox = g.append("g");
bBoxBorder = bBox.append("rect")
.attr("rx", "8")
@@ -373,21 +392,29 @@ function CommunityNode(parent, initial) {
.attr("fill", "#686766")
.attr("stroke", "none");
var dissolveBtn = bBox.append("image")
+ .attr("id", self._id + "_dissolve")
.attr("xlink:href", "img/icon_delete.png")
.attr("width", "16")
.attr("height", "16")
.attr("x", "5")
.attr("y", "2")
.attr("style", "cursor:pointer")
- .on("click", dissolve),
+ .on("click", function() {
+ self.dissolve();
+ start();
+ }),
collapseBtn = bBox.append("image")
+ .attr("id", self._id + "_collapse")
.attr("xlink:href", "img/gv_collapse.png")
.attr("width", "16")
.attr("height", "16")
.attr("x", "25")
.attr("y", "2")
.attr("style", "cursor:pointer")
- .on("click", collapse),
+ .on("click", function() {
+ self.collapse();
+ start();
+ }),
title = bBox.append("text")
.attr("x", "45")
.attr("y", "15")
@@ -403,15 +430,16 @@ function CommunityNode(parent, initial) {
});
},
- shapeAll = function(g, shapeFunc, colourMapper) {
+ shapeAll = function(g, shapeFunc, colourFunc, eventsFunc, start, colourMapper) {
+ // First unbind all click events that are proably still bound
+ g.on("click", null);
if (self._expanded) {
- addBoundingBox(g);
+ addBoundingBox(g, start);
addDistortion();
- addNodeShapes(g, shapeFunc, colourMapper);
+ addNodeShapes(g, shapeFunc, colourFunc, eventsFunc, start, colourMapper);
return;
}
- addCollapsedShape(g, shapeFunc, colourMapper);
- addCollapsedLabel(g, colourMapper);
+ addCollapsedShape(g, shapeFunc, colourFunc, start, colourMapper);
};
////////////////////////////////////
diff --git a/html/admin/js/graphViewer/graph/eventDispatcher.js b/html/admin/js/graphViewer/graph/eventDispatcher.js
index f28348a445..ad3d5fd404 100644
--- a/html/admin/js/graphViewer/graph/eventDispatcher.js
+++ b/html/admin/js/graphViewer/graph/eventDispatcher.js
@@ -167,6 +167,10 @@ function EventDispatcher(nodeShaper, edgeShaper, config) {
if (config.expand !== undefined) {
if (eventlib.checkExpandConfig(config.expand)) {
self.events.EXPAND = new eventlib.Expand(config.expand);
+ nodeShaper.setGVStartFunction(function() {
+ config.expand.reshapeNodes();
+ config.expand.startCallback();
+ });
}
}
if (config.drag !== undefined) {
diff --git a/html/admin/js/graphViewer/graph/nodeShaper.js b/html/admin/js/graphViewer/graph/nodeShaper.js
index 2c0999da43..00381ffd83 100644
--- a/html/admin/js/graphViewer/graph/nodeShaper.js
+++ b/html/admin/js/graphViewer/graph/nodeShaper.js
@@ -82,7 +82,6 @@ function NodeShaper(parent, flags, idfunc) {
var self = this,
nodes = [],
visibleLabels = true,
-
splitLabel = function(label) {
if (label === undefined) {
return [""];
@@ -103,6 +102,7 @@ function NodeShaper(parent, flags, idfunc) {
noop = function (node) {
},
+ start = noop,
defaultDistortion = function(n) {
return {
x: n.x,
@@ -165,13 +165,13 @@ function NodeShaper(parent, flags, idfunc) {
});
addShape(normal);
community.each(function(c) {
- c.shape(d3.select(this), addShape, colourMapper);
+ c.shape(d3.select(this), addShape, addColor, addEvents, start, colourMapper);
});
if (visibleLabels) {
addLabel(normal);
}
- addColor(g);
- addEvents(g);
+ addColor(normal);
+ addEvents(normal);
addDistortion();
},
@@ -512,6 +512,10 @@ function NodeShaper(parent, flags, idfunc) {
colourMapper.setChangeListener(callback);
};
+ self.setGVStartFunction = function(func) {
+ start = func;
+ };
+
}
NodeShaper.shapes = Object.freeze({
diff --git a/html/admin/js/graphViewer/jasmine_test/specCommunityNode/communityNodeSpec.js b/html/admin/js/graphViewer/jasmine_test/specCommunityNode/communityNodeSpec.js
index e86d8844c8..79626683a8 100644
--- a/html/admin/js/graphViewer/jasmine_test/specCommunityNode/communityNodeSpec.js
+++ b/html/admin/js/graphViewer/jasmine_test/specCommunityNode/communityNodeSpec.js
@@ -363,8 +363,8 @@
describe('shaping functionality', function() {
- var tSpan1, tSpan2, tSpan3, text, g, shaper, colourMapper, box, boxGroup, boxRect,
- parent, c, width, titleBG, disBtn, titleText, colBtn;
+ var tSpan1, tSpan2, tSpan3, text, g, shaper, gv, colourMapper, box, boxGroup, boxRect,
+ parent, c, width, titleBG, disBtn, titleText, colBtn, comShapeInner;
beforeEach(function() {
parent = {
@@ -462,6 +462,22 @@
return this;
}
};
+ comShapeInner = {
+ attr: function() {},
+ on: function() {},
+ select: function() {
+ return {
+ attr: function() {
+ return width;
+ }
+ };
+ },
+ append: function(type) {
+ if (type === "text") {
+ return text;
+ }
+ }
+ };
text = {
attr: function() {
return this;
@@ -480,28 +496,26 @@
}
}
};
- g = {
- select: function() {
- return {
- attr: function() {
- return width;
- }
- };
- },
+ g = {
attr: function() {
return this;
},
append: function(type) {
- if (type === "text") {
- return text;
- }
if (type === "g") {
return boxGroup;
}
+ },
+ on: function() {
+ return this;
}
};
shaper = {
- shapeFunc: function() {}
+ shapeFunc: function() {},
+ colourFunc: function() {},
+ eventsFunc: function() {}
+ };
+ gv = {
+ start: function() {}
};
colourMapper = {
getForegroundCommunityColour: function() {
@@ -548,33 +562,70 @@
expect(otherC._isCommunity).toBeTruthy();
});
- it('should shape the collapsed community with given functions', function() {
- spyOn(g, "attr").andCallThrough();
+ it('should shape the collapsed community with given functions', function() {
+ g = {
+ on: function() {
+ return this;
+ },
+ append: function() {
+ return comShapeInner;
+ }
+ };
spyOn(g, "append").andCallThrough();
+ spyOn(g, "on").andCallThrough();
spyOn(shaper, "shapeFunc").andCallThrough();
+ spyOn(comShapeInner, "attr").andCallThrough();
spyOn(colourMapper, "getForegroundCommunityColour").andCallThrough();
- c.shape(g, shaper.shapeFunc, colourMapper);
+ c.shape(
+ g,
+ shaper.shapeFunc,
+ shaper.colourFunc,
+ shaper.eventsFunc,
+ gv.start,
+ colourMapper
+ );
expect(colourMapper.getForegroundCommunityColour).wasCalled();
- expect(g.attr).wasCalledWith("stroke", "black");
- expect(shaper.shapeFunc).wasCalledWith(g, 9);
- expect(shaper.shapeFunc).wasCalledWith(g, 6);
- expect(shaper.shapeFunc).wasCalledWith(g, 3);
- expect(shaper.shapeFunc).wasCalledWith(g);
+ expect(g.append).wasCalledWith("g");
+ expect(g.on).wasCalledWith("click", null);
+ expect(comShapeInner.attr).wasCalledWith("stroke", "black");
+ expect(shaper.shapeFunc).wasCalledWith(comShapeInner, 9);
+ expect(shaper.shapeFunc).wasCalledWith(comShapeInner, 6);
+ expect(shaper.shapeFunc).wasCalledWith(comShapeInner, 3);
+ expect(shaper.shapeFunc).wasCalledWith(comShapeInner);
});
it('should add a label containing the size of a community', function() {
+ g = {
+ on: function() {
+ return this;
+ },
+ append: function() {
+ return comShapeInner;
+ }
+ };
+
spyOn(g, "append").andCallThrough();
+ spyOn(comShapeInner, "append").andCallThrough();
spyOn(text, "attr").andCallThrough();
spyOn(text, "append").andCallThrough();
spyOn(tSpan1, "attr").andCallThrough();
spyOn(tSpan1, "text").andCallThrough();
spyOn(colourMapper, "getForegroundCommunityColour").andCallThrough();
- c.shape(g, shaper.shapeFunc, colourMapper);
+ c.shape(
+ g,
+ shaper.shapeFunc,
+ shaper.colourFunc,
+ shaper.eventsFunc,
+ gv.start,
+ colourMapper
+ );
- expect(g.append).wasCalledWith("text");
+
+ expect(g.append).wasCalledWith("g");
+ expect(comShapeInner.append).wasCalledWith("text");
expect(text.attr).wasCalledWith("text-anchor", "middle");
expect(text.attr).wasCalledWith("fill", "black");
expect(text.attr).wasCalledWith("stroke", "none");
@@ -588,12 +639,20 @@
});
it('should add a label if a reason is given', function() {
+ g = {
+ on: function() {
+ return this;
+ },
+ append: function() {
+ return comShapeInner;
+ }
+ };
c._reason = {
key: "key",
value: "label"
};
- spyOn(g, "append").andCallThrough();
+ spyOn(comShapeInner, "append").andCallThrough();
spyOn(text, "attr").andCallThrough();
spyOn(text, "append").andCallThrough();
spyOn(tSpan1, "attr").andCallThrough();
@@ -603,9 +662,17 @@
spyOn(tSpan3, "attr").andCallThrough();
spyOn(tSpan3, "text").andCallThrough();
spyOn(colourMapper, "getForegroundCommunityColour").andCallThrough();
- c.shape(g, shaper.shapeFunc, colourMapper);
+ c.shape(
+ g,
+ shaper.shapeFunc,
+ shaper.colourFunc,
+ shaper.eventsFunc,
+ gv.start,
+ colourMapper
+ );
- expect(g.append).wasCalledWith("text");
+
+ expect(comShapeInner.append).wasCalledWith("text");
expect(text.attr).wasCalledWith("text-anchor", "middle");
expect(text.attr).wasCalledWith("fill", "black");
expect(text.attr).wasCalledWith("stroke", "none");
@@ -697,7 +764,14 @@
spyOn(titleText, "attr").andCallThrough();
- c.shape(g, shaper.shapeFunc, colourMapper);
+ c.shape(
+ g,
+ shaper.shapeFunc,
+ shaper.colourFunc,
+ shaper.eventsFunc,
+ gv.start,
+ colourMapper
+ );
expect(g.append).wasCalledWith("g");
expect(boxGroup.append).wasCalledWith("rect");
@@ -747,7 +821,15 @@
spyOn(observer, "observe").andCallThrough();
spyOn(observer, "disconnect").andCallThrough();
- c.shape(g, shaper.shapeFunc, colourMapper);
+ c.shape(
+ g,
+ shaper.shapeFunc,
+ shaper.colourFunc,
+ shaper.eventsFunc,
+ gv.start,
+ colourMapper
+ );
+
expect(document.getElementById).wasCalledWith(c._id);
expect(observer.observe).wasCalledWith(
@@ -785,7 +867,15 @@
spyOn(iAll, "remove").andCallThrough();
- c.shape(g, shaper.shapeFunc, colourMapper);
+ c.shape(
+ g,
+ shaper.shapeFunc,
+ shaper.colourFunc,
+ shaper.eventsFunc,
+ gv.start,
+ colourMapper
+ );
+
expect(g.selectAll).wasCalledWith(".node");
expect(nodeSelector.data).wasCalledWith(c.getNodes(), jasmine.any(Function));
@@ -812,7 +902,15 @@
nodes[4].x = 20;
nodes[4].y = -20;
- c.shape(g, shaper.shapeFunc, colourMapper);
+ c.shape(
+ g,
+ shaper.shapeFunc,
+ shaper.colourFunc,
+ shaper.eventsFunc,
+ gv.start,
+ colourMapper
+ );
+
expect(nodes[0].position).toEqual({
x: -20,
@@ -1304,6 +1402,31 @@
});
+ describe('user interaction', function() {
+
+ describe('if community is collapsed', function() {
+
+ });
+
+ describe('if the community is expanded', function() {
+
+ var c, parent;
+
+ beforeEach(function() {
+ parent = {
+ dissolveCommunity: function() {}
+ };
+ c = new CommunityNode(parent, nodes.slice(0, 5));
+ });
+
+ it('should be possible to collapse the community', function() {
+
+ });
+
+ });
+
+ });
+
describe('convenience methods', function() {
var parent;
diff --git a/html/admin/js/graphViewer/ui/eventDispatcherControls.js b/html/admin/js/graphViewer/ui/eventDispatcherControls.js
index efc6e2d4f2..f76f057eb9 100644
--- a/html/admin/js/graphViewer/ui/eventDispatcherControls.js
+++ b/html/admin/js/graphViewer/ui/eventDispatcherControls.js
@@ -2,7 +2,7 @@
/*global $, _, d3*/
/*global document, window*/
/*global modalDialogHelper, uiComponentsHelper */
-/*global EventDispatcher, EventLibrary*/
+/*global EventDispatcher*/
////////////////////////////////////////////////////////////////////////////////
/// @brief Graph functionality
///
@@ -76,7 +76,6 @@ function EventDispatcherControls(list, nodeShaper, edgeShaper, dispatcherConfig)
edit: "edit"
},
baseClass = "event",
- eventlib = new EventLibrary(),
dispatcher = new EventDispatcher(nodeShaper, edgeShaper, dispatcherConfig),
setCursorIcon = function(icon) {