mirror of
https://bitbucket.org/wisemapping/wisemapping-open-source.git
synced 2024-11-26 07:44:56 +01:00
More operations supported.
This commit is contained in:
parent
9c41f0719c
commit
c2748f67cf
@ -28,3 +28,5 @@ mindplot.collaboration = {};
|
||||
mindplot.collaboration.framework = {};
|
||||
mindplot.collaboration.framework.brix = {};
|
||||
mindplot.collaboration.framework.brix.model = {};
|
||||
|
||||
mindplot.nlayout = {};
|
||||
|
@ -3,21 +3,29 @@ mindplot.nlayout.ChildrenSorterStrategy = new Class({
|
||||
|
||||
},
|
||||
|
||||
predict:function(treeSet, parent, position) {
|
||||
throw "Method must be implemented";
|
||||
},
|
||||
|
||||
sorter: function(treeSet, parent, child, order) {
|
||||
throw "Method must be implemented";
|
||||
},
|
||||
|
||||
computeChildrenIdByHeights: function(treeSet, node) {
|
||||
throw "Method must be implemented";
|
||||
},
|
||||
|
||||
computeOffsets:function(treeSet, node) {
|
||||
throw "Method must be implemented";
|
||||
},
|
||||
|
||||
insert: function(treeSet, parent, child, order) {
|
||||
throw "Method must be implemented";
|
||||
},
|
||||
|
||||
detach:function(treeSet, node) {
|
||||
throw "Method must be implemented";
|
||||
},
|
||||
|
||||
predict:function(treeSet, parent, position) {
|
||||
throw "Method must be implemented";
|
||||
},
|
||||
|
||||
verify:function(treeSet, node) {
|
||||
throw "Method must be implemented";
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
@ -15,10 +15,11 @@ mindplot.nlayout.LayoutManager = new Class({
|
||||
updateNodeSize: function(id, size) {
|
||||
var node = this._treeSet.find(id);
|
||||
node.setSize(size);
|
||||
// @Todo: finish...
|
||||
},
|
||||
|
||||
updateShirkState: function(id, isShrink) {
|
||||
|
||||
// @Todo: finish...
|
||||
},
|
||||
|
||||
connectNode: function(parentId, childId, order) {
|
||||
@ -29,12 +30,9 @@ mindplot.nlayout.LayoutManager = new Class({
|
||||
this._layout.connectNode(parentId, childId, order);
|
||||
},
|
||||
|
||||
disconnectNode: function(sourceId) {
|
||||
|
||||
},
|
||||
|
||||
deleteNode : function(id) {
|
||||
|
||||
disconnectNode: function(id) {
|
||||
$assert($defined(id), "id can not be null");
|
||||
this._layout.disconnectNode(id);
|
||||
},
|
||||
|
||||
addNode:function(id, size, position) {
|
||||
@ -43,6 +41,20 @@ mindplot.nlayout.LayoutManager = new Class({
|
||||
this._treeSet.add(result);
|
||||
},
|
||||
|
||||
removeNode: function(id) {
|
||||
$assert($defined(id), "id can not be null");
|
||||
var node = this._treeSet.find(id);
|
||||
|
||||
// Is It connected ?
|
||||
if (this._treeSet.getParent(node)) {
|
||||
this.disconnectNode(id);
|
||||
}
|
||||
|
||||
// Remove the all the branch ...
|
||||
this._treeSet.remove(id);
|
||||
|
||||
},
|
||||
|
||||
predict: function(parentId, childId, position) {
|
||||
$assert($defined(parentId), "parentId can not be null");
|
||||
$assert($defined(childId), "childId can not be null");
|
||||
@ -50,7 +62,7 @@ mindplot.nlayout.LayoutManager = new Class({
|
||||
|
||||
var parent = this._treeSet.find(parentId);
|
||||
var sorter = parent.getSorter();
|
||||
var result = sorter.predict(parent, this._treeSet, position);
|
||||
return sorter.predict(parent, this._treeSet, position);
|
||||
},
|
||||
|
||||
dump: function() {
|
||||
@ -64,13 +76,12 @@ mindplot.nlayout.LayoutManager = new Class({
|
||||
// Collect changes ...
|
||||
this._collectChanges();
|
||||
|
||||
if (fireEvents) {
|
||||
this.flushEvents();
|
||||
if (!$(fireEvents) || fireEvents) {
|
||||
this._flushEvents();
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
flushEvents: function() {
|
||||
_flushEvents: function() {
|
||||
this._events.forEach(function(event) {
|
||||
this.fireEvent('change', event);
|
||||
}, this);
|
||||
|
@ -1,6 +1,6 @@
|
||||
mindplot.nlayout.Node = new Class({
|
||||
initialize:function(id, size, position, sorter) {
|
||||
$assert(!isNaN(id), "id can not be null");
|
||||
$assert(typeof id === 'number' && isFinite(id), "id can not be null");
|
||||
$assert(size, "size can not be null");
|
||||
$assert(position, "position can not be null");
|
||||
$assert(sorter, "sorter can not be null");
|
||||
@ -18,7 +18,7 @@ mindplot.nlayout.Node = new Class({
|
||||
},
|
||||
|
||||
setOrder: function(order) {
|
||||
$assert(!isNaN(order), "Order can not be null");
|
||||
$assert(typeof order === 'number' && isFinite(order), "Order can not be null. Value:" + order);
|
||||
this._setProperty('order', order, false);
|
||||
},
|
||||
|
||||
@ -64,8 +64,8 @@ mindplot.nlayout.Node = new Class({
|
||||
|
||||
setPosition : function(position) {
|
||||
$assert($defined(position), "Position can not be null");
|
||||
$assert(!isNaN(position.x), "x can not be null");
|
||||
$assert(!isNaN(position.y), "y can not be null");
|
||||
$assert($defined(position.x), "x can not be null");
|
||||
$assert($defined(position.y), "y can not be null");
|
||||
|
||||
this._setProperty('position', Object.clone(position));
|
||||
},
|
||||
@ -110,7 +110,7 @@ mindplot.nlayout.Node = new Class({
|
||||
|
||||
|
||||
toString: function() {
|
||||
return "[order:" + this.getOrder() + ", position: {" + this.getPosition().x + "," + this.getPosition().y + "}]";
|
||||
return "[id:" + this.getId() + ", order:" + this.getOrder() + ", position: {" + this.getPosition().x + "," + this.getPosition().y + "}]";
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -1,8 +1,6 @@
|
||||
mindplot.nlayout.OriginalLayout = new Class({
|
||||
initialize: function(treeSet) {
|
||||
this._treeSet = treeSet;
|
||||
|
||||
this._heightByNode = {};
|
||||
},
|
||||
|
||||
createNode:function(id, size, position, type) {
|
||||
@ -20,17 +18,33 @@ mindplot.nlayout.OriginalLayout = new Class({
|
||||
var parent = this._treeSet.find(parentId);
|
||||
var child = this._treeSet.find(childId);
|
||||
|
||||
// Connect the new node ...
|
||||
this._treeSet.connect(parentId, childId);
|
||||
|
||||
// Insert the new node ...
|
||||
var sorter = parent.getSorter();
|
||||
sorter.insert(this._treeSet, parent, child, order);
|
||||
|
||||
// Connect the new node ...
|
||||
this._treeSet.connect(parentId, childId);
|
||||
|
||||
// Fire a basic validation ...
|
||||
sorter.verify(this._treeSet, parent);
|
||||
},
|
||||
|
||||
disconnectNode: function(nodeId) {
|
||||
var node = this._treeSet.find(nodeId);
|
||||
$assert(this._treeSet.getParent(node),"Node already disconnected");
|
||||
|
||||
// Remove from children list.
|
||||
var sorter = node.getSorter();
|
||||
sorter.detach(this._treeSet, node);
|
||||
|
||||
// Disconnect the new node ...
|
||||
this._treeSet.disconnect(nodeId);
|
||||
|
||||
// Fire a basic validation ...
|
||||
sorter.verify(this._treeSet, node);
|
||||
|
||||
},
|
||||
|
||||
layout: function() {
|
||||
var roots = this._treeSet.getTreeRoots();
|
||||
roots.forEach(function(node) {
|
||||
@ -42,12 +56,7 @@ mindplot.nlayout.OriginalLayout = new Class({
|
||||
var heightById = sorter.computeChildrenIdByHeights(this._treeSet, node);
|
||||
|
||||
this._layoutChildren(node, heightById);
|
||||
}.bind(this));
|
||||
|
||||
// Finally, return the list of nodes and properties that has been changed during the layout ...
|
||||
|
||||
|
||||
|
||||
}, this);
|
||||
},
|
||||
|
||||
_layoutChildren: function(node, heightById) {
|
||||
@ -57,11 +66,11 @@ mindplot.nlayout.OriginalLayout = new Class({
|
||||
var childrenOrderMoved = children.some(function(child) {
|
||||
return child.hasOrderChanged();
|
||||
});
|
||||
var heightChanged = this._heightByNode[nodeId] != heightById[nodeId];
|
||||
throw "Esto no esta bien:"+ this._heightByNode;
|
||||
|
||||
// If ether any of the nodes has been changed of position or the height of the children is not
|
||||
// the same, children nodes must be repositioned ....
|
||||
var newBranchHeight = heightById[nodeId];
|
||||
var heightChanged = node._branchHeight != newBranchHeight;
|
||||
if (childrenOrderMoved || heightChanged) {
|
||||
|
||||
var sorter = node.getSorter();
|
||||
@ -73,12 +82,14 @@ mindplot.nlayout.OriginalLayout = new Class({
|
||||
var newPos = {x:parentPosition.x + offset.x,y:parentPosition.y + offset.y};
|
||||
this._treeSet.updateBranchPosition(child, newPos);
|
||||
}.bind(this));
|
||||
|
||||
node._branchHeight = newBranchHeight;
|
||||
}
|
||||
|
||||
// Continue reordering the children nodes ...
|
||||
children.forEach(function(child) {
|
||||
this._layoutChildren(child, heightById);
|
||||
}.bind(this));
|
||||
}, this);
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -23,31 +23,32 @@ mindplot.nlayout.RootedTreeSet = new Class({
|
||||
this._rootNodes.push(this._decodate(node));
|
||||
},
|
||||
|
||||
remove: function(node) {
|
||||
throw "Must be implemted";
|
||||
remove: function(nodeId) {
|
||||
$assert($defined(nodeId), 'nodeId can not be null');
|
||||
var node = this.find(nodeId);
|
||||
this._rootNodes.erase(node);
|
||||
},
|
||||
|
||||
connect: function(parentId, childId) {
|
||||
$assert($defined(parentId), 'parent can not be null');
|
||||
$assert($defined(childId), 'child can not be null');
|
||||
|
||||
var parent = this.find(parentId, true);
|
||||
var parent = this.find(parentId);
|
||||
var child = this.find(childId, true);
|
||||
$assert(!child._parent, 'node already connected. Id:' + child.getId() + ",previous:" + child._parent);
|
||||
|
||||
|
||||
parent._children.push(child);
|
||||
child._parent = parent;
|
||||
this._rootNodes.erase(child);
|
||||
},
|
||||
|
||||
disconnect: function(nodeId) {
|
||||
$assert(node, 'node can not be null');
|
||||
$assert(node._parent, 'child node not connected connected');
|
||||
$assert($defined(nodeId), 'nodeId can not be null');
|
||||
var node = this.find(nodeId);
|
||||
$assert(node._parent, "Node is not connected");
|
||||
|
||||
node._parent._children.erase(node);
|
||||
this._isolated.push(node);
|
||||
|
||||
this._rootNodes.push(node);
|
||||
node._parent = null;
|
||||
},
|
||||
|
||||
@ -63,7 +64,7 @@ mindplot.nlayout.RootedTreeSet = new Class({
|
||||
break;
|
||||
}
|
||||
}
|
||||
$assert(validate ? result : true, 'node could not be found id:' + id);
|
||||
$assert($defined(validate) ? result : true, 'node could not be found id:' + id);
|
||||
return result;
|
||||
|
||||
},
|
||||
@ -91,6 +92,11 @@ mindplot.nlayout.RootedTreeSet = new Class({
|
||||
return node._children;
|
||||
},
|
||||
|
||||
getParent:function(node) {
|
||||
$assert(node, 'node can not be null');
|
||||
return node._parent;
|
||||
},
|
||||
|
||||
dump: function() {
|
||||
var branches = this._rootNodes;
|
||||
var result = "";
|
||||
|
@ -65,28 +65,42 @@ mindplot.nlayout.SymetricSorder = new Class({
|
||||
},
|
||||
|
||||
insert: function(treeSet, parent, child, order) {
|
||||
var children = treeSet.getChildren(parent);
|
||||
var children = this._getSortedChildren(treeSet, parent);
|
||||
$assert(order <= children.length, "Order must be continues and can not have holes. Order:" + order);
|
||||
|
||||
// Sort array list ..
|
||||
children.sort(function(a, b) {
|
||||
return a.getOrder() - b.getOrder()
|
||||
});
|
||||
|
||||
// Shift all the elements in one .
|
||||
for (var i = order; i < children.length; i++) {
|
||||
var node = children[i];
|
||||
node.setOrder(node.getOrder() + 1);
|
||||
node.setOrder(i + 1);
|
||||
}
|
||||
child.setOrder(order);
|
||||
},
|
||||
|
||||
verify:function(treeSet, node) {
|
||||
// Check that all is consistent ...
|
||||
var children = treeSet.getChildren(node);
|
||||
children.sort(function(a, b) {
|
||||
detach:function(treeSet, node) {
|
||||
var parent = treeSet.getParent(node);
|
||||
var children = this._getSortedChildren(treeSet, parent);
|
||||
var order = node.getOrder();
|
||||
$assert(children[order] === node, "Node seems not to be in the right position");
|
||||
|
||||
// Shift all the nodes ...
|
||||
for (var i = node.getOrder() + 1; i < children.length; i++) {
|
||||
var child = children[i];
|
||||
child.setOrder(child.getOrder() - 1);
|
||||
}
|
||||
node.setOrder(0);
|
||||
},
|
||||
|
||||
_getSortedChildren:function(treeSet, node) {
|
||||
var result = treeSet.getChildren(node);
|
||||
result.sort(function(a, b) {
|
||||
return a.getOrder() - b.getOrder()
|
||||
});
|
||||
return result;
|
||||
},
|
||||
|
||||
verify:function(treeSet, node) {
|
||||
// Check that all is consistent ...
|
||||
var children = this._getSortedChildren(treeSet, node);
|
||||
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
$assert(children[i].getOrder() == i, "missing order elements");
|
||||
@ -98,10 +112,7 @@ mindplot.nlayout.SymetricSorder = new Class({
|
||||
$assert(node, "node can no be null.");
|
||||
$assert("order can no be null.");
|
||||
|
||||
var children = treeSet.getChildren(node);
|
||||
children.sort(function(a, b) {
|
||||
return a.getOrder() - b.getOrder()
|
||||
});
|
||||
var children = this._getSortedChildren(treeSet, node);
|
||||
|
||||
// Compute heights ...
|
||||
var heights = children.map(function(child) {
|
||||
|
@ -2,10 +2,11 @@ mindplot.nlayout.TestSuite = new Class({
|
||||
Extends: mindplot.nlayout.ChildrenSorterStrategy,
|
||||
initialize:function() {
|
||||
|
||||
// this.testAligned();
|
||||
this.testAligned();
|
||||
this.testEvents();
|
||||
|
||||
// @ Agregar tests que garantice que no se reposicional cosan inecesariamente 2 veces...
|
||||
this.testEventsComplex();
|
||||
this.testDisconnect();
|
||||
this.testRemoveNode();
|
||||
},
|
||||
|
||||
testAligned: function() {
|
||||
@ -37,26 +38,15 @@ mindplot.nlayout.TestSuite = new Class({
|
||||
manager.connectNode(0, 2, 0);
|
||||
manager.connectNode(1, 3, 0);
|
||||
|
||||
// Reposition ...
|
||||
manager.layout();
|
||||
console.log("Updated tree:");
|
||||
manager.dump();
|
||||
|
||||
// Listen for changes ...
|
||||
console.log("Updated nodes ...");
|
||||
// Basic layout repositioning ...
|
||||
console.log("-- Updated tree ---");
|
||||
var events = [];
|
||||
manager.addEvent('change', function(event) {
|
||||
console.log("Updated nodes: {id:" + event.getId() + ", order: " + event.getOrder() + ",position: {" + event.getPosition().x + "," + event.getPosition().y + "}");
|
||||
events.push(event);
|
||||
});
|
||||
manager.flushEvents();
|
||||
|
||||
// Second flush must not fire events ...
|
||||
console.log("---- Test Flush ---");
|
||||
|
||||
events.empty();
|
||||
manager.flushEvents();
|
||||
$assert(events.length == 0, "Event should not be fire twice.");
|
||||
manager.layout(true);
|
||||
manager.dump();
|
||||
|
||||
// Ok, if a new node is added, this an event should be fired ...
|
||||
console.log("---- Layout without changes should not affect the tree ---");
|
||||
@ -64,7 +54,130 @@ mindplot.nlayout.TestSuite = new Class({
|
||||
manager.layout(true);
|
||||
|
||||
$assert(events.length == 0, "Unnecessary tree updated.");
|
||||
},
|
||||
|
||||
testEventsComplex: function() {
|
||||
var size = {width:10,height:10};
|
||||
var position = {x:0,y:0};
|
||||
var manager = new mindplot.nlayout.LayoutManager(0, size);
|
||||
|
||||
// Add 3 nodes...
|
||||
manager.addNode(1, size, position);
|
||||
manager.addNode(2, size, position);
|
||||
manager.addNode(3, size, position);
|
||||
manager.addNode(4, size, position);
|
||||
|
||||
// Now connect one with two....
|
||||
manager.connectNode(0, 1, 0);
|
||||
manager.connectNode(1, 2, 0);
|
||||
manager.connectNode(1, 3, 1);
|
||||
|
||||
var events = [];
|
||||
manager.addEvent('change', function(event) {
|
||||
console.log("Updated nodes: {id:" + event.getId() + ", order: " + event.getOrder() + ",position: {" + event.getPosition().x + "," + event.getPosition().y + "}");
|
||||
events.push(event);
|
||||
});
|
||||
|
||||
// Reposition ...
|
||||
manager.layout(true);
|
||||
manager.dump();
|
||||
|
||||
// Add a new node and connect. Only children nodes should be affected.
|
||||
console.log("---- Connect a new node ---");
|
||||
|
||||
events.empty();
|
||||
manager.connectNode(1, 4, 2);
|
||||
manager.layout(true);
|
||||
manager.dump();
|
||||
|
||||
// @todo: This seems no to be ok...
|
||||
$assert(events.length == 4, "Only 3 nodes should be repositioned.");
|
||||
},
|
||||
|
||||
testDisconnect: function() {
|
||||
var size = {width:10,height:10};
|
||||
var position = {x:0,y:0};
|
||||
var manager = new mindplot.nlayout.LayoutManager(0, size);
|
||||
|
||||
// Prepare a sample graph ...
|
||||
manager.addNode(1, size, position);
|
||||
manager.addNode(2, size, position);
|
||||
manager.addNode(3, size, position);
|
||||
manager.addNode(4, size, position);
|
||||
|
||||
manager.connectNode(0, 1, 0);
|
||||
manager.connectNode(1, 2, 0);
|
||||
manager.connectNode(1, 3, 1);
|
||||
manager.connectNode(3, 4, 0);
|
||||
|
||||
var events = [];
|
||||
manager.addEvent('change', function(event) {
|
||||
var pos = event.getPosition();
|
||||
var posStr = pos ? ",position: {" + pos.x + "," + event.getPosition().y : "";
|
||||
console.log("Updated nodes: {id:" + event.getId() + ", order: " + event.getOrder() + posStr + "}");
|
||||
events.push(event);
|
||||
});
|
||||
|
||||
manager.layout(true);
|
||||
manager.dump();
|
||||
|
||||
// Now, disconnect one node ...
|
||||
console.log("--- Disconnect a single node ---");
|
||||
events.empty();
|
||||
manager.disconnectNode(2);
|
||||
manager.layout(true);
|
||||
manager.dump();
|
||||
|
||||
$assert(events.some(
|
||||
function(event) {
|
||||
return event.getId() == 2;
|
||||
}), "Event for disconnected node seems not to be propagated");
|
||||
|
||||
// Great, let's disconnect a not with children.
|
||||
console.log("--- Disconnect a node with children ---");
|
||||
manager.disconnectNode(3);
|
||||
manager.layout(true);
|
||||
manager.dump();
|
||||
|
||||
$assert(events.some(
|
||||
function(event) {
|
||||
return event.getId() == 2;
|
||||
}), "Event for disconnected node seems not to be propagated");
|
||||
},
|
||||
|
||||
testRemoveNode: function() {
|
||||
var size = {width:10,height:10};
|
||||
var position = {x:0,y:0};
|
||||
var manager = new mindplot.nlayout.LayoutManager(0, size);
|
||||
|
||||
// Prepare a sample graph ...
|
||||
manager.addNode(1, size, position);
|
||||
manager.addNode(2, size, position);
|
||||
manager.addNode(3, size, position);
|
||||
manager.addNode(4, size, position);
|
||||
|
||||
manager.connectNode(0, 1, 0);
|
||||
manager.connectNode(1, 2, 0);
|
||||
manager.connectNode(1, 3, 1);
|
||||
manager.connectNode(3, 4, 0);
|
||||
|
||||
var events = [];
|
||||
manager.addEvent('change', function(event) {
|
||||
var pos = event.getPosition();
|
||||
var posStr = pos ? ",position: {" + pos.x + "," + event.getPosition().y : "";
|
||||
console.log("Updated nodes: {id:" + event.getId() + ", order: " + event.getOrder() + posStr + "}");
|
||||
events.push(event);
|
||||
});
|
||||
manager.layout(true);
|
||||
manager.dump();
|
||||
|
||||
// Test removal of a connected node ...
|
||||
console.log("--- Remove node 3 ---");
|
||||
manager.removeNode(3);
|
||||
manager.layout(true);
|
||||
manager.dump();
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user