diff --git a/mindplot/src/main/javascript/layout/Node.js b/mindplot/src/main/javascript/layout/Node.js index 409d190d..b87a32a5 100644 --- a/mindplot/src/main/javascript/layout/Node.js +++ b/mindplot/src/main/javascript/layout/Node.js @@ -157,6 +157,11 @@ mindplot.layout.Node = new Class({ return this._sorter; }, + getVertex: function() { + var a = {x: this.getPosition().x - this.getSize().width/2, y:this.getPosition().y - this.getSize().height/2}; + var b = {x: this.getPosition().x + this.getSize().width/2, y:this.getPosition().y + this.getSize().height/2}; + return {a:a, b:b}; + }, toString: function() { return "[id:" + this.getId() + ", order:" + this.getOrder() + ", position: {" + this.getPosition().x + "," + this.getPosition().y + "}, size: {" + this.getSize().width + "}," + this.getSize().height + ", shrink:" + this.areChildrenShrunken() + "]"; diff --git a/mindplot/src/main/javascript/layout/OriginalLayout.js b/mindplot/src/main/javascript/layout/OriginalLayout.js index b80b38d1..6f6b0ea2 100644 --- a/mindplot/src/main/javascript/layout/OriginalLayout.js +++ b/mindplot/src/main/javascript/layout/OriginalLayout.js @@ -74,6 +74,8 @@ mindplot.layout.OriginalLayout = new Class({ var heightById = sorter.computeChildrenIdByHeights(this._treeSet, node); this._layoutChildren(node, heightById); + + this._fixOverlapping(node, heightById); }, this); }, @@ -118,6 +120,67 @@ mindplot.layout.OriginalLayout = new Class({ children.forEach(function(child) { this._layoutChildren(child, heightById); }, this); + }, + + _fixOverlapping: function(node, heightById) { +// console.log("\t\tnode {id:" + node.getId() + "}"); //TODO(gb): Remove trace!!! + var children = this._treeSet.getChildren(node); + var freeChildren = children.filter(function(child) {return child.isFree()}); + + // 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!!! + + // 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); + }, + + _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(); + return nodeAVertex.a.x < nodeBVertex.b.x && nodeAVertex.b.x > nodeBVertex.a.x && + nodeAVertex.a.y < nodeBVertex.b.y && nodeAVertex.b.y > nodeBVertex.a.y; } }); diff --git a/mindplot/src/main/javascript/layout/RootedTreeSet.js b/mindplot/src/main/javascript/layout/RootedTreeSet.js index de162409..b79c9fed 100644 --- a/mindplot/src/main/javascript/layout/RootedTreeSet.js +++ b/mindplot/src/main/javascript/layout/RootedTreeSet.js @@ -127,8 +127,8 @@ mindplot.layout.RootedTreeSet = new Class({ return this._getAncestors(this.getParent(node), []); }, - _getAncestors: function(node, nodes) { - var result = nodes; + _getAncestors: function(node, ancestors) { + var result = ancestors; if (node) { result.push(node); this._getAncestors(this.getParent(node), result); @@ -138,8 +138,13 @@ mindplot.layout.RootedTreeSet = new Class({ getSiblings: function(node) { $assert(node, 'node cannot be null'); - var siblings = node._parent._children; - return siblings.erase(node); + if (!$defined(node._parent)) { + return []; + } + var siblings = node._parent._children.filter(function(child) { + return child != node; + }); + return siblings; }, getParent:function(node) { @@ -184,14 +189,15 @@ mindplot.layout.RootedTreeSet = new Class({ var order = node.getOrder() == null ? "r" : node.getOrder(); var text = canvas.text(node.getPosition().x + canvas.width / 2, node.getPosition().y + canvas.height / 2, node.getId() + "[" + order + "]"); text.attr('fill', '#FFF'); - var fillColor = this._rootNodes.contains(node) ? "#000" : "#c00"; + var fillColor = this._rootNodes.contains(node) ? "#000" : (node.isFree() ? "#abc" : "#c00"); rect.attr('fill', fillColor); + var rectPosition = {x: rect.attr("x") - canvas.width/2 + rect.attr("width")/2, y:rect.attr("y") - canvas.height/2 + rect.attr("height")/2}; rect.click(function() { - console.log("[id:" + node.getId() + ", order:" + node.getOrder() + ", position:(" + node.getPosition().x + "," + node.getPosition().y + "), size:" + node.getSize().width + "x" + node.getSize().height + ", sorter:" + node.getSorter() +"]"); + console.log("[id:" + node.getId() + ", order:" + node.getOrder() + ", position:(" + rectPosition.x + "," + rectPosition.y + "), size:" + node.getSize().width + "x" + node.getSize().height + ", sorter:" + node.getSorter() +"]"); }); text.click(function() { - console.log("[id:" + node.getId() + ", order:" + node.getOrder() + ", position:(" + node.getPosition().x + "," + node.getPosition().y + "), size:" + node.getSize().width + "x" + node.getSize().height + ", sorter:" + node.getSorter() +"]"); + console.log("[id:" + node.getId() + ", order:" + node.getOrder() + ", position:(" + rectPosition.x + "," + rectPosition.y + "), size:" + node.getSize().width + "x" + node.getSize().height + ", sorter:" + node.getSorter() +"]"); }); for (var i = 0; i < children.length; i++) { diff --git a/mindplot/src/test/javascript/static/TestSuite.js b/mindplot/src/test/javascript/static/TestSuite.js index b40004ef..6551d06b 100644 --- a/mindplot/src/test/javascript/static/TestSuite.js +++ b/mindplot/src/test/javascript/static/TestSuite.js @@ -688,6 +688,16 @@ mindplot.layout.TestSuite = new Class({ 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}); } }); diff --git a/mindplot/src/test/javascript/static/layout.html b/mindplot/src/test/javascript/static/layout.html index eece9033..08e186f3 100644 --- a/mindplot/src/test/javascript/static/layout.html +++ b/mindplot/src/test/javascript/static/layout.html @@ -114,6 +114,8 @@
+ +