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
@@ -3,9 +3,15 @@
3
3
  position: absolute;
4
4
  color: #1A1A1A;
5
5
  border-color: #97B0F8;
6
+ border-width: 1px;
6
7
  background-color: #D5DDF6;
7
8
  display: inline-block;
8
9
  padding: 5px;
10
+
11
+ /* TODO: enable css transitions
12
+ -webkit-transition: top .4s ease-in-out, bottom .4s ease-in-out;
13
+ transition: top .4s ease-in-out, bottom .4s ease-in-out;
14
+ /**/
9
15
  }
10
16
 
11
17
  .vis.timeline .item.selected {
@@ -20,48 +26,30 @@
20
26
 
21
27
  .vis.timeline .item.point.selected {
22
28
  background-color: #FFF785;
23
- z-index: 999;
24
- }
25
- .vis.timeline .item.point.selected .dot {
26
- border-color: #FFC200;
27
- }
28
-
29
- .vis.timeline .item.cluster {
30
- /* TODO: use another color or pattern? */
31
- background: #97B0F8 url('img/cluster_bg.png');
32
- color: white;
33
- }
34
- .vis.timeline .item.cluster.point {
35
- border-color: #D5DDF6;
36
29
  }
37
30
 
38
31
  .vis.timeline .item.box {
39
32
  text-align: center;
40
33
  border-style: solid;
41
- border-width: 1px;
42
- border-radius: 5px;
43
- -moz-border-radius: 5px; /* For Firefox 3.6 and older */
34
+ border-radius: 2px;
44
35
  }
45
36
 
46
37
  .vis.timeline .item.point {
47
38
  background: none;
48
39
  }
49
40
 
50
- .vis.timeline .dot,
51
41
  .vis.timeline .item.dot {
52
- padding: 0;
53
- border: 5px solid #97B0F8;
54
42
  position: absolute;
55
- border-radius: 5px;
56
- -moz-border-radius: 5px; /* For Firefox 3.6 and older */
43
+ padding: 0;
44
+ border-width: 4px;
45
+ border-style: solid;
46
+ border-radius: 4px;
57
47
  }
58
48
 
59
49
  .vis.timeline .item.range,
60
50
  .vis.timeline .item.rangeoverflow{
61
51
  border-style: solid;
62
- border-width: 1px;
63
52
  border-radius: 2px;
64
- -moz-border-radius: 2px; /* For Firefox 3.6 and older */
65
53
  box-sizing: border-box;
66
54
  }
67
55
 
@@ -82,6 +70,11 @@
82
70
  width: 0;
83
71
  border-left-width: 1px;
84
72
  border-left-style: solid;
73
+
74
+ /* TODO: enable css transitions
75
+ -webkit-transition: height .4s ease-in-out, top .4s ease-in-out;
76
+ transition: height .4s ease-in-out, top .4s ease-in-out;
77
+ /**/
85
78
  }
86
79
 
