mirror of https://gitee.com/bigwinds/arangodb
GraphViewer: Events are now piped though community nodes, contained nodes are now clickable
This commit is contained in:
parent
ce0df062dd
commit
cded8c87ed
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
////////////////////////////////////
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue