|
@ -11,7 +11,7 @@ function Timeline (container, items, options) { |
|
|
this.options = { |
|
|
this.options = { |
|
|
orientation: 'bottom', |
|
|
orientation: 'bottom', |
|
|
autoResize: true, |
|
|
autoResize: true, |
|
|
editable: true, |
|
|
|
|
|
|
|
|
editable: false, |
|
|
selectable: true, |
|
|
selectable: true, |
|
|
snap: null, // will be specified after timeaxis is created
|
|
|
snap: null, // will be specified after timeaxis is created
|
|
|
|
|
|
|
|
@ -25,7 +25,20 @@ function Timeline (container, items, options) { |
|
|
showMinorLabels: true, |
|
|
showMinorLabels: true, |
|
|
showMajorLabels: true, |
|
|
showMajorLabels: true, |
|
|
showCurrentTime: false, |
|
|
showCurrentTime: false, |
|
|
showCustomTime: false |
|
|
|
|
|
|
|
|
showCustomTime: false, |
|
|
|
|
|
|
|
|
|
|
|
onAdd: function (item, callback) { |
|
|
|
|
|
callback(item); |
|
|
|
|
|
}, |
|
|
|
|
|
onUpdate: function (item, callback) { |
|
|
|
|
|
callback(item); |
|
|
|
|
|
}, |
|
|
|
|
|
onMoved: function (item, callback) { |
|
|
|
|
|
callback(item); |
|
|
|
|
|
}, |
|
|
|
|
|
onRemove: function (item, callback) { |
|
|
|
|
|
callback(item); |
|
|
|
|
|
} |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
// controller
|
|
|
// controller
|
|
@ -57,6 +70,9 @@ function Timeline (container, items, options) { |
|
|
// multi select when holding mouse/touch, or on ctrl+click
|
|
|
// multi select when holding mouse/touch, or on ctrl+click
|
|
|
this.controller.on('hold', this._onMultiSelectItem.bind(this)); |
|
|
this.controller.on('hold', this._onMultiSelectItem.bind(this)); |
|
|
|
|
|
|
|
|
|
|
|
// add item on doubletap
|
|
|
|
|
|
this.controller.on('doubletap', this._onAddItem.bind(this)); |
|
|
|
|
|
|
|
|
// item panel
|
|
|
// item panel
|
|
|
var itemOptions = Object.create(this.options); |
|
|
var itemOptions = Object.create(this.options); |
|
|
itemOptions.left = function () { |
|
|
itemOptions.left = function () { |
|
@ -408,9 +424,7 @@ Timeline.prototype.getSelection = function getSelection() { |
|
|
*/ |
|
|
*/ |
|
|
// TODO: move this function to ItemSet
|
|
|
// TODO: move this function to ItemSet
|
|
|
Timeline.prototype._onSelectItem = function (event) { |
|
|
Timeline.prototype._onSelectItem = function (event) { |
|
|
if (!this.options.selectable) { |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (!this.options.selectable) return; |
|
|
|
|
|
|
|
|
var item = ItemSet.itemFromTarget(event); |
|
|
var item = ItemSet.itemFromTarget(event); |
|
|
|
|
|
|
|
@ -424,6 +438,63 @@ Timeline.prototype._onSelectItem = function (event) { |
|
|
event.stopPropagation(); |
|
|
event.stopPropagation(); |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Handle creation and updates of an item on double tap |
|
|
|
|
|
* @param event |
|
|
|
|
|
* @private |
|
|
|
|
|
*/ |
|
|
|
|
|
Timeline.prototype._onAddItem = function (event) { |
|
|
|
|
|
if (!this.options.selectable) return; |
|
|
|
|
|
|
|
|
|
|
|
var me = this, |
|
|
|
|
|
item = ItemSet.itemFromTarget(event); |
|
|
|
|
|
|
|
|
|
|
|
if (item) { |
|
|
|
|
|
// update item
|
|
|
|
|
|
|
|
|
|
|
|
// execute async handler to update the item (or cancel it)
|
|
|
|
|
|
var itemData = me.itemsData.get(item.id); // get a clone of the data from the dataset
|
|
|
|
|
|
this.options.onUpdate(itemData, function (itemData) { |
|
|
|
|
|
if (itemData) { |
|
|
|
|
|
me.itemsData.update(itemData); |
|
|
|
|
|
} |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
// add item
|
|
|
|
|
|
var xAbs = vis.util.getAbsoluteLeft(this.rootPanel.frame); |
|
|
|
|
|
var x = event.gesture.center.pageX - xAbs; |
|
|
|
|
|
var newItem = { |
|
|
|
|
|
start: this.timeaxis.snap(this._toTime(x)), |
|
|
|
|
|
content: 'new item' |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
var id = util.randomUUID(); |
|
|
|
|
|
newItem[this.itemsData.fieldId] = id; |
|
|
|
|
|
|
|
|
|
|
|
var group = GroupSet.groupFromTarget(event); |
|
|
|
|
|
if (group) { |
|
|
|
|
|
newItem.group = group.groupId; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// execute async handler to customize (or cancel) adding an item
|
|
|
|
|
|
this.options.onAdd(newItem, function (item) { |
|
|
|
|
|
if (item) { |
|
|
|
|
|
me.itemsData.add(newItem); |
|
|
|
|
|
|
|
|
|
|
|
// select the created item after it is repainted
|
|
|
|
|
|
me.controller.once('repaint', function () { |
|
|
|
|
|
me.setSelection([id]); |
|
|
|
|
|
|
|
|
|
|
|
me.controller.emit('select', { |
|
|
|
|
|
items: me.getSelection() |
|
|
|
|
|
}); |
|
|
|
|
|
}.bind(me)); |
|
|
|
|
|
} |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* Handle selecting/deselecting multiple items when holding an item |
|
|
* Handle selecting/deselecting multiple items when holding an item |
|
|
* @param {Event} event |
|
|
* @param {Event} event |
|
@ -431,9 +502,7 @@ Timeline.prototype._onSelectItem = function (event) { |
|
|
*/ |
|
|
*/ |
|
|
// TODO: move this function to ItemSet
|
|
|
// TODO: move this function to ItemSet
|
|
|
Timeline.prototype._onMultiSelectItem = function (event) { |
|
|
Timeline.prototype._onMultiSelectItem = function (event) { |
|
|
if (!this.options.selectable) { |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (!this.options.selectable) return; |
|
|
|
|
|
|
|
|
var selection, |
|
|
var selection, |
|
|
item = ItemSet.itemFromTarget(event); |
|
|
item = ItemSet.itemFromTarget(event); |
|
@ -460,33 +529,7 @@ Timeline.prototype._onMultiSelectItem = function (event) { |
|
|
} |
|
|
} |
|
|
else { |
|
|
else { |
|
|
// create a new item
|
|
|
// create a new item
|
|
|
var xAbs = vis.util.getAbsoluteLeft(this.rootPanel.frame); |
|
|
|
|
|
var x = event.gesture.center.pageX - xAbs; |
|
|
|
|
|
var newItem = { |
|
|
|
|
|
start: this.timeaxis.snap(this._toTime(x)), |
|
|
|
|
|
content: 'new item' |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
var id = util.randomUUID(); |
|
|
|
|
|
newItem[this.itemsData.fieldId] = id; |
|
|
|
|
|
|
|
|
|
|
|
var group = GroupSet.groupFromTarget(event); |
|
|
|
|
|
if (group) { |
|
|
|
|
|
newItem.group = group.groupId; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// TODO: implement an async handler to customize adding an item
|
|
|
|
|
|
|
|
|
|
|
|
this.itemsData.add(newItem); |
|
|
|
|
|
|
|
|
|
|
|
// select the created item after it is repainted
|
|
|
|
|
|
this.controller.once('repaint', function () { |
|
|
|
|
|
this.setSelection([id]); |
|
|
|
|
|
|
|
|
|
|
|
this.controller.emit('select', { |
|
|
|
|
|
items: this.getSelection() |
|
|
|
|
|
}); |
|
|
|
|
|
}.bind(this)); |
|
|
|
|
|
|
|
|
this._onAddItem(event); |
|
|
} |
|
|
} |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|