@ -26,8 +26,8 @@ var BACKGROUND = '__background__'; // reserved group id for background items wit
* /
* /
function ItemSet ( body , options ) {
function ItemSet ( body , options ) {
this . body = body ;
this . body = body ;
this . defaultOptions = {
this . defaultOptions = {
rtl : false ,
type : null , // 'box', 'point', 'range', 'background'
type : null , // 'box', 'point', 'range', 'background'
orientation : {
orientation : {
item : 'bottom' // item orientation: 'top' or 'bottom'
item : 'bottom' // item orientation: 'top' or 'bottom'
@ -96,7 +96,7 @@ function ItemSet(body, options) {
// options is shared by this ItemSet and all its items
// options is shared by this ItemSet and all its items
this . options = util . extend ( { } , this . defaultOptions ) ;
this . options = util . extend ( { } , this . defaultOptions ) ;
// options for getting items from the DataSet with the correct type
// options for getting items from the DataSet with the correct type
this . itemOptions = {
this . itemOptions = {
type : { start : 'Date' , end : 'Date' }
type : { start : 'Date' , end : 'Date' }
@ -230,8 +230,8 @@ ItemSet.prototype._create = function(){
// add item on doubletap
// add item on doubletap
this . hammer . on ( 'doubletap' , this . _onAddItem . bind ( this ) ) ;
this . hammer . on ( 'doubletap' , this . _onAddItem . bind ( this ) ) ;
this . groupHammer = new Hammer ( this . body . dom . leftContainer ) ;
this . groupHammer = new Hammer ( this . body . dom . leftContainer ) ;
this . groupHammer . on ( 'panstart' , this . _onGroupDragStart . bind ( this ) ) ;
this . groupHammer . on ( 'panstart' , this . _onGroupDragStart . bind ( this ) ) ;
this . groupHammer . on ( 'panmove' , this . _onGroupDrag . bind ( this ) ) ;
this . groupHammer . on ( 'panmove' , this . _onGroupDrag . bind ( this ) ) ;
this . groupHammer . on ( 'panend' , this . _onGroupDragEnd . bind ( this ) ) ;
this . groupHammer . on ( 'panend' , this . _onGroupDragEnd . bind ( this ) ) ;
@ -308,7 +308,7 @@ ItemSet.prototype._create = function(){
ItemSet . prototype . setOptions = function ( options ) {
ItemSet . prototype . setOptions = function ( options ) {
if ( options ) {
if ( options ) {
// copy all options that we know
// copy all options that we know
var fields = [ 'type' , 'align' , 'order' , 'stack' , 'selectable' , 'multiselect' , 'itemsAlwaysDraggable' , 'multiselectPerGroup' , 'groupOrder' , 'dataAttributes' , 'template' , 'groupTemplate' , 'hide' , 'snap' , 'groupOrderSwap' ] ;
var fields = [ 'type' , 'rtl' , ' align' , 'order' , 'stack' , 'selectable' , 'multiselect' , 'itemsAlwaysDraggable' , 'multiselectPerGroup' , 'groupOrder' , 'dataAttributes' , 'template' , 'groupTemplate' , 'hide' , 'snap' , 'groupOrderSwap' ] ;
util . selectiveExtend ( fields , this . options , options ) ;
util . selectiveExtend ( fields , this . options , options ) ;
if ( 'orientation' in options ) {
if ( 'orientation' in options ) {
@ -498,8 +498,14 @@ ItemSet.prototype.getSelection = function() {
* /
* /
ItemSet . prototype . getVisibleItems = function ( ) {
ItemSet . prototype . getVisibleItems = function ( ) {
var range = this . body . range . getRange ( ) ;
var range = this . body . range . getRange ( ) ;
var left = this . body . util . toScreen ( range . start ) ;
var right = this . body . util . toScreen ( range . end ) ;
if ( this . options . rtl ) {
var right = this . body . util . toScreen ( range . start ) ;
var left = this . body . util . toScreen ( range . end ) ;
} else {
var left = this . body . util . toScreen ( range . start ) ;
var right = this . body . util . toScreen ( range . end ) ;
}
var ids = [ ] ;
var ids = [ ] ;
for ( var groupId in this . groups ) {
for ( var groupId in this . groups ) {
@ -512,8 +518,14 @@ ItemSet.prototype.getVisibleItems = function() {
for ( var i = 0 ; i < rawVisibleItems . length ; i ++ ) {
for ( var i = 0 ; i < rawVisibleItems . length ; i ++ ) {
var item = rawVisibleItems [ i ] ;
var item = rawVisibleItems [ i ] ;
// TODO: also check whether visible vertically
// TODO: also check whether visible vertically
if ( ( item . left < right ) && ( item . left + item . width > left ) ) {
ids . push ( item . id ) ;
if ( this . options . rtl ) {
if ( ( item . right < left ) && ( item . right + item . width > right ) ) {
ids . push ( item . id ) ;
}
} else {
if ( ( item . left < right ) && ( item . left + item . width > left ) ) {
ids . push ( item . id ) ;
}
}
}
}
}
}
}
@ -552,7 +564,12 @@ ItemSet.prototype.redraw = function() {
// recalculate absolute position (before redrawing groups)
// recalculate absolute position (before redrawing groups)
this . props . top = this . body . domProps . top . height + this . body . domProps . border . top ;
this . props . top = this . body . domProps . top . height + this . body . domProps . border . top ;
this . props . left = this . body . domProps . left . width + this . body . domProps . border . left ;
if ( this . options . rtl ) {
this . props . right = this . body . domProps . right . width + this . body . domProps . border . right ;
} else {
this . props . left = this . body . domProps . left . width + this . body . domProps . border . left ;
}
// update class name
// update class name
frame . className = 'vis-itemset' ;
frame . className = 'vis-itemset' ;
@ -605,7 +622,11 @@ ItemSet.prototype.redraw = function() {
this . dom . axis . style . top = asSize ( ( orientation == 'top' ) ?
this . dom . axis . style . top = asSize ( ( orientation == 'top' ) ?
( this . body . domProps . top . height + this . body . domProps . border . top ) :
( this . body . domProps . top . height + this . body . domProps . border . top ) :
( this . body . domProps . top . height + this . body . domProps . centerContainer . height ) ) ;
( this . body . domProps . top . height + this . body . domProps . centerContainer . height ) ) ;
this . dom . axis . style . left = '0' ;
if ( this . options . rtl ) {
this . dom . axis . style . right = '0' ;
} else {
this . dom . axis . style . left = '0' ;
}
// check if this component is resized
// check if this component is resized
resized = this . _isResized ( ) || resized ;
resized = this . _isResized ( ) || resized ;
@ -1245,8 +1266,15 @@ ItemSet.prototype._onDragStart = function (event) {
* /
* /
ItemSet . prototype . _onDragStartAddItem = function ( event ) {
ItemSet . prototype . _onDragStartAddItem = function ( event ) {
var snap = this . options . snap || null ;
var snap = this . options . snap || null ;
var xAbs = util . getAbsoluteLeft ( this . dom . frame ) ;
var x = event . center . x - xAbs - 10 ; // minus 10 to compensate for the drag starting as soon as you've moved 10px
if ( this . options . rtl ) {
var xAbs = util . getAbsoluteRight ( this . dom . frame ) ;
var x = xAbs - event . center . x + 10 ; // plus 10 to compensate for the drag starting as soon as you've moved 10px
} else {
var xAbs = util . getAbsoluteLeft ( this . dom . frame ) ;
var x = event . center . x - xAbs - 10 ; // minus 10 to compensate for the drag starting as soon as you've moved 10px
}
var time = this . body . util . toTime ( x ) ;
var time = this . body . util . toTime ( x ) ;
var scale = this . body . util . getScale ( ) ;
var scale = this . body . util . getScale ( ) ;
var step = this . body . util . getStep ( ) ;
var step = this . body . util . getStep ( ) ;
@ -1267,7 +1295,6 @@ ItemSet.prototype._onDragStartAddItem = function (event) {
if ( group ) {
if ( group ) {
itemData . group = group . groupId ;
itemData . group = group . groupId ;
}
}
var newItem = new RangeItem ( itemData , this . conversion , this . options ) ;
var newItem = new RangeItem ( itemData , this . conversion , this . options ) ;
newItem . id = id ; // TODO: not so nice setting id afterwards
newItem . id = id ; // TODO: not so nice setting id afterwards
newItem . data = this . _cloneItemData ( itemData ) ;
newItem . data = this . _cloneItemData ( itemData ) ;
@ -1275,10 +1302,15 @@ ItemSet.prototype._onDragStartAddItem = function (event) {
var props = {
var props = {
item : newItem ,
item : newItem ,
dragRight : true ,
initialX : event . center . x ,
initialX : event . center . x ,
data : newItem . data
data : newItem . data
} ;
} ;
if ( this . options . rtl ) {
props . dragLeft = true ;
} else {
props . dragRight = true ;
}
this . touchParams . itemProps = [ props ] ;
this . touchParams . itemProps = [ props ] ;
event . stopPropagation ( ) ;
event . stopPropagation ( ) ;
@ -1295,7 +1327,13 @@ ItemSet.prototype._onDrag = function (event) {
var me = this ;
var me = this ;
var snap = this . options . snap || null ;
var snap = this . options . snap || null ;
var xOffset = this . body . dom . root . offsetLeft + this . body . domProps . left . width ;
if ( this . options . rtl ) {
var xOffset = this . body . dom . root . offsetLeft + this . body . domProps . right . width ;
} else {
var xOffset = this . body . dom . root . offsetLeft + this . body . domProps . left . width ;
}
var scale = this . body . util . getScale ( ) ;
var scale = this . body . util . getScale ( ) ;
var step = this . body . util . getStep ( ) ;
var step = this . body . util . getStep ( ) ;
@ -1319,7 +1357,12 @@ ItemSet.prototype._onDrag = function (event) {
this . touchParams . itemProps . forEach ( function ( props ) {
this . touchParams . itemProps . forEach ( function ( props ) {
var current = me . body . util . toTime ( event . center . x - xOffset ) ;
var current = me . body . util . toTime ( event . center . x - xOffset ) ;
var initial = me . body . util . toTime ( props . initialX - xOffset ) ;
var initial = me . body . util . toTime ( props . initialX - xOffset ) ;
var offset = current - initial ; // ms
if ( this . options . rtl ) {
var offset = - ( current - initial ) ; // ms
} else {
var offset = ( current - initial ) ; // ms
}
var itemData = this . _cloneItemData ( props . item . data ) ; // clone the data
var itemData = this . _cloneItemData ( props . item . data ) ; // clone the data
if ( props . item . editable === false ) {
if ( props . item . editable === false ) {
@ -1328,29 +1371,47 @@ ItemSet.prototype._onDrag = function (event) {
var updateTimeAllowed = me . options . editable . updateTime ||
var updateTimeAllowed = me . options . editable . updateTime ||
props . item . editable === true ;
props . item . editable === true ;
if ( updateTimeAllowed ) {
if ( updateTimeAllowed ) {
if ( props . dragLeft ) {
if ( props . dragLeft ) {
// drag left side of a range item
// drag left side of a range item
if ( itemData . start != undefined ) {
var initialStart = util . convert ( props . data . start , 'Date' ) ;
var start = new Date ( initialStart . valueOf ( ) + offset ) ;
// TODO: pass a Moment instead of a Date to snap(). (Breaking change)
itemData . start = snap ? snap ( start , scale , step ) : start ;
if ( this . options . rtl ) {
if ( itemData . end != undefined ) {
var initialEnd = util . convert ( props . data . end , 'Date' ) ;
var end = new Date ( initialEnd . valueOf ( ) + offset ) ;
// TODO: pass a Moment instead of a Date to snap(). (Breaking change)
itemData . end = snap ? snap ( end , scale , step ) : end ;
}
} else {
if ( itemData . start != undefined ) {
var initialStart = util . convert ( props . data . start , 'Date' ) ;
var start = new Date ( initialStart . valueOf ( ) + offset ) ;
// TODO: pass a Moment instead of a Date to snap(). (Breaking change)
itemData . start = snap ? snap ( start , scale , step ) : start ;
}
}
}
}
}
else if ( props . dragRight ) {
else if ( props . dragRight ) {
// drag right side of a range item
// drag right side of a range item
if ( itemData . end != undefined ) {
var initialEnd = util . convert ( props . data . end , 'Date' ) ;
var end = new Date ( initialEnd . valueOf ( ) + offset ) ;
// TODO: pass a Moment instead of a Date to snap(). (Breaking change)
itemData . end = snap ? snap ( end , scale , step ) : end ;
if ( this . options . rtl ) {
if ( itemData . start != undefined ) {
var initialStart = util . convert ( props . data . start , 'Date' ) ;
var start = new Date ( initialStart . valueOf ( ) + offset ) ;
// TODO: pass a Moment instead of a Date to snap(). (Breaking change)
itemData . start = snap ? snap ( start , scale , step ) : start ;
}
} else {
if ( itemData . end != undefined ) {
var initialEnd = util . convert ( props . data . end , 'Date' ) ;
var end = new Date ( initialEnd . valueOf ( ) + offset ) ;
// TODO: pass a Moment instead of a Date to snap(). (Breaking change)
itemData . end = snap ? snap ( end , scale , step ) : end ;
}
}
}
}
}
else {
else {
// drag both start and end
// drag both start and end
if ( itemData . start != undefined ) {
if ( itemData . start != undefined ) {
var initialStart = util . convert ( props . data . start , 'Date' ) . valueOf ( ) ;
var initialStart = util . convert ( props . data . start , 'Date' ) . valueOf ( ) ;
var start = new Date ( initialStart + offset ) ;
var start = new Date ( initialStart + offset ) ;
@ -1366,6 +1427,8 @@ ItemSet.prototype._onDrag = function (event) {
// TODO: pass a Moment instead of a Date to snap(). (Breaking change)
// TODO: pass a Moment instead of a Date to snap(). (Breaking change)
itemData . start = snap ? snap ( start , scale , step ) : start ;
itemData . start = snap ? snap ( start , scale , step ) : start ;
}
}
}
}
}
}
}
}
@ -1706,8 +1769,15 @@ ItemSet.prototype._onAddItem = function (event) {
}
}
else {
else {
// add item
// add item
var xAbs = util . getAbsoluteLeft ( this . dom . frame ) ;
var x = event . center . x - xAbs ;
if ( this . options . rtl ) {
var xAbs = util . getAbsoluteRight ( this . dom . frame ) ;
var x = xAbs - event . center . x ;
} else {
var xAbs = util . getAbsoluteLeft ( this . dom . frame ) ;
var x = event . center . x - xAbs ;
}
// var xAbs = util.getAbsoluteLeft(this.dom.frame);
// var x = event.center.x - xAbs;
var start = this . body . util . toTime ( x ) ;
var start = this . body . util . toTime ( x ) ;
var scale = this . body . util . getScale ( ) ;
var scale = this . body . util . getScale ( ) ;
var step = this . body . util . getStep ( ) ;
var step = this . body . util . getStep ( ) ;