87
80
  .vis.timeline .item .content {
@@ -1,9 +1,15 @@
1
1
 
2
2
  .vis.timeline .itemset {
3
- position: absolute;
3
+ position: relative;
4
4
  padding: 0;
5
5
  margin: 0;
6
- overflow: hidden;
6
+
7
+ box-sizing: border-box;
8
+
9
+ /* FIXME: get transition working for rootpanel and itemset
10
+ -webkit-transition: height 4s ease-in-out;
11
+ transition: height 4s ease-in-out;
12
+ /**/
7
13
  }
8
14
 
9
15
  .vis.timeline .background {
@@ -12,6 +18,21 @@
12
18
  .vis.timeline .foreground {
13
19
  }
14
20
 
15
- .vis.timeline .itemset-axis {
16
- position: absolute;
21
+ .vis.timeline .axis {
22
+ overflow: visible;
23
+ }
24
+
25
+ .vis.timeline .group {
26
+ position: relative;
27
+ box-sizing: border-box;
28
+ }
29
+
30
+ .vis.timeline.top .group {
31
+ border-top: 1px solid #bfbfbf;
32
+ border-bottom: none;
33
+ }
34
+
35
+ .vis.timeline.bottom .group {
36
+ border-top: none;
37
+ border-bottom: 1px solid #bfbfbf;
17
38
  }
@@ -0,0 +1,34 @@
1
+
2
+ .vis.timeline .labelset {
3
+ position: relative;
4
+ width: 100%;
5
+
6
+ overflow: hidden;
7
+
8
+ box-sizing: border-box;
9
+ }
10
+
11
+ .vis.timeline .labelset .vlabel {
12
+ position: relative;
13
+ left: 0;
14
+ top: 0;
15
+ width: 100%;
16
+ color: #4d4d4d;
17
+
18
+ box-sizing: border-box;
19
+ }
20
+
21
+ .vis.timeline.top .labelset .vlabel {
22
+ border-top: 1px solid #bfbfbf;
23
+ border-bottom: none;
24
+ }
25
+
26
+ .vis.timeline.bottom .labelset .vlabel {
27
+ border-top: none;
28
+ border-bottom: 1px solid #bfbfbf;
29
+ }
30
+
31
+ .vis.timeline .labelset .vlabel .inner {
32
+ display: inline-block;
33
+ padding: 5px;
34
+ }
@@ -4,11 +4,25 @@
4
4
  overflow: hidden;
5
5
 
6
6
  border: 1px solid #bfbfbf;
7
- -moz-box-sizing: border-box;
8
7
  box-sizing: border-box;
8
+
9
+ /* FIXME: there is an issue with the height of the items when panel height is animated
10
+ -webkit-transition: height 4s ease-in-out;
11
+ transition: height 4s ease-in-out;
12
+ /**/
9
13
  }
10
14
 
11
15
  .vis.timeline .vpanel {
12
16
  position: absolute;
13
17
  overflow: hidden;
18
+
19
+ box-sizing: border-box;
20
+ }
21
+
22
+ .vis.timeline .vpanel.side {
23
+ border-right: 1px solid #bfbfbf;
24
+ }
25
+
26
+ .vis.timeline .vpanel.side.hidden {
27
+ display: none;
14
28
  }
@@ -1,15 +1,15 @@
1
- .vis.timeline .axis {
2
- position: relative;
1
+ .vis.timeline .timeaxis {
2
+ position: absolute;
3
3
  }
4
4
 
5
- .vis.timeline .axis .text {
5
+ .vis.timeline .timeaxis .text {
6
6
  position: absolute;
7
7
  color: #4d4d4d;
8
8
  padding: 3px;
9
9
  white-space: nowrap;
10
10
  }
11
11
 
12
- .vis.timeline .axis .text.measure {
12
+ .vis.timeline .timeaxis .text.measure {
13
13
  position: absolute;
14
14
  padding-left: 0;
15
15
  padding-right: 0;
@@ -18,13 +18,13 @@
18
18
  visibility: hidden;
19
19
  }
20
20
 
21
- .vis.timeline .axis .grid.vertical {
21
+ .vis.timeline .timeaxis .grid.vertical {
22
22
  position: absolute;
23
23
  width: 0;
24
24
  border-right: 1px solid;
25
25
  }
26
26
 
27
- .vis.timeline .axis .grid.horizontal {
27
+ .vis.timeline .timeaxis .grid.horizontal {
28
28
  position: absolute;
29
29
  left: 0;
30
30
  width: 100%;
@@ -32,10 +32,10 @@
32
32
  border-bottom: 1px solid;
33
33
  }
34
34
 
35
- .vis.timeline .axis .grid.minor {
35
+ .vis.timeline .timeaxis .grid.minor {
36
36
  border-color: #e5e5e5;
37
37
  }
38
38
 
39
- .vis.timeline .axis .grid.major {
39
+ .vis.timeline .timeaxis .grid.major {
40
40
  border-color: #bfbfbf;
41
41
  }
@@ -1,26 +1,27 @@
1
1
  /**
2
2
  * @constructor Item
3
- * @param {ItemSet} parent
4
3
  * @param {Object} data Object containing (optional) parameters type,
5
4
  * start, end, content, group, className.
6
5
  * @param {Object} [options] Options to set initial property values
7
6
  * @param {Object} [defaultOptions] default options
8
7
  * // TODO: describe available options
9
8
  */
10
- function Item (parent, data, options, defaultOptions) {
11
- this.parent = parent;
9
+ function Item (data, options, defaultOptions) {
10
+ this.id = null;
11
+ this.parent = null;
12
12
  this.data = data;
13
13
  this.dom = null;
14
14
  this.options = options || {};
15
15
  this.defaultOptions = defaultOptions || {};
16
16
 
17
17
  this.selected = false;
18
- this.visible = false;
19
- this.top = 0;
20
- this.left = 0;
21
- this.width = 0;
22
- this.height = 0;
23
- this.offset = 0;
18
+ this.displayed = false;
19
+ this.dirty = true;
20
+
21
+ this.top = null;
22
+ this.left = null;
23
+ this.width = null;
24
+ this.height = null;
24
25
  }
25
26
 
26
27
  /**
@@ -28,7 +29,7 @@ function Item (parent, data, options, defaultOptions) {
28
29
  */
29
30
  Item.prototype.select = function select() {
30
31
  this.selected = true;
31
- if (this.visible) this.repaint();
32
+ if (this.displayed) this.repaint();
32
33
  };
33
34
 
34
35
  /**
@@ -36,7 +37,34 @@ Item.prototype.select = function select() {
36
37
  */
37
38
  Item.prototype.unselect = function unselect() {
38
39
  this.selected = false;
39
- if (this.visible) this.repaint();
40
+ if (this.displayed) this.repaint();
41
+ };
42
+
43
+ /**
44
+ * Set a parent for the item
45
+ * @param {ItemSet | Group} parent
46
+ */
47
+ Item.prototype.setParent = function setParent(parent) {
48
+ if (this.displayed) {
49
+ this.hide();
50
+ this.parent = parent;
51
+ if (this.parent) {
52
+ this.show();
53
+ }
54
+ }
55
+ else {
56
+ this.parent = parent;
57
+ }
58
+ };
59
+
60
+ /**
61
+ * Check whether this item is visible inside given range
62
+ * @returns {{start: Number, end: Number}} range with a timestamp for start and end
63
+ * @returns {boolean} True if visible
64
+ */
65
+ Item.prototype.isVisible = function isVisible (range) {
66
+ // Should be implemented by Item implementations
67
+ return false;
40
68
  };
41
69
 
42
70
  /**
@@ -57,40 +85,34 @@ Item.prototype.hide = function hide() {
57
85
 
58
86
  /**
59
87
  * Repaint the item
60
- * @return {Boolean} changed
61
88
  */
62
89
  Item.prototype.repaint = function repaint() {
63
90
  // should be implemented by the item
64
- return false;
65
91
  };
66
92
 
67
93
  /**
68
- * Reflow the item
69
- * @return {Boolean} resized
94
+ * Reposition the Item horizontally
70
95
  */
71
- Item.prototype.reflow = function reflow() {
96
+ Item.prototype.repositionX = function repositionX() {
72
97
  // should be implemented by the item
73
- return false;
74
98
  };
75
99
 
76
100
  /**
77
- * Give the item a display offset in pixels
78
- * @param {Number} offset Offset on screen in pixels
101
+ * Reposition the Item vertically
79
102
  */
80
- Item.prototype.setOffset = function setOffset(offset) {
81
- this.offset = offset;
103
+ Item.prototype.repositionY = function repositionY() {
104
+ // should be implemented by the item
82
105
  };
83
106
 
84
107
  /**
85
108
  * Repaint a delete button on the top right of the item when the item is selected
86
109
  * @param {HTMLElement} anchor
87
- * @private
110
+ * @protected
88
111
  */
89
112
  Item.prototype._repaintDeleteButton = function (anchor) {
90
- if (this.selected && this.options.editable && !this.dom.deleteButton) {
113
+ if (this.selected && this.options.editable.remove && !this.dom.deleteButton) {
91
114
  // create and show button
92
- var parent = this.parent;
93
- var id = this.id;
115
+ var me = this;
94
116
 
95
117
  var deleteButton = document.createElement('div');
96
118
  deleteButton.className = 'delete';
@@ -99,7 +121,7 @@ Item.prototype._repaintDeleteButton = function (anchor) {
99
121
  Hammer(deleteButton, {
100
122
  preventDefault: true
101
123
  }).on('tap', function (event) {
102
- parent.removeItem(id);
124
+ me.parent.removeFromDataSet(me);
103
125
  event.stopPropagation();
104
126
  });
105
127
 
@@ -1,304 +1,230 @@
1
1
  /**
2
2
  * @constructor ItemBox
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 ItemBox (parent, data, options, defaultOptions) {
10
+ function ItemBox (data, options, defaultOptions) {
12
11
  this.props = {
13
12
  dot: {
14
- left: 0,
15
- top: 0,
16
13
  width: 0,
17
14
  height: 0
18
15
  },
19
16
  line: {
20
- top: 0,
21
- left: 0,
22
17
  width: 0,
23
18
  height: 0
24
19
  }
25
20
  };
26
21
 
27
- Item.call(this, parent, data, options, defaultOptions);
22
+ // validate data
23
+ if (data) {
24
+ if (data.start == undefined) {
25
+ throw new Error('Property "start" missing in item ' + data);
26
+ }
27
+ }
28
+
29
+ Item.call(this, data, options, defaultOptions);
28
30
  }
29
31
 
30
- ItemBox.prototype = new Item (null, null);
32
+ ItemBox.prototype = new Item (null);
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
+ ItemBox.prototype.isVisible = function isVisible (range) {
40
+ // determine visibility
41
+ // TODO: account for the real width of the item. Right now we just add 1/4 to the window
42
+ var interval = (range.end - range.start) / 4;
43
+ return (this.data.start > range.start - interval) && (this.data.start < range.end + interval);
44
+ };
31
45
 
32
46
  /**
33
47
  * Repaint the item
34
- * @return {Boolean} changed
35
48
  */
36
49
  ItemBox.prototype.repaint = function repaint() {
37
- // TODO: make an efficient repaint
38
- var changed = false;
39
50
  var dom = this.dom;
40
-
41
51
  if (!dom) {
42
- this._create();
52
+ // create DOM
53
+ this.dom = {};
43
54
  dom = this.dom;
44
- changed = true;
55
+
56
+ // create main box
57
+ dom.box = document.createElement('DIV');
58
+
59
+ // contents box (inside the background box). used for making margins
60
+ dom.content = document.createElement('DIV');
61
+ dom.content.className = 'content';
62
+ dom.box.appendChild(dom.content);
63
+
64
+ // line to axis
65
+ dom.line = document.createElement('DIV');
66
+ dom.line.className = 'line';
67
+
68
+ // dot on axis
69
+ dom.dot = document.createElement('DIV');
70
+ dom.dot.className = 'dot';
71
+
72
+ // attach this item as attribute
73
+ dom.box['timeline-item'] = this;
45
74
  }
46
75
 
47
- if (dom) {
48
- if (!this.parent) {
49
- throw new Error('Cannot repaint item: no parent attached');
76
+ // append DOM to parent DOM
77
+ if (!this.parent) {
78
+ throw new Error('Cannot repaint item: no parent attached');
79
+ }
80
+ if (!dom.box.parentNode) {
81
+ var foreground = this.parent.getForeground();
82
+ if (!foreground) throw new Error('Cannot repaint time axis: parent has no foreground container element');
83
+ foreground.appendChild(dom.box);
84
+ }
85
+ if (!dom.line.parentNode) {
86
+ var background = this.parent.getBackground();
87
+ if (!background) throw new Error('Cannot repaint time axis: parent has no background container element');
88
+ background.appendChild(dom.line);
89
+ }
90
+ if (!dom.dot.parentNode) {
91
+ var axis = this.parent.getAxis();
92
+ if (!background) throw new Error('Cannot repaint time axis: parent has no axis container element');
93
+ axis.appendChild(dom.dot);
94
+ }
95
+ this.displayed = true;
96
+
97
+ // update contents
98
+ if (this.data.content != this.content) {
99
+ this.content = this.data.content;
100
+ if (this.content instanceof Element) {
101
+ dom.content.innerHTML = '';
102
+ dom.content.appendChild(this.content);
50
103
  }
51
-
52
- if (!dom.box.parentNode) {
53
- var foreground = this.parent.getForeground();
54
- if (!foreground) {
55
- throw new Error('Cannot repaint time axis: ' +
56
- 'parent has no foreground container element');
57
- }
58
- foreground.appendChild(dom.box);
59
- changed = true;
104
+ else if (this.data.content != undefined) {
105
+ dom.content.innerHTML = this.content;
60
106
  }
61
-
62
- if (!dom.line.parentNode) {
63
- var background = this.parent.getBackground();
64
- if (!background) {
65
- throw new Error('Cannot repaint time axis: ' +
66
- 'parent has no background container element');
67
- }
68
- background.appendChild(dom.line);
69
- changed = true;
107
+ else {
108
+ throw new Error('Property "content" missing in item ' + this.data.id);
70
109
  }
71
110
 
72
- if (!dom.dot.parentNode) {
73
- var axis = this.parent.getAxis();
74
- if (!background) {
75
- throw new Error('Cannot repaint time axis: ' +
76
- 'parent has no axis container element');
77
- }
78
- axis.appendChild(dom.dot);
79
- changed = true;
80
- }
111
+ this.dirty = true;
112
+ }
81
113
 
82
- this._repaintDeleteButton(dom.box);
83
-
84
- // update contents
85
- if (this.data.content != this.content) {
86
- this.content = this.data.content;
87
- if (this.content instanceof Element) {
88
- dom.content.innerHTML = '';
89
- dom.content.appendChild(this.content);
90
- }
91
- else if (this.data.content != undefined) {
92
- dom.content.innerHTML = this.content;
93
- }
94
- else {
95
- throw new Error('Property "content" missing in item ' + this.data.id);
96
- }
97
- changed = true;
98
- }
114
+ // update class
115
+ var className = (this.data.className? ' ' + this.data.className : '') +
116
+ (this.selected ? ' selected' : '');
117
+ if (this.className != className) {
118
+ this.className = className;
119
+ dom.box.className = 'item box' + className;
120
+ dom.line.className = 'item line' + className;
121
+ dom.dot.className = 'item dot' + className;
99
122
 
100
- // update class
101
- var className = (this.data.className? ' ' + this.data.className : '') +
102
- (this.selected ? ' selected' : '');
103
- if (this.className != className) {
104
- this.className = className;
105
- dom.box.className = 'item box' + className;
106
- dom.line.className = 'item line' + className;
107
- dom.dot.className = 'item dot' + className;
108
- changed = true;
109
- }
123
+ this.dirty = true;
110
124
  }
111
125
 
112
- return changed;
126
+ // recalculate size
127
+ if (this.dirty) {
128
+ this.props.dot.height = dom.dot.offsetHeight;
129
+ this.props.dot.width = dom.dot.offsetWidth;
130
+ this.props.line.width = dom.line.offsetWidth;
131
+ this.width = dom.box.offsetWidth;
132
+ this.height = dom.box.offsetHeight;
133
+
134
+ this.dirty = false;
135
+ }
136
+
137
+ this._repaintDeleteButton(dom.box);
113
138
  };
114
139
 
115
140
  /**
116
- * Show the item in the DOM (when not already visible). The items DOM will
141
+ * Show the item in the DOM (when not already displayed). The items DOM will
117
142
  * be created when needed.
118
- * @return {Boolean} changed
119
143
  */
120
144
  ItemBox.prototype.show = function show() {
121
- if (!this.dom || !this.dom.box.parentNode) {
122
- return this.repaint();
123
- }
124
- else {
125
- return false;
145
+ if (!this.displayed) {
146
+ this.repaint();
126
147
  }
127
148
  };
128
149
 
129
150
  /**
130
151
  * Hide the item from the DOM (when visible)
131
- * @return {Boolean} changed
132
152
  */
133
153
  ItemBox.prototype.hide = function hide() {
134
- var changed = false,
135
- dom = this.dom;
136
- if (dom) {
137
- if (dom.box.parentNode) {
138
- dom.box.parentNode.removeChild(dom.box);
139
- changed = true;
140
- }
141
- if (dom.line.parentNode) {
142
- dom.line.parentNode.removeChild(dom.line);
143
- }
144
- if (dom.dot.parentNode) {
145
- dom.dot.parentNode.removeChild(dom.dot);
146
- }
154
+ if (this.displayed) {
155
+ var dom = this.dom;
156
+
157
+ if (dom.box.parentNode) dom.box.parentNode.removeChild(dom.box);
158
+ if (dom.line.parentNode) dom.line.parentNode.removeChild(dom.line);
159
+ if (dom.dot.parentNode) dom.dot.parentNode.removeChild(dom.dot);
160
+
161
+ this.top = null;
162
+ this.left = null;
163
+
164
+ this.displayed = false;
147
165
  }
148
- return changed;
149
166
  };
150
167
 
151
168
  /**
152
- * Reflow the item: calculate its actual size and position from the DOM
153
- * @return {boolean} resized returns true if the axis is resized
154
- * @override
169
+ * Reposition the item horizontally
170
+ * @Override
155
171
  */
156
- ItemBox.prototype.reflow = function reflow() {
157
- var changed = 0,
158
- update,
159
- dom,
160
- props,
161
- options,
162
- margin,
163
- start,
164
- align,
165
- orientation,
166
- top,
172
+ ItemBox.prototype.repositionX = function repositionX() {
173
+ var start = this.defaultOptions.toScreen(this.data.start),
174
+ align = this.options.align || this.defaultOptions.align,
167
175
  left,
168
- data,
169
- range;
176
+ box = this.dom.box,
177
+ line = this.dom.line,
178
+ dot = this.dom.dot;
170
179
 
171
- if (this.data.start == undefined) {
172
- throw new Error('Property "start" missing in item ' + this.data.id);
180
+ // calculate left position of the box
181
+ if (align == 'right') {
182
+ this.left = start - this.width;
173
183
  }
174
-
175
- data = this.data;
176
- range = this.parent && this.parent.range;
177
- if (data && range) {
178
- // TODO: account for the width of the item
179
- var interval = (range.end - range.start);
180
- this.visible = (data.start > range.start - interval) && (data.start < range.end + interval);
184
+ else if (align == 'left') {
185
+ this.left = start;
181
186
  }
182
187
  else {
183
- this.visible = false;
188
+ // default or 'center'
189
+ this.left = start - this.width / 2;
184
190
  }
185
191
 
186
- if (this.visible) {
187
- dom = this.dom;
188
- if (dom) {
189
- update = util.updateProperty;
190
- props = this.props;
191
- options = this.options;
192
- start = this.parent.toScreen(this.data.start) + this.offset;
193
- align = options.align || this.defaultOptions.align;
194
- margin = options.margin && options.margin.axis || this.defaultOptions.margin.axis;
195
- orientation = options.orientation || this.defaultOptions.orientation;
196
-
197
- changed += update(props.dot, 'height', dom.dot.offsetHeight);
198
- changed += update(props.dot, 'width', dom.dot.offsetWidth);
199
- changed += update(props.line, 'width', dom.line.offsetWidth);
200
- changed += update(props.line, 'height', dom.line.offsetHeight);
201
- changed += update(props.line, 'top', dom.line.offsetTop);
202
- changed += update(this, 'width', dom.box.offsetWidth);
203
- changed += update(this, 'height', dom.box.offsetHeight);
204
- if (align == 'right') {
205
- left = start - this.width;
206
- }
207
- else if (align == 'left') {
208
- left = start;
209
- }
210
- else {
211
- // default or 'center'
212
- left = start - this.width / 2;
213
- }
214
- changed += update(this, 'left', left);
215
-
216
- changed += update(props.line, 'left', start - props.line.width / 2);
217
- changed += update(props.dot, 'left', start - props.dot.width / 2);
218
- changed += update(props.dot, 'top', -props.dot.height / 2);
219
- if (orientation == 'top') {
220
- top = margin;
221
-
222
- changed += update(this, 'top', top);
223
- }
224
- else {
225
- // default or 'bottom'
226
- var parentHeight = this.parent.height;
227
- top = parentHeight - this.height - margin;
228
-
229
- changed += update(this, 'top', top);
230
- }
231
- }
232
- else {
233
- changed += 1;
234
- }
235
- }
236
-
237
- return (changed > 0);
238
- };
239
-
240
- /**
241
- * Create an items DOM
242
- * @private
243
- */
244
- ItemBox.prototype._create = function _create() {
245
- var dom = this.dom;
246
- if (!dom) {
247
- this.dom = dom = {};
192
+ // reposition box
193
+ box.style.left = this.left + 'px';
248
194
 
249
- // create the box
250
- dom.box = document.createElement('DIV');
251
- // className is updated in repaint()
195
+ // reposition line
196
+ line.style.left = (start - this.props.line.width / 2) + 'px';
252
197
 
253
- // contents box (inside the background box). used for making margins
254
- dom.content = document.createElement('DIV');
255
- dom.content.className = 'content';
256
- dom.box.appendChild(dom.content);
257
-
258
- // line to axis
259
- dom.line = document.createElement('DIV');
260
- dom.line.className = 'line';
261
-
262
- // dot on axis
263
- dom.dot = document.createElement('DIV');
264
- dom.dot.className = 'dot';
265
-
266
- // attach this item as attribute
267
- dom.box['timeline-item'] = this;
268
- }
198
+ // reposition dot
199
+ dot.style.left = (start - this.props.dot.width / 2) + 'px';
269
200
  };
270
201
 
271
202
  /**
272
- * Reposition the item, recalculate its left, top, and width, using the current
273
- * range and size of the items itemset
274
- * @override
203
+ * Reposition the item vertically
204
+ * @Override
275
205
  */
276
- ItemBox.prototype.reposition = function reposition() {
277
- var dom = this.dom,
278
- props = this.props,
279
- orientation = this.options.orientation || this.defaultOptions.orientation;
280
-
281
- if (dom) {
282
- var box = dom.box,
283
- line = dom.line,
284
- dot = dom.dot;
285
-
286
- box.style.left = this.left + 'px';
287
- box.style.top = this.top + 'px';
288
-
289
- line.style.left = props.line.left + 'px';
290
- if (orientation == 'top') {
291
- line.style.top = 0 + 'px';
292
- line.style.height = this.top + 'px';
293
- }
294
- else {
295
- // orientation 'bottom'
296
- line.style.top = (this.top + this.height) + 'px';
297
- line.style.height = Math.max(this.parent.height - this.top - this.height +
298
- this.props.dot.height / 2, 0) + 'px';
299
- }
206
+ ItemBox.prototype.repositionY = function repositionY () {
207
+ var orientation = this.options.orientation || this.defaultOptions.orientation,
208
+ box = this.dom.box,
209
+ line = this.dom.line,
210
+ dot = this.dom.dot;
211
+
212
+ if (orientation == 'top') {
213
+ box.style.top = (this.top || 0) + 'px';
214
+ box.style.bottom = '';
215
+
216
+ line.style.top = '0';
217
+ line.style.bottom = '';
218
+ line.style.height = (this.parent.top + this.top + 1) + 'px';
219
+ }
220
+ else { // orientation 'bottom'
221
+ box.style.top = '';
222
+ box.style.bottom = (this.top || 0) + 'px';
300
223
 
301
- dot.style.left = props.dot.left + 'px';
302
- dot.style.top = props.dot.top + 'px';
224
+ line.style.top = (this.parent.top + this.parent.height - this.top - 1) + 'px';
225
+ line.style.bottom = '0';
226
+ line.style.height = '';
303
227
  }
228
+
229
+ dot.style.top = (-this.props.dot.height / 2) + 'px';
304
230
  };