@ -206,19 +206,7 @@ Group.prototype.getLabelWidth = function() {
return this . props . label . width ;
return this . props . label . width ;
} ;
} ;
/ * *
* Repaint this group
* @ param { { start : number , end : number } } range
* @ param { { item : { horizontal : number , vertical : number } , axis : number } } margin
* @ param { boolean } [ forceRestack = false ] Force restacking of all items
* @ return { boolean } Returns true if the group is resized
* /
Group . prototype . redraw = function ( range , margin , forceRestack ) {
var resized = false ;
// force recalculation of the height of the items when the marker height changed
// (due to the Timeline being attached to the DOM or changed from display:none to visible)
Group . prototype . _didMarkerHeightChange = function ( ) {
var markerHeight = this . dom . marker . clientHeight ;
var markerHeight = this . dom . marker . clientHeight ;
if ( markerHeight != this . lastMarkerHeight ) {
if ( markerHeight != this . lastMarkerHeight ) {
this . lastMarkerHeight = markerHeight ;
this . lastMarkerHeight = markerHeight ;
@ -226,27 +214,22 @@ Group.prototype.redraw = function(range, margin, forceRestack) {
item . dirty = true ;
item . dirty = true ;
if ( item . displayed ) item . redraw ( ) ;
if ( item . displayed ) item . redraw ( ) ;
} ) ;
} ) ;
return true ;
}
}
forceRestack = true ;
}
// recalculate the height of the subgroups
this . _calculateSubGroupHeights ( margin ) ;
// calculate actual size and position
Group . prototype . _calculateGroupSizeAndPosition = function ( ) {
var foreground = this . dom . foreground ;
var foreground = this . dom . foreground ;
this . top = foreground . offsetTop ;
this . top = foreground . offsetTop ;
this . right = foreground . offsetLeft ;
this . right = foreground . offsetLeft ;
this . width = foreground . offsetWidth ;
this . width = foreground . offsetWidth ;
}
var lastIsVisible = this . isVisible ;
this . isVisible = this . _isGroupVisible ( range , margin ) ;
var restack = forceRestack || this . stackDirty || ( this . isVisible && ! lastIsVisible ) ;
Group . prototype . _redrawItems = function ( forceRestack , lastIsVisible , margin , range ) {
var restack = forceRestack || this . stackDirty || this . isVisible && ! lastIsVisible ;
this . _updateSubgroupsSizes ( ) ;
// if restacking, reposition visible items vertically
if ( restack ) {
// if restacking, reposition visible items vertically
if ( restack ) {
if ( typeof this . itemSet . options . order === 'function' ) {
if ( typeof this . itemSet . options . order === 'function' ) {
// a custom order function
// a custom order function
// brute force restack of all items
// brute force restack of all items
@ -255,7 +238,7 @@ Group.prototype.redraw = function(range, margin, forceRestack) {
var me = this ;
var me = this ;
var limitSize = false ;
var limitSize = false ;
util . forEach ( this . items , function ( item ) {
util . forEach ( this . items , function ( item ) {
if ( ! item . dom ) { // If this item has never been displayed then the dom property will not be defined, this means we need to measure the size
if ( ! item . displayed ) {
item . redraw ( ) ;
item . redraw ( ) ;
me . visibleItems . push ( item ) ;
me . visibleItems . push ( item ) ;
}
}
@ -268,41 +251,41 @@ Group.prototype.redraw = function(range, margin, forceRestack) {
} ) ;
} ) ;
stack . stack ( customOrderedItems , margin , true /* restack=true */ ) ;
stack . stack ( customOrderedItems , margin , true /* restack=true */ ) ;
this . visibleItems = this . _updateItemsInRange ( this . orderedItems , this . visibleItems , range ) ;
this . visibleItems = this . _updateItemsInRange ( this . orderedItems , this . visibleItems , range ) ;
}
else {
} else {
// no custom order function, lazy stacking
// no custom order function, lazy stacking
this . visibleItems = this . _updateItemsInRange ( this . orderedItems , this . visibleItems , range ) ;
this . visibleItems = this . _updateItemsInRange ( this . orderedItems , this . visibleItems , range ) ;
if ( this . itemSet . options . stack ) { // TODO: ugly way to access options...
stack . stack ( this . visibleItems , margin , true /* restack=true */ ) ;
}
else { // no stacking
if ( this . itemSet . options . stack ) {
// TODO: ugly way to access options...
stack . stack ( this . visibleItems , margin , true /* restack=true */ ) ;
} else {
// no stacking
stack . nostack ( this . visibleItems , margin , this . subgroups , this . itemSet . options . stackSubgroups ) ;
stack . nostack ( this . visibleItems , margin , this . subgroups , this . itemSet . options . stackSubgroups ) ;
}
}
}
}
this . stackDirty = false ;
this . stackDirty = false ;
}
}
// recalculate the height of the group
var height = this . _calculateHeight ( margin ) ;
}
// calculate actual size and position
foreground = this . dom . foreground ;
this . top = foreground . offsetTop ;
this . right = foreground . offsetLeft ;
this . width = foreground . offsetWidth ;
Group . prototype . _didResize = function ( resized , height ) {
resized = util . updateProperty ( this , 'height' , height ) || resized ;
resized = util . updateProperty ( this , 'height' , height ) || resized ;
// recalculate size of label
// recalculate size of label
resized = util . updateProperty ( this . props . label , 'width' , this . dom . inner . clientWidth ) || resized ;
resized = util . updateProperty ( this . props . label , 'height' , this . dom . inner . clientHeight ) || resized ;
var labelWidth = this . dom . inner . clientWidth ;
var labelHeight = this . dom . inner . clientHeight ;
resized = util . updateProperty ( this . props . label , 'width' , labelWidth ) || resized ;
resized = util . updateProperty ( this . props . label , 'height' , labelHeight ) || resized ;
return resized ;
}
// apply new height
this . dom . background . style . height = height + 'px' ;
this . dom . foreground . style . height = height + 'px' ;
Group . prototype . _applyGroupHeight = function ( height ) {
this . dom . background . style . height = height + 'px' ;
this . dom . foreground . style . height = height + 'px' ;
this . dom . label . style . height = height + 'px' ;
this . dom . label . style . height = height + 'px' ;
}
// update vertical position of items after they are re-stacked and the height of the group is calculated
// update vertical position of items after they are re-stacked and the height of the group is calculated
Group . prototype . _updateItemsVerticalPosition = function ( resized , margin ) {
for ( var i = 0 , ii = this . visibleItems . length ; i < ii ; i ++ ) {
for ( var i = 0 , ii = this . visibleItems . length ; i < ii ; i ++ ) {
var item = this . visibleItems [ i ] ;
var item = this . visibleItems [ i ] ;
item . repositionY ( margin ) ;
item . repositionY ( margin ) ;
@ -312,10 +295,84 @@ Group.prototype.redraw = function(range, margin, forceRestack) {
}
}
if ( ! this . isVisible && this . height ) {
if ( ! this . isVisible && this . height ) {
return resized = false ;
return false ;
}
}
return resized ;
return resized ;
}
/ * *
* Repaint this group
* @ param { { start : number , end : number } } range
* @ param { { item : { horizontal : number , vertical : number } , axis : number } } margin
* @ param { boolean } [ forceRestack = false ] Force restacking of all items
* @ param { boolean } [ returnQueue = false ] return the queue or if the group resized
* @ return { boolean } Returns true if the group is resized or the redraw queue if returnQueue = true
* /
Group . prototype . redraw = function ( range , margin , forceRestack , returnQueue ) {
var resized = false ;
var lastIsVisible = this . isVisible ;
var height ;
var queue = [
// force recalculation of the height of the items when the marker height changed
// (due to the Timeline being attached to the DOM or changed from display:none to visible)
( function ( ) {
forceRestack = this . _didMarkerHeightChange . bind ( this ) ;
} ) . bind ( this ) ,
// recalculate the height of the subgroups
this . _updateSubGroupHeights . bind ( this , margin ) ,
// calculate actual size and position
this . _calculateGroupSizeAndPosition . bind ( this ) ,
// check if group is visible
( function ( ) {
this . isVisible = this . _isGroupVisible . bind ( this ) ( range , margin ) ;
} ) . bind ( this ) ,
// redraw Items if needed
( function ( ) {
this . _redrawItems . bind ( this ) ( forceRestack , lastIsVisible , margin , range )
} ) . bind ( this ) ,
// update subgroups
this . _updateSubgroupsSizes . bind ( this ) ,
// recalculate the height of the group
( function ( ) {
height = this . _calculateHeight . bind ( this ) ( margin ) ;
} ) . bind ( this ) ,
// calculate actual size and position again
this . _calculateGroupSizeAndPosition . bind ( this ) ,
// check if resized
( function ( ) {
resized = this . _didResize . bind ( this ) ( resized , height )
} ) . bind ( this ) ,
// apply group height
( function ( ) {
this . _applyGroupHeight . bind ( this ) ( height )
} ) . bind ( this ) ,
// update vertical position of items after they are re-stacked and the height of the group is calculated
( function ( ) {
return resized = this . _updateItemsVerticalPosition . bind ( this ) ( resized , margin )
} ) . bind ( this )
]
if ( returnQueue ) {
return queue ;
} else {
var result ;
queue . forEach ( function ( fn ) {
result = fn ( ) ;
} ) ;
return result ;
}
} ;
} ;
/ * *
/ * *
@ -324,7 +381,7 @@ Group.prototype.redraw = function(range, margin, forceRestack) {
* @ param { { item : vis . Item } } margin
* @ param { { item : vis . Item } } margin
* @ private
* @ private
* /
* /
Group . prototype . _calcul ateSubGroupHeights = function ( margin ) {
Group . prototype . _upd ateSubGroupHeights = function ( margin ) {
if ( Object . keys ( this . subgroups ) . length > 0 ) {
if ( Object . keys ( this . subgroups ) . length > 0 ) {
var me = this ;
var me = this ;