diff --git a/mindplot/src/main/javascript/layout/LayoutManager.js b/mindplot/src/main/javascript/layout/LayoutManager.js index a41b9d03..ea4d3565 100644 --- a/mindplot/src/main/javascript/layout/LayoutManager.js +++ b/mindplot/src/main/javascript/layout/LayoutManager.js @@ -102,11 +102,24 @@ mindplot.layout.LayoutManager = new Class({ return this; }, - predict: function(parentId, position) { + predict: function(parentId, position, free) { $assert($defined(parentId), "parentId can not be null"); - var parent = this._treeSet.find(parentId); var sorter = parent.getSorter(); + + if (free) { + $assert($defined(position), "position cannot be null for predict in free positioning"); + var rootNode = this._treeSet.getRootNode(parent); + var direction = parent.getPosition().x > rootNode.getPosition().x ? 1 : -1; + + var xPos = direction > 0 ? + (position.x >= parent.getPosition().x ? position.x : parent.getPosition().x) : + (position.x <= parent.getPosition().x ? position.x : parent.getPosition().x); + + return {order:0, position:{x: xPos, y:position.y}}; + } + + var result = sorter.predict(parent, this._treeSet, position); return {order:result[0],position:result[1]}; }, diff --git a/mindplot/src/main/javascript/layout/Node.js b/mindplot/src/main/javascript/layout/Node.js index 7032be3f..1a0225cd 100644 --- a/mindplot/src/main/javascript/layout/Node.js +++ b/mindplot/src/main/javascript/layout/Node.js @@ -94,10 +94,13 @@ mindplot.layout.Node = new Class({ }, hasPositionChanged: function() { - return this._isPropertyChanged('position'); }, + hasSizeChanged: function() { + return this._isPropertyChanged('size'); + }, + getPosition: function() { return this._getProperty('position'); }, diff --git a/mindplot/src/main/javascript/layout/OriginalLayout.js b/mindplot/src/main/javascript/layout/OriginalLayout.js index 17ccc17d..f627a5d4 100644 --- a/mindplot/src/main/javascript/layout/OriginalLayout.js +++ b/mindplot/src/main/javascript/layout/OriginalLayout.js @@ -53,6 +53,10 @@ mindplot.layout.OriginalLayout = new Class({ var parent = this._treeSet.getParent(node); $assert(parent, "Node already disconnected"); + // Make it fixed + node.setFree(false); + node.setFreeDisplacement({x:0, y:0}); + // Remove from children list. var sorter = parent.getSorter(); sorter.detach(this._treeSet, node); @@ -85,9 +89,7 @@ mindplot.layout.OriginalLayout = new Class({ var children = this._treeSet.getChildren(node); var parent = this._treeSet.getParent(node); var childrenOrderMoved = children.some(function(child) { return child.hasOrderChanged(); }); - - var childrenFreeChanged = children.some(function(child) { return child.hasFreeChanged(); }); - var freeChanged = node.hasFreeChanged() || childrenFreeChanged; + var childrenSizeChanged = children.some(function(child) { return child.hasSizeChanged(); }); // 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 .... @@ -97,7 +99,7 @@ mindplot.layout.OriginalLayout = new Class({ var heightChanged = node._branchHeight != newBranchHeight; node._heightChanged = heightChanged || parentHeightChanged; - if (childrenOrderMoved || heightChanged || parentHeightChanged) { + if (childrenOrderMoved || childrenSizeChanged || heightChanged || parentHeightChanged) { var sorter = node.getSorter(); var offsetById = sorter.computeOffsets(this._treeSet, node); var parentPosition = node.getPosition(); diff --git a/mindplot/src/test/javascript/static/TestSuite.js b/mindplot/src/test/javascript/static/TestSuite.js index f30a0142..9ac6c16b 100644 --- a/mindplot/src/test/javascript/static/TestSuite.js +++ b/mindplot/src/test/javascript/static/TestSuite.js @@ -19,18 +19,20 @@ mindplot.layout.TestSuite = new Class({ Extends: mindplot.layout.ChildrenSorterStrategy, initialize:function() { - this.testAligned(); - this.testSymmetry(); - this.testBalanced(); - this.testEvents(); - this.testEventsComplex(); - this.testDisconnect(); - this.testReconnect(); - this.testRemoveNode(); - this.testSymmetricPredict(); - this.testBalancedPredict(); - this.testSize(); - this.testFreePosition(); +// this.testAligned(); +// this.testSymmetry(); +// this.testBalanced(); +// this.testEvents(); +// this.testEventsComplex(); +// this.testDisconnect(); +// this.testReconnect(); +// this.testRemoveNode(); +// this.testSymmetricPredict(); +// this.testBalancedPredict(); +// this.testSize(); +// this.testFreePosition(); +// this.testFreePredict(); + this.testReconnectFreeNode(); }, testAligned: function() { @@ -734,6 +736,130 @@ mindplot.layout.TestSuite = new Class({ manager.connectNode(17,25,0); manager.layout(true); manager.plot("testFreePosition9", {width:1400, height:600}); + }, + + testFreePredict: function() { + console.log("testFreePredict:"); + var position = {x:0,y:0}; + var manager = new mindplot.layout.LayoutManager(0, mindplot.layout.TestSuite.ROOT_NODE_SIZE); + + // Prepare a sample graph ... + manager.addNode(1, mindplot.layout.TestSuite.NODE_SIZE, position); + manager.addNode(2, mindplot.layout.TestSuite.NODE_SIZE, position); + manager.addNode(3, mindplot.layout.TestSuite.NODE_SIZE, position); + manager.addNode(4, mindplot.layout.TestSuite.NODE_SIZE, position); + manager.addNode(5, mindplot.layout.TestSuite.NODE_SIZE, position); + manager.addNode(6, mindplot.layout.TestSuite.NODE_SIZE, position); + manager.addNode(7, mindplot.layout.TestSuite.NODE_SIZE, position); + manager.addNode(8, mindplot.layout.TestSuite.NODE_SIZE, position); + manager.addNode(9, mindplot.layout.TestSuite.NODE_SIZE, position); + manager.addNode(10, mindplot.layout.TestSuite.NODE_SIZE, position); + manager.addNode(11, mindplot.layout.TestSuite.NODE_SIZE, position); + + manager.connectNode(0, 1, 0); + manager.connectNode(0, 2, 1); + manager.connectNode(0, 3, 2); + manager.connectNode(3, 4, 0); + manager.connectNode(3, 5, 1); + manager.connectNode(3, 6, 2); + manager.connectNode(5, 7, 0); + manager.connectNode(5, 8, 1); + manager.connectNode(5, 11, 2); + manager.connectNode(2, 9, 0); + manager.connectNode(2, 10, 1); + + manager.layout(); + var graph = manager.plot("testFreePredict1", {width:1000, height:400}); + + var pos1 = {x: 370, y:80}; + var predict1 = manager.predict(11, pos1, true); + $assert(predict1.position.x == pos1.x && predict1.position.y == pos1.y, "free predict should return the same position"); + + var pos2 = {x: -200, y:80}; + var predict2 = manager.predict(2, pos2, true); + $assert(predict2.position.x == pos2.x && predict2.position.y == pos2.y, "free predict should return the same position"); + + var pos3 = {x: 200, y:30}; + var node5 = manager.find(5); + var predict3 = manager.predict(5, pos3, true); + $assert(predict3.position.x == node5.getPosition().x && predict3.position.y == pos3.y, "free predict should return the x-coordinate of the node"); + + var pos4 = {x: -100, y:45}; + var node10 = manager.find(10); + var predict4 = manager.predict(10, pos4, true); + $assert(predict4.position.x == node10.getPosition().x && predict4.position.y == pos4.y, "free predict should return the x-coordinate of the node"); + + this._plotPrediction(graph, predict1); + this._plotPrediction(graph, predict2); + this._plotPrediction(graph, predict3); + this._plotPrediction(graph, predict4); + }, + + testReconnectFreeNode: function() { + console.log("testReconnectFreeNode:"); + var position = {x:0,y:0}; + var manager = new mindplot.layout.LayoutManager(0, mindplot.layout.TestSuite.ROOT_NODE_SIZE); + + // Prepare a sample graph ... + manager.addNode(1, mindplot.layout.TestSuite.NODE_SIZE, position); + manager.addNode(2, mindplot.layout.TestSuite.NODE_SIZE, position); + manager.addNode(3, mindplot.layout.TestSuite.NODE_SIZE, position); + manager.addNode(4, mindplot.layout.TestSuite.NODE_SIZE, position); + manager.addNode(5, mindplot.layout.TestSuite.NODE_SIZE, position); + manager.addNode(6, mindplot.layout.TestSuite.NODE_SIZE, position); + manager.addNode(7, mindplot.layout.TestSuite.NODE_SIZE, position); + manager.addNode(8, mindplot.layout.TestSuite.NODE_SIZE, position); + manager.addNode(9, mindplot.layout.TestSuite.NODE_SIZE, position); + manager.addNode(10, mindplot.layout.TestSuite.NODE_SIZE, position); + manager.addNode(11, mindplot.layout.TestSuite.NODE_SIZE, position); + + manager.connectNode(0, 1, 0); + manager.connectNode(0, 2, 1); + manager.connectNode(0, 3, 2); + manager.connectNode(3, 4, 0); + manager.connectNode(3, 5, 1); + manager.connectNode(3, 6, 2); + manager.connectNode(5, 7, 0); + manager.connectNode(5, 8, 1); + manager.connectNode(5, 11, 2); + manager.connectNode(2, 9, 0); + manager.connectNode(2, 10, 1); + + manager.layout(); + manager.plot("testReconnectFreeNode1", {width:1000, height:400}); + + console.log("move node 5"); + manager.moveNode(5, {x:250, y:30}); + manager.layout(); + manager.plot("testReconnectFreeNode2", {width:1000, height:400}); + + console.log("reconnect node 5 to node 2"); + manager.disconnectNode(5); + manager.connectNode(2,5,2); + manager.layout(); + manager.plot("testReconnectFreeNode3", {width:1000, height:400}); + + console.log("move node 8"); + manager.moveNode(8, {x:-370, y:60}); + manager.layout(); + manager.plot("testReconnectFreeNode4", {width:1000, height:400}); + + //TODO(gb): fix this. node 11 is not positioned correctly + console.log("reconnect node 5 to node 10"); + manager.disconnectNode(5); + manager.connectNode(10,5,0); + manager.layout(); + manager.plot("testReconnectFreeNode5", {width:1000, height:400}); + +// console.log("reconnect node 5 to node 3"); +// manager.disconnectNode(5); +// manager.connectNode(3,5,2); +// manager.layout(); +// manager.plot("testReconnectFreeNode6", {width:1000, height:400}); + +// manager.moveNode(8, {x:370, y:30}); +// manager.layout(); +// manager.plot("testReconnectFreeNode2", {width:1000, height:400}); } }); diff --git a/mindplot/src/test/javascript/static/layout.html b/mindplot/src/test/javascript/static/layout.html index e97c6d3a..fa15e882 100644 --- a/mindplot/src/test/javascript/static/layout.html +++ b/mindplot/src/test/javascript/static/layout.html @@ -121,5 +121,16 @@
+