@ -37,16 +37,15 @@ exports.orderByEnd = function(items) {
* items having a top === null will be re - stacked
* /
exports . stack = function ( items , margin , force ) {
var i , iMax ;
if ( force ) {
// reset top position of all items
for ( i = 0 , iMax = items . length ; i < iMax ; i ++ ) {
for ( var i = 0 ; i < items . length ; i ++ ) {
items [ i ] . top = null ;
}
}
// calculate new, non-overlapping positions
for ( i = 0 , iMax = items . length ; i < iMax ; i ++ ) {
for ( var i = 0 ; i < items . length ; i ++ ) {
var item = items [ i ] ;
if ( item . stack && item . top === null ) {
// initialize top position
@ -80,29 +79,70 @@ exports.stack = function(items, margin, force) {
* All visible items
* @ param { { item : { horizontal : number , vertical : number } , axis : number } } margin
* Margins between items and between items and the axis .
* @ param { subgroups [ ] } subgroups
* All subgroups
* /
exports . nostack = function ( items , margin , subgroups ) {
var i , iMax , newTop ;
// reset top position of all items
for ( i = 0 , iMax = items . length ; i < iMax ; i ++ ) {
if ( items [ i ] . data . subgroup !== undefined ) {
newTop = margin . axis ;
exports . nostack = function ( items , margin , subgroups , stackSubgroups ) {
for ( var i = 0 ; i < items . length ; i ++ ) {
if ( items [ i ] . data . subgroup == undefined ) {
items [ i ] . top = margin . item . vertical ;
} else if ( items [ i ] . data . subgroup !== undefined && stackSubgroups ) {
var newTop = 0 ;
for ( var subgroup in subgroups ) {
if ( subgroups . hasOwnProperty ( subgroup ) ) {
if ( subgroups [ subgroup ] . visible == true && subgroups [ subgroup ] . index < subgroups [ items [ i ] . data . subgroup ] . index ) {
newTop += subgroups [ subgroup ] . height + margin . item . vertical ;
newTop += subgroups [ subgroup ] . height ;
subgroups [ items [ i ] . data . subgroup ] . top = newTop ;
}
}
}
items [ i ] . top = newTop ;
}
else {
items [ i ] . top = margin . axis ;
items [ i ] . top = newTop + 0.5 * margin . item . vertical ;
}
}
if ( ! stackSubgroups ) {
exports . stackSubgroups ( items , margin , subgroups )
}
} ;
/ * *
* Adjust vertical positions of the subgroups such that they don ' t overlap each
* other .
* @ param { subgroups [ ] } subgroups
* All subgroups
* @ param { { item : { horizontal : number , vertical : number } , axis : number } } margin
* Margins between items and between items and the axis .
* /
exports . stackSubgroups = function ( items , margin , subgroups ) {
for ( var subgroup in subgroups ) {
if ( subgroups . hasOwnProperty ( subgroup ) ) {
subgroups [ subgroup ] . top = 0 ;
do {
// TODO: optimize checking for overlap. when there is a gap without items,
// you only need to check for items from the next item on, not from zero
var collidingItem = null ;
for ( var otherSubgroup in subgroups ) {
if ( subgroups [ otherSubgroup ] . top !== null && otherSubgroup !== subgroup && subgroups [ subgroup ] . index > subgroups [ otherSubgroup ] . index && exports . collisionByTimes ( subgroups [ subgroup ] , subgroups [ otherSubgroup ] ) ) {
collidingItem = subgroups [ otherSubgroup ] ;
break ;
}
}
if ( collidingItem != null ) {
// There is a collision. Reposition the subgroups above the colliding element
subgroups [ subgroup ] . top = collidingItem . top + collidingItem . height ;
}
} while ( collidingItem ) ;
}
}
for ( var i = 0 ; i < items . length ; i ++ ) {
if ( items [ i ] . data . subgroup !== undefined ) {
items [ i ] . top = subgroups [ items [ i ] . data . subgroup ] . top + 0.5 * margin . item . vertical ;
}
}
}
/ * *
* Test if the two provided items collide
* The items must have parameters left , width , top , and height .
@ -127,3 +167,17 @@ exports.collision = function(a, b, margin, rtl) {
( a . top + a . height + margin . vertical - EPSILON ) > b . top ) ;
}
} ;
/ * *
* Test if the two provided objects collide
* The objects must have parameters start , end , top , and height .
* @ param { Object } a The first Object
* @ param { Object } b The second Object
* @ return { boolean } true if a and b collide , else false
* /
exports . collisionByTimes = function ( a , b ) {
return (
( a . start < b . start && a . end > b . start && a . top < ( b . top + b . height ) && ( a . top + a . height ) > b . top ) ||
( b . start < a . start && b . end > a . start && b . top < ( a . top + a . height ) && ( b . top + b . height ) > a . top )
)
}