diff --git a/html/admin/js/graphViewer/graph/JSONAdapter.js b/html/admin/js/graphViewer/graph/JSONAdapter.js index 3d12f00e07..cfa894b226 100644 --- a/html/admin/js/graphViewer/graph/JSONAdapter.js +++ b/html/admin/js/graphViewer/graph/JSONAdapter.js @@ -79,6 +79,9 @@ function JSONAdapter(jsonPath, nodes, edges, width, height) { return this.start + Math.random() * this.range; }; + self.loadNode = function(nodeId, callback) { + self.loadNodeFromTreeById(nodeId, callback); + }; self.loadNodeFromTreeById = function(nodeId, callback) { var json = jsonPath + nodeId + ".json"; diff --git a/html/admin/js/graphViewer/graph/arangoAdapter.js b/html/admin/js/graphViewer/graph/arangoAdapter.js index eb42488b3f..f256b667df 100644 --- a/html/admin/js/graphViewer/graph/arangoAdapter.js +++ b/html/admin/js/graphViewer/graph/arangoAdapter.js @@ -489,6 +489,10 @@ function ArangoAdapter(nodes, edges, config) { }); }; + self.loadNode = function(nodeId, callback) { + self.loadNodeFromTreeById(nodeId, callback); + }; + self.loadNodeFromTreeById = function(nodeId, callback) { sendQuery(queries.traversalById, { id: nodeId diff --git a/html/admin/js/graphViewer/graph/eventLibrary.js b/html/admin/js/graphViewer/graph/eventLibrary.js index 67198b1cb7..3cefa65244 100644 --- a/html/admin/js/graphViewer/graph/eventLibrary.js +++ b/html/admin/js/graphViewer/graph/eventLibrary.js @@ -67,8 +67,8 @@ function EventLibrary() { if (config.startCallback === undefined) { throw "A callback to the Start-method has to be defined"; } - if (config.loadNode === undefined) { - throw "A callback to load a node has to be defined"; + if (config.adapter === undefined) { + throw "An adapter to load data has to be defined"; } if (config.reshapeNodes === undefined) { throw "A callback to reshape nodes has to be defined"; @@ -81,7 +81,9 @@ function EventLibrary() { var edges = config.edges, nodes = config.nodes, startCallback = config.startCallback, - loadNode = config.loadNode, + adapter = config.adapter, + loadNode = adapter.loadNode, + expandCom = adapter.expandCommunity, reshapeNodes = config.reshapeNodes, removeNode = function (node) { var i; @@ -126,8 +128,12 @@ function EventLibrary() { }, expandNode = function(n) { - n._expanded = true; - loadNode(n._id, startCallback); + if (/^\*community/.test(n._id)) { + expandCom(n, startCallback); + } else { + n._expanded = true; + loadNode(n._id, startCallback); + } }; return function(n) { diff --git a/html/admin/js/graphViewer/graph/nodeShaper.js b/html/admin/js/graphViewer/graph/nodeShaper.js index 3d80af419e..d60e7cd1cd 100644 --- a/html/admin/js/graphViewer/graph/nodeShaper.js +++ b/html/admin/js/graphViewer/graph/nodeShaper.js @@ -64,6 +64,7 @@ function NodeShaper(parent, flags, idfunc) { "use strict"; var self = this, + communityRegEx = /^\*community/, nodes = [], visibleLabels = true, noop = function (node) { @@ -91,7 +92,17 @@ function NodeShaper(parent, flags, idfunc) { addColor = noop, addShape = noop, addLabel = noop, - + addCommunityShape = function(g) { + g.append("polygon") + .attr("points", "0,-25 -16,20 23,-10 -23,-10 16,20"); + }, + addCommunityLabel = function(g) { + g.append("text") // Append a label for the node + .attr("text-anchor", "middle") // Define text-anchor + .text(function(d) { + return d._size; + }); + }, unbindEvents = function() { // Hard unbind the dragging self.parent @@ -120,9 +131,18 @@ function NodeShaper(parent, flags, idfunc) { }, addQue = function (g) { - addShape(g); + var community = g.filter(function(n) { + return communityRegEx.test(n._id); + }), + normal = g.filter(function(n) { + return !communityRegEx.test(n._id); + }); + addCommunityShape(community); + addShape(normal); + if (visibleLabels) { - addLabel(g); + addCommunityLabel(community); + addLabel(normal); } addColor(g); addEvents(g); @@ -158,7 +178,12 @@ function NodeShaper(parent, flags, idfunc) { // Append the group and class to all new g.enter() .append("g") - .attr("class", "node") // node is CSS class that might be edited + .attr("class", function(d) { + if (communityRegEx.test(d._id)) { + return "node communitynode"; + } + return "node"; + }) // node is CSS class that might be edited .attr("id", idFunction); // Remove all old g.exit().remove(); @@ -176,7 +201,8 @@ function NodeShaper(parent, flags, idfunc) { case NodeShaper.shapes.CIRCLE: radius = shape.radius || 25; addShape = function (node) { - node.append("circle") // Display nodes as circles + node + .append("circle") // Display nodes as circles .attr("r", radius); // Set radius }; break; diff --git a/html/admin/js/graphViewer/graphViewer.js b/html/admin/js/graphViewer/graphViewer.js index ffcab615d3..75cc74e204 100644 --- a/html/admin/js/graphViewer/graphViewer.js +++ b/html/admin/js/graphViewer/graphViewer.js @@ -174,7 +174,7 @@ function GraphViewer(svg, width, height, adapterConfig, config) { edges: edges, nodes: nodes, startCallback: self.start, - loadNode: self.adapter.loadNodeFromTreeById, + adapter: self.adapter, reshapeNodes: self.nodeShaper.reshapeNodes }, drag: { diff --git a/html/admin/js/graphViewer/jasmine_test/helper/mocks.js b/html/admin/js/graphViewer/jasmine_test/helper/mocks.js index f11f015c7b..da8e5270db 100644 --- a/html/admin/js/graphViewer/jasmine_test/helper/mocks.js +++ b/html/admin/js/graphViewer/jasmine_test/helper/mocks.js @@ -43,7 +43,9 @@ var mocks = mocks || {}; patchNode: function(){}, createEdge: function(){}, deleteEdge: function(){}, - patchEdge: function(){} + patchEdge: function(){}, + loadNode: function(){}, + expandCommunity: function(){} }; }()); \ No newline at end of file diff --git a/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js b/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js index babdd9b2f1..63926e00c3 100644 --- a/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specAdapter/arangoAdapterSpec.js @@ -907,7 +907,6 @@ expect(this.fakeReducerRequest).not.toHaveBeenCalled(); }); - it('should trigger the reducer if the limit is set too small', function() { spyOn(this, "fakeReducerRequest").andCallFake(function() { return [c0]; diff --git a/html/admin/js/graphViewer/jasmine_test/specAdapter/interfaceSpec.js b/html/admin/js/graphViewer/jasmine_test/specAdapter/interfaceSpec.js index d3011970da..485dd09d1b 100644 --- a/html/admin/js/graphViewer/jasmine_test/specAdapter/interfaceSpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specAdapter/interfaceSpec.js @@ -56,6 +56,7 @@ var describeInterface = function (testee) { }); // Add functions to load here: + expect(testee).toHaveFunction("loadNode", 2); expect(testee).toHaveFunction("loadNodeFromTreeById", 2); expect(testee).toHaveFunction("requestCentralityChildren", 2); expect(testee).toHaveFunction("loadNodeFromTreeByAttributeValue", 3); diff --git a/html/admin/js/graphViewer/jasmine_test/specEvents/eventDispatcherSpec.js b/html/admin/js/graphViewer/jasmine_test/specEvents/eventDispatcherSpec.js index 2aea9bda5f..ac7bd7ee46 100644 --- a/html/admin/js/graphViewer/jasmine_test/specEvents/eventDispatcherSpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specEvents/eventDispatcherSpec.js @@ -62,6 +62,8 @@ spyOn(adapter, "createEdge"); spyOn(adapter, "patchEdge"); spyOn(adapter, "deleteEdge"); + spyOn(adapter, "loadNode"); + spyOn(adapter, "expandCommunity"); }; beforeEach(function() { @@ -74,9 +76,6 @@ nodes = []; edges = []; - this.loadNode = function() {}; - spyOn(this, "loadNode"); - defaultPosition = { x: 1, y: 1, @@ -87,7 +86,7 @@ edges: edges, nodes: nodes, startCallback: function() {}, - loadNode: this.loadNode, + adapter: adapter, reshapeNodes: function() {} }; @@ -437,7 +436,7 @@ }); waitsFor(function() { - return this.loadNode.wasCalled; + return adapter.loadNode.wasCalled; }, 1000, "The loadNode function should have been called."); runs(function() { diff --git a/html/admin/js/graphViewer/jasmine_test/specEvents/eventDispatcherUISpec.js b/html/admin/js/graphViewer/jasmine_test/specEvents/eventDispatcherUISpec.js index f49038b680..e641dccb45 100644 --- a/html/admin/js/graphViewer/jasmine_test/specEvents/eventDispatcherUISpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specEvents/eventDispatcherUISpec.js @@ -51,6 +51,8 @@ spyOn(adapter, "createEdge"); spyOn(adapter, "patchEdge"); spyOn(adapter, "deleteEdge"); + spyOn(adapter, "loadNode"); + spyOn(adapter, "expandCommunity"); }; @@ -87,15 +89,13 @@ }]; adapter = mocks.adapter; layouter = mocks.layouter; - this.loadNode = function() {}; - spyOn(this, "loadNode"); addSpies(); var expandConfig = { edges: edges, nodes: nodes, startCallback: function() {}, - loadNode: this.loadNode, + adapter: adapter, reshapeNodes: function() {} }, @@ -307,7 +307,7 @@ helper.simulateMouseEvent("click", "1"); - expect(this.loadNode).toHaveBeenCalledWith(nodes[0]._id, jasmine.any(Function)); + expect(adapter.loadNode).toHaveBeenCalledWith(nodes[0]._id, jasmine.any(Function)); }); }); diff --git a/html/admin/js/graphViewer/jasmine_test/specEvents/eventLibrarySpec.js b/html/admin/js/graphViewer/jasmine_test/specEvents/eventLibrarySpec.js index 377a58fc9f..a87de74c62 100644 --- a/html/admin/js/graphViewer/jasmine_test/specEvents/eventLibrarySpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specEvents/eventLibrarySpec.js @@ -1,6 +1,6 @@ /*jslint indent: 2, nomen: true, maxlen: 100, white: true plusplus: true */ /*global beforeEach, afterEach */ -/*global describe, it, expect */ +/*global describe, it, expect, jasmine */ /*global runs, spyOn, waitsFor */ /*global window, eb, loadFixtures, document, $ */ /*global EventLibrary*/ @@ -40,13 +40,15 @@ var eventLib, nodeShaperDummy = {}, - edgeShaperDummy = {}; + edgeShaperDummy = {}, + adapterDummy = {}; beforeEach(function() { eventLib = new EventLibrary(); nodeShaperDummy.reshapeNodes = function() {}; edgeShaperDummy.reshapeEdges = function() {}; - + adapterDummy.loadNode = function() {}; + adapterDummy.expandCommunity = function() {}; spyOn(nodeShaperDummy, "reshapeNodes"); spyOn(edgeShaperDummy, "reshapeEdges"); }); @@ -59,10 +61,6 @@ edges, loadedNodes, started, - loadNodeCallback = function(node) { - loaded++; - loadedNodes.push(node); - }, reshapeNodesCallback = function() { reshaped++; }, @@ -84,7 +82,7 @@ edges: edges, nodes: nodes, startCallback: startCallback, - loadNode: loadNodeCallback, + adapter: adapterDummy, reshapeNodes: reshapeNodesCallback }; }); @@ -96,6 +94,11 @@ _inboundCounter: 0 }; nodes.push(node); + spyOn(adapterDummy, "loadNode").andCallFake(function(node) { + loaded++; + loadedNodes.push(node); + }); + //config.adapter = adapterDummy.loadNode; testee = eventLib.Expand(config); testee(node); @@ -206,7 +209,19 @@ expect(c2._outboundCounter).toEqual(1); }); - + it('should expand a community node properly', function() { + var comm = { + _id: "*community_1" + }; + nodes.push(comm); + + spyOn(adapterDummy, "expandCommunity"); + + testee = eventLib.Expand(config); + testee(comm); + + expect(adapterDummy.expandCommunity).toHaveBeenCalledWith(comm, jasmine.any(Function)); + }); describe('setup process', function() { @@ -248,14 +263,14 @@ function() { eventLib.Expand(testConfig); } - ).toThrow("A callback to load a node has to be defined"); + ).toThrow("An adapter to load data has to be defined"); }); it('should throw an error if reshape node callback is not given', function() { testConfig.edges = []; testConfig.nodes = []; testConfig.startCallback = function(){}; - testConfig.loadNode = function(){}; + testConfig.adapter = adapterDummy; expect( function() { eventLib.Expand(testConfig); diff --git a/html/admin/js/graphViewer/jasmine_test/specGraphViewer/graphViewerSpec.js b/html/admin/js/graphViewer/jasmine_test/specGraphViewer/graphViewerSpec.js index 62e314bd9a..4dc6c49423 100644 --- a/html/admin/js/graphViewer/jasmine_test/specGraphViewer/graphViewerSpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specGraphViewer/graphViewerSpec.js @@ -153,7 +153,7 @@ describe("Graph Viewer", function() { edges: [], nodes: [], startCallback: jasmine.any(Function), - loadNode: jasmine.any(Function), + adapter: jasmine.any(Object), reshapeNodes: jasmine.any(Function) }, drag: { @@ -172,7 +172,7 @@ describe("Graph Viewer", function() { edges: [], nodes: [], startCallback: jasmine.any(Function), - loadNode: jasmine.any(Function), + adapter: jasmine.any(Object), reshapeNodes: jasmine.any(Function) }); expect(viewer.dispatcherConfig.drag).toEqual({ diff --git a/html/admin/js/graphViewer/jasmine_test/specNodeShaper/nodeShaperSpec.js b/html/admin/js/graphViewer/jasmine_test/specNodeShaper/nodeShaperSpec.js index 7058539ef4..b60db1b0f2 100644 --- a/html/admin/js/graphViewer/jasmine_test/specNodeShaper/nodeShaperSpec.js +++ b/html/admin/js/graphViewer/jasmine_test/specNodeShaper/nodeShaperSpec.js @@ -1018,6 +1018,7 @@ var nodes = helper.createSimpleNodes([0, 1, 2]), commNode = { _id: "*community_42", + _size: 4, _inboundCounter: 0, _outboundCounter: 0, position: { @@ -1031,10 +1032,31 @@ shaper.drawNodes(nodes); expect($("svg .communitynode").length).toEqual(1); expect($("svg #\\*community_42")[0]).toBeDefined(); - star = $("svg #\\*community_42 polygon")[0]; - expect(star).toBeDefined(); - expect(star.points).toEqual("0,-25 -16,20 23,-10 -23,-10 16,20"); + star = $("svg #\\*community_42 polygon"); + expect(star.length).toEqual(1); + expect(star.attr("points")).toEqual("0,-25 -16,20 23,-10 -23,-10 16,20"); }); + + it('should print the size of the capsulated community', function() { + var nodes = helper.createSimpleNodes([0, 1, 2]), + commNode = { + _id: "*community_42", + _size: 4, + _inboundCounter: 0, + _outboundCounter: 0, + position: { + x: 1, + y: 1, + z: 1 + } + }, + text; + nodes.push(commNode); + shaper.drawNodes(nodes); + text = $("svg #\\*community_42 text")[0].textContent; + expect(text).toEqual("4"); + }); + }); });