diff --git a/mindplot/src/main/javascript/layout/LayoutManager.js b/mindplot/src/main/javascript/layout/LayoutManager.js index 487480ed..22a1c918 100644 --- a/mindplot/src/main/javascript/layout/LayoutManager.js +++ b/mindplot/src/main/javascript/layout/LayoutManager.js @@ -169,6 +169,7 @@ mindplot.layout.LayoutManager = new Class({ node.resetPositionState(); node.resetOrderState(); + node.resetFreeState(); this._events.push(event); } this._collectChanges(this._treeSet.getChildren(node)); diff --git a/mindplot/src/main/javascript/layout/Node.js b/mindplot/src/main/javascript/layout/Node.js index b87a32a5..ae11b4dc 100644 --- a/mindplot/src/main/javascript/layout/Node.js +++ b/mindplot/src/main/javascript/layout/Node.js @@ -40,7 +40,6 @@ mindplot.layout.Node = new Class({ }, isFree: function() { - var result = this._getProperty('free'); return this._getProperty('free'); }, @@ -48,6 +47,10 @@ mindplot.layout.Node = new Class({ return this._isPropertyChanged('free'); }, + hasFreeDisplacementChanged: function() { + return this._isPropertyChanged('freeDisplacement'); + }, + setShrunken: function(value) { this._setProperty('shrink', value); }, @@ -75,6 +78,13 @@ mindplot.layout.Node = new Class({ } }, + resetFreeState : function() { + var prop = this._properties['freeDisplacement']; + if (prop) { + prop.hasChanged = false; + } + }, + getOrder: function() { return this._getProperty('order'); }, diff --git a/mindplot/src/main/javascript/layout/OriginalLayout.js b/mindplot/src/main/javascript/layout/OriginalLayout.js index 6f6b0ea2..ddf1c1a9 100644 --- a/mindplot/src/main/javascript/layout/OriginalLayout.js +++ b/mindplot/src/main/javascript/layout/OriginalLayout.js @@ -75,7 +75,7 @@ mindplot.layout.OriginalLayout = new Class({ this._layoutChildren(node, heightById); - this._fixOverlapping(node, heightById); + this._fixOverlapping(node); }, this); }, @@ -97,13 +97,16 @@ mindplot.layout.OriginalLayout = new Class({ var heightChanged = node._branchHeight != newBranchHeight; node._heightChanged = heightChanged || parentHeightChanged; - if (childrenOrderMoved || heightChanged || parentHeightChanged || freeChanged) { + + + if (childrenOrderMoved || heightChanged || parentHeightChanged) { var sorter = node.getSorter(); var offsetById = sorter.computeOffsets(this._treeSet, node); var parentPosition = node.getPosition(); children.forEach(function(child) { var freeDisplacement = child.getFreeDisplacement(); + var freeDisplacement = {x:0, y:0}; var offset = offsetById[child.getId()]; var parentX = parentPosition.x; var parentY = parentPosition.y; @@ -122,60 +125,24 @@ mindplot.layout.OriginalLayout = new Class({ }, this); }, - _fixOverlapping: function(node, heightById) { -// console.log("\t\tnode {id:" + node.getId() + "}"); //TODO(gb): Remove trace!!! + _fixOverlapping: function(node) { var children = this._treeSet.getChildren(node); - var freeChildren = children.filter(function(child) {return child.isFree()}); + if (node.hasFreeDisplacementChanged()) { + var yOffset = node.getFreeDisplacement().y; + var branchesToShift = this._treeSet.getBranchesInVerticalDirection(node, yOffset); + this._treeSet.shiftBranchPosition(node, node.getFreeDisplacement().x, node.getFreeDisplacement().y); - // Check for overlap only for free children - freeChildren.forEach(function(child) { - var childVertex = child.getVertex(); -// console.log("\t\t\tchild {id:" + child.getId() + ", x0:(" + childVertex.a.x + "," + childVertex.a.y + "), x1:(" + childVertex.b.x + "," + childVertex.b.y + ")}"); //TODO(gb): Remove trace!!! + branchesToShift.forEach(function(branch) { + this._treeSet.shiftBranchPosition(branch, 0, yOffset); + },this); - // Overlap should only occur with siblings (?) - var colliders = this._getColliders(child); - - - colliders.forEach(function(collider) { - console.log("\t\t\tcollider {id:" + collider.getId() + ", with:" + child.getId() +"}"); //TODO(gb): Remove trace!!! - }, this); - - if (colliders.length == 0) { - console.log("\t\t\tNo colliders"); //TODO(gb): Remove trace!!! - } - }, this); + } children.forEach(function(child) { - this._fixOverlapping(child, heightById); + this._fixOverlapping(child); }, this); }, - _getColliders: function(node) { - console.log("\t\tcheck with colliders for node " + node.getId() + ":`"); //TODO(gb): Remove trace!!! - var siblings = this._treeSet.getSiblings(node); - var colliders = []; - siblings.forEach(function(sibling) { - var collisions = this._checkCollision(node, sibling, colliders); - if (this._nodesCollide(node, sibling)) { - collisions.push(sibling); - } - }, this); - - return colliders; - }, - - _checkCollision: function(checkNode, node, colliders) { - var children = this._treeSet.getChildren(node); - children.forEach(function(child) { - if (this._nodesCollide(checkNode, child)) { - colliders.push(child); - } - this._checkCollision(checkNode, child, colliders); - }, this); - - return colliders; - }, - _nodesCollide: function(nodeA, nodeB) { var nodeAVertex = nodeA.getVertex(); var nodeBVertex = nodeB.getVertex(); diff --git a/mindplot/src/main/javascript/layout/RootedTreeSet.js b/mindplot/src/main/javascript/layout/RootedTreeSet.js index b79c9fed..9fd92bb8 100644 --- a/mindplot/src/main/javascript/layout/RootedTreeSet.js +++ b/mindplot/src/main/javascript/layout/RootedTreeSet.js @@ -216,19 +216,45 @@ mindplot.layout.RootedTreeSet = new Class({ var children = this.getChildren(node); children.forEach(function(child) { - this._shiftBranchPosition(child, xOffset, yOffset); + this.shiftBranchPosition(child, xOffset, yOffset); }.bind(this)); }, - _shiftBranchPosition : function(node, xOffset, yOffset) { + shiftBranchPosition: function(node, xOffset, yOffset) { var position = node.getPosition(); node.setPosition({x:position.x + xOffset, y:position.y + yOffset}); var children = this.getChildren(node); children.forEach(function(child) { - this._shiftBranchPosition(child, xOffset, yOffset); + this.shiftBranchPosition(child, xOffset, yOffset); }.bind(this)); + }, + + getBranchesInVerticalDirection: function(node, yOffset) { + // siblings with lower or higher order, depending on the direction of the offset + var siblings = this.getSiblings(node).filter(function(sibling) { + if (yOffset < 0) + return sibling.getOrder() < node.getOrder(); + else + return sibling.getOrder() > node.getOrder(); + }); + + // direct descendants of the root that do not contain the node and are on the same side + // and on the direction of the offset + var rootNode = this.getRootNode(node); + var branches = this.getChildren(rootNode).filter(function(child) { + return this._find(node.getId(), child); + }, this); + + var branch = branches[0]; + var rootDescendants = this.getSiblings(branch).filter(function(sibling) { + var sameSide = node.getPosition().x > rootNode.getPosition().x ? sibling.getPosition().x > rootNode.getPosition().x : sibling.getPosition().x < rootNode.getPosition().x; + var sameDirection = yOffset < 0 ? sibling.getOrder() < branch.getOrder() : sibling.getOrder() > branch.getOrder(); + return sameSide && sameDirection; + }, this); + + return siblings.combine(rootDescendants); } }); diff --git a/mindplot/src/test/javascript/static/TestSuite.js b/mindplot/src/test/javascript/static/TestSuite.js index c8af7de5..a9dfb4ac 100644 --- a/mindplot/src/test/javascript/static/TestSuite.js +++ b/mindplot/src/test/javascript/static/TestSuite.js @@ -19,18 +19,18 @@ 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.testAligned(); + this.testSymmetry(); + this.testBalanced(); + this.testEvents(); + this.testEventsComplex(); + this.testDisconnect(); + this.testReconnect(); + this.testRemoveNode(); + this.testSymmetricPredict(); + this.testBalancedPredict(); this.testSize(); -// this.testFreePosition(); + this.testFreePosition(); }, testAligned: function() { @@ -668,47 +668,51 @@ mindplot.layout.TestSuite = new Class({ 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.addNode(12, mindplot.layout.TestSuite.NODE_SIZE, position); + manager.addNode(13, mindplot.layout.TestSuite.NODE_SIZE, position); + manager.addNode(14, mindplot.layout.TestSuite.NODE_SIZE, position); + manager.addNode(15, mindplot.layout.TestSuite.NODE_SIZE, position); + manager.addNode(16, mindplot.layout.TestSuite.NODE_SIZE, position); + manager.addNode(17, mindplot.layout.TestSuite.NODE_SIZE, position); + manager.addNode(18, mindplot.layout.TestSuite.NODE_SIZE, position); + manager.addNode(19, mindplot.layout.TestSuite.NODE_SIZE, position); + manager.addNode(20, mindplot.layout.TestSuite.NODE_SIZE, position); + manager.addNode(21, mindplot.layout.TestSuite.NODE_SIZE, position); + manager.addNode(22, mindplot.layout.TestSuite.NODE_SIZE, position); + + manager.connectNode(0,1,0).connectNode(0,2,1).connectNode(0,3,2).connectNode(0,4,3); + manager.connectNode(4,21,0).connectNode(4,22,0); + manager.connectNode(1,5,0); + manager.connectNode(5,6,0).connectNode(6,8,0).connectNode(8,9,0); + manager.connectNode(5,7,1).connectNode(7,10,0); + manager.connectNode(3,11,0).connectNode(11,14,0).connectNode(14,18,0).connectNode(14,19,1).connectNode(14,20,2); + manager.connectNode(3,12,1).connectNode(12,15,0).connectNode(12,16,1).connectNode(12,17,2); + manager.connectNode(3,13,2); manager.layout(); - manager.plot("testFreePosition1", {width:1000, height:400}); + manager.plot("testFreePosition1", {width:1400, height:600}); - console.log("\tmove node 5 to (280,20)"); - manager.move(5, {x:280, y:20}); + console.log("move node 12 to (300,30)"); + manager.move(12, {x:300, y:30}); manager.layout(); - manager.plot("testFreePosition2", {width:1000, height:400}); + manager.plot("testFreePosition2", {width:1400, height:600}); - 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("move node 13 to (340,180)"); + manager.move(13, {x:340, y:180}); + manager.layout(true); + manager.plot("testFreePosition3", {width:1400, height:600}); - 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("move node 11 to (250,-50)"); + manager.move(11, {x:250, y:-50}); + manager.layout(true); + manager.plot("testFreePosition4", {width:1400, height:600}); - 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}); - - console.log("\tmove node 13 to overlap node 11:"); - manager.move(13, {x:415, y:70}); - manager.layout(); - manager.plot("testFreePosition6", {width:1000, height:400}); - - console.log("\tmove node 1 to overlap node 4:"); - manager.move(1, {x:250, y:-90}); - manager.layout(); - manager.plot("testFreePosition7", {width:1000, height:400}); + console.log("move node 7 to (350,-190)"); + manager.move(7, {x:350, y:-190}); + manager.layout(true); + manager.plot("testFreePosition5", {width:1400, height:600}); } }); mindplot.layout.TestSuite.NODE_SIZE = {width:80, height:30}, -mindplot.layout.TestSuite.ROOT_NODE_SIZE = {width:120, height:40} - +mindplot.layout.TestSuite.ROOT_NODE_SIZE = {width:120, height:40} \ No newline at end of file diff --git a/mindplot/src/test/javascript/static/layout.html b/mindplot/src/test/javascript/static/layout.html index e35e8f7e..fb59bf05 100644 --- a/mindplot/src/test/javascript/static/layout.html +++ b/mindplot/src/test/javascript/static/layout.html @@ -116,8 +116,6 @@
-
-
\ No newline at end of file