vis-rails 0.0.6 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
  };