vis-rails 0.0.6 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/lib/vis/rails/version.rb +1 -1
  3. data/vendor/assets/javascripts/vis.js +2 -9
  4. data/vendor/assets/vis/DataSet.js +17 -9
  5. data/vendor/assets/vis/graph/Edge.js +49 -24
  6. data/vendor/assets/vis/graph/Graph.js +268 -64
  7. data/vendor/assets/vis/graph/Groups.js +1 -1
  8. data/vendor/assets/vis/graph/Node.js +18 -67
  9. data/vendor/assets/vis/graph/Popup.js +40 -13
  10. data/vendor/assets/vis/graph/css/graph-navigation.css +18 -14
  11. data/vendor/assets/vis/graph/graphMixins/ClusterMixin.js +7 -5
  12. data/vendor/assets/vis/graph/graphMixins/HierarchicalLayoutMixin.js +20 -5
  13. data/vendor/assets/vis/graph/graphMixins/ManipulationMixin.js +33 -33
  14. data/vendor/assets/vis/graph/graphMixins/MixinLoader.js +30 -32
  15. data/vendor/assets/vis/graph/graphMixins/NavigationMixin.js +33 -1
  16. data/vendor/assets/vis/graph/graphMixins/SectorsMixin.js +2 -2
  17. data/vendor/assets/vis/graph/graphMixins/SelectionMixin.js +72 -60
  18. data/vendor/assets/vis/graph/graphMixins/physics/BarnesHut.js +43 -18
  19. data/vendor/assets/vis/graph/graphMixins/physics/HierarchialRepulsion.js +8 -8
  20. data/vendor/assets/vis/graph/graphMixins/physics/PhysicsMixin.js +309 -129
  21. data/vendor/assets/vis/graph/graphMixins/physics/Repulsion.js +10 -10
  22. data/vendor/assets/vis/module/exports.js +1 -2
  23. data/vendor/assets/vis/module/header.js +2 -2
  24. data/vendor/assets/vis/timeline/Range.js +53 -93
  25. data/vendor/assets/vis/timeline/Timeline.js +328 -224
  26. data/vendor/assets/vis/timeline/component/Component.js +17 -95
  27. data/vendor/assets/vis/timeline/component/CurrentTime.js +54 -59
  28. data/vendor/assets/vis/timeline/component/CustomTime.js +55 -83
  29. data/vendor/assets/vis/timeline/component/Group.js +398 -75
  30. data/vendor/assets/vis/timeline/component/ItemSet.js +662 -403
  31. data/vendor/assets/vis/timeline/component/Panel.js +118 -60
  32. data/vendor/assets/vis/timeline/component/RootPanel.js +80 -132
  33. data/vendor/assets/vis/timeline/component/TimeAxis.js +191 -277
  34. data/vendor/assets/vis/timeline/component/css/item.css +16 -23
  35. data/vendor/assets/vis/timeline/component/css/itemset.css +25 -4
  36. data/vendor/assets/vis/timeline/component/css/labelset.css +34 -0
  37. data/vendor/assets/vis/timeline/component/css/panel.css +15 -1
  38. data/vendor/assets/vis/timeline/component/css/timeaxis.css +8 -8
  39. data/vendor/assets/vis/timeline/component/item/Item.js +48 -26
  40. data/vendor/assets/vis/timeline/component/item/ItemBox.js +156 -230
  41. data/vendor/assets/vis/timeline/component/item/ItemPoint.js +118 -166
  42. data/vendor/assets/vis/timeline/component/item/ItemRange.js +135 -187
  43. data/vendor/assets/vis/timeline/component/item/ItemRangeOverflow.js +29 -92
  44. data/vendor/assets/vis/timeline/stack.js +112 -0
  45. data/vendor/assets/vis/util.js +136 -38
  46. metadata +4 -18
  47. data/vendor/assets/vis/.gitignore +0 -1
  48. data/vendor/assets/vis/EventBus.js +0 -89
  49. data/vendor/assets/vis/events.js +0 -116
  50. data/vendor/assets/vis/graph/ClusterMixin.js +0 -1019
  51. data/vendor/assets/vis/graph/NavigationMixin.js +0 -245
  52. data/vendor/assets/vis/graph/SectorsMixin.js +0 -547
  53. data/vendor/assets/vis/graph/SelectionMixin.js +0 -515
  54. data/vendor/assets/vis/graph/img/downarrow.png +0 -0
  55. data/vendor/assets/vis/graph/img/leftarrow.png +0 -0
  56. data/vendor/assets/vis/graph/img/rightarrow.png +0 -0
  57. data/vendor/assets/vis/graph/img/uparrow.png +0 -0
  58. data/vendor/assets/vis/timeline/Controller.js +0 -183
  59. data/vendor/assets/vis/timeline/Stack.js +0 -190
  60. data/vendor/assets/vis/timeline/component/ContentPanel.js +0 -113
  61. data/vendor/assets/vis/timeline/component/GroupSet.js +0 -580
  62. data/vendor/assets/vis/timeline/component/css/groupset.css +0 -59
