1
0
Fork 0

conflict resolution

This commit is contained in:
Thomas Richter 2013-06-03 15:12:35 +02:00
commit d54ba9ea76
12 changed files with 290 additions and 75 deletions

View File

@ -28,9 +28,8 @@
}
svg.graphViewer text {
font: 11px Arial;
font: 12px Arial;
pointer-events: none;
stroke: #000;
}
.capitalize {

View File

@ -1,5 +1,5 @@
/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true */
/*global _, $, window*/
/*global _, $, window, d3*/
/*global EventLibrary*/
////////////////////////////////////////////////////////////////////////////////
/// @brief Graph functionality

View File

@ -67,6 +67,24 @@ function NodeShaper(parent, flags, idfunc) {
communityRegEx = /^\*community/,
nodes = [],
visibleLabels = true,
splitLabel = function(label) {
if (label === undefined) {
return [""];
}
if (typeof label !== "string") {
label = String(label);
}
var chunks = label.match(/[\w\W]{1,10}(\s|$)|\S+?(\s|$)/g);
chunks[0] = $.trim(chunks[0]);
chunks[1] = $.trim(chunks[1]);
if (chunks.length > 2) {
chunks.length = 2;
chunks[1] += "...";
}
return chunks;
},
noop = function (node) {
},
@ -195,7 +213,7 @@ function NodeShaper(parent, flags, idfunc) {
},
parseShapeFlag = function (shape) {
var radius, width, height;
var radius, width, height, translateX, translateY;
switch (shape.type) {
case NodeShaper.shapes.NONE:
addShape = noop;
@ -209,12 +227,28 @@ function NodeShaper(parent, flags, idfunc) {
};
break;
case NodeShaper.shapes.RECT:
width = shape.width || 20;
height = shape.height || 10;
width = shape.width || 120;
height = shape.height || 24;
if (_.isFunction(width)) {
translateX = function(d) {
return -(width(d) / 2);
};
} else {
translateX = -(width / 2);
}
if (_.isFunction(height)) {
translateY = function(d) {
return -(height(d) / 2);
};
} else {
translateY = -(height / 2);
}
addShape = function(node) {
node.append("rect") // Display nodes as rectangles
.attr("width", width) // Set width
.attr("height", height); // Set height
.attr("height", height) // Set height
.attr("x", translateX)
.attr("y", translateY);
};
break;
case undefined:
@ -227,19 +261,43 @@ function NodeShaper(parent, flags, idfunc) {
parseLabelFlag = function (label) {
if (_.isFunction(label)) {
addLabel = function (node) {
node.append("text") // Append a label for the node
var textN = node.append("text") // Append a label for the node
.attr("text-anchor", "middle") // Define text-anchor
.attr("stroke", "black") // Foce a black color20*75)
.text(label);
.attr("fill", "black") // Force a black color
.attr("stroke", "none"); // Make it readable
textN.each(function(d) {
var chunks = splitLabel(label(d));
d3.select(this).append("tspan")
.attr("x", "0")
.attr("dy", "0")
.text(chunks[0]);
if (chunks.length === 2) {
d3.select(this).append("tspan")
.attr("x", "0")
.attr("dy", "20")
.text(chunks[1]);
}
});
};
} else {
addLabel = function (node) {
node.append("text") // Append a label for the node
var textN = node.append("text") // Append a label for the node
.attr("text-anchor", "middle") // Define text-anchor
.attr("stroke", "black") // Foce a black color20*75)
.text(function(d) {
return d._data[label] !== undefined ? d._data[label] : "";
});
.attr("fill", "black") // Force a black color
.attr("stroke", "none"); // Make it readable
textN.each(function(d) {
var chunks = splitLabel(d._data[label]);
d3.select(this).append("tspan")
.attr("x", "0")
.attr("dy", "0")
.text(chunks[0]);
if (chunks.length === 2) {
d3.select(this).append("tspan")
.attr("x", "0")
.attr("dy", "20")
.text(chunks[1]);
}
});
};
}
},
@ -282,9 +340,15 @@ function NodeShaper(parent, flags, idfunc) {
case "attribute":
addColor = function (g) {
g.attr("fill", function(n) {
if (n._data === undefined) {
return colourMapper.getColour(undefined);
}
return colourMapper.getColour(n._data[color.key]);
});
g.attr("stroke", function(n) {
if (n._data === undefined) {
return colourMapper.getColour(undefined);
}
return colourMapper.getColour(n._data[color.key]);
});
};
@ -339,7 +403,7 @@ function NodeShaper(parent, flags, idfunc) {
if (flags.shape === undefined) {
flags.shape = {
type: NodeShaper.shapes.CIRCLE
type: NodeShaper.shapes.RECT
};
}

View File

@ -291,8 +291,6 @@
expect(adapter.patchEdge).toHaveBeenCalledWith(
edges[0],
{
_from: "1",
_to: "2",
label: "newLabel"
},
jasmine.any(Function));
@ -425,22 +423,27 @@
helper.simulateMouseEvent("mousedown", "2");
expect(edgeShaper.addAnEdgeFollowingTheCursor).toHaveBeenCalledWith(
0, 0
-$("svg").offset().left, -$("svg").offset().top
);
});
it('the cursor-line should follow the cursor on mousemove over svg', function() {
dispatcherUI.addControlConnect();
var x = 40,
y= 50,
line;
helper.simulateMouseEvent("click", "control_event_connect");
helper.simulateMouseEvent("mousedown", "2");
helper.simulateMouseMoveEvent("svg", 40, 50);
helper.simulateMouseMoveEvent("svg", x, y);
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");
line = $("#connectionLine");
//The Helper event triggers at (0,0) no matter where the node is.
expect(line.attr("x1")).toEqual(String(- $("svg").offset().left));
expect(line.attr("y1")).toEqual(String(- $("svg").offset().top));
expect(line.attr("x2")).toEqual(String(x - $("svg").offset().left));
expect(line.attr("y2")).toEqual(String(y - $("svg").offset().top));
});
it('the cursor-line should disappear on mouseup on svg', function() {

View File

@ -315,7 +315,7 @@
expect($(menuSelector)[0]).toBeADropdownMenu();
expect($("> button", menuSelector).text()).toEqual("Configure ");
expect($(menuSelector + " #control_adapter_collections").length).toEqual(1);
expect($(menuSelector + " #control_node_label").length).toEqual(1);
expect($(menuSelector + " #control_node_labelandcolour").length).toEqual(1);
});
it('should have the same layout as the web interface', function() {

View File

@ -117,18 +117,19 @@
expect(clicked[2]).toBeUndefined();
});
it('should display circles by default', function() {
it('should have correct default values', function() {
var node = [{_id: 1}],
shaper = new NodeShaper(d3.select("svg"));
shaper.drawNodes(node);
expect($("svg .node")[0]).toBeDefined();
expect($("svg .node").length).toEqual(1);
expect($("svg #1")[0]).toBeDefined();
expect($("svg circle")[0]).toBeDefined();
expect($("svg circle").length).toEqual(1);
expect($("svg .node circle")[0]).toBeDefined();
expect($("svg .node circle").length).toEqual(1);
expect($("svg #1 circle")[0].attributes.r.value).toEqual("25");
expect($("svg rect")[0]).toBeDefined();
expect($("svg rect").length).toEqual(1);
expect($("svg .node rect")[0]).toBeDefined();
expect($("svg .node rect").length).toEqual(1);
expect($("svg #1 rect").attr("width")).toEqual("120");
expect($("svg #1 rect").attr("height")).toEqual("24");
});
describe('testing for colours', function() {
@ -310,8 +311,8 @@
});
it('should be able to change display formats', function() {
expect($("svg circle").length).toEqual(3);
expect($("svg rect").length).toEqual(0);
expect($("svg circle").length).toEqual(0);
expect($("svg rect").length).toEqual(3);
shaper.changeTo({shape: {type: NodeShaper.shapes.NONE}});
expect($("svg circle").length).toEqual(0);
expect($("svg rect").length).toEqual(0);
@ -321,6 +322,9 @@
shaper.changeTo({shape: {type: NodeShaper.shapes.NONE}});
expect($("svg circle").length).toEqual(0);
expect($("svg rect").length).toEqual(0);
shaper.changeTo({shape: {type: NodeShaper.shapes.CIRCLE}});
expect($("svg circle").length).toEqual(3);
expect($("svg rect").length).toEqual(0);
});
it('should be able to add a click event to existing nodes', function() {
@ -550,33 +554,48 @@
});
it('should be able to use a fixed size', function() {
shaper = new NodeShaper(d3.select("svg"),
{
shape: {
type: NodeShaper.shapes.RECT,
width: 15,
height: 10
}
});
var nodes = [
{_id: 1},
{_id: 2},
{_id: 3},
{_id: 4},
{_id: 5}
];
shaper.drawNodes(nodes);
expect($("svg #1 rect")[0].attributes.width.value).toEqual("15");
expect($("svg #2 rect")[0].attributes.width.value).toEqual("15");
expect($("svg #3 rect")[0].attributes.width.value).toEqual("15");
expect($("svg #4 rect")[0].attributes.width.value).toEqual("15");
expect($("svg #5 rect")[0].attributes.width.value).toEqual("15");
],
width = 15,
height = 10;
shaper = new NodeShaper(d3.select("svg"),
{
shape: {
type: NodeShaper.shapes.RECT,
width: width,
height: height
}
});
expect($("svg #1 rect")[0].attributes.height.value).toEqual("10");
expect($("svg #2 rect")[0].attributes.height.value).toEqual("10");
expect($("svg #3 rect")[0].attributes.height.value).toEqual("10");
expect($("svg #4 rect")[0].attributes.height.value).toEqual("10");
expect($("svg #5 rect")[0].attributes.height.value).toEqual("10");
shaper.drawNodes(nodes);
expect($("svg #1 rect").attr("width")).toEqual(String(width));
expect($("svg #2 rect").attr("width")).toEqual(String(width));
expect($("svg #3 rect").attr("width")).toEqual(String(width));
expect($("svg #4 rect").attr("width")).toEqual(String(width));
expect($("svg #5 rect").attr("width")).toEqual(String(width));
expect($("svg #1 rect").attr("x")).toEqual(String(-(width / 2)));
expect($("svg #2 rect").attr("x")).toEqual(String(-(width / 2)));
expect($("svg #3 rect").attr("x")).toEqual(String(-(width / 2)));
expect($("svg #4 rect").attr("x")).toEqual(String(-(width / 2)));
expect($("svg #5 rect").attr("x")).toEqual(String(-(width / 2)));
expect($("svg #1 rect").attr("height")).toEqual(String(height));
expect($("svg #2 rect").attr("height")).toEqual(String(height));
expect($("svg #3 rect").attr("height")).toEqual(String(height));
expect($("svg #4 rect").attr("height")).toEqual(String(height));
expect($("svg #5 rect").attr("height")).toEqual(String(height));
expect($("svg #1 rect").attr("y")).toEqual(String(-(height / 2)));
expect($("svg #2 rect").attr("y")).toEqual(String(-(height / 2)));
expect($("svg #3 rect").attr("y")).toEqual(String(-(height / 2)));
expect($("svg #4 rect").attr("y")).toEqual(String(-(height / 2)));
expect($("svg #5 rect").attr("y")).toEqual(String(-(height / 2)));
});
@ -604,19 +623,33 @@
});
shaper.drawNodes(nodes);
expect($("svg #1 rect")[0].attributes.width.value).toEqual("11");
expect($("svg #2 rect")[0].attributes.width.value).toEqual("12");
expect($("svg #3 rect")[0].attributes.width.value).toEqual("13");
expect($("svg #4 rect")[0].attributes.width.value).toEqual("14");
expect($("svg #5 rect")[0].attributes.width.value).toEqual("15");
expect($("svg #1 rect").attr("width")).toEqual("11");
expect($("svg #2 rect").attr("width")).toEqual("12");
expect($("svg #3 rect").attr("width")).toEqual("13");
expect($("svg #4 rect").attr("width")).toEqual("14");
expect($("svg #5 rect").attr("width")).toEqual("15");
expect($("svg #1 rect")[0].attributes.height.value).toEqual("9");
expect($("svg #2 rect")[0].attributes.height.value).toEqual("8");
expect($("svg #3 rect")[0].attributes.height.value).toEqual("7");
expect($("svg #4 rect")[0].attributes.height.value).toEqual("6");
expect($("svg #5 rect")[0].attributes.height.value).toEqual("5");
expect($("svg #1 rect").attr("x")).toEqual(String(-(11 / 2)));
expect($("svg #2 rect").attr("x")).toEqual(String(-(12 / 2)));
expect($("svg #3 rect").attr("x")).toEqual(String(-(13 / 2)));
expect($("svg #4 rect").attr("x")).toEqual(String(-(14 / 2)));
expect($("svg #5 rect").attr("x")).toEqual(String(-(15 / 2)));
expect($("svg #1 rect").attr("height")).toEqual("9");
expect($("svg #2 rect").attr("height")).toEqual("8");
expect($("svg #3 rect").attr("height")).toEqual("7");
expect($("svg #4 rect").attr("height")).toEqual("6");
expect($("svg #5 rect").attr("height")).toEqual("5");
expect($("svg #1 rect").attr("y")).toEqual(String(-(9 / 2)));
expect($("svg #2 rect").attr("y")).toEqual(String(-(8 / 2)));
expect($("svg #3 rect").attr("y")).toEqual(String(-(7 / 2)));
expect($("svg #4 rect").attr("y")).toEqual(String(-(6 / 2)));
expect($("svg #5 rect").attr("y")).toEqual(String(-(5 / 2)));
});
});
describe('configured for label', function () {
@ -646,6 +679,20 @@
expect($("svg .node text")[0].textContent).toEqual("MyLabel");
});
it('should set up the text element correctly', function() {
var node = [{
_id: 1,
_data: {
"label": "MyLabel"
}
}],
textEl;
shaper.drawNodes(node);
textEl = $("svg .node text");
expect(textEl.attr("fill")).toEqual("black");
expect(textEl.attr("stroke")).toEqual("none");
});
it('should ignore other attributes', function () {
var nodes = [
{
@ -736,6 +783,45 @@
});
it('should automatically line-break long multi-word labels', function() {
var node = [{
_id: 1,
_data: {
label: "Label with many words"
}
}],
textEl,
spans;
shaper.drawNodes(node);
textEl = $("svg .node text");
spans = $("tspan", textEl);
expect($(spans.get(0)).text()).toEqual("Label with");
expect($(spans.get(0)).attr("x")).toEqual("0");
expect($(spans.get(0)).attr("dy")).toEqual("0");
expect($(spans.get(1)).text()).toEqual("many words");
expect($(spans.get(1)).attr("x")).toEqual("0");
expect($(spans.get(1)).attr("dy")).toEqual("20");
});
it('should automatically cut labels with more then 20 characters', function() {
var node = [{
_id: 1,
_data: {
label: "The quick brown foxx is jumping lazy over the fence"
}
}],
textEl,
spans;
shaper.drawNodes(node);
textEl = $("svg .node text");
spans = $("tspan", textEl);
expect($(spans.get(0)).text()).toEqual("The quick");
expect($(spans.get(1)).text()).toEqual("brown foxx...");
});
});
describe('using a function for labels', function () {

View File

@ -263,6 +263,33 @@
});
it('should be able to add a switch colour on attribute control to the list', function() {
runs(function() {
shaperUI.addControlOpticLabelAndColour();
expect($("#control_node_list #control_node_labelandcolour").length).toEqual(1);
expect($("#control_node_list #control_node_labelandcolour")[0]).toConformToListCSS();
helper.simulateMouseEvent("click", "control_node_labelandcolour");
$("#control_node_labelandcolour_key").attr("value", "label");
helper.simulateMouseEvent("click", "control_node_labelandcolour_submit");
expect(shaper.changeTo).toHaveBeenCalledWith({
label: "label",
color: {
type: "attribute",
key: "label"
}
});
});
waitsFor(function() {
return $("#control_node_attributecolour_modal").length === 0;
}, 2000, "The modal dialog should disappear.");
});
it('should be able to add all optic controls to the list', function () {
shaperUI.addAllOptics();

View File

@ -225,8 +225,8 @@ function EventDispatcherControls(list, cursorIconBox, nodeShaper, edgeShaper, di
setCursorIcon(icon);
rebindNodes({
mousedown: dispatcher.events.STARTCREATEEDGE(function(startNode, ev) {
var pos = getCursorPositionInSVG(ev);
var moveCB = edgeShaper.addAnEdgeFollowingTheCursor(pos.x, pos.y);
var pos = getCursorPositionInSVG(ev),
moveCB = edgeShaper.addAnEdgeFollowingTheCursor(pos.x, pos.y);
dispatcher.bind("svg", "mousemove", function(ev) {
var pos = getCursorPositionInSVG(ev);
moveCB(pos.x, pos.y);

View File

@ -231,7 +231,7 @@ function GraphViewerUI(container, adapterConfig, optWidth, optHeight, viewerConf
buttons.appendChild(configureDropDown);
adapterUI.addControlChangeCollections();
nodeShaperUI.addControlOpticLabel();
nodeShaperUI.addControlOpticLabelAndColour();
/*
buttons.appendChild(nodeShaperDropDown);

View File

@ -169,20 +169,26 @@ var modalDialogHelper = modalDialogHelper || {};
tableToJSON = function() {
var result = {};
_.each($("#" + idprefix + "table tr"), function(tr) {
var key = tr.children[0].children[0].value,
value = tr.children[1].children[0].value;
result[key] = value;
});
return result;
};
_.each(object, function(value, key) {
var tr = document.createElement("tr"),
keyTh = document.createElement("th"),
valueTh = document.createElement("th"),
keyInput,
valueInput;
var internalRegex = /^_(id|rev|key|from|to)/,
tr = document.createElement("tr"),
keyTh = document.createElement("th"),
valueTh = document.createElement("th"),
keyInput,
valueInput;
if (internalRegex.test(key)) {
return;
}
table.appendChild(tr);
tr.appendChild(keyTh);
keyTh.className = "collectionTh";

View File

@ -192,6 +192,36 @@ function NodeShaperControls(list, shaper) {
});
};
//////////////////////////////////////////////////////////////////
// Mixed Buttons
//////////////////////////////////////////////////////////////////
this.addControlOpticLabelAndColour = function() {
var prefix = "control_node_labelandcolour",
idprefix = prefix + "_";
uiComponentsHelper.createButton(baseClass, list, "Label", prefix, function() {
modalDialogHelper.createModalDialog("Switch Label Attribute",
idprefix, [{
type: "text",
id: "key"
}], function () {
var key = $("#" + idprefix + "key").attr("value");
shaper.changeTo({
label: key,
color: {
type: "attribute",
key: key
}
});
}
);
});
};
//////////////////////////////////////////////////////////////////
// Multiple Buttons
//////////////////////////////////////////////////////////////////
this.addAllOptics = function () {
self.addControlOpticShapeNone();
self.addControlOpticShapeCircle();

View File

@ -380,11 +380,11 @@ function get_graph_graph (req, res) {
/// @RESTRETURNCODES
///
/// @RESTRETURNCODE{200}
/// is returned if the graph was deleted sucessfully and `waitForSync` was
/// is returned if the graph was deleted and `waitForSync` was
/// `true`.
///
/// @RESTRETURNCODE{202}
/// is returned if the graph was deleted sucessfully and `waitForSync` was
/// is returned if the graph was deleted and `waitForSync` was
/// `false`.
///
/// @RESTRETURNCODE{404}