mirror of https://gitee.com/bigwinds/arangodb
GraphViewer: A line is now displayed to help connecting two nodes
This commit is contained in:
parent
4ff14a0228
commit
5d2008d4bb
|
@ -50,7 +50,8 @@ function EdgeShaper(parent, flags, idfunc) {
|
|||
edges = [],
|
||||
toplevelSVG,
|
||||
visibleLabels = true,
|
||||
|
||||
followEdge = {},
|
||||
followEdgeG,
|
||||
idFunction = function(d) {
|
||||
return d.source._id + "-" + d.target._id;
|
||||
},
|
||||
|
@ -319,6 +320,8 @@ function EdgeShaper(parent, flags, idfunc) {
|
|||
idFunction = idfunc;
|
||||
}
|
||||
|
||||
followEdgeG = toplevelSVG.append("g");
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
/// Public functions
|
||||
|
@ -351,6 +354,24 @@ function EdgeShaper(parent, flags, idfunc) {
|
|||
}
|
||||
shapeEdges();
|
||||
};
|
||||
|
||||
self.addAnEdgeFollowingTheCursor = function(x, y) {
|
||||
followEdge = followEdgeG.append("line");
|
||||
followEdge.attr("stroke", "black")
|
||||
.attr("id", "connectionLine")
|
||||
.attr("x1", x)
|
||||
.attr("y1", y)
|
||||
.attr("x2", x)
|
||||
.attr("y2", y);
|
||||
return function(x, y) {
|
||||
followEdge.attr("x2", x).attr("y2", y);
|
||||
};
|
||||
};
|
||||
|
||||
self.removeCursorFollowingEdge = function() {
|
||||
followEdge.remove();
|
||||
followEdge = {};
|
||||
};
|
||||
}
|
||||
|
||||
EdgeShaper.shapes = Object.freeze({
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true */
|
||||
/*global _, $*/
|
||||
/*global _, $, window*/
|
||||
/*global EventLibrary*/
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Graph functionality
|
||||
|
@ -80,11 +80,14 @@ function EventDispatcher(nodeShaper, edgeShaper, config) {
|
|||
|
||||
self.events.STARTCREATEEDGE = function(callback) {
|
||||
return function(node) {
|
||||
var e = d3.event || window.event;
|
||||
edgeStart = node;
|
||||
didInsert = false;
|
||||
if (callback !== undefined) {
|
||||
callback();
|
||||
callback(node, e);
|
||||
}
|
||||
// Necessary to omit dragging of the graph
|
||||
e.stopPropagation();
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
beforeEach(function () {
|
||||
svg = document.createElement("svg");
|
||||
svg.id = "svg";
|
||||
document.body.appendChild(svg);
|
||||
});
|
||||
|
||||
|
@ -274,6 +275,55 @@
|
|||
expect($("#1-5 line").attr("x2")).toEqual("28.284271247461902");
|
||||
});
|
||||
|
||||
it('should be able to draw an edge that follows the cursor', function() {
|
||||
var line,
|
||||
jqLine,
|
||||
cursorX,
|
||||
cursorY,
|
||||
nodeX = 15,
|
||||
nodeY = 20,
|
||||
shaper = new EdgeShaper(d3.select("svg")),
|
||||
moveCB = shaper.addAnEdgeFollowingTheCursor(nodeX, nodeY);
|
||||
|
||||
cursorX = 20;
|
||||
cursorY = 30;
|
||||
moveCB(cursorX, cursorY);
|
||||
|
||||
expect($("#connectionLine").length).toEqual(1);
|
||||
|
||||
jqLine = $("#connectionLine");
|
||||
line = document.getElementById("connectionLine");
|
||||
expect(line.tagName.toLowerCase()).toEqual("line");
|
||||
expect(jqLine.attr("x1")).toEqual(String(nodeX));
|
||||
expect(jqLine.attr("y1")).toEqual(String(nodeY));
|
||||
|
||||
expect(jqLine.attr("x2")).toEqual(String(cursorX));
|
||||
expect(jqLine.attr("y2")).toEqual(String(cursorY));
|
||||
|
||||
cursorX = 45;
|
||||
cursorY = 12;
|
||||
moveCB(cursorX, cursorY);
|
||||
expect(jqLine.attr("x2")).toEqual(String(cursorX));
|
||||
expect(jqLine.attr("y2")).toEqual(String(cursorY));
|
||||
});
|
||||
|
||||
it('should be able to remove the cursor-following edge on demand', function() {
|
||||
var line,
|
||||
cursorX,
|
||||
cursorY,
|
||||
nodeX = 15,
|
||||
nodeY = 20,
|
||||
shaper = new EdgeShaper(d3.select("svg")),
|
||||
moveCB;
|
||||
|
||||
moveCB = shaper.addAnEdgeFollowingTheCursor(nodeX, nodeY);
|
||||
cursorX = 20;
|
||||
cursorY = 30;
|
||||
moveCB(cursorX, cursorY);
|
||||
shaper.removeCursorFollowingEdge();
|
||||
expect($("#connectionLine").length).toEqual(0);
|
||||
});
|
||||
|
||||
describe('testing for colours', function() {
|
||||
|
||||
it('should have a default colouring of no colour flag is given', function() {
|
||||
|
|
|
@ -61,17 +61,21 @@
|
|||
beforeEach(function () {
|
||||
nodes = [{
|
||||
_id: 1,
|
||||
_rev: 1,
|
||||
_key: 1,
|
||||
x: 3,
|
||||
y: 4,
|
||||
_data: {
|
||||
_id: 1,
|
||||
_rev: 1,
|
||||
_key: 1,
|
||||
name: "Alice"
|
||||
}
|
||||
},{
|
||||
_id: 2,
|
||||
_rev: 2,
|
||||
_key: 2,
|
||||
x: 1,
|
||||
y: 2,
|
||||
_data: {
|
||||
_rev: 2,
|
||||
_key: 2,
|
||||
_id: 2
|
||||
}
|
||||
}];
|
||||
|
@ -122,6 +126,7 @@
|
|||
};
|
||||
|
||||
svg = document.createElement("svg");
|
||||
svg.id = "svg";
|
||||
document.body.appendChild(svg);
|
||||
nodeShaper = new NodeShaper(d3.select("svg"));
|
||||
edgeShaper = new EdgeShaper(d3.select("svg"));
|
||||
|
@ -265,7 +270,7 @@
|
|||
helper.simulateMouseEvent("click", "control_event_node_edit_submit");
|
||||
expect(adapter.patchNode).toHaveBeenCalledWith(
|
||||
nodes[0],
|
||||
{ _id: "1",
|
||||
{
|
||||
name: "Bob"
|
||||
},
|
||||
jasmine.any(Function));
|
||||
|
@ -286,9 +291,6 @@
|
|||
expect(adapter.patchEdge).toHaveBeenCalledWith(
|
||||
edges[0],
|
||||
{
|
||||
_id: "12",
|
||||
_rev: "12",
|
||||
_key: "12",
|
||||
_from: "1",
|
||||
_to: "2",
|
||||
label: "newLabel"
|
||||
|
@ -373,41 +375,95 @@
|
|||
});
|
||||
});
|
||||
|
||||
it('should be able to add a connect control to the list', function() {
|
||||
runs(function() {
|
||||
describe('the connect control', function() {
|
||||
|
||||
it('should be added to the list', function() {
|
||||
runs(function() {
|
||||
dispatcherUI.addControlConnect();
|
||||
|
||||
expect($("#control_event_list #control_event_connect").length).toEqual(1);
|
||||
|
||||
helper.simulateMouseEvent("click", "control_event_connect");
|
||||
|
||||
expect(nodeShaper.changeTo).toHaveBeenCalledWith({
|
||||
actions: {
|
||||
reset: true,
|
||||
mousedown: jasmine.any(Function),
|
||||
mouseup: jasmine.any(Function)
|
||||
}
|
||||
});
|
||||
|
||||
expect(edgeShaper.changeTo).toHaveBeenCalledWith({
|
||||
actions: {
|
||||
reset: true
|
||||
}
|
||||
});
|
||||
|
||||
expect(mousePointerbox.className).toEqual("mousepointer icon-resize-horizontal");
|
||||
|
||||
helper.simulateMouseEvent("mousedown", "2");
|
||||
|
||||
helper.simulateMouseEvent("mouseup", "1");
|
||||
|
||||
expect(adapter.createEdge).toHaveBeenCalledWith(
|
||||
{source: nodes[1], target: nodes[0]},
|
||||
jasmine.any(Function)
|
||||
);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
it('should draw a line from startNode following the cursor', function() {
|
||||
var line,
|
||||
cursorX,
|
||||
cursorY;
|
||||
|
||||
spyOn(edgeShaper, "addAnEdgeFollowingTheCursor");
|
||||
|
||||
dispatcherUI.addControlConnect();
|
||||
|
||||
expect($("#control_event_list #control_event_connect").length).toEqual(1);
|
||||
|
||||
helper.simulateMouseEvent("click", "control_event_connect");
|
||||
|
||||
expect(nodeShaper.changeTo).toHaveBeenCalledWith({
|
||||
actions: {
|
||||
reset: true,
|
||||
mousedown: jasmine.any(Function),
|
||||
mouseup: jasmine.any(Function)
|
||||
}
|
||||
});
|
||||
|
||||
expect(edgeShaper.changeTo).toHaveBeenCalledWith({
|
||||
actions: {
|
||||
reset: true
|
||||
}
|
||||
});
|
||||
|
||||
expect(mousePointerbox.className).toEqual("mousepointer icon-resize-horizontal");
|
||||
|
||||
helper.simulateMouseEvent("mousedown", "2");
|
||||
|
||||
helper.simulateMouseEvent("mouseup", "1");
|
||||
|
||||
expect(adapter.createEdge).toHaveBeenCalledWith(
|
||||
{source: nodes[1], target: nodes[0]},
|
||||
jasmine.any(Function)
|
||||
expect(edgeShaper.addAnEdgeFollowingTheCursor).toHaveBeenCalledWith(
|
||||
0, 0
|
||||
);
|
||||
});
|
||||
|
||||
it('the cursor-line should follow the cursor on mousemove over svg', function() {
|
||||
dispatcherUI.addControlConnect();
|
||||
helper.simulateMouseEvent("click", "control_event_connect");
|
||||
helper.simulateMouseEvent("mousedown", "2");
|
||||
|
||||
});
|
||||
helper.simulateMouseMoveEvent("svg", 40, 50);
|
||||
|
||||
var line = $("#connectionLine");
|
||||
expect(line.attr("x1")).toEqual(String(nodes[1].x));
|
||||
expect(line.attr("y1")).toEqual(String(nodes[1].y));
|
||||
expect(line.attr("x2")).toEqual("40");
|
||||
expect(line.attr("y2")).toEqual("50");
|
||||
});
|
||||
|
||||
it('the cursor-line should disappear on mouseup on svg', function() {
|
||||
spyOn(edgeShaper, "removeCursorFollowingEdge");
|
||||
dispatcherUI.addControlConnect();
|
||||
helper.simulateMouseEvent("click", "control_event_connect");
|
||||
helper.simulateMouseEvent("mousedown", "2");
|
||||
helper.simulateMouseEvent("mouseup", "1-2");
|
||||
expect(edgeShaper.removeCursorFollowingEdge).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('the cursor-line should disappear on mouseup on svg', function() {
|
||||
spyOn(edgeShaper, "removeCursorFollowingEdge");
|
||||
dispatcherUI.addControlConnect();
|
||||
helper.simulateMouseEvent("click", "control_event_connect");
|
||||
helper.simulateMouseEvent("mousedown", "2");
|
||||
helper.simulateMouseEvent("mouseup", "1");
|
||||
expect(edgeShaper.removeCursorFollowingEdge).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
it('should be able to add all controls to the list', function () {
|
||||
dispatcherUI.addAll();
|
||||
|
|
|
@ -111,6 +111,13 @@ function EventDispatcherControls(list, cursorIconBox, nodeShaper, edgeShaper, di
|
|||
return res;
|
||||
},
|
||||
|
||||
getCursorPositionInSVG = function (ev) {
|
||||
var pos = getCursorPosition(ev);
|
||||
pos.x -= $('svg').offset().left;
|
||||
pos.y -= $('svg').offset().top;
|
||||
return pos;
|
||||
},
|
||||
|
||||
moveCursorBox = function(ev) {
|
||||
var pos = getCursorPosition(ev);
|
||||
pos.x += 7;
|
||||
|
@ -217,14 +224,25 @@ function EventDispatcherControls(list, cursorIconBox, nodeShaper, edgeShaper, di
|
|||
callback = function() {
|
||||
setCursorIcon(icon);
|
||||
rebindNodes({
|
||||
mousedown: dispatcher.events.STARTCREATEEDGE(),
|
||||
mousedown: dispatcher.events.STARTCREATEEDGE(function(startNode, ev) {
|
||||
var pos = getCursorPositionInSVG(ev);
|
||||
var moveCB = edgeShaper.addAnEdgeFollowingTheCursor(pos.x, pos.y);
|
||||
dispatcher.bind("svg", "mousemove", function(ev) {
|
||||
var pos = getCursorPositionInSVG(ev);
|
||||
moveCB(pos.x, pos.y);
|
||||
});
|
||||
}),
|
||||
mouseup: dispatcher.events.FINISHCREATEEDGE(function(edge){
|
||||
edgeShaper.removeCursorFollowingEdge();
|
||||
dispatcher.bind("svg", "mousemove", function(){});
|
||||
})
|
||||
});
|
||||
rebindEdges();
|
||||
rebindSVG({
|
||||
mouseup: dispatcher.events.CANCELCREATEEDGE(),
|
||||
mouseout: dispatcher.events.CANCELCREATEEDGE()
|
||||
mouseup: function() {
|
||||
dispatcher.events.CANCELCREATEEDGE();
|
||||
edgeShaper.removeCursorFollowingEdge();
|
||||
}
|
||||
});
|
||||
};
|
||||
createIcon(icon, "connect", callback);
|
||||
|
|
Loading…
Reference in New Issue