@@ -1,14 +1,13 @@
1
1
  /**
2
2
  * @constructor ItemPoint
3
3
  * @extends Item
4
- * @param {ItemSet} parent
5
4
  * @param {Object} data Object containing parameters start
6
5
  * content, className.
7
6
  * @param {Object} [options] Options to set initial property values
8
7
  * @param {Object} [defaultOptions] default options
9
8
  * // TODO: describe available options
10
9
  */
11
- function ItemPoint (parent, data, options, defaultOptions) {
10
+ function ItemPoint (data, options, defaultOptions) {
12
11
  this.props = {
13
12
  dot: {
14
13
  top: 0,
@@ -21,219 +20,172 @@ function ItemPoint (parent, data, options, defaultOptions) {
21
20
  }
22
21
  };
23
22
 
24
- Item.call(this, parent, data, options, defaultOptions);
23
+ // validate data
24
+ if (data) {
25
+ if (data.start == undefined) {
26
+ throw new Error('Property "start" missing in item ' + data);
27
+ }
28
+ }
29
+
30
+ Item.call(this, data, options, defaultOptions);
25
31
  }
26
32
 
27
- ItemPoint.prototype = new Item (null, null);
33
+ ItemPoint.prototype = new Item (null);
34
+
35
+ /**
36
+ * Check whether this item is visible inside given range
37
+ * @returns {{start: Number, end: Number}} range with a timestamp for start and end
38
+ * @returns {boolean} True if visible
39
+ */
40
+ ItemPoint.prototype.isVisible = function isVisible (range) {
41
+ // determine visibility
42
+ // TODO: account for the real width of the item. Right now we just add 1/4 to the window
43
+ var interval = (range.end - range.start) / 4;
44
+ return (this.data.start > range.start - interval) && (this.data.start < range.end + interval);
45
+ };
28
46
 
29
47
  /**
30
48
  * Repaint the item
31
- * @return {Boolean} changed
32
49
  */
33
50
  ItemPoint.prototype.repaint = function repaint() {
34
- // TODO: make an efficient repaint
35
- var changed = false;
36
51
  var dom = this.dom;
37
-
38
52
  if (!dom) {
39
- this._create();
53
+ // create DOM
54
+ this.dom = {};
40
55
  dom = this.dom;
41
- changed = true;
56
+
57
+ // background box
58
+ dom.point = document.createElement('div');
59
+ // className is updated in repaint()
60
+
61
+ // contents box, right from the dot
62
+ dom.content = document.createElement('div');
63
+ dom.content.className = 'content';
64
+ dom.point.appendChild(dom.content);
65
+
66
+ // dot at start
67
+ dom.dot = document.createElement('div');
68
+ dom.point.appendChild(dom.dot);
69
+
70
+ // attach this item as attribute
71
+ dom.point['timeline-item'] = this;
42
72
  }
43
73
 
44
- if (dom) {
45
- if (!this.parent) {
46
- throw new Error('Cannot repaint item: no parent attached');
47
- }
74
+ // append DOM to parent DOM
75
+ if (!this.parent) {
76
+ throw new Error('Cannot repaint item: no parent attached');
77
+ }
78
+ if (!dom.point.parentNode) {
48
79
  var foreground = this.parent.getForeground();
49
80
  if (!foreground) {
50
- throw new Error('Cannot repaint time axis: ' +
51
- 'parent has no foreground container element');
81
+ throw new Error('Cannot repaint time axis: parent has no foreground container element');
52
82
  }
53
-
54
- if (!dom.point.parentNode) {
55
- foreground.appendChild(dom.point);
56
- foreground.appendChild(dom.point);
57
- changed = true;
83
+ foreground.appendChild(dom.point);
84
+ }
85
+ this.displayed = true;
86
+
87
+ // update contents
88
+ if (this.data.content != this.content) {
89
+ this.content = this.data.content;
90
+ if (this.content instanceof Element) {
91
+ dom.content.innerHTML = '';
92
+ dom.content.appendChild(this.content);
58
93
  }
59
-
60
- // update contents
61
- if (this.data.content != this.content) {
62
- this.content = this.data.content;
63
- if (this.content instanceof Element) {
64
- dom.content.innerHTML = '';
65
- dom.content.appendChild(this.content);
66
- }
67
- else if (this.data.content != undefined) {
68
- dom.content.innerHTML = this.content;
69
- }
70
- else {
71
- throw new Error('Property "content" missing in item ' + this.data.id);
72
- }
73
- changed = true;
94
+ else if (this.data.content != undefined) {
95
+ dom.content.innerHTML = this.content;
96
+ }
97
+ else {
98
+ throw new Error('Property "content" missing in item ' + this.data.id);
74
99
  }
75
100
 
76
- this._repaintDeleteButton(dom.point);
101
+ this.dirty = true;
102
+ }
77
103
 
78
- // update class
79
- var className = (this.data.className? ' ' + this.data.className : '') +
80
- (this.selected ? ' selected' : '');
81
- if (this.className != className) {
82
- this.className = className;
83
- dom.point.className = 'item point' + className;
84
- changed = true;
85
- }
104
+ // update class
105
+ var className = (this.data.className? ' ' + this.data.className : '') +
106
+ (this.selected ? ' selected' : '');
107
+ if (this.className != className) {
108
+ this.className = className;
109
+ dom.point.className = 'item point' + className;
110
+ dom.dot.className = 'item dot' + className;
111
+
112
+ this.dirty = true;
113
+ }
114
+
115
+ // recalculate size
116
+ if (this.dirty) {
117
+ this.width = dom.point.offsetWidth;
118
+ this.height = dom.point.offsetHeight;
119
+ this.props.dot.width = dom.dot.offsetWidth;
120
+ this.props.dot.height = dom.dot.offsetHeight;
121
+ this.props.content.height = dom.content.offsetHeight;
122
+
123
+ // resize contents
124
+ dom.content.style.marginLeft = 2 * this.props.dot.width + 'px';
125
+ //dom.content.style.marginRight = ... + 'px'; // TODO: margin right
126
+
127
+ dom.dot.style.top = ((this.height - this.props.dot.height) / 2) + 'px';
128
+ dom.dot.style.left = (this.props.dot.width / 2) + 'px';
129
+
130
+ this.dirty = false;
86
131
  }
87
132
 
88
- return changed;
133
+ this._repaintDeleteButton(dom.point);
89
134
  };
90
135
 
91
136
  /**
92
137
  * Show the item in the DOM (when not already visible). The items DOM will
93
138
  * be created when needed.
94
- * @return {Boolean} changed
95
139
  */
96
140
  ItemPoint.prototype.show = function show() {
97
- if (!this.dom || !this.dom.point.parentNode) {
98
- return this.repaint();
99
- }
100
- else {
101
- return false;
141
+ if (!this.displayed) {
142
+ this.repaint();
102
143
  }
103
144
  };
104
145
 
105
146
  /**
106
147
  * Hide the item from the DOM (when visible)
107
- * @return {Boolean} changed
108
148
  */
109
149
  ItemPoint.prototype.hide = function hide() {
110
- var changed = false,
111
- dom = this.dom;
112
- if (dom) {
113
- if (dom.point.parentNode) {
114
- dom.point.parentNode.removeChild(dom.point);
115
- changed = true;
150
+ if (this.displayed) {
151
+ if (this.dom.point.parentNode) {
152
+ this.dom.point.parentNode.removeChild(this.dom.point);
116
153
  }
117
- }
118
- return changed;
119
- };
120
154
 
121
- /**
122
- * Reflow the item: calculate its actual size from the DOM
123
- * @return {boolean} resized returns true if the axis is resized
124
- * @override
125
- */
126
- ItemPoint.prototype.reflow = function reflow() {
127
- var changed = 0,
128
- update,
129
- dom,
130
- props,
131
- options,
132
- margin,
133
- orientation,
134
- start,
135
- top,
136
- data,
137
- range;
138
-
139
- if (this.data.start == undefined) {
140
- throw new Error('Property "start" missing in item ' + this.data.id);
141
- }
155
+ this.top = null;
156
+ this.left = null;
142
157
 
143
- data = this.data;
144
- range = this.parent && this.parent.range;
145
- if (data && range) {
146
- // TODO: account for the width of the item
147
- var interval = (range.end - range.start);
148
- this.visible = (data.start > range.start - interval) && (data.start < range.end);
149
- }
150
- else {
151
- this.visible = false;
158
+ this.displayed = false;
152
159
  }
153
-
154
- if (this.visible) {
155
- dom = this.dom;
156
- if (dom) {
157
- update = util.updateProperty;
158
- props = this.props;
159
- options = this.options;
160
- orientation = options.orientation || this.defaultOptions.orientation;
161
- margin = options.margin && options.margin.axis || this.defaultOptions.margin.axis;
162
- start = this.parent.toScreen(this.data.start) + this.offset;
163
-
164
- changed += update(this, 'width', dom.point.offsetWidth);
165
- changed += update(this, 'height', dom.point.offsetHeight);
166
- changed += update(props.dot, 'width', dom.dot.offsetWidth);
167
- changed += update(props.dot, 'height', dom.dot.offsetHeight);
168
- changed += update(props.content, 'height', dom.content.offsetHeight);
169
-
170
- if (orientation == 'top') {
171
- top = margin;
172
- }
173
- else {
174
- // default or 'bottom'
175
- var parentHeight = this.parent.height;
176
- top = Math.max(parentHeight - this.height - margin, 0);
177
- }
178
- changed += update(this, 'top', top);
179
- changed += update(this, 'left', start - props.dot.width / 2);
180
- changed += update(props.content, 'marginLeft', 1.5 * props.dot.width);
181
- //changed += update(props.content, 'marginRight', 0.5 * props.dot.width); // TODO
182
-
183
- changed += update(props.dot, 'top', (this.height - props.dot.height) / 2);
184
- }
185
- else {
186
- changed += 1;
187
- }
188
- }
189
-
190
- return (changed > 0);
191
160
  };
192
161
 
193
162
  /**
194
- * Create an items DOM
195
- * @private
163
+ * Reposition the item horizontally
164
+ * @Override
196
165
  */
197
- ItemPoint.prototype._create = function _create() {
198
- var dom = this.dom;
199
- if (!dom) {
200
- this.dom = dom = {};
166
+ ItemPoint.prototype.repositionX = function repositionX() {
167
+ var start = this.defaultOptions.toScreen(this.data.start);
201
168
 
202
- // background box
203
- dom.point = document.createElement('div');
204
- // className is updated in repaint()
205
-
206
- // contents box, right from the dot
207
- dom.content = document.createElement('div');
208
- dom.content.className = 'content';
209
- dom.point.appendChild(dom.content);
169
+ this.left = start - this.props.dot.width;
210
170
 
211
- // dot at start
212
- dom.dot = document.createElement('div');
213
- dom.dot.className = 'dot';
214
- dom.point.appendChild(dom.dot);
215
-
216
- // attach this item as attribute
217
- dom.point['timeline-item'] = this;
218
- }
171
+ // reposition point
172
+ this.dom.point.style.left = this.left + 'px';
219
173
  };
220
174
 
221
175
  /**
222
- * Reposition the item, recalculate its left, top, and width, using the current
223
- * range and size of the items itemset
224
- * @override
176
+ * Reposition the item vertically
177
+ * @Override
225
178
  */
226
- ItemPoint.prototype.reposition = function reposition() {
227
- var dom = this.dom,
228
- props = this.props;
179
+ ItemPoint.prototype.repositionY = function repositionY () {
180
+ var orientation = this.options.orientation || this.defaultOptions.orientation,
181
+ point = this.dom.point;
229
182
 
230
- if (dom) {
231
- dom.point.style.top = this.top + 'px';
232
- dom.point.style.left = this.left + 'px';
233
-
234
- dom.content.style.marginLeft = props.content.marginLeft + 'px';
235
- //dom.content.style.marginRight = props.content.marginRight + 'px'; // TODO
236
-
237
- dom.dot.style.top = props.dot.top + 'px';
183
+ if (orientation == 'top') {
184
+ point.style.top = this.top + 'px';
185
+ point.style.bottom = '';
186
+ }
187
+ else {
188
+ point.style.top = '';
189
+ point.style.bottom = this.top + 'px';
238
190
  }
239
191
  };
@@ -1,100 +1,129 @@
1
1
  /**
2
2
  * @constructor ItemRange
3
3
  * @extends Item
4
- * @param {ItemSet} parent
5
4
  * @param {Object} data Object containing parameters start, end
6
5
  * content, className.
7
6
  * @param {Object} [options] Options to set initial property values
8
7
  * @param {Object} [defaultOptions] default options
9
8
  * // TODO: describe available options
10
9
  */
11
- function ItemRange (parent, data, options, defaultOptions) {
10
+ function ItemRange (data, options, defaultOptions) {
12
11
  this.props = {
13
12
  content: {
14
- left: 0,
15
13
  width: 0
16
14
  }
17
15
  };
18
16
 
19
- Item.call(this, parent, data, options, defaultOptions);
17
+ // validate data
18
+ if (data) {
19
+ if (data.start == undefined) {
20
+ throw new Error('Property "start" missing in item ' + data.id);
21
+ }
22
+ if (data.end == undefined) {
23
+ throw new Error('Property "end" missing in item ' + data.id);
24
+ }
25
+ }
26
+
27
+ Item.call(this, data, options, defaultOptions);
20
28
  }
21
29
 
22
- ItemRange.prototype = new Item (null, null);
30
+ ItemRange.prototype = new Item (null);
31
+
32
+ ItemRange.prototype.baseClassName = 'item range';
33
+
34
+ /**
35
+ * Check whether this item is visible inside given range
36
+ * @returns {{start: Number, end: Number}} range with a timestamp for start and end
37
+ * @returns {boolean} True if visible
38
+ */
39
+ ItemRange.prototype.isVisible = function isVisible (range) {
40
+ // determine visibility
41
+ return (this.data.start < range.end) && (this.data.end > range.start);
42
+ };
23
43
 
24
44
  /**
25
45
  * Repaint the item
26
- * @return {Boolean} changed
27
46
  */
28
47
  ItemRange.prototype.repaint = function repaint() {
29
- // TODO: make an efficient repaint
30
- var changed = false;
31
48
  var dom = this.dom;
32
-
33
49
  if (!dom) {
34
- this._create();
50
+ // create DOM
51
+ this.dom = {};
35
52
  dom = this.dom;
36
- changed = true;
53
+
54
+ // background box
55
+ dom.box = document.createElement('div');
56
+ // className is updated in repaint()
57
+
58
+ // contents box
59
+ dom.content = document.createElement('div');
60
+ dom.content.className = 'content';
61
+ dom.box.appendChild(dom.content);
62
+
63
+ // attach this item as attribute
64
+ dom.box['timeline-item'] = this;
37
65
  }
38
66
 
39
- if (dom) {
40
- if (!this.parent) {
41
- throw new Error('Cannot repaint item: no parent attached');
42
- }
67
+ // append DOM to parent DOM
68
+ if (!this.parent) {
69
+ throw new Error('Cannot repaint item: no parent attached');
70
+ }
71
+ if (!dom.box.parentNode) {
43
72
  var foreground = this.parent.getForeground();
44
73
  if (!foreground) {
45
- throw new Error('Cannot repaint time axis: ' +
46
- 'parent has no foreground container element');
74
+ throw new Error('Cannot repaint time axis: parent has no foreground container element');
47
75
  }
48
-
49
- if (!dom.box.parentNode) {
50
- foreground.appendChild(dom.box);
51
- changed = true;
76
+ foreground.appendChild(dom.box);
77
+ }
78
+ this.displayed = true;
79
+
80
+ // update contents
81
+ if (this.data.content != this.content) {
82
+ this.content = this.data.content;
83
+ if (this.content instanceof Element) {
84
+ dom.content.innerHTML = '';
85
+ dom.content.appendChild(this.content);
52
86
  }
53
-
54
- // update content
55
- if (this.data.content != this.content) {
56
- this.content = this.data.content;
57
- if (this.content instanceof Element) {
58
- dom.content.innerHTML = '';
59
- dom.content.appendChild(this.content);
60
- }
61
- else if (this.data.content != undefined) {
62
- dom.content.innerHTML = this.content;
63
- }
64
- else {
65
- throw new Error('Property "content" missing in item ' + this.data.id);
66
- }
67
- changed = true;
87
+ else if (this.data.content != undefined) {
88
+ dom.content.innerHTML = this.content;
68
89
  }
69
-
70
- this._repaintDeleteButton(dom.box);
71
- this._repaintDragLeft();
72
- this._repaintDragRight();
73
-
74
- // update class
75
- var className = (this.data.className ? (' ' + this.data.className) : '') +
76
- (this.selected ? ' selected' : '');
77
- if (this.className != className) {
78
- this.className = className;
79
- dom.box.className = 'item range' + className;
80
- changed = true;
90
+ else {
91
+ throw new Error('Property "content" missing in item ' + this.data.id);
81
92
  }
93
+
94
+ this.dirty = true;
95
+ }
96
+
97
+ // update class
98
+ var className = (this.data.className ? (' ' + this.data.className) : '') +
99
+ (this.selected ? ' selected' : '');
100
+ if (this.className != className) {
101
+ this.className = className;
102
+ dom.box.className = this.baseClassName + className;
103
+
104
+ this.dirty = true;
82
105
  }
83
106
 
84
- return changed;
107
+ // recalculate size
108
+ if (this.dirty) {
109
+ this.props.content.width = this.dom.content.offsetWidth;
110
+ this.height = this.dom.box.offsetHeight;
111
+
112
+ this.dirty = false;
113
+ }
114
+
115
+ this._repaintDeleteButton(dom.box);
116
+ this._repaintDragLeft();
117
+ this._repaintDragRight();
85
118
  };
86
119
 
87
120
  /**
88
121
  * Show the item in the DOM (when not already visible). The items DOM will
89
122
  * be created when needed.
90
- * @return {Boolean} changed
91
123
  */
92
124
  ItemRange.prototype.show = function show() {
93
- if (!this.dom || !this.dom.box.parentNode) {
94
- return this.repaint();
95
- }
96
- else {
97
- return false;
125
+ if (!this.displayed) {
126
+ this.repaint();
98
127
  }
99
128
  };
100
129
 
@@ -103,163 +132,82 @@ ItemRange.prototype.show = function show() {
103
132
  * @return {Boolean} changed
104
133
  */
105
134
  ItemRange.prototype.hide = function hide() {
106
- var changed = false,
107
- dom = this.dom;
108
- if (dom) {
109
- if (dom.box.parentNode) {
110
- dom.box.parentNode.removeChild(dom.box);
111
- changed = true;
135
+ if (this.displayed) {
136
+ var box = this.dom.box;
137
+
138
+ if (box.parentNode) {
139
+ box.parentNode.removeChild(box);
112
140
  }
141
+
142
+ this.top = null;
143
+ this.left = null;
144
+
145
+ this.displayed = false;
113
146
  }
114
- return changed;
115
147
  };
116
148
 
117
149
  /**
118
- * Reflow the item: calculate its actual size from the DOM
119
- * @return {boolean} resized returns true if the axis is resized
120
- * @override
150
+ * Reposition the item horizontally
151
+ * @Override
121
152
  */
122
- ItemRange.prototype.reflow = function reflow() {
123
- var changed = 0,
124
- dom,
125
- props,
126
- options,
127
- margin,
128
- padding,
129
- parent,
130
- start,
131
- end,
132
- data,
133
- range,
134
- update,
135
- box,
136
- parentWidth,
137
- contentLeft,
138
- orientation,
139
- top;
140
-
141
- if (this.data.start == undefined) {
142
- throw new Error('Property "start" missing in item ' + this.data.id);
153
+ ItemRange.prototype.repositionX = function repositionX() {
154
+ var props = this.props,
155
+ parentWidth = this.parent.width,
156
+ start = this.defaultOptions.toScreen(this.data.start),
157
+ end = this.defaultOptions.toScreen(this.data.end),
158
+ padding = 'padding' in this.options ? this.options.padding : this.defaultOptions.padding,
159
+ contentLeft;
160
+
161
+ // limit the width of the this, as browsers cannot draw very wide divs
162
+ if (start < -parentWidth) {
163
+ start = -parentWidth;
143
164
  }
144
- if (this.data.end == undefined) {
145
- throw new Error('Property "end" missing in item ' + this.data.id);
165
+ if (end > 2 * parentWidth) {
166
+ end = 2 * parentWidth;
146
167
  }
147
168
 
148
- data = this.data;
149
- range = this.parent && this.parent.range;
150
- if (data && range) {
151
- // TODO: account for the width of the item. Take some margin
152
- this.visible = (data.start < range.end) && (data.end > range.start);
169
+ // when range exceeds left of the window, position the contents at the left of the visible area
170
+ if (start < 0) {
171
+ contentLeft = Math.min(-start,
172
+ (end - start - props.content.width - 2 * padding));
173
+ // TODO: remove the need for options.padding. it's terrible.
153
174
  }
154
175
  else {
155
- this.visible = false;
176
+ contentLeft = 0;
156
177
  }
157
178
 
158
- if (this.visible) {
159
- dom = this.dom;
160
- if (dom) {
161
- props = this.props;
162
- options = this.options;
163
- parent = this.parent;
164
- start = parent.toScreen(this.data.start) + this.offset;
165
- end = parent.toScreen(this.data.end) + this.offset;
166
- update = util.updateProperty;
167
- box = dom.box;
168
- parentWidth = parent.width;
169
- orientation = options.orientation || this.defaultOptions.orientation;
170
- margin = options.margin && options.margin.axis || this.defaultOptions.margin.axis;
171
- padding = options.padding || this.defaultOptions.padding;
172
-
173
- changed += update(props.content, 'width', dom.content.offsetWidth);
174
-
175
- changed += update(this, 'height', box.offsetHeight);
176
-
177
- // limit the width of the this, as browsers cannot draw very wide divs
178
- if (start < -parentWidth) {
179
- start = -parentWidth;
180
- }
181
- if (end > 2 * parentWidth) {
182
- end = 2 * parentWidth;
183
- }
184
-
185
- // when range exceeds left of the window, position the contents at the left of the visible area
186
- if (start < 0) {
187
- contentLeft = Math.min(-start,
188
- (end - start - props.content.width - 2 * padding));
189
- // TODO: remove the need for options.padding. it's terrible.
190
- }
191
- else {
192
- contentLeft = 0;
193
- }
194
- changed += update(props.content, 'left', contentLeft);
195
-
196
- if (orientation == 'top') {
197
- top = margin;
198
- changed += update(this, 'top', top);
199
- }
200
- else {
201
- // default or 'bottom'
202
- top = parent.height - this.height - margin;
203
- changed += update(this, 'top', top);
204
- }
205
-
206
- changed += update(this, 'left', start);
207
- changed += update(this, 'width', Math.max(end - start, 1)); // TODO: reckon with border width;
208
- }
209
- else {
210
- changed += 1;
211
- }
212
- }
179
+ this.left = start;
180
+ this.width = Math.max(end - start, 1);
213
181
 
214
- return (changed > 0);
182
+ this.dom.box.style.left = this.left + 'px';
183
+ this.dom.box.style.width = this.width + 'px';
184
+ this.dom.content.style.left = contentLeft + 'px';
215
185
  };
216
186
 
217
187
  /**
218
- * Create an items DOM
219
- * @private
188
+ * Reposition the item vertically
189
+ * @Override
220
190
  */
221
- ItemRange.prototype._create = function _create() {
222
- var dom = this.dom;
223
- if (!dom) {
224
- this.dom = dom = {};
225
- // background box
226
- dom.box = document.createElement('div');
227
- // className is updated in repaint()
228
-
229
- // contents box
230
- dom.content = document.createElement('div');
231
- dom.content.className = 'content';
232
- dom.box.appendChild(dom.content);
191
+ ItemRange.prototype.repositionY = function repositionY() {
192
+ var orientation = this.options.orientation || this.defaultOptions.orientation,
193
+ box = this.dom.box;
233
194
 
234
- // attach this item as attribute
235
- dom.box['timeline-item'] = this;
195
+ if (orientation == 'top') {
196
+ box.style.top = this.top + 'px';
197
+ box.style.bottom = '';
236
198
  }
237
- };
238
-
239
- /**
240
- * Reposition the item, recalculate its left, top, and width, using the current
241
- * range and size of the items itemset
242
- * @override
243
- */
244
- ItemRange.prototype.reposition = function reposition() {
245
- var dom = this.dom,
246
- props = this.props;
247
-
248
- if (dom) {
249
- dom.box.style.top = this.top + 'px';
250
- dom.box.style.left = this.left + 'px';
251
- dom.box.style.width = this.width + 'px';
252
-
253
- dom.content.style.left = props.content.left + 'px';
199
+ else {
200
+ box.style.top = '';
201
+ box.style.bottom = this.top + 'px';
254
202
  }
255
203
  };
256
204
 
257
205
  /**
258
206
  * Repaint a drag area on the left side of the range when the range is selected
259
- * @private
207
+ * @protected
260
208
  */
261
209
  ItemRange.prototype._repaintDragLeft = function () {
262
- if (this.selected && this.options.editable && !this.dom.dragLeft) {
210
+ if (this.selected && this.options.editable.updateTime && !this.dom.dragLeft) {
263
211
  // create and show drag area
264
212
  var dragLeft = document.createElement('div');
265
213
  dragLeft.className = 'drag-left';
@@ -286,10 +234,10 @@ ItemRange.prototype._repaintDragLeft = function () {
286
234
 
287
235
  /**
288
236
  * Repaint a drag area on the right side of the range when the range is selected
289
- * @private
237
+ * @protected
290
238
  */
291
239
  ItemRange.prototype._repaintDragRight = function () {
292
- if (this.selected && this.options.editable && !this.dom.dragRight) {
240
+ if (this.selected && this.options.editable.updateTime && !this.dom.dragRight) {
293
241
  // create and show drag area
294
242
  var dragRight = document.createElement('div');
295
243
  dragRight.className = 'drag-right';