diff --git a/dist/vis.css b/dist/vis.css index 32bfe22c..64f86eac 100644 --- a/dist/vis.css +++ b/dist/vis.css @@ -11,7 +11,7 @@ box-sizing: border-box; } -.vis.timeline .panel { +.vis.timeline .vpanel { position: absolute; overflow: hidden; } @@ -51,7 +51,7 @@ border-bottom: 1px solid #bfbfbf; } -.vis.timeline .labels .label-set .label { +.vis.timeline .labels .label-set .vlabel { position: absolute; left: 0; top: 0; @@ -59,19 +59,19 @@ color: #4d4d4d; } -.vis.timeline.top .labels .label-set .label, +.vis.timeline.top .labels .label-set .vlabel, .vis.timeline.top .groupset .itemset-axis { border-top: 1px solid #bfbfbf; border-bottom: none; } -.vis.timeline.bottom .labels .label-set .label, +.vis.timeline.bottom .labels .label-set .vlabel, .vis.timeline.bottom .groupset .itemset-axis { border-top: none; border-bottom: 1px solid #bfbfbf; } -.vis.timeline .labels .label-set .label .inner { +.vis.timeline .labels .label-set .vlabel .inner { display: inline-block; padding: 5px; } @@ -101,6 +101,7 @@ border-color: #97B0F8; background-color: #D5DDF6; display: inline-block; + padding: 5px; } .vis.timeline .item.selected { @@ -109,6 +110,10 @@ z-index: 999; } +.vis.timeline.editable .item.selected { + cursor: move; +} + .vis.timeline .item.point.selected { background-color: #FFF785; z-index: 999; @@ -139,43 +144,35 @@ } .vis.timeline .dot { + padding: 0; border: 5px solid #97B0F8; position: absolute; border-radius: 5px; -moz-border-radius: 5px; /* For Firefox 3.6 and older */ } -.vis.timeline .item.range { - overflow: hidden; +.vis.timeline .item.range, +.vis.timeline .item.rangeoverflow{ border-style: solid; border-width: 1px; border-radius: 2px; -moz-border-radius: 2px; /* For Firefox 3.6 and older */ + box-sizing: border-box; } -.vis.timeline .item.rangeoverflow { - border-style: solid; - border-width: 1px; - border-radius: 2px; - -moz-border-radius: 2px; /* For Firefox 3.6 and older */ -} - -.vis.timeline .item.range .drag-left, .vis.timeline .item.rangeoverflow .drag-left { - cursor: w-resize; - z-index: 1000; -} - -.vis.timeline .item.range .drag-right, .vis.timeline .item.rangeoverflow .drag-right { - cursor: e-resize; - z-index: 1000; -} - -.vis.timeline .item.range .content, .vis.timeline .item.rangeoverflow .content { +.vis.timeline .item.range .content, +.vis.timeline .item.rangeoverflow .content { position: relative; display: inline-block; } +.vis.timeline .item.range .content { + overflow: hidden; + max-width: 100%; +} + .vis.timeline .item.line { + padding: 0; position: absolute; width: 0; border-left-width: 1px; @@ -183,11 +180,44 @@ } .vis.timeline .item .content { - margin: 5px; white-space: nowrap; overflow: hidden; } +.vis.timeline .item .delete { + background: url('img/timeline/delete.png') no-repeat top center; + position: absolute; + width: 24px; + height: 24px; + top: 0; + right: -24px; + cursor: pointer; +} + +.vis.timeline .item.range .drag-left, +.vis.timeline .item.rangeoverflow .drag-left { + position: absolute; + width: 24px; + height: 100%; + top: 0; + left: -4px; + + cursor: w-resize; + z-index: 10000; +} + +.vis.timeline .item.range .drag-right, +.vis.timeline .item.rangeoverflow .drag-right { + position: absolute; + width: 24px; + height: 100%; + top: 0; + right: -4px; + + cursor: e-resize; + z-index: 10001; /* a little higher z-index than .drag-left */ +} + .vis.timeline .axis { position: relative; } diff --git a/src/graph/Graph.js b/src/graph/Graph.js index fd402de6..81427587 100644 --- a/src/graph/Graph.js +++ b/src/graph/Graph.js @@ -231,6 +231,9 @@ function Graph (container, data, options) { } } +// Extend Graph with an Emitter mixin +Emitter(Graph.prototype); + /** * Get the script path where the vis.js library is located * @@ -592,44 +595,6 @@ Graph.prototype.setOptions = function (options) { this._redraw(); }; -/** - * Add event listener - * @param {String} event Event name. Available events: - * 'select' - * @param {function} callback Callback function, invoked as callback(properties) - * where properties is an optional object containing - * event specific properties. - */ -Graph.prototype.on = function on (event, callback) { - var available = ['select','frameResize']; - - if (available.indexOf(event) == -1) { - throw new Error('Unknown event "' + event + '". Choose from ' + available.join()); - } - - events.addListener(this, event, callback); -}; - -/** - * Remove an event listener - * @param {String} event Event name - * @param {function} callback Callback function - */ -Graph.prototype.off = function off (event, callback) { - events.removeListener(this, event, callback); -}; - -/** - * fire an event - * @param {String} event The name of an event, for example 'select' - * @param {Object} params Optional object with event parameters - * @private - */ -Graph.prototype._trigger = function (event, params) { - events.trigger(this, event, params); -}; - - /** * Create the main frame for the Graph. * This function is executed once when a Graph object is created. The frame @@ -1173,7 +1138,7 @@ Graph.prototype.setSize = function(width, height) { this.manipulationDiv.style.width = this.frame.canvas.clientWidth; } - this._trigger('frameResize', {width:this.frame.canvas.width,height:this.frame.canvas.height}); + this.emit('frameResize', {width:this.frame.canvas.width,height:this.frame.canvas.height}); }; /** @@ -1212,7 +1177,7 @@ Graph.prototype._setNodes = function(nodes) { // subscribe to new dataset var me = this; util.forEach(this.nodesListeners, function (callback, event) { - me.nodesData.subscribe(event, callback); + me.nodesData.on(event, callback); }); // draw all new nodes @@ -1338,7 +1303,7 @@ Graph.prototype._setEdges = function(edges) { // subscribe to new dataset var me = this; util.forEach(this.edgesListeners, function (callback, event) { - me.edgesData.subscribe(event, callback); + me.edgesData.on(event, callback); }); // draw all new nodes @@ -1638,6 +1603,7 @@ Graph.prototype._drawNodes = function(ctx,alwaysShow) { if (alwaysShow === undefined) { alwaysShow = false; } + // first draw the unselected nodes var nodes = this.nodes; var selected = []; diff --git a/src/graph/graphMixins/SelectionMixin.js b/src/graph/graphMixins/SelectionMixin.js index 01b59511..6de9305d 100644 --- a/src/graph/graphMixins/SelectionMixin.js +++ b/src/graph/graphMixins/SelectionMixin.js @@ -165,7 +165,7 @@ var SelectionMixin = { this.selectionObj = {}; if (doNotTrigger == false) { - this._trigger('select', this.getSelection()); + this.emit('select', this.getSelection()); } }, @@ -192,7 +192,7 @@ var SelectionMixin = { } if (doNotTrigger == false) { - this._trigger('select', this.getSelection()); + this.emit('select', this.getSelection()); } }, @@ -364,7 +364,7 @@ var SelectionMixin = { this._removeFromSelection(object); } if (doNotTrigger == false) { - this._trigger('select', this.getSelection()); + this.emit('select', this.getSelection()); } }, diff --git a/src/timeline/component/item/Item.js b/src/timeline/component/item/Item.js index 33e74285..4b9faf45 100644 --- a/src/timeline/component/item/Item.js +++ b/src/timeline/component/item/Item.js @@ -74,9 +74,43 @@ Item.prototype.reflow = function reflow() { }; /** - * Return the items width - * @return {Integer} width + * Give the item a display offset in pixels + * @param {Number} offset Offset on screen in pixels */ -Item.prototype.getWidth = function getWidth() { - return this.width; -} +Item.prototype.setOffset = function setOffset(offset) { + this.offset = offset; +}; + +/** + * Repaint a delete button on the top right of the item when the item is selected + * @param {HTMLElement} anchor + * @private + */ +Item.prototype._repaintDeleteButton = function (anchor) { + if (this.selected && this.options.editable && !this.dom.deleteButton) { + // create and show button + var parent = this.parent; + var id = this.id; + + var deleteButton = document.createElement('div'); + deleteButton.className = 'delete'; + deleteButton.title = 'Delete this item'; + + Hammer(deleteButton, { + preventDefault: true + }).on('tap', function (event) { + parent.removeItem(id); + event.stopPropagation(); + }); + + anchor.appendChild(deleteButton); + this.dom.deleteButton = deleteButton; + } + else if (!this.selected && this.dom.deleteButton) { + // remove button + if (this.dom.deleteButton.parentNode) { + this.dom.deleteButton.parentNode.removeChild(this.dom.deleteButton); + } + this.dom.deleteButton = null; + } +};