Balanced Layout first level approach
This commit is contained in:
175
mindplot/src/main/javascript/nlayout/BalancedSorter.js
Normal file
175
mindplot/src/main/javascript/nlayout/BalancedSorter.js
Normal file
@@ -0,0 +1,175 @@
|
||||
mindplot.nlayout.BalancedSorter = new Class({
|
||||
Extends: mindplot.nlayout.ChildrenSorterStrategy,
|
||||
|
||||
initialize: function() {
|
||||
|
||||
},
|
||||
|
||||
computeChildrenIdByHeights: function(treeSet, node) {
|
||||
var result = {};
|
||||
this._computeChildrenHeight(treeSet, node, result);
|
||||
return result;
|
||||
},
|
||||
|
||||
_computeChildrenHeight : function(treeSet, node, heightCache) {
|
||||
var height = node.getSize().height + (mindplot.nlayout.BalancedSorter.INTERNODE_VERTICAL_PADDING * 2); // 2* Top and down padding;
|
||||
|
||||
var result;
|
||||
var children = treeSet.getChildren(node);
|
||||
if (children.length == 0) {
|
||||
result = height;
|
||||
} else {
|
||||
var childrenHeight = 0;
|
||||
children.forEach(function(child) {
|
||||
childrenHeight += this._computeChildrenHeight(treeSet, child, heightCache);
|
||||
}, this);
|
||||
|
||||
result = Math.max(height, childrenHeight);
|
||||
}
|
||||
|
||||
if (heightCache) {
|
||||
heightCache[node.getId()] = result;
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
predict : function(parent, graph, position) {
|
||||
|
||||
// No children...
|
||||
var children = graph.getChildren(parent);
|
||||
if (children.length == 0) {
|
||||
return [0,parent.getPosition()]; // @Todo:Change x ...
|
||||
}
|
||||
|
||||
// Try to fit within ...
|
||||
//
|
||||
// - Order is change if the position top position is changed ...
|
||||
// - Suggested position is the middle between the two topics...
|
||||
//
|
||||
var result = null;
|
||||
children.forEach(function(child) {
|
||||
var cpos = child.getPosition();
|
||||
if (position.y > cpos.y) {
|
||||
result = [child.getOrder(),{x:cpos.x,y:cpos.y + child.getSize().height}];
|
||||
}
|
||||
});
|
||||
|
||||
// Ok, no overlap. Suggest a new order.
|
||||
if (result) {
|
||||
var last = children.getLast();
|
||||
result = [last.getOrder() + 1,{x:cpos.x,y:cpos.y - (mindplot.nlayout.BalancedSorter.INTERNODE_VERTICAL_PADDING * 4)}];
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
insert: function(treeSet, parent, child, order) {
|
||||
var children = this._getSortedChildren(treeSet, parent);
|
||||
$assert(order <= children.length, "Order must be continues and can not have holes. Order:" + order);
|
||||
$assert(order <= children.length, "Order must be continues and can not have holes. Order:" + order);
|
||||
|
||||
// Shift all the elements in one .
|
||||
for (var i = order; i < children.length; i++) {
|
||||
var node = children[i];
|
||||
node.setOrder(i + 1);
|
||||
}
|
||||
child.setOrder(order);
|
||||
},
|
||||
|
||||
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");
|
||||
}
|
||||
},
|
||||
|
||||
computeOffsets:function(treeSet, node) {
|
||||
$assert(treeSet, "treeSet can no be null.");
|
||||
$assert(node, "node can no be null.");
|
||||
|
||||
var children = this._getSortedChildren(treeSet, node);
|
||||
|
||||
// Compute heights ...
|
||||
var heights = children.map(function(child) {
|
||||
return {id:child.getId(), order:child.getOrder(), height:this._computeChildrenHeight(treeSet, child)};
|
||||
}, this);
|
||||
|
||||
|
||||
// Compute the center of the branch ...
|
||||
var totalPHeight = 0;
|
||||
var totalNHeight = 0;
|
||||
//TODO(gb): optimize using filter
|
||||
heights.forEach(function(elem) {
|
||||
if (elem.order % 2 == 0) {
|
||||
totalPHeight += elem.height;
|
||||
} else {
|
||||
totalNHeight += elem.height;
|
||||
}
|
||||
});
|
||||
var psum = totalPHeight/2;
|
||||
var nsum = totalNHeight/2;
|
||||
var totalDifference = totalPHeight - totalNHeight;
|
||||
var ysum = 0;
|
||||
|
||||
// Calculate the offsets ...
|
||||
var result = {};
|
||||
for (var i = 0; i < heights.length; i++) {
|
||||
var direction = heights[i].order % 2 ? -1 : 1;
|
||||
|
||||
if (direction > 0) {
|
||||
psum = psum - heights[i].height;
|
||||
ysum = psum;
|
||||
} else {
|
||||
nsum = nsum - heights[i].height;
|
||||
ysum = nsum;
|
||||
}
|
||||
|
||||
// console.log("node {id: " + heights[i].id + ", order: " + heights[i].order + ", psum: " + psum + ", nsum: " + nsum + "}"); //TODO(gb): Remove trace!!!
|
||||
// console.log("totalPHeight: " + totalPHeight + ", totalNHeight: " + totalNHeight); //TODO(gb): Remove trace!!!
|
||||
console.log("node {id: " + heights[i].id + ", totalDifference: " + totalDifference + ", direction: " + direction + "}"); //TODO(gb): Remove trace!!!
|
||||
|
||||
var yOffset = ysum + heights[i].height/2;
|
||||
var xOffset = direction * (node.getSize().width + mindplot.nlayout.SymetricSorter.INTERNODE_HORIZONTAL_PADDING);
|
||||
|
||||
$assert(!isNaN(xOffset), "xOffset can not be null");
|
||||
$assert(!isNaN(yOffset), "yOffset can not be null");
|
||||
|
||||
result[heights[i].id] = {x:xOffset,y:yOffset};
|
||||
}
|
||||
console.log("----------------------\n"); //TODO(gb): Remove trace!!!
|
||||
return result;
|
||||
},
|
||||
|
||||
toString:function() {
|
||||
return "Balanced Sorter";
|
||||
}
|
||||
});
|
||||
|
||||
mindplot.nlayout.BalancedSorter.INTERNODE_VERTICAL_PADDING = 5;
|
||||
mindplot.nlayout.BalancedSorter.INTERNODE_HORIZONTAL_PADDING = 5;
|
||||
mindplot.nlayout.BalancedSorter.INITIAL_HEIGHT = 100;
|
Reference in New Issue
Block a user