From 171c3aee8f0a556150858a3cc830340fe1d704ef Mon Sep 17 00:00:00 2001 From: Gonzalo Bellver Date: Sun, 15 Jan 2012 18:08:31 -0300 Subject: [PATCH] Free positioning started. Nodes can move freely, but collisions might occurr --- .../main/javascript/layout/LayoutManager.js | 20 ++++++-- mindplot/src/main/javascript/layout/Node.js | 28 +++++++++++ .../main/javascript/layout/OriginalLayout.js | 13 ++--- .../main/javascript/layout/SymmetricSorter.js | 5 +- .../src/test/javascript/static/TestSuite.js | 48 +++++++++++++++++++ .../src/test/javascript/static/layout.html | 7 +++ 6 files changed, 108 insertions(+), 13 deletions(-) diff --git a/mindplot/src/main/javascript/layout/LayoutManager.js b/mindplot/src/main/javascript/layout/LayoutManager.js index b0182359..a8a67526 100644 --- a/mindplot/src/main/javascript/layout/LayoutManager.js +++ b/mindplot/src/main/javascript/layout/LayoutManager.js @@ -48,14 +48,20 @@ mindplot.layout.LayoutManager = new Class({ return this._treeSet.find(id); }, - move: function() { - //TODO(gb): implement + move: function(id, position) { + $assert($defined(id), "id cannot be null"); + $assert($defined(position), "position cannot be null"); + $assert($defined(position.x), "x can not be null"); + $assert($defined(position.y), "y can not be null"); + var node = this._treeSet.find(id); + node.setFree(true); + node.setFreeDisplacement({x:position.x - node.getPosition().x, y:position.y-node.getPosition().y}); }, connectNode: function(parentId, childId, order) { - $assert($defined(parentId), "parentId can not be null"); - $assert($defined(childId), "childId can not be null"); - $assert($defined(order), "order can not be null"); + $assert($defined(parentId), "parentId cannot be null"); + $assert($defined(childId), "childId cannot be null"); + $assert($defined(order), "order cannot be null"); this._layout.connectNode(parentId, childId, order); @@ -73,6 +79,8 @@ mindplot.layout.LayoutManager = new Class({ $assert($defined(id), "id can not be null"); var result = this._layout.createNode(id, size, position, 'topic'); this._treeSet.add(result); + + return this; }, removeNode: function(id) { @@ -124,6 +132,8 @@ mindplot.layout.LayoutManager = new Class({ if (!$(fireEvents) || fireEvents) { this._flushEvents(); } + + return this; }, _flushEvents: function() { diff --git a/mindplot/src/main/javascript/layout/Node.js b/mindplot/src/main/javascript/layout/Node.js index 84b9c031..77a1e269 100644 --- a/mindplot/src/main/javascript/layout/Node.js +++ b/mindplot/src/main/javascript/layout/Node.js @@ -35,6 +35,19 @@ mindplot.layout.Node = new Class({ return this._id; }, + setFree: function(value) { + this._setProperty('free', value); + }, + + isFree: function() { + var result = this._getProperty('free'); + return this._getProperty('free'); + }, + + hasFreeChanged: function() { + return this._isPropertyChanged('free'); + }, + setShrunken: function(value) { this._setProperty('shrink', value); }, @@ -88,6 +101,21 @@ mindplot.layout.Node = new Class({ return this._getProperty('size'); }, + setFreeDisplacement: function(displacement) { + $assert($defined(displacement), "Position can not be null"); + $assert($defined(displacement.x), "x can not be null"); + $assert($defined(displacement.y), "y can not be null"); + var oldDisplacement = this.getFreeDisplacement(); + var newDisplacement = {x:oldDisplacement.x + displacement.x, y:oldDisplacement.y + displacement.y}; + + this._setProperty('freeDisplacement', Object.clone(newDisplacement)); + }, + + getFreeDisplacement: function() { + var freeDisplacement = this._getProperty('freeDisplacement'); + return (freeDisplacement || {x:0, y:0}); + }, + setPosition : function(position) { $assert($defined(position), "Position can not be null"); $assert($defined(position.x), "x can not be null"); diff --git a/mindplot/src/main/javascript/layout/OriginalLayout.js b/mindplot/src/main/javascript/layout/OriginalLayout.js index 0444e16a..b80b38d1 100644 --- a/mindplot/src/main/javascript/layout/OriginalLayout.js +++ b/mindplot/src/main/javascript/layout/OriginalLayout.js @@ -71,7 +71,6 @@ mindplot.layout.OriginalLayout = new Class({ // Calculate all node heights ... var sorter = node.getSorter(); - // @Todo: This must not be implemented in this way.Each sorter could have different notion of heights ... var heightById = sorter.computeChildrenIdByHeights(this._treeSet, node); this._layoutChildren(node, heightById); @@ -83,9 +82,10 @@ mindplot.layout.OriginalLayout = new Class({ var nodeId = node.getId(); var children = this._treeSet.getChildren(node); var parent = this._treeSet.getParent(node); - var childrenOrderMoved = children.some(function(child) { - return child.hasOrderChanged(); - }); + var childrenOrderMoved = children.some(function(child) { return child.hasOrderChanged(); }); + + var childrenFreeChanged = children.some(function(child) { return child.hasFreeChanged(); }); + var freeChanged = node.hasFreeChanged() || childrenFreeChanged; // 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 .... @@ -95,17 +95,18 @@ mindplot.layout.OriginalLayout = new Class({ var heightChanged = node._branchHeight != newBranchHeight; node._heightChanged = heightChanged || parentHeightChanged; - if (childrenOrderMoved || heightChanged || parentHeightChanged) { + if (childrenOrderMoved || heightChanged || parentHeightChanged || freeChanged) { var sorter = node.getSorter(); var offsetById = sorter.computeOffsets(this._treeSet, node); var parentPosition = node.getPosition(); children.forEach(function(child) { + var freeDisplacement = child.getFreeDisplacement(); var offset = offsetById[child.getId()]; var parentX = parentPosition.x; var parentY = parentPosition.y; - var newPos = {x:parentX + offset.x,y:parentY + offset.y}; + var newPos = {x:parentX + freeDisplacement.x + offset.x, y:parentY + freeDisplacement.y + offset.y}; this._treeSet.updateBranchPosition(child, newPos); }.bind(this)); diff --git a/mindplot/src/main/javascript/layout/SymmetricSorter.js b/mindplot/src/main/javascript/layout/SymmetricSorter.js index 4cec29a0..310e9dc0 100644 --- a/mindplot/src/main/javascript/layout/SymmetricSorter.js +++ b/mindplot/src/main/javascript/layout/SymmetricSorter.js @@ -111,9 +111,10 @@ mindplot.layout.SymmetricSorter = new Class({ var result = {}; for (var i = 0; i < heights.length; i++) { ysum = ysum - heights[i].height; - var parent = treeSet.getParent(treeSet.find(heights[i].id)); + var childNode = treeSet.find(heights[i].id); + var parent = treeSet.getParent(childNode); - var rootNode = treeSet.getRootNode(treeSet.find(heights[i].id)); + var rootNode = treeSet.getRootNode(childNode); var direction = parent.getPosition().x > rootNode.getPosition().x ? 1 : -1; var yOffset = ysum + heights[i].height / 2; diff --git a/mindplot/src/test/javascript/static/TestSuite.js b/mindplot/src/test/javascript/static/TestSuite.js index 91a7b082..b40004ef 100644 --- a/mindplot/src/test/javascript/static/TestSuite.js +++ b/mindplot/src/test/javascript/static/TestSuite.js @@ -30,6 +30,7 @@ mindplot.layout.TestSuite = new Class({ this.testSymmetricPredict(); this.testBalancedPredict(); this.testSize(); + this.testFreePosition(); }, testAligned: function() { @@ -640,6 +641,53 @@ mindplot.layout.TestSuite = new Class({ this._plotPrediction(graph3, manager.predict(9, null)); this._plotPrediction(graph3, manager.predict(3, null)); this._plotPrediction(graph3, manager.predict(1, null)); + }, + + testFreePosition: function() { + console.log("testFreePosition:"); + 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).connectNode(0, 2, 1).connectNode(0, 3, 2); + manager.connectNode(3, 4, 0).connectNode(3, 5, 1).connectNode(3, 6, 2); + manager.connectNode(5, 7, 0).connectNode(5, 8, 1).connectNode(5, 11, 2); + manager.connectNode(2, 9, 0).connectNode(2, 10, 1); + + manager.layout(); + manager.plot("testFreePosition1", {width:1000, height:400}); + + console.log("\tmove node 5 to (280,20)"); + manager.move(5, {x:280, y:20}); + manager.layout(); + manager.plot("testFreePosition2", {width:1000, height:400}); + + console.log("\tmove node 5 to (300,60)"); + manager.move(5, {x:300, y:60}); + manager.layout(); + manager.plot("testFreePosition3", {width:1000, height:400}); + + console.log("\tmove node 2 to (-200,100)"); + manager.move(2, {x:-200, y:100}); + manager.layout(); + manager.plot("testFreePosition4", {width:1000, height:400}); + + console.log("\tadd nodes as children of 3 and 5:"); + manager.addNode(12, mindplot.layout.TestSuite.NODE_SIZE, position).connectNode(3,12,3); + manager.addNode(13, mindplot.layout.TestSuite.NODE_SIZE, position).connectNode(5,13,3); + manager.layout(); + manager.plot("testFreePosition5", {width:1000, height:400}); } }); diff --git a/mindplot/src/test/javascript/static/layout.html b/mindplot/src/test/javascript/static/layout.html index 40b60309..eece9033 100644 --- a/mindplot/src/test/javascript/static/layout.html +++ b/mindplot/src/test/javascript/static/layout.html @@ -108,5 +108,12 @@
+

testFreePosition:

+
+
+
+
+
+ \ No newline at end of file