1
0
Fork 0

Merge branch 'devel' of https://github.com/triAGENS/ArangoDB into devel

This commit is contained in:
Jan Steemann 2013-07-23 11:20:02 +02:00
commit 7e91193074
8 changed files with 247 additions and 93 deletions

View File

@ -620,6 +620,7 @@ function AbstractAdapter(nodes, edges, descendant, config) {
expandNode = function(n, startCallback) { expandNode = function(n, startCallback) {
if (n._isCommunity) { if (n._isCommunity) {
console.log("Adapter Explore!");
self.expandCommunity(n, startCallback); self.expandCommunity(n, startCallback);
} else { } else {
n._expanded = true; n._expanded = true;

View File

@ -32,7 +32,9 @@
function CommunityNode(parent, initial) { function CommunityNode(parent, initial) {
"use strict"; "use strict";
if (_.isUndefined(parent) || !_.isFunction(parent.dissolveCommunity)) { if (_.isUndefined(parent)
|| !_.isFunction(parent.dissolveCommunity)
|| !_.isFunction(parent.checkNodeLimit)) {
throw "A parent element has to be given."; throw "A parent element has to be given.";
} }
@ -77,7 +79,7 @@ function CommunityNode(parent, initial) {
getSourcePosition = function(e) { getSourcePosition = function(e) {
if (self._expanded) { if (self._expanded) {
var p = self.position, var p = self.position,
diff = e._source, diff = e._source.position,
x = p.x + diff.x, x = p.x + diff.x,
y = p.y + diff.y, y = p.y + diff.y,
z = p.z + diff.z; z = p.z + diff.z;
@ -94,9 +96,9 @@ function CommunityNode(parent, initial) {
getTargetPosition = function(e) { getTargetPosition = function(e) {
if (self._expanded) { if (self._expanded) {
var p = self.position, var p = self.position,
diff = e._target, diff = e._target.position,
x = p.x + diff.x, x = p.x + p.z * diff.x,
y = p.y + diff.y, y = p.y + p.z * diff.y,
z = p.z + diff.z; z = p.z + diff.z;
return { return {
x: x, x: x,
@ -293,30 +295,6 @@ function CommunityNode(parent, initial) {
this._expanded = false; this._expanded = false;
}, },
addDistortion = function() {
// Fake Layouting TODO
_.each(nodeArray, function(n) {
n.position = {
x: n.x,
y: n.y,
z: 1
};
});
},
addShape = function (g, shapeFunc, colourMapper) {
g.attr("stroke", colourMapper.getForegroundCommunityColour());
shapeFunc(g);
},
addCollapsedShape = function(g, shapeFunc, colourMapper) {
g.attr("stroke", colourMapper.getForegroundCommunityColour());
shapeFunc(g, 9);
shapeFunc(g, 6);
shapeFunc(g, 3);
shapeFunc(g);
},
addCollapsedLabel = function(g, colourMapper) { addCollapsedLabel = function(g, colourMapper) {
var width = g.select("rect").attr("width"), var width = g.select("rect").attr("width"),
textN = g.append("text") // Append a label for the node textN = g.append("text") // Append a label for the node
@ -342,7 +320,23 @@ function CommunityNode(parent, initial) {
.text(self._size); .text(self._size);
}, },
addNodeShapes = function(g, shapeFunc, colourMapper) { addCollapsedShape = function(g, shapeFunc, start, colourMapper) {
var inner = g.append("g")
.attr("stroke", colourMapper.getForegroundCommunityColour())
.attr("fill", colourMapper.getCommunityColour());
shapeFunc(inner, 9);
shapeFunc(inner, 6);
shapeFunc(inner, 3);
shapeFunc(inner);
inner.on("click", function() {
self.expand();
parent.checkNodeLimit(self);
start();
});
addCollapsedLabel(inner, colourMapper);
},
addNodeShapes = function(g, shapeQue) {
var interior = g.selectAll(".node") var interior = g.selectAll(".node")
.data(nodeArray, function(d) { .data(nodeArray, function(d) {
return d._id; return d._id;
@ -356,10 +350,10 @@ function CommunityNode(parent, initial) {
// Remove all old // Remove all old
interior.exit().remove(); interior.exit().remove();
interior.selectAll("* > *").remove(); interior.selectAll("* > *").remove();
addShape(interior, shapeFunc, colourMapper); shapeQue(interior);
}, },
addBoundingBox = function(g) { addBoundingBox = function(g, start) {
bBox = g.append("g"); bBox = g.append("g");
bBoxBorder = bBox.append("rect") bBoxBorder = bBox.append("rect")
.attr("rx", "8") .attr("rx", "8")
@ -373,21 +367,29 @@ function CommunityNode(parent, initial) {
.attr("fill", "#686766") .attr("fill", "#686766")
.attr("stroke", "none"); .attr("stroke", "none");
var dissolveBtn = bBox.append("image") var dissolveBtn = bBox.append("image")
.attr("id", self._id + "_dissolve")
.attr("xlink:href", "img/icon_delete.png") .attr("xlink:href", "img/icon_delete.png")
.attr("width", "16") .attr("width", "16")
.attr("height", "16") .attr("height", "16")
.attr("x", "5") .attr("x", "5")
.attr("y", "2") .attr("y", "2")
.attr("style", "cursor:pointer") .attr("style", "cursor:pointer")
.on("click", dissolve), .on("click", function() {
self.dissolve();
start();
}),
collapseBtn = bBox.append("image") collapseBtn = bBox.append("image")
.attr("id", self._id + "_collapse")
.attr("xlink:href", "img/gv_collapse.png") .attr("xlink:href", "img/gv_collapse.png")
.attr("width", "16") .attr("width", "16")
.attr("height", "16") .attr("height", "16")
.attr("x", "25") .attr("x", "25")
.attr("y", "2") .attr("y", "2")
.attr("style", "cursor:pointer") .attr("style", "cursor:pointer")
.on("click", collapse), .on("click", function() {
self.collapse();
start();
}),
title = bBox.append("text") title = bBox.append("text")
.attr("x", "45") .attr("x", "45")
.attr("y", "15") .attr("y", "15")
@ -403,15 +405,26 @@ function CommunityNode(parent, initial) {
}); });
}, },
shapeAll = function(g, shapeFunc, colourMapper) { addDistortion = function(distFunc) {
_.each(nodeArray, function(n) {
//n.position = distFunc(n);
n.position = {
x: n.x,
y: n.y,
z: 1
};
});
},
shapeAll = function(g, shapeFunc, shapeQue, start, colourMapper) {
// First unbind all click events that are proably still bound
g.on("click", null);
if (self._expanded) { if (self._expanded) {
addBoundingBox(g); addBoundingBox(g, start);
addDistortion(); addNodeShapes(g, shapeQue, start, colourMapper);
addNodeShapes(g, shapeFunc, colourMapper);
return; return;
} }
addCollapsedShape(g, shapeFunc, colourMapper); addCollapsedShape(g, shapeFunc, start, colourMapper);
addCollapsedLabel(g, colourMapper);
}; };
//////////////////////////////////// ////////////////////////////////////
@ -478,6 +491,7 @@ function CommunityNode(parent, initial) {
this.expand = expand; this.expand = expand;
this.shape = shapeAll; this.shape = shapeAll;
this.addDistortion = addDistortion;
this.getSourcePosition = getSourcePosition; this.getSourcePosition = getSourcePosition;

View File

@ -167,6 +167,10 @@ function EventDispatcher(nodeShaper, edgeShaper, config) {
if (config.expand !== undefined) { if (config.expand !== undefined) {
if (eventlib.checkExpandConfig(config.expand)) { if (eventlib.checkExpandConfig(config.expand)) {
self.events.EXPAND = new eventlib.Expand(config.expand); self.events.EXPAND = new eventlib.Expand(config.expand);
nodeShaper.setGVStartFunction(function() {
config.expand.reshapeNodes();
config.expand.startCallback();
});
} }
} }
if (config.drag !== undefined) { if (config.drag !== undefined) {

View File

@ -82,7 +82,6 @@ function NodeShaper(parent, flags, idfunc) {
var self = this, var self = this,
nodes = [], nodes = [],
visibleLabels = true, visibleLabels = true,
splitLabel = function(label) { splitLabel = function(label) {
if (label === undefined) { if (label === undefined) {
return [""]; return [""];
@ -103,6 +102,7 @@ function NodeShaper(parent, flags, idfunc) {
noop = function (node) { noop = function (node) {
}, },
start = noop,
defaultDistortion = function(n) { defaultDistortion = function(n) {
return { return {
x: n.x, x: n.x,
@ -114,6 +114,9 @@ function NodeShaper(parent, flags, idfunc) {
addDistortion = function() { addDistortion = function() {
_.each(nodes, function(n) { _.each(nodes, function(n) {
n.position = distortion(n); n.position = distortion(n);
if (n._isCommunity) {
n.addDistortion(distortion);
}
}); });
}, },
colourMapper = new ColourMapper(), colourMapper = new ColourMapper(),
@ -165,13 +168,13 @@ function NodeShaper(parent, flags, idfunc) {
}); });
addShape(normal); addShape(normal);
community.each(function(c) { community.each(function(c) {
c.shape(d3.select(this), addShape, colourMapper); c.shape(d3.select(this), addShape, addQue, start, colourMapper);
}); });
if (visibleLabels) { if (visibleLabels) {
addLabel(normal); addLabel(normal);
} }
addColor(g); addColor(normal);
addEvents(g); addEvents(normal);
addDistortion(); addDistortion();
}, },
@ -512,6 +515,10 @@ function NodeShaper(parent, flags, idfunc) {
colourMapper.setChangeListener(callback); colourMapper.setChangeListener(callback);
}; };
self.setGVStartFunction = function(func) {
start = func;
};
} }
NodeShaper.shapes = Object.freeze({ NodeShaper.shapes = Object.freeze({

View File

@ -129,9 +129,14 @@ function ZoomManager(width, height, svg, g, nodeShaper, edgeShaper, config, limi
edgeShaper.activateLabel(currentZoom >= labelToggle); edgeShaper.activateLabel(currentZoom >= labelToggle);
calcDistortionValues(); calcDistortionValues();
currentTranslation = $.extend({}, d3.event.translate); currentTranslation = $.extend({}, d3.event.translate);
g.attr("transform", var trans = "translate(" + d3.event.translate + ")",
"translate(" + d3.event.translate + ")" scale = " scale(" + currentZoom + ")";
+ " scale(" + currentZoom + ")"); if (g._isCommunity) {
g.attr("transform", trans);
} else {
g.attr("transform", trans + scale);
}
}); });
}, },

View File

@ -58,7 +58,8 @@
expect( expect(
function() { function() {
var t = new CommunityNode({ var t = new CommunityNode({
dissolveCommunity: function() {} dissolveCommunity: function() {},
checkNodeLimit: function() {}
}); });
} }
).not.toThrow(); ).not.toThrow();
@ -67,7 +68,8 @@
it('should create a ForceLayouter on setup', function() { it('should create a ForceLayouter on setup', function() {
spyOn(window, "ForceLayouter"); spyOn(window, "ForceLayouter");
var t = new CommunityNode({ var t = new CommunityNode({
dissolveCommunity: function() {} dissolveCommunity: function() {},
checkNodeLimit: function() {}
}); });
expect(window.ForceLayouter).wasCalledWith({ expect(window.ForceLayouter).wasCalledWith({
distance: 100, distance: 100,
@ -88,7 +90,8 @@
beforeEach(function() { beforeEach(function() {
var parent = { var parent = {
dissolveCommunity: function() {} dissolveCommunity: function() {},
checkNodeLimit: function() {}
}; };
testee = new CommunityNode(parent, nodes.slice(3, 13)); testee = new CommunityNode(parent, nodes.slice(3, 13));
this.addMatchers({ this.addMatchers({
@ -188,7 +191,8 @@
beforeEach(function() { beforeEach(function() {
parent = { parent = {
dissolveCommunity: function() {} dissolveCommunity: function() {},
checkNodeLimit: function() {}
}; };
layouter = { layouter = {
start: function() {}, start: function() {},
@ -363,12 +367,13 @@
describe('shaping functionality', function() { describe('shaping functionality', function() {
var tSpan1, tSpan2, tSpan3, text, g, shaper, colourMapper, box, boxGroup, boxRect, var tSpan1, tSpan2, tSpan3, text, g, shaper, gv, colourMapper, box, boxGroup, boxRect,
parent, c, width, titleBG, disBtn, titleText, colBtn; parent, c, width, titleBG, disBtn, titleText, colBtn, comShapeInner;
beforeEach(function() { beforeEach(function() {
parent = { parent = {
dissolveCommunity: function() {} dissolveCommunity: function() {},
checkNodeLimit: function() {}
}; };
var tspans = 0; var tspans = 0;
width = 90; width = 90;
@ -462,6 +467,26 @@
return this; return this;
} }
}; };
comShapeInner = {
attr: function() {
return this;
},
on: function() {
return this;
},
select: function() {
return {
attr: function() {
return width;
}
};
},
append: function(type) {
if (type === "text") {
return text;
}
}
};
text = { text = {
attr: function() { attr: function() {
return this; return this;
@ -481,27 +506,24 @@
} }
}; };
g = { g = {
select: function() {
return {
attr: function() {
return width;
}
};
},
attr: function() { attr: function() {
return this; return this;
}, },
append: function(type) { append: function(type) {
if (type === "text") {
return text;
}
if (type === "g") { if (type === "g") {
return boxGroup; return boxGroup;
} }
},
on: function() {
return this;
} }
}; };
shaper = { shaper = {
shapeFunc: function() {} shapeFunc: function() {},
shapeQue: function() {}
};
gv = {
start: function() {}
}; };
colourMapper = { colourMapper = {
getForegroundCommunityColour: function() { getForegroundCommunityColour: function() {
@ -549,32 +571,67 @@
}); });
it('should shape the collapsed community with given functions', function() { it('should shape the collapsed community with given functions', function() {
spyOn(g, "attr").andCallThrough(); g = {
on: function() {
return this;
},
append: function() {
return comShapeInner;
}
};
spyOn(g, "append").andCallThrough(); spyOn(g, "append").andCallThrough();
spyOn(g, "on").andCallThrough();
spyOn(shaper, "shapeFunc").andCallThrough(); spyOn(shaper, "shapeFunc").andCallThrough();
spyOn(comShapeInner, "attr").andCallThrough();
spyOn(colourMapper, "getForegroundCommunityColour").andCallThrough(); spyOn(colourMapper, "getForegroundCommunityColour").andCallThrough();
c.shape(g, shaper.shapeFunc, colourMapper); c.shape(
g,
shaper.shapeFunc,
shaper.shapeQue,
gv.start,
colourMapper
);
expect(colourMapper.getForegroundCommunityColour).wasCalled(); expect(colourMapper.getForegroundCommunityColour).wasCalled();
expect(g.attr).wasCalledWith("stroke", "black"); expect(g.append).wasCalledWith("g");
expect(shaper.shapeFunc).wasCalledWith(g, 9); expect(g.on).wasCalledWith("click", null);
expect(shaper.shapeFunc).wasCalledWith(g, 6); expect(comShapeInner.attr).wasCalledWith("stroke", "black");
expect(shaper.shapeFunc).wasCalledWith(g, 3); expect(shaper.shapeFunc).wasCalledWith(comShapeInner, 9);
expect(shaper.shapeFunc).wasCalledWith(g); 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() { 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(g, "append").andCallThrough();
spyOn(comShapeInner, "append").andCallThrough();
spyOn(text, "attr").andCallThrough(); spyOn(text, "attr").andCallThrough();
spyOn(text, "append").andCallThrough(); spyOn(text, "append").andCallThrough();
spyOn(tSpan1, "attr").andCallThrough(); spyOn(tSpan1, "attr").andCallThrough();
spyOn(tSpan1, "text").andCallThrough(); spyOn(tSpan1, "text").andCallThrough();
spyOn(colourMapper, "getForegroundCommunityColour").andCallThrough(); spyOn(colourMapper, "getForegroundCommunityColour").andCallThrough();
c.shape(g, shaper.shapeFunc, colourMapper); c.shape(
g,
shaper.shapeFunc,
shaper.shapeQue,
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("text-anchor", "middle");
expect(text.attr).wasCalledWith("fill", "black"); expect(text.attr).wasCalledWith("fill", "black");
expect(text.attr).wasCalledWith("stroke", "none"); expect(text.attr).wasCalledWith("stroke", "none");
@ -588,12 +645,20 @@
}); });
it('should add a label if a reason is given', function() { it('should add a label if a reason is given', function() {
g = {
on: function() {
return this;
},
append: function() {
return comShapeInner;
}
};
c._reason = { c._reason = {
key: "key", key: "key",
value: "label" value: "label"
}; };
spyOn(g, "append").andCallThrough(); spyOn(comShapeInner, "append").andCallThrough();
spyOn(text, "attr").andCallThrough(); spyOn(text, "attr").andCallThrough();
spyOn(text, "append").andCallThrough(); spyOn(text, "append").andCallThrough();
spyOn(tSpan1, "attr").andCallThrough(); spyOn(tSpan1, "attr").andCallThrough();
@ -603,9 +668,16 @@
spyOn(tSpan3, "attr").andCallThrough(); spyOn(tSpan3, "attr").andCallThrough();
spyOn(tSpan3, "text").andCallThrough(); spyOn(tSpan3, "text").andCallThrough();
spyOn(colourMapper, "getForegroundCommunityColour").andCallThrough(); spyOn(colourMapper, "getForegroundCommunityColour").andCallThrough();
c.shape(g, shaper.shapeFunc, colourMapper); c.shape(
g,
shaper.shapeFunc,
shaper.shapeQue,
gv.start,
colourMapper
);
expect(g.append).wasCalledWith("text");
expect(comShapeInner.append).wasCalledWith("text");
expect(text.attr).wasCalledWith("text-anchor", "middle"); expect(text.attr).wasCalledWith("text-anchor", "middle");
expect(text.attr).wasCalledWith("fill", "black"); expect(text.attr).wasCalledWith("fill", "black");
expect(text.attr).wasCalledWith("stroke", "none"); expect(text.attr).wasCalledWith("stroke", "none");
@ -697,7 +769,13 @@
spyOn(titleText, "attr").andCallThrough(); spyOn(titleText, "attr").andCallThrough();
c.shape(g, shaper.shapeFunc, colourMapper); c.shape(
g,
shaper.shapeFunc,
shaper.shapeQue,
gv.start,
colourMapper
);
expect(g.append).wasCalledWith("g"); expect(g.append).wasCalledWith("g");
expect(boxGroup.append).wasCalledWith("rect"); expect(boxGroup.append).wasCalledWith("rect");
@ -747,7 +825,14 @@
spyOn(observer, "observe").andCallThrough(); spyOn(observer, "observe").andCallThrough();
spyOn(observer, "disconnect").andCallThrough(); spyOn(observer, "disconnect").andCallThrough();
c.shape(g, shaper.shapeFunc, colourMapper); c.shape(
g,
shaper.shapeFunc,
shaper.shapeQue,
gv.start,
colourMapper
);
expect(document.getElementById).wasCalledWith(c._id); expect(document.getElementById).wasCalledWith(c._id);
expect(observer.observe).wasCalledWith( expect(observer.observe).wasCalledWith(
@ -783,9 +868,15 @@
spyOn(iG, "attr").andCallThrough(); spyOn(iG, "attr").andCallThrough();
spyOn(iExit, "remove").andCallThrough(); spyOn(iExit, "remove").andCallThrough();
spyOn(iAll, "remove").andCallThrough(); spyOn(iAll, "remove").andCallThrough();
spyOn(shaper, "shapeQue").andCallThrough();
c.shape(
c.shape(g, shaper.shapeFunc, colourMapper); g,
shaper.shapeFunc,
shaper.shapeQue,
gv.start,
colourMapper
);
expect(g.selectAll).wasCalledWith(".node"); expect(g.selectAll).wasCalledWith(".node");
expect(nodeSelector.data).wasCalledWith(c.getNodes(), jasmine.any(Function)); expect(nodeSelector.data).wasCalledWith(c.getNodes(), jasmine.any(Function));
@ -797,6 +888,8 @@
expect(iExit.remove).wasCalled(); expect(iExit.remove).wasCalled();
expect(interior.selectAll).wasCalledWith("* > *"); expect(interior.selectAll).wasCalledWith("* > *");
expect(iAll.remove).wasCalled(); expect(iAll.remove).wasCalled();
expect(shaper.shapeQue).wasCalledWith(interior);
}); });
it('should apply distortion on the interior nodes', function() { it('should apply distortion on the interior nodes', function() {
@ -812,7 +905,8 @@
nodes[4].x = 20; nodes[4].x = 20;
nodes[4].y = -20; nodes[4].y = -20;
c.shape(g, shaper.shapeFunc, colourMapper); c.addDistortion();
expect(nodes[0].position).toEqual({ expect(nodes[0].position).toEqual({
x: -20, x: -20,
@ -851,7 +945,8 @@
beforeEach(function() { beforeEach(function() {
parent = { parent = {
dissolveCommunity: function() {} dissolveCommunity: function() {},
checkNodeLimit: function() {}
}; };
layouter = { layouter = {
start: function() {}, start: function() {},
@ -1275,7 +1370,8 @@
beforeEach(function() { beforeEach(function() {
parent = { parent = {
dissolveCommunity: function() {} dissolveCommunity: function() {},
checkNodeLimit: function() {}
}; };
}); });
@ -1304,13 +1400,40 @@
}); });
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() {},
checkNodeLimit: function() {}
};
c = new CommunityNode(parent, nodes.slice(0, 5));
});
it('should be possible to collapse the community', function() {
});
});
});
describe('convenience methods', function() { describe('convenience methods', function() {
var parent; var parent;
beforeEach(function() { beforeEach(function() {
parent = { parent = {
dissolveCommunity: function() {} dissolveCommunity: function() {},
checkNodeLimit: function() {}
}; };
}); });

View File

@ -1365,7 +1365,8 @@
beforeEach(function() { beforeEach(function() {
shaper = new NodeShaper(d3.select("svg")); shaper = new NodeShaper(d3.select("svg"));
adapter = { adapter = {
dissolveCommunity: function() {} dissolveCommunity: function() {},
checkNodeLimit: function() {}
}; };
}); });

View File

@ -2,7 +2,7 @@
/*global $, _, d3*/ /*global $, _, d3*/
/*global document, window*/ /*global document, window*/
/*global modalDialogHelper, uiComponentsHelper */ /*global modalDialogHelper, uiComponentsHelper */
/*global EventDispatcher, EventLibrary*/ /*global EventDispatcher*/
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief Graph functionality /// @brief Graph functionality
/// ///
@ -76,7 +76,6 @@ function EventDispatcherControls(list, nodeShaper, edgeShaper, dispatcherConfig)
edit: "edit" edit: "edit"
}, },
baseClass = "event", baseClass = "event",
eventlib = new EventLibrary(),
dispatcher = new EventDispatcher(nodeShaper, edgeShaper, dispatcherConfig), dispatcher = new EventDispatcher(nodeShaper, edgeShaper, dispatcherConfig),
setCursorIcon = function(icon) { setCursorIcon = function(icon) {