From 8ef8a1e0b2fd4938c3b5fc4b7aa8001f11e71884 Mon Sep 17 00:00:00 2001
From: jos
Date: Thu, 12 Jun 2014 15:23:02 +0200
Subject: [PATCH 01/37] Implemented options `zoomable` and `moveable`
---
HISTORY.md | 2 ++
docs/timeline.html | 20 ++++++++++++++++++++
src/timeline/Range.js | 24 ++++++++++++++++++++++--
src/timeline/Timeline.js | 2 --
4 files changed, 44 insertions(+), 4 deletions(-)
diff --git a/HISTORY.md b/HISTORY.md
index 5f65d033..23cbe489 100644
--- a/HISTORY.md
+++ b/HISTORY.md
@@ -6,7 +6,9 @@ http://visjs.org
### Timeline
+- Implemented options `zoomable` and `moveable`.
- Changed default value of option `showCurrentTime` to true.
+- Internal refactoring and simplification of the code.
### Graph
diff --git a/docs/timeline.html b/docs/timeline.html
index 43abb226..544aa463 100644
--- a/docs/timeline.html
+++ b/docs/timeline.html
@@ -458,6 +458,16 @@ var options = {
Specifies the minimum height for the Timeline. Can be a number in pixels or a string like "300px".
+
+
moveable
+
Boolean
+
true
+
+ Specifies whether the Timeline can be moved and zoomed by dragging the window.
+ See also option zoomable.
+
+
+
onAdd
Function
@@ -599,6 +609,16 @@ var options = {
The width of the timeline in pixels or as a percentage.
+
+
zoomable
+
Boolean
+
true
+
+ Specifies whether the Timeline can be zoomed by pinching or scrolling in the window.
+ Only applicable when option moveable is set true.
+
+
+
zoomMax
Number
diff --git a/src/timeline/Range.js b/src/timeline/Range.js
index 4aa1c4fc..266472b1 100644
--- a/src/timeline/Range.js
+++ b/src/timeline/Range.js
@@ -18,6 +18,8 @@ function Range(body, options) {
start: null,
end: null,
direction: 'horizontal', // 'horizontal' or 'vertical'
+ moveable: true,
+ zoomable: true,
min: null,
max: null,
zoomMin: 10, // milliseconds
@@ -57,11 +59,16 @@ Range.prototype = new Component();
* (end - start).
* {Number} zoomMax Set a maximum value for
* (end - start).
+ * {Boolean} moveable Enable moving of the range
+ * by dragging. True by default
+ * {Boolean} zoomable Enable zooming of the range
+ * by pinching/scrolling. True by default
*/
Range.prototype.setOptions = function (options) {
if (options) {
// copy the options that we know
- util.selectiveExtend(['direction', 'min', 'max', 'zoomMin', 'zoomMax'], this.options, options);
+ var fields = ['direction', 'min', 'max', 'zoomMin', 'zoomMax', 'moveable', 'zoomable'];
+ util.selectiveExtend(fields, this.options, options);
if ('start' in options || 'end' in options) {
// apply a new range. both start and end are optional
@@ -262,6 +269,9 @@ var touchParams = {};
* @private
*/
Range.prototype._onDragStart = function(event) {
+ // only allow dragging when configured as movable
+ if (!this.options.moveable) return;
+
// refuse to drag when we where pinching to prevent the timeline make a jump
// when releasing the fingers in opposite order from the touch screen
if (touchParams.ignore) return;
@@ -282,6 +292,9 @@ Range.prototype._onDragStart = function(event) {
* @private
*/
Range.prototype._onDrag = function (event) {
+ // only allow dragging when configured as movable
+ if (!this.options.moveable) return;
+
var direction = this.options.direction;
validateDirection(direction);
@@ -311,6 +324,9 @@ Range.prototype._onDrag = function (event) {
* @private
*/
Range.prototype._onDragEnd = function (event) {
+ // only allow dragging when configured as movable
+ if (!this.options.moveable) return;
+
// refuse to drag when we where pinching to prevent the timeline make a jump
// when releasing the fingers in opposite order from the touch screen
if (touchParams.ignore) return;
@@ -335,7 +351,8 @@ Range.prototype._onDragEnd = function (event) {
* @private
*/
Range.prototype._onMouseWheel = function(event) {
- // TODO: reckon with option zoomable
+ // only allow zooming when configured as zoomable and moveable
+ if (!(this.options.zoomable && this.options.moveable)) return;
// retrieve delta
var delta = 0;
@@ -408,6 +425,9 @@ Range.prototype._onHold = function () {
* @private
*/
Range.prototype._onPinch = function (event) {
+ // only allow zooming when configured as zoomable and moveable
+ if (!(this.options.zoomable && this.options.moveable)) return;
+
touchParams.ignore = true;
// TODO: reckon with option zoomable
diff --git a/src/timeline/Timeline.js b/src/timeline/Timeline.js
index 15429a0f..76dc4e35 100644
--- a/src/timeline/Timeline.js
+++ b/src/timeline/Timeline.js
@@ -17,8 +17,6 @@ function Timeline (container, items, options) {
height: null,
maxHeight: null,
minHeight: null
-
- // TODO: implement options moveable and zoomable
};
this.options = util.deepExtend({}, this.defaultOptions);
From f133b3e035e832b4ec3da7d5f60c9993650c2106 Mon Sep 17 00:00:00 2001
From: jos
Date: Thu, 12 Jun 2014 15:43:06 +0200
Subject: [PATCH 02/37] Updated main example in docs
---
docs/index.html | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/docs/index.html b/docs/index.html
index 7a83de95..1d6e3bd8 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -162,16 +162,23 @@ var timeline = new vis.Timeline(container, data, options);
<div id="visualization"></div>
<script type="text/javascript">
+ // DOM element where the Timeline will be attached
var container = document.getElementById('visualization');
- var data = [
+
+ // Create a DataSet (allows two way data-binding)
+ var data = new vis.DataSet([
{id: 1, content: 'item 1', start: '2013-04-20'},
{id: 2, content: 'item 2', start: '2013-04-14'},
{id: 3, content: 'item 3', start: '2013-04-18'},
{id: 4, content: 'item 4', start: '2013-04-16', end: '2013-04-19'},
{id: 5, content: 'item 5', start: '2013-04-25'},
{id: 6, content: 'item 6', start: '2013-04-27'}
- ];
+ ]);
+
+ // Configuration for the Timeline
var options = {};
+
+ // Create a Timeline
var timeline = new vis.Timeline(container, data, options);
</script>
</body>
From 62bc49b1e17c68234612aedef2aaac2f48a7b2ff Mon Sep 17 00:00:00 2001
From: jos
Date: Thu, 12 Jun 2014 16:24:54 +0200
Subject: [PATCH 03/37] Removed some redundant code
---
src/timeline/component/ItemSet.js | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/src/timeline/component/ItemSet.js b/src/timeline/component/ItemSet.js
index 8e1f8274..95c5ed86 100644
--- a/src/timeline/component/ItemSet.js
+++ b/src/timeline/component/ItemSet.js
@@ -430,14 +430,8 @@ ItemSet.prototype.redraw = function() {
height = Math.max(height, minHeight);
this.stackDirty = false;
- // reposition frame
- frame.style.left = asSize(options.left, '');
- frame.style.right = asSize(options.right, '');
- frame.style.top = asSize((orientation == 'top') ? '0' : '');
- frame.style.bottom = asSize((orientation == 'top') ? '' : '0');
- frame.style.width = asSize(options.width, '100%');
+ // update frame height
frame.style.height = asSize(height);
- //frame.style.height = asSize('height' in options ? options.height : height); // TODO: reckon with height
// calculate actual size and position
this.props.top = frame.offsetTop;
From 1a9325da612b5a864a64a1f3c4729110d37c203f Mon Sep 17 00:00:00 2001
From: jos
Date: Thu, 12 Jun 2014 16:31:33 +0200
Subject: [PATCH 04/37] Added missing option orientation needed by Timeline
itself
---
src/timeline/Timeline.js | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/timeline/Timeline.js b/src/timeline/Timeline.js
index 76dc4e35..bf4e0965 100644
--- a/src/timeline/Timeline.js
+++ b/src/timeline/Timeline.js
@@ -13,6 +13,7 @@ function Timeline (container, items, options) {
autoResize: true,
+ orientation: 'bottom',
width: null,
height: null,
maxHeight: null,
@@ -181,6 +182,9 @@ Timeline.prototype._create = function (container) {
/**
* Set options. Options will be passed to all components loaded in the Timeline.
* @param {Object} [options]
+ * {String} orientation
+ * Vertical orienation for the Timeline:
+ * 'bottom' (default) or 'top'
* {String | Number} width
* Width for the timeline, a number in pixels or
* a css string like '1000px' or '75%'. '100%' by default.
@@ -203,7 +207,7 @@ Timeline.prototype._create = function (container) {
Timeline.prototype.setOptions = function (options) {
if (options) {
// copy the known options
- var fields = ['width', 'height', 'minHeight', 'maxHeight', 'autoResize', 'start', 'end'];
+ var fields = ['width', 'height', 'minHeight', 'maxHeight', 'autoResize', 'start', 'end', 'orientation'];
util.selectiveExtend(fields, this.options, options);
// enable/disable autoResize
From 0420c72b608df732a766a547e6600d9922224a10 Mon Sep 17 00:00:00 2001
From: jos
Date: Thu, 12 Jun 2014 17:35:22 +0200
Subject: [PATCH 05/37] Implemented support for vertical dragging (needs some
refinement)
---
HISTORY.md | 1 +
src/timeline/Range.js | 15 ++-----
src/timeline/Timeline.js | 92 ++++++++++++++++++++++++++++++++++++----
3 files changed, 87 insertions(+), 21 deletions(-)
diff --git a/HISTORY.md b/HISTORY.md
index 23cbe489..5a0e9d50 100644
--- a/HISTORY.md
+++ b/HISTORY.md
@@ -6,6 +6,7 @@ http://visjs.org
### Timeline
+- Implemented support for dragging the timeline contents vertically.
- Implemented options `zoomable` and `moveable`.
- Changed default value of option `showCurrentTime` to true.
- Internal refactoring and simplification of the code.
diff --git a/src/timeline/Range.js b/src/timeline/Range.js
index 266472b1..250de3b5 100644
--- a/src/timeline/Range.js
+++ b/src/timeline/Range.js
@@ -276,8 +276,6 @@ Range.prototype._onDragStart = function(event) {
// when releasing the fingers in opposite order from the touch screen
if (touchParams.ignore) return;
- // TODO: reckon with option movable
-
touchParams.start = this.start;
touchParams.end = this.end;
@@ -287,7 +285,7 @@ Range.prototype._onDragStart = function(event) {
};
/**
- * Perform dragging operating.
+ * Perform dragging operation
* @param {Event} event
* @private
*/
@@ -298,9 +296,6 @@ Range.prototype._onDrag = function (event) {
var direction = this.options.direction;
validateDirection(direction);
- // TODO: reckon with option movable
-
-
// refuse to drag when we where pinching to prevent the timeline make a jump
// when releasing the fingers in opposite order from the touch screen
if (touchParams.ignore) return;
@@ -319,7 +314,7 @@ Range.prototype._onDrag = function (event) {
};
/**
- * Stop dragging operating.
+ * Stop dragging operation
* @param {event} event
* @private
*/
@@ -331,8 +326,6 @@ Range.prototype._onDragEnd = function (event) {
// when releasing the fingers in opposite order from the touch screen
if (touchParams.ignore) return;
- // TODO: reckon with option movable
-
if (this.body.dom.root) {
this.body.dom.root.style.cursor = 'auto';
}
@@ -404,7 +397,7 @@ Range.prototype._onTouch = function (event) {
touchParams.center = null;
// don't move the range when dragging a selected event
- // TODO: it's not so neat to have to know about the state of the ItemSet
+ // TODO: it's not so neat to have to know about ItemSet here
var item = ItemSet.itemFromTarget(event);
if (item && item.selected && this.options.editable) {
touchParams.ignore = true;
@@ -430,8 +423,6 @@ Range.prototype._onPinch = function (event) {
touchParams.ignore = true;
- // TODO: reckon with option zoomable
-
if (event.gesture.touches.length > 1) {
if (!touchParams.center) {
touchParams.center = getPointer(event.gesture.center, this.body.dom.center);
diff --git a/src/timeline/Timeline.js b/src/timeline/Timeline.js
index bf4e0965..2b68a5e5 100644
--- a/src/timeline/Timeline.js
+++ b/src/timeline/Timeline.js
@@ -135,6 +135,8 @@ Timeline.prototype._create = function (container) {
this.on('rangechange', this.redraw.bind(this));
this.on('change', this.redraw.bind(this));
+ this.on('dragstart', this._onDragStart.bind(this));
+ this.on('drag', this._onDrag.bind(this));
// create event listeners for all interesting events, these events will be
// emitted via emitter
@@ -146,7 +148,7 @@ Timeline.prototype._create = function (container) {
var me = this;
var events = [
'pinch',
- //'tap', 'doubletap', 'hold', // TODO: catching the events here disables selecting an item
+ 'tap', 'doubletap', 'hold',
'dragstart', 'drag', 'dragend',
'mousewheel', 'DOMMouseScroll' // DOMMouseScroll is needed for Firefox
];
@@ -171,7 +173,8 @@ Timeline.prototype._create = function (container) {
right: {},
top: {},
bottom: {},
- border: {}
+ border: {},
+ scrollTop: 0
};
// attach the root panel to the provided container
@@ -183,8 +186,8 @@ Timeline.prototype._create = function (container) {
* Set options. Options will be passed to all components loaded in the Timeline.
* @param {Object} [options]
* {String} orientation
- * Vertical orienation for the Timeline:
- * 'bottom' (default) or 'top'
+ * Vertical orientation for the Timeline,
+ * can be 'bottom' (default) or 'top'.
* {String | Number} width
* Width for the timeline, a number in pixels or
* a css string like '1000px' or '75%'. '100%' by default.
@@ -563,21 +566,26 @@ Timeline.prototype.redraw = function() {
dom.bottom.style.left = props.left.width + 'px';
dom.bottom.style.top = (props.top.height + props.centerContainer.height) + 'px';
+ // update the scrollTop, feasible range for the offset can be changed
+ // when the height of the Timeline or of the contents of the center changed
+ this._setScrollTop(this._getScrollTop());
+
// reposition the scrollable contents
var offset;
if (options.orientation == 'top') {
- offset = 0;
+ offset = this.props.scrollTop;
}
else { // orientation == 'bottom'
// keep the items aligned to the axis at the bottom
- offset = props.centerContainer.height - props.center.height;
+ offset = this.props.scrollTop + props.centerContainer.height - props.center.height;
}
+
dom.center.style.left = '0';
- dom.center.style.top = offset+ 'px';
+ dom.center.style.top = offset + 'px';
dom.left.style.left = '0';
- dom.left.style.top = offset+ 'px';
+ dom.left.style.top = offset + 'px';
dom.right.style.left = '0';
- dom.right.style.top = offset+ 'px';
+ dom.right.style.top = offset + 'px';
// redraw all components
this.components.forEach(function (component) {
@@ -679,3 +687,69 @@ Timeline.prototype._stopAutoResize = function () {
// TODO: remove event listener on window.resize
};
+
+/**
+ * Start moving the timeline vertically
+ * @param {Event} event
+ * @private
+ */
+Timeline.prototype._onDragStart = function (event) {
+ touchParams.initialScrollTop = this.props.scrollTop;
+};
+
+/**
+ * Move the timeline vertically
+ * @param {Event} event
+ * @private
+ */
+Timeline.prototype._onDrag = function (event) {
+/* TODO: no dragging when pinching
+ // refuse to drag when we where pinching to prevent the timeline make a jump
+ // when releasing the fingers in opposite order from the touch screen
+ if (touchParams.pinching) return;
+*/
+ var delta = event.gesture.deltaY;
+
+ var oldScrollTop = this._getScrollTop();
+ var newScrollTop = this._setScrollTop(touchParams.initialScrollTop + delta);
+
+ if (newScrollTop != oldScrollTop) {
+ this.redraw(); // TODO: this causes two redraws when dragging, the other is triggered by rangechange already
+ }
+};
+
+/**
+ * Apply a scrollTop
+ * @param {Number} scrollTop
+ * @returns {Number} scrollTop Returns the applied scrollTop
+ * @private
+ */
+Timeline.prototype._setScrollTop = function (scrollTop) {
+ // limit the scrollTop to the feasible scroll range
+ var scrollTopMax = Math.max(this.props.center.height - this.props.centerContainer.height, 0);
+ if (this.options.orientation == 'top') {
+ if (scrollTop > 0) scrollTop = 0;
+ if (scrollTop < -scrollTopMax) scrollTop = -scrollTopMax;
+ }
+ else { // orientation == 'bottom'
+ if (scrollTop < 0) scrollTop = 0;
+ if (scrollTop > scrollTopMax) scrollTop = scrollTopMax;
+ }
+
+ // apply new scroll top
+ this.props.scrollTop = scrollTop;
+
+ return scrollTop;
+};
+
+/**
+ * Get the current scrollTop
+ * @returns {number} scrollTop
+ * @private
+ */
+Timeline.prototype._getScrollTop = function () {
+ return this.props.scrollTop;
+};
+
+// global (private) object to store drag params
+var touchParams = {};
From 63c36ffb6fb6fef75e08a38159e501ac051660b1 Mon Sep 17 00:00:00 2001
From: jos
Date: Fri, 13 Jun 2014 10:57:26 +0200
Subject: [PATCH 06/37] Fixed vertical drag issue while pinching
---
src/timeline/Range.js | 51 ++++++++++++++++++---------------------
src/timeline/Timeline.js | 35 ++++++++++++++++++++-------
test/timeline.html | 6 ++---
test/timeline_groups.html | 8 +++---
4 files changed, 56 insertions(+), 44 deletions(-)
diff --git a/src/timeline/Range.js b/src/timeline/Range.js
index 250de3b5..f2f8212e 100644
--- a/src/timeline/Range.js
+++ b/src/timeline/Range.js
@@ -27,6 +27,10 @@ function Range(body, options) {
};
this.options = util.extend({}, this.defaultOptions);
+ this.props = {
+ touch: {}
+ };
+
// drag listeners for dragging
this.body.emitter.on('dragstart', this._onDragStart.bind(this));
this.body.emitter.on('drag', this._onDrag.bind(this));
@@ -260,9 +264,6 @@ Range.conversion = function (start, end, width) {
}
};
-// global (private) object to store drag params
-var touchParams = {};
-
/**
* Start dragging horizontally or vertically
* @param {Event} event
@@ -274,10 +275,10 @@ Range.prototype._onDragStart = function(event) {
// refuse to drag when we where pinching to prevent the timeline make a jump
// when releasing the fingers in opposite order from the touch screen
- if (touchParams.ignore) return;
+ if (!this.props.touch.allowDragging) return;
- touchParams.start = this.start;
- touchParams.end = this.end;
+ this.props.touch.start = this.start;
+ this.props.touch.end = this.end;
if (this.body.dom.root) {
this.body.dom.root.style.cursor = 'move';
@@ -298,14 +299,15 @@ Range.prototype._onDrag = function (event) {
// refuse to drag when we where pinching to prevent the timeline make a jump
// when releasing the fingers in opposite order from the touch screen
- if (touchParams.ignore) return;
+ if (!this.props.touch.allowDragging) return;
+ console.log('onDrag range');
var delta = (direction == 'horizontal') ? event.gesture.deltaX : event.gesture.deltaY,
- interval = (touchParams.end - touchParams.start),
+ interval = (this.props.touch.end - this.props.touch.start),
width = (direction == 'horizontal') ? this.body.domProps.center.width : this.body.domProps.center.height,
diffRange = -delta / width * interval;
- this._applyRange(touchParams.start + diffRange, touchParams.end + diffRange);
+ this._applyRange(this.props.touch.start + diffRange, this.props.touch.end + diffRange);
this.body.emitter.emit('rangechange', {
start: new Date(this.start),
@@ -324,7 +326,7 @@ Range.prototype._onDragEnd = function (event) {
// refuse to drag when we where pinching to prevent the timeline make a jump
// when releasing the fingers in opposite order from the touch screen
- if (touchParams.ignore) return;
+ if (!this.props.touch.allowDragging) return;
if (this.body.dom.root) {
this.body.dom.root.style.cursor = 'auto';
@@ -391,17 +393,10 @@ Range.prototype._onMouseWheel = function(event) {
* @private
*/
Range.prototype._onTouch = function (event) {
- touchParams.start = this.start;
- touchParams.end = this.end;
- touchParams.ignore = false;
- touchParams.center = null;
-
- // don't move the range when dragging a selected event
- // TODO: it's not so neat to have to know about ItemSet here
- var item = ItemSet.itemFromTarget(event);
- if (item && item.selected && this.options.editable) {
- touchParams.ignore = true;
- }
+ this.props.touch.start = this.start;
+ this.props.touch.end = this.end;
+ this.props.touch.allowDragging = true;
+ this.props.touch.center = null;
};
/**
@@ -409,7 +404,7 @@ Range.prototype._onTouch = function (event) {
* @private
*/
Range.prototype._onHold = function () {
- touchParams.ignore = true;
+ this.props.touch.allowDragging = false;
};
/**
@@ -421,19 +416,19 @@ Range.prototype._onPinch = function (event) {
// only allow zooming when configured as zoomable and moveable
if (!(this.options.zoomable && this.options.moveable)) return;
- touchParams.ignore = true;
+ this.props.touch.allowDragging = false;
if (event.gesture.touches.length > 1) {
- if (!touchParams.center) {
- touchParams.center = getPointer(event.gesture.center, this.body.dom.center);
+ if (!this.props.touch.center) {
+ this.props.touch.center = getPointer(event.gesture.center, this.body.dom.center);
}
var scale = 1 / event.gesture.scale,
- initDate = this._pointerToDate(touchParams.center);
+ initDate = this._pointerToDate(this.props.touch.center);
// calculate new start and end
- var newStart = parseInt(initDate + (touchParams.start - initDate) * scale);
- var newEnd = parseInt(initDate + (touchParams.end - initDate) * scale);
+ var newStart = parseInt(initDate + (this.props.touch.start - initDate) * scale);
+ var newEnd = parseInt(initDate + (this.props.touch.end - initDate) * scale);
// apply new range
this.setRange(newStart, newEnd);
diff --git a/src/timeline/Timeline.js b/src/timeline/Timeline.js
index 2b68a5e5..dc88373e 100644
--- a/src/timeline/Timeline.js
+++ b/src/timeline/Timeline.js
@@ -135,6 +135,8 @@ Timeline.prototype._create = function (container) {
this.on('rangechange', this.redraw.bind(this));
this.on('change', this.redraw.bind(this));
+ this.on('touch', this._onTouch.bind(this));
+ this.on('pinch', this._onPinch.bind(this));
this.on('dragstart', this._onDragStart.bind(this));
this.on('drag', this._onDrag.bind(this));
@@ -147,7 +149,7 @@ Timeline.prototype._create = function (container) {
var me = this;
var events = [
- 'pinch',
+ 'touch', 'pinch',
'tap', 'doubletap', 'hold',
'dragstart', 'drag', 'dragend',
'mousewheel', 'DOMMouseScroll' // DOMMouseScroll is needed for Firefox
@@ -176,6 +178,7 @@ Timeline.prototype._create = function (container) {
border: {},
scrollTop: 0
};
+ this.touch = {}; // store state information needed for touch events
// attach the root panel to the provided container
if (!container) throw new Error('No container provided');
@@ -688,13 +691,31 @@ Timeline.prototype._stopAutoResize = function () {
// TODO: remove event listener on window.resize
};
+/**
+ * Start moving the timeline vertically
+ * @param {Event} event
+ * @private
+ */
+Timeline.prototype._onTouch = function (event) {
+ this.touch.allowDragging = true;
+};
+
+/**
+ * Start moving the timeline vertically
+ * @param {Event} event
+ * @private
+ */
+Timeline.prototype._onPinch = function (event) {
+ this.touch.allowDragging = false;
+};
+
/**
* Start moving the timeline vertically
* @param {Event} event
* @private
*/
Timeline.prototype._onDragStart = function (event) {
- touchParams.initialScrollTop = this.props.scrollTop;
+ this.touch.initialScrollTop = this.props.scrollTop;
};
/**
@@ -703,15 +724,14 @@ Timeline.prototype._onDragStart = function (event) {
* @private
*/
Timeline.prototype._onDrag = function (event) {
-/* TODO: no dragging when pinching
// refuse to drag when we where pinching to prevent the timeline make a jump
// when releasing the fingers in opposite order from the touch screen
- if (touchParams.pinching) return;
-*/
+ if (!this.touch.allowDragging) return;
+
var delta = event.gesture.deltaY;
var oldScrollTop = this._getScrollTop();
- var newScrollTop = this._setScrollTop(touchParams.initialScrollTop + delta);
+ var newScrollTop = this._setScrollTop(this.touch.initialScrollTop + delta);
if (newScrollTop != oldScrollTop) {
this.redraw(); // TODO: this causes two redraws when dragging, the other is triggered by rangechange already
@@ -750,6 +770,3 @@ Timeline.prototype._setScrollTop = function (scrollTop) {
Timeline.prototype._getScrollTop = function () {
return this.props.scrollTop;
};
-
-// global (private) object to store drag params
-var touchParams = {};
diff --git a/test/timeline.html b/test/timeline.html
index 83e49b32..f28dcfa7 100644
--- a/test/timeline.html
+++ b/test/timeline.html
@@ -28,10 +28,10 @@
diff --git a/test/timeline_groups.html b/test/timeline_groups.html
index 7e7b78f0..e2a5f2e8 100644
--- a/test/timeline_groups.html
+++ b/test/timeline_groups.html
@@ -31,10 +31,10 @@
@@ -79,7 +79,7 @@
updateGroup: true
},
//stack: false,
- //height: 200,
+ height: 200,
groupOrder: 'content'
};
From fe7cc726669b394c08869d663fe243a015e3f823 Mon Sep 17 00:00:00 2001
From: jos
Date: Fri, 13 Jun 2014 11:47:35 +0200
Subject: [PATCH 07/37] Implemented shadows when vertical scroll is possible
---
src/timeline/Range.js | 1 -
src/timeline/Timeline.js | 92 +++++++++++++++++++---------
src/timeline/component/css/panel.css | 18 ++++++
test/timeline_groups.html | 1 +
4 files changed, 82 insertions(+), 30 deletions(-)
diff --git a/src/timeline/Range.js b/src/timeline/Range.js
index f2f8212e..135d992a 100644
--- a/src/timeline/Range.js
+++ b/src/timeline/Range.js
@@ -300,7 +300,6 @@ Range.prototype._onDrag = function (event) {
// refuse to drag when we where pinching to prevent the timeline make a jump
// when releasing the fingers in opposite order from the touch screen
if (!this.props.touch.allowDragging) return;
- console.log('onDrag range');
var delta = (direction == 'horizontal') ? event.gesture.deltaX : event.gesture.deltaY,
interval = (this.props.touch.end - this.props.touch.start),
diff --git a/src/timeline/Timeline.js b/src/timeline/Timeline.js
index dc88373e..7c36b485 100644
--- a/src/timeline/Timeline.js
+++ b/src/timeline/Timeline.js
@@ -107,6 +107,12 @@ Timeline.prototype._create = function (container) {
this.dom.right = document.createElement('div');
this.dom.top = document.createElement('div');
this.dom.bottom = document.createElement('div');
+ this.dom.shadowTop = document.createElement('div');
+ this.dom.shadowBottom = document.createElement('div');
+ this.dom.shadowTopLeft = document.createElement('div');
+ this.dom.shadowBottomLeft = document.createElement('div');
+ this.dom.shadowTopRight = document.createElement('div');
+ this.dom.shadowBottomRight = document.createElement('div');
this.dom.background.className = 'vispanel background';
this.dom.backgroundVertical.className = 'vispanel background vertical';
@@ -119,6 +125,12 @@ Timeline.prototype._create = function (container) {
this.dom.left.className = 'content';
this.dom.center.className = 'content';
this.dom.right.className = 'content';
+ this.dom.shadowTop.className = 'shadow top';
+ this.dom.shadowBottom.className = 'shadow bottom';
+ this.dom.shadowTopLeft.className = 'shadow top';
+ this.dom.shadowBottomLeft.className = 'shadow bottom';
+ this.dom.shadowTopRight.className = 'shadow top';
+ this.dom.shadowBottomRight.className = 'shadow bottom';
this.dom.root.appendChild(this.dom.background);
this.dom.root.appendChild(this.dom.backgroundVertical);
@@ -133,6 +145,13 @@ Timeline.prototype._create = function (container) {
this.dom.leftContainer.appendChild(this.dom.left);
this.dom.rightContainer.appendChild(this.dom.right);
+ this.dom.centerContainer.appendChild(this.dom.shadowTop);
+ this.dom.centerContainer.appendChild(this.dom.shadowBottom);
+ this.dom.leftContainer.appendChild(this.dom.shadowTopLeft);
+ this.dom.leftContainer.appendChild(this.dom.shadowBottomLeft);
+ this.dom.rightContainer.appendChild(this.dom.shadowTopRight);
+ this.dom.rightContainer.appendChild(this.dom.shadowBottomRight);
+
this.on('rangechange', this.redraw.bind(this));
this.on('change', this.redraw.bind(this));
this.on('touch', this._onTouch.bind(this));
@@ -176,7 +195,8 @@ Timeline.prototype._create = function (container) {
top: {},
bottom: {},
border: {},
- scrollTop: 0
+ scrollTop: 0,
+ scrollTopMin: 0
};
this.touch = {}; // store state information needed for touch events
@@ -571,24 +591,26 @@ Timeline.prototype.redraw = function() {
// update the scrollTop, feasible range for the offset can be changed
// when the height of the Timeline or of the contents of the center changed
- this._setScrollTop(this._getScrollTop());
+ this._updateScrollTop();
// reposition the scrollable contents
- var offset;
- if (options.orientation == 'top') {
- offset = this.props.scrollTop;
- }
- else { // orientation == 'bottom'
- // keep the items aligned to the axis at the bottom
- offset = this.props.scrollTop + props.centerContainer.height - props.center.height;
- }
-
- dom.center.style.left = '0';
- dom.center.style.top = offset + 'px';
- dom.left.style.left = '0';
- dom.left.style.top = offset + 'px';
- dom.right.style.left = '0';
- dom.right.style.top = offset + 'px';
+ var offset = this.props.scrollTop;
+ dom.center.style.left = '0';
+ dom.center.style.top = offset + 'px';
+ dom.left.style.left = '0';
+ dom.left.style.top = offset + 'px';
+ dom.right.style.left = '0';
+ dom.right.style.top = offset + 'px';
+
+ // show shadows when vertical scrolling is available
+ var visibilityTop = this.props.scrollTop == 0 ? 'hidden' : '';
+ var visibilityBottom = this.props.scrollTop == this.props.scrollTopMin ? 'hidden' : '';
+ dom.shadowTop.style.visibility = visibilityTop;
+ dom.shadowBottom.style.visibility = visibilityBottom;
+ dom.shadowTopLeft.style.visibility = visibilityTop;
+ dom.shadowBottomLeft.style.visibility = visibilityBottom;
+ dom.shadowTopRight.style.visibility = visibilityTop;
+ dom.shadowBottomRight.style.visibility = visibilityBottom;
// redraw all components
this.components.forEach(function (component) {
@@ -745,21 +767,33 @@ Timeline.prototype._onDrag = function (event) {
* @private
*/
Timeline.prototype._setScrollTop = function (scrollTop) {
- // limit the scrollTop to the feasible scroll range
- var scrollTopMax = Math.max(this.props.center.height - this.props.centerContainer.height, 0);
- if (this.options.orientation == 'top') {
- if (scrollTop > 0) scrollTop = 0;
- if (scrollTop < -scrollTopMax) scrollTop = -scrollTopMax;
- }
- else { // orientation == 'bottom'
- if (scrollTop < 0) scrollTop = 0;
- if (scrollTop > scrollTopMax) scrollTop = scrollTopMax;
+ this.props.scrollTop = scrollTop;
+ this._updateScrollTop();
+ return this.props.scrollTop;
+};
+
+/**
+ * Update the current scrollTop when the height of the containers has been changed
+ * @returns {Number} scrollTop Returns the applied scrollTop
+ * @private
+ */
+Timeline.prototype._updateScrollTop = function () {
+ // recalculate the scrollTopMin
+ var scrollTopMin = this.props.centerContainer.height - this.props.center.height; // is negative or zero
+ if (scrollTopMin != this.props.scrollTopMin) {
+ // in case of bottom orientation, change the scrollTop such that the contents
+ // do not move relative to the time axis at the bottom
+ if (this.options.orientation == 'bottom') {
+ this.props.scrollTop += (scrollTopMin - this.props.scrollTopMin);
+ }
+ this.props.scrollTopMin = scrollTopMin;
}
- // apply new scroll top
- this.props.scrollTop = scrollTop;
+ // limit the scrollTop to the feasible scroll range
+ if (this.props.scrollTop > 0) this.props.scrollTop = 0;
+ if (this.props.scrollTop < scrollTopMin) this.props.scrollTop = scrollTopMin;
- return scrollTop;
+ return this.props.scrollTop;
};
/**
diff --git a/src/timeline/component/css/panel.css b/src/timeline/component/css/panel.css
index 0469e674..53f7e967 100644
--- a/src/timeline/component/css/panel.css
+++ b/src/timeline/component/css/panel.css
@@ -49,3 +49,21 @@
.vis.timeline .vispanel > .content {
position: relative;
}
+
+.vis.timeline .vispanel .shadow {
+ position: absolute;
+ width: 100%;
+ height: 1px;
+ box-shadow: 0 0 10px rgba(0,0,0,0.8);
+ z-index: 1;
+}
+
+.vis.timeline .vispanel .shadow.top {
+ top: -1px;
+ left: 0;
+}
+
+.vis.timeline .vispanel .shadow.bottom {
+ bottom: -1px;
+ left: 0;
+}
\ No newline at end of file
diff --git a/test/timeline_groups.html b/test/timeline_groups.html
index e2a5f2e8..1fd57844 100644
--- a/test/timeline_groups.html
+++ b/test/timeline_groups.html
@@ -72,6 +72,7 @@
// create visualization
var container = document.getElementById('visualization');
var options = {
+ //orientation: 'top',
editable: {
add: true,
remove: true,
From 9b4ab61d67c26aeba20325e0d0ded08e7037b90f Mon Sep 17 00:00:00 2001
From: jos
Date: Fri, 13 Jun 2014 11:54:44 +0200
Subject: [PATCH 08/37] Fixed shadows always being visible
---
src/timeline/Timeline.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/timeline/Timeline.js b/src/timeline/Timeline.js
index 7c36b485..719ebd6d 100644
--- a/src/timeline/Timeline.js
+++ b/src/timeline/Timeline.js
@@ -779,7 +779,7 @@ Timeline.prototype._setScrollTop = function (scrollTop) {
*/
Timeline.prototype._updateScrollTop = function () {
// recalculate the scrollTopMin
- var scrollTopMin = this.props.centerContainer.height - this.props.center.height; // is negative or zero
+ var scrollTopMin = Math.min(this.props.centerContainer.height - this.props.center.height, 0); // is negative or zero
if (scrollTopMin != this.props.scrollTopMin) {
// in case of bottom orientation, change the scrollTop such that the contents
// do not move relative to the time axis at the bottom
From 1cd1540f2824cbedd8f89cc51e67d7edefa24045 Mon Sep 17 00:00:00 2001
From: jos
Date: Fri, 13 Jun 2014 12:03:29 +0200
Subject: [PATCH 09/37] Fixed a bug in vertical offset when height of container
> height of contents
---
src/timeline/Timeline.js | 3 +++
test/timeline_groups.html | 2 +-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/timeline/Timeline.js b/src/timeline/Timeline.js
index 719ebd6d..ca24de0b 100644
--- a/src/timeline/Timeline.js
+++ b/src/timeline/Timeline.js
@@ -595,6 +595,9 @@ Timeline.prototype.redraw = function() {
// reposition the scrollable contents
var offset = this.props.scrollTop;
+ if (options.orientation == 'bottom') {
+ offset += Math.max(this.props.centerContainer.height - this.props.center.height, 0);
+ }
dom.center.style.left = '0';
dom.center.style.top = offset + 'px';
dom.left.style.left = '0';
diff --git a/test/timeline_groups.html b/test/timeline_groups.html
index 1fd57844..de2f5b16 100644
--- a/test/timeline_groups.html
+++ b/test/timeline_groups.html
@@ -80,7 +80,7 @@
updateGroup: true
},
//stack: false,
- height: 200,
+ //height: 200,
groupOrder: 'content'
};
From 610702f21e2bcf90736c14c9460d319db3ea7994 Mon Sep 17 00:00:00 2001
From: jos
Date: Fri, 13 Jun 2014 12:37:25 +0200
Subject: [PATCH 10/37] Removed all usage of style.bottom
---
src/timeline/component/TimeAxis.js | 18 ++----------------
src/timeline/component/css/panel.css | 2 ++
src/timeline/component/item/ItemBox.js | 16 +++++-----------
src/timeline/component/item/ItemPoint.js | 4 +---
src/timeline/component/item/ItemRange.js | 4 +---
5 files changed, 11 insertions(+), 33 deletions(-)
diff --git a/src/timeline/component/TimeAxis.js b/src/timeline/component/TimeAxis.js
index eadafa86..3dffeb5d 100644
--- a/src/timeline/component/TimeAxis.js
+++ b/src/timeline/component/TimeAxis.js
@@ -238,14 +238,7 @@ TimeAxis.prototype._repaintMinorText = function (x, text, orientation) {
label.childNodes[0].nodeValue = text;
- if (orientation == 'top') {
- label.style.top = this.props.majorLabelHeight + 'px';
- label.style.bottom = '';
- }
- else {
- label.style.top = '';
- label.style.bottom = this.props.majorLabelHeight + 'px';
- }
+ label.style.top = (orientation == 'top') ? (this.props.majorLabelHeight + 'px') : '0';
label.style.left = x + 'px';
//label.title = title; // TODO: this is a heavy operation
};
@@ -274,14 +267,7 @@ TimeAxis.prototype._repaintMajorText = function (x, text, orientation) {
label.childNodes[0].nodeValue = text;
//label.title = title; // TODO: this is a heavy operation
- if (orientation == 'top') {
- label.style.top = '0px';
- label.style.bottom = '';
- }
- else {
- label.style.top = '';
- label.style.bottom = '0px';
- }
+ label.style.top = (orientation == 'top') ? '0' : (this.props.minorLabelHeight + 'px');
label.style.left = x + 'px';
};
diff --git a/src/timeline/component/css/panel.css b/src/timeline/component/css/panel.css
index 53f7e967..4c259f77 100644
--- a/src/timeline/component/css/panel.css
+++ b/src/timeline/component/css/panel.css
@@ -55,7 +55,9 @@
width: 100%;
height: 1px;
box-shadow: 0 0 10px rgba(0,0,0,0.8);
+ /* TODO: find a nice way to ensure shadows are drawn on top of items
z-index: 1;
+ */
}
.vis.timeline .vispanel .shadow.top {
diff --git a/src/timeline/component/item/ItemBox.js b/src/timeline/component/item/ItemBox.js
index 149b0da2..d97102d4 100644
--- a/src/timeline/component/item/ItemBox.js
+++ b/src/timeline/component/item/ItemBox.js
@@ -211,20 +211,14 @@ ItemBox.prototype.repositionY = function() {
dot = this.dom.dot;
if (orientation == 'top') {
- box.style.top = (this.top || 0) + 'px';
- box.style.bottom = '';
-
- line.style.top = '0';
- line.style.bottom = '';
+ box.style.top = (this.top || 0) + 'px';
+ line.style.top = '0';
line.style.height = (this.parent.top + this.top + 1) + 'px';
}
else { // orientation 'bottom'
- box.style.top = '';
- box.style.bottom = (this.top || 0) + 'px';
-
- line.style.top = (this.parent.top + this.parent.height - this.top - 1) + 'px';
- line.style.bottom = '0';
- line.style.height = '';
+ box.style.top = (this.parent.height - this.top - this.height || 0) + 'px';
+ line.style.top = (this.parent.height - this.top - 1) + 'px';
+ line.style.height = this.top + 'px';
}
dot.style.top = (-this.props.dot.height / 2) + 'px';
diff --git a/src/timeline/component/item/ItemPoint.js b/src/timeline/component/item/ItemPoint.js
index 9d1664ea..ebb74c28 100644
--- a/src/timeline/component/item/ItemPoint.js
+++ b/src/timeline/component/item/ItemPoint.js
@@ -183,10 +183,8 @@ ItemPoint.prototype.repositionY = function() {
if (orientation == 'top') {
point.style.top = this.top + 'px';
- point.style.bottom = '';
}
else {
- point.style.top = '';
- point.style.bottom = this.top + 'px';
+ point.style.top = (this.parent.height - this.top - this.height) + 'px';
}
};
diff --git a/src/timeline/component/item/ItemRange.js b/src/timeline/component/item/ItemRange.js
index 859245b6..00a2b241 100644
--- a/src/timeline/component/item/ItemRange.js
+++ b/src/timeline/component/item/ItemRange.js
@@ -195,11 +195,9 @@ ItemRange.prototype.repositionY = function() {
if (orientation == 'top') {
box.style.top = this.top + 'px';
- box.style.bottom = '';
}
else {
- box.style.top = '';
- box.style.bottom = this.top + 'px';
+ box.style.top = (this.parent.height - this.top - this.height) + 'px';
}
};
From 30da48a49ead845335912add4e0cd9bb1648290b Mon Sep 17 00:00:00 2001
From: jos
Date: Fri, 13 Jun 2014 13:58:00 +0200
Subject: [PATCH 11/37] Fixed a bug in positioning/sizing the vertical lines of
box items
---
src/timeline/component/css/item.css | 10 ----------
src/timeline/component/css/itemset.css | 17 -----------------
src/timeline/component/item/ItemBox.js | 7 +++++--
3 files changed, 5 insertions(+), 29 deletions(-)
diff --git a/src/timeline/component/css/item.css b/src/timeline/component/css/item.css
index 413112cf..1291a49f 100644
--- a/src/timeline/component/css/item.css
+++ b/src/timeline/component/css/item.css
@@ -7,11 +7,6 @@
background-color: #D5DDF6;
display: inline-block;
padding: 5px;
-
- /* TODO: enable css transitions
- -webkit-transition: top .4s ease-in-out, bottom .4s ease-in-out;
- transition: top .4s ease-in-out, bottom .4s ease-in-out;
- /**/
}
.vis.timeline .item.selected {
@@ -70,11 +65,6 @@
width: 0;
border-left-width: 1px;
border-left-style: solid;
-
- /* TODO: enable css transitions
- -webkit-transition: height .4s ease-in-out, top .4s ease-in-out;
- transition: height .4s ease-in-out, top .4s ease-in-out;
- /**/
}
.vis.timeline .item .content {
diff --git a/src/timeline/component/css/itemset.css b/src/timeline/component/css/itemset.css
index 3acb7a88..c2f5f03a 100644
--- a/src/timeline/component/css/itemset.css
+++ b/src/timeline/component/css/itemset.css
@@ -5,11 +5,6 @@
margin: 0;
box-sizing: border-box;
-
- /* FIXME: get transition working for rootpanel and itemset
- -webkit-transition: height 4s ease-in-out;
- transition: height 4s ease-in-out;
- /**/
}
.vis.timeline .itemset .background,
@@ -40,15 +35,3 @@
.vis.timeline .group:last-child {
border-bottom: none;
}
-
-/*
-.vis.timeline.top .group {
- border-top: 1px solid #bfbfbf;
- border-bottom: none;
-}
-
-.vis.timeline.bottom .group {
- border-top: none;
- border-bottom: 1px solid #bfbfbf;
-}
-*/
\ No newline at end of file
diff --git a/src/timeline/component/item/ItemBox.js b/src/timeline/component/item/ItemBox.js
index d97102d4..f1f30f36 100644
--- a/src/timeline/component/item/ItemBox.js
+++ b/src/timeline/component/item/ItemBox.js
@@ -216,9 +216,12 @@ ItemBox.prototype.repositionY = function() {
line.style.height = (this.parent.top + this.top + 1) + 'px';
}
else { // orientation 'bottom'
+ var itemSetHeight = this.parent.itemSet.props.height; // TODO: this is nasty
+ var lineHeight = itemSetHeight - this.parent.top - this.parent.height + this.top;
+
box.style.top = (this.parent.height - this.top - this.height || 0) + 'px';
- line.style.top = (this.parent.height - this.top - 1) + 'px';
- line.style.height = this.top + 'px';
+ line.style.top = (itemSetHeight - lineHeight) + 'px';
+ line.style.height = (lineHeight) + 'px';
}
dot.style.top = (-this.props.dot.height / 2) + 'px';
From fe6cdfca4c360e82abaaca5334fb89d1230505b6 Mon Sep 17 00:00:00 2001
From: jos
Date: Fri, 13 Jun 2014 13:59:44 +0200
Subject: [PATCH 12/37] Added a start with animation (not yet working and
disabled)
---
Jakefile.js | 1 +
src/timeline/component/css/animation.css | 31 ++++++++++++++++++++++++
2 files changed, 32 insertions(+)
create mode 100644 src/timeline/component/css/animation.css
diff --git a/Jakefile.js b/Jakefile.js
index 41ec9264..ea904115 100644
--- a/Jakefile.js
+++ b/Jakefile.js
@@ -44,6 +44,7 @@ task('build', {async: true}, function () {
'./src/timeline/component/css/timeaxis.css',
'./src/timeline/component/css/currenttime.css',
'./src/timeline/component/css/customtime.css',
+ './src/timeline/component/css/animation.css',
'./src/graph/css/graph-manipulation.css',
'./src/graph/css/graph-navigation.css'
diff --git a/src/timeline/component/css/animation.css b/src/timeline/component/css/animation.css
new file mode 100644
index 00000000..ce41fbf5
--- /dev/null
+++ b/src/timeline/component/css/animation.css
@@ -0,0 +1,31 @@
+/* TODO: get animation working nicely
+.vis.timeline.root {
+ -webkit-transition: height .4s ease-in-out;
+ transition: height .4s ease-in-out;
+}
+
+.vis.timeline .vispanel {
+ -webkit-transition: height .4s ease-in-out, top .4s ease-in-out;
+ transition: height .4s ease-in-out, top .4s ease-in-out;
+}
+
+.vis.timeline .axis {
+ -webkit-transition: top .4s ease-in-out;
+ transition: top .4s ease-in-out;
+}
+
+.vis.timeline .group {
+ -webkit-transition: height .4s ease-in-out;
+ transition: height .4s ease-in-out;
+}
+
+.vis.timeline .item {
+ -webkit-transition: top .4s ease-in-out;
+ transition: top .4s ease-in-out;
+}
+
+.vis.timeline .item.line {
+ -webkit-transition: height .4s ease-in-out, top .4s ease-in-out;
+ transition: height .4s ease-in-out, top .4s ease-in-out;
+}
+/**/
\ No newline at end of file
From e41fdf45bce6f9dd91e58bc0b25322f3d50aa055 Mon Sep 17 00:00:00 2001
From: jos
Date: Fri, 13 Jun 2014 14:04:55 +0200
Subject: [PATCH 13/37] Small update in animation.css
---
src/timeline/component/css/animation.css | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/timeline/component/css/animation.css b/src/timeline/component/css/animation.css
index ce41fbf5..ea2b20f9 100644
--- a/src/timeline/component/css/animation.css
+++ b/src/timeline/component/css/animation.css
@@ -14,7 +14,8 @@
transition: top .4s ease-in-out;
}
-.vis.timeline .group {
+.vis.timeline .group,
+.vis.timeline .labelset .vlabel {
-webkit-transition: height .4s ease-in-out;
transition: height .4s ease-in-out;
}
From cd62233c603fd970fd09a3bdcf33f7654cb0fa9f Mon Sep 17 00:00:00 2001
From: jos
Date: Fri, 13 Jun 2014 17:13:03 +0200
Subject: [PATCH 14/37] Few fixes to get animation better (still not there)
---
src/timeline/component/css/animation.css | 13 +++++++------
src/timeline/component/item/ItemBox.js | 4 +++-
2 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/src/timeline/component/css/animation.css b/src/timeline/component/css/animation.css
index ea2b20f9..0b03f57f 100644
--- a/src/timeline/component/css/animation.css
+++ b/src/timeline/component/css/animation.css
@@ -1,24 +1,25 @@
-/* TODO: get animation working nicely
.vis.timeline.root {
+ /*
-webkit-transition: height .4s ease-in-out;
transition: height .4s ease-in-out;
+ */
}
.vis.timeline .vispanel {
+ /*
-webkit-transition: height .4s ease-in-out, top .4s ease-in-out;
transition: height .4s ease-in-out, top .4s ease-in-out;
+ */
}
.vis.timeline .axis {
+ /*
-webkit-transition: top .4s ease-in-out;
transition: top .4s ease-in-out;
+ */
}
-.vis.timeline .group,
-.vis.timeline .labelset .vlabel {
- -webkit-transition: height .4s ease-in-out;
- transition: height .4s ease-in-out;
-}
+/* TODO: get animation working nicely
.vis.timeline .item {
-webkit-transition: top .4s ease-in-out;
diff --git a/src/timeline/component/item/ItemBox.js b/src/timeline/component/item/ItemBox.js
index f1f30f36..6a067826 100644
--- a/src/timeline/component/item/ItemBox.js
+++ b/src/timeline/component/item/ItemBox.js
@@ -212,8 +212,10 @@ ItemBox.prototype.repositionY = function() {
if (orientation == 'top') {
box.style.top = (this.top || 0) + 'px';
+
line.style.top = '0';
line.style.height = (this.parent.top + this.top + 1) + 'px';
+ line.style.bottom = '';
}
else { // orientation 'bottom'
var itemSetHeight = this.parent.itemSet.props.height; // TODO: this is nasty
@@ -221,7 +223,7 @@ ItemBox.prototype.repositionY = function() {
box.style.top = (this.parent.height - this.top - this.height || 0) + 'px';
line.style.top = (itemSetHeight - lineHeight) + 'px';
- line.style.height = (lineHeight) + 'px';
+ line.style.bottom = '0';
}
dot.style.top = (-this.props.dot.height / 2) + 'px';
From 5a8e6ddbbecae36fd57fe241628767e57f802d91 Mon Sep 17 00:00:00 2001
From: jos
Date: Tue, 17 Jun 2014 10:48:35 +0200
Subject: [PATCH 15/37] Fixed #167: property `className` of groups not being
applied to related contents and background elements, and not being updated
once applied.
---
HISTORY.md | 4 +++-
src/timeline/component/Group.js | 16 ++++++++++++++--
src/timeline/component/css/itemset.css | 8 ++------
3 files changed, 19 insertions(+), 9 deletions(-)
diff --git a/HISTORY.md b/HISTORY.md
index 5a0e9d50..f4c363f3 100644
--- a/HISTORY.md
+++ b/HISTORY.md
@@ -2,7 +2,7 @@
http://visjs.org
-## 2014-06-06, version 1.1.1
+## not yet released, version 1.1.1
### Timeline
@@ -10,6 +10,8 @@ http://visjs.org
- Implemented options `zoomable` and `moveable`.
- Changed default value of option `showCurrentTime` to true.
- Internal refactoring and simplification of the code.
+- Fixed property `className` of groups not being applied to related contents and
+ background elements, and not being updated once applied.
### Graph
diff --git a/src/timeline/component/Group.js b/src/timeline/component/Group.js
index 343ba185..6184c750 100644
--- a/src/timeline/component/Group.js
+++ b/src/timeline/component/Group.js
@@ -16,6 +16,7 @@ function Group (groupId, data, itemSet) {
height: 0
}
};
+ this.className = null;
this.items = {}; // items filtered by groupId of this group
this.visibleItems = []; // items currently visible in window
@@ -49,8 +50,10 @@ Group.prototype._create = function() {
this.dom.foreground = foreground;
this.dom.background = document.createElement('div');
+ this.dom.background.className = 'group';
this.dom.axis = document.createElement('div');
+ this.dom.axis.className = 'group';
// create a hidden marker to detect when the Timelines container is attached
// to the DOM, or the style of a parent of the Timeline is changed from
@@ -86,9 +89,18 @@ Group.prototype.setData = function(data) {
}
// update className
- var className = data && data.className;
- if (className) {
+ var className = data && data.className || null;
+ if (className != this.className) {
+ if (this.className) {
+ util.removeClassName(this.dom.label, className);
+ util.removeClassName(this.dom.foreground, className);
+ util.removeClassName(this.dom.background, className);
+ util.removeClassName(this.dom.axis, className);
+ }
util.addClassName(this.dom.label, className);
+ util.addClassName(this.dom.foreground, className);
+ util.addClassName(this.dom.background, className);
+ util.addClassName(this.dom.axis, className);
}
};
diff --git a/src/timeline/component/css/itemset.css b/src/timeline/component/css/itemset.css
index c2f5f03a..b8f76203 100644
--- a/src/timeline/component/css/itemset.css
+++ b/src/timeline/component/css/itemset.css
@@ -14,10 +14,6 @@
height: 100%;
}
-.vis.timeline .itemset.foreground {
- overflow: hidden;
-}
-
.vis.timeline .axis {
position: absolute;
width: 100%;
@@ -26,12 +22,12 @@
z-index: 1;
}
-.vis.timeline .group {
+.vis.timeline .foreground .group {
position: relative;
box-sizing: border-box;
border-bottom: 1px solid #bfbfbf;
}
-.vis.timeline .group:last-child {
+.vis.timeline .foreground .group:last-child {
border-bottom: none;
}
From b4945faedd82add975ba6605e3c947c191dc7e41 Mon Sep 17 00:00:00 2001
From: jos
Date: Tue, 17 Jun 2014 11:48:44 +0200
Subject: [PATCH 16/37] Renamed DataSet option `convert` to `type`.
---
HISTORY.md | 6 +-
docs/dataset.html | 10 +--
examples/timeline/02_interactive.html | 2 +-
examples/timeline/03_a_lot_of_data.html | 2 +-
examples/timeline/06_event_listeners.html | 5 +-
src/DataSet.js | 85 ++++++++++++-----------
src/timeline/Timeline.js | 2 +-
test/dataset.js | 6 +-
8 files changed, 62 insertions(+), 56 deletions(-)
diff --git a/HISTORY.md b/HISTORY.md
index f4c363f3..0fdf68c5 100644
--- a/HISTORY.md
+++ b/HISTORY.md
@@ -2,7 +2,7 @@
http://visjs.org
-## not yet released, version 1.1.1
+## not yet released, version 2.0.0
### Timeline
@@ -19,6 +19,10 @@ http://visjs.org
- Fixed dataManipulation.initiallyVisible functionality (thanks theGrue).
- Forced typecast of fontSize to Number.
+### DataSet
+
+- Renamed option `convert` to `type`.
+
## 2014-06-06, version 1.1.0
diff --git a/docs/dataset.html b/docs/dataset.html
index 0828e37e..723affae 100644
--- a/docs/dataset.html
+++ b/docs/dataset.html
@@ -91,7 +91,7 @@ console.log('filtered items', items);
// retrieve formatted items
var items = data.get({
fields: ['id', 'date'],
- convert: {
+ type: {
date: 'ISODate'
}
});
@@ -149,7 +149,7 @@ var data = new vis.DataSet([data] [, options])
-
convert
+
type
Object.<String, String>
none
@@ -227,7 +227,7 @@ var data = new vis.DataSet([data] [, options])
Number[]
Get ids of all items or of a filtered set of items.
- Available options are described in section Data Selection, except that options fields and convert are not applicable in case of getIds.
+ Available options are described in section Data Selection, except that options fields and type are not applicable in case of getIds.
An object containing field names as key, and data types as value.
@@ -700,7 +700,7 @@ data.add([
// retrieve formatted items
var items = data.get({
fields: ['id', 'date', 'group'], // output the specified fields only
- convert: {
+ type: {
date: 'Date', // convert the date fields to Date objects
group: 'String' // convert the group fields to Strings
}
diff --git a/examples/timeline/02_interactive.html b/examples/timeline/02_interactive.html
index e2f5e417..32d8f97d 100644
--- a/examples/timeline/02_interactive.html
+++ b/examples/timeline/02_interactive.html
@@ -22,7 +22,7 @@
+
+
Serialization and deserialization
+
+
This example shows how to serialize and deserialize JSON data, and load this in the Timeline via a DataSet. Serialization and deserialization is needed when loading or saving data from a server.