vis-rails 0.0.1

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 (71) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.gitmodules +3 -0
  4. data/.project +11 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE +202 -0
  7. data/README.md +29 -0
  8. data/Rakefile +1 -0
  9. data/lib/vis/rails/engine.rb +6 -0
  10. data/lib/vis/rails/version.rb +5 -0
  11. data/lib/vis/rails.rb +7 -0
  12. data/vendor/assets/javascripts/vis.js +1 -0
  13. data/vendor/assets/stylesheets/vis.css +3 -0
  14. data/vendor/assets/vis/DataSet.js +936 -0
  15. data/vendor/assets/vis/DataView.js +281 -0
  16. data/vendor/assets/vis/EventBus.js +89 -0
  17. data/vendor/assets/vis/events.js +116 -0
  18. data/vendor/assets/vis/graph/ClusterMixin.js +1019 -0
  19. data/vendor/assets/vis/graph/Edge.js +620 -0
  20. data/vendor/assets/vis/graph/Graph.js +2111 -0
  21. data/vendor/assets/vis/graph/Groups.js +80 -0
  22. data/vendor/assets/vis/graph/Images.js +41 -0
  23. data/vendor/assets/vis/graph/NavigationMixin.js +245 -0
  24. data/vendor/assets/vis/graph/Node.js +978 -0
  25. data/vendor/assets/vis/graph/Popup.js +105 -0
  26. data/vendor/assets/vis/graph/SectorsMixin.js +547 -0
  27. data/vendor/assets/vis/graph/SelectionMixin.js +515 -0
  28. data/vendor/assets/vis/graph/dotparser.js +829 -0
  29. data/vendor/assets/vis/graph/img/downarrow.png +0 -0
  30. data/vendor/assets/vis/graph/img/leftarrow.png +0 -0
  31. data/vendor/assets/vis/graph/img/minus.png +0 -0
  32. data/vendor/assets/vis/graph/img/plus.png +0 -0
  33. data/vendor/assets/vis/graph/img/rightarrow.png +0 -0
  34. data/vendor/assets/vis/graph/img/uparrow.png +0 -0
  35. data/vendor/assets/vis/graph/img/zoomExtends.png +0 -0
  36. data/vendor/assets/vis/graph/shapes.js +225 -0
  37. data/vendor/assets/vis/module/exports.js +68 -0
  38. data/vendor/assets/vis/module/header.js +24 -0
  39. data/vendor/assets/vis/module/imports.js +32 -0
  40. data/vendor/assets/vis/shim.js +252 -0
  41. data/vendor/assets/vis/timeline/Controller.js +172 -0
  42. data/vendor/assets/vis/timeline/Range.js +553 -0
  43. data/vendor/assets/vis/timeline/Stack.js +192 -0
  44. data/vendor/assets/vis/timeline/TimeStep.js +449 -0
  45. data/vendor/assets/vis/timeline/Timeline.js +476 -0
  46. data/vendor/assets/vis/timeline/component/Component.js +148 -0
  47. data/vendor/assets/vis/timeline/component/ContentPanel.js +113 -0
  48. data/vendor/assets/vis/timeline/component/CurrentTime.js +101 -0
  49. data/vendor/assets/vis/timeline/component/CustomTime.js +255 -0
  50. data/vendor/assets/vis/timeline/component/Group.js +129 -0
  51. data/vendor/assets/vis/timeline/component/GroupSet.js +546 -0
  52. data/vendor/assets/vis/timeline/component/ItemSet.js +612 -0
  53. data/vendor/assets/vis/timeline/component/Panel.js +112 -0
  54. data/vendor/assets/vis/timeline/component/RootPanel.js +215 -0
  55. data/vendor/assets/vis/timeline/component/TimeAxis.js +522 -0
  56. data/vendor/assets/vis/timeline/component/css/currenttime.css +5 -0
  57. data/vendor/assets/vis/timeline/component/css/customtime.css +6 -0
  58. data/vendor/assets/vis/timeline/component/css/groupset.css +59 -0
  59. data/vendor/assets/vis/timeline/component/css/item.css +93 -0
  60. data/vendor/assets/vis/timeline/component/css/itemset.css +17 -0
  61. data/vendor/assets/vis/timeline/component/css/panel.css +14 -0
  62. data/vendor/assets/vis/timeline/component/css/timeaxis.css +41 -0
  63. data/vendor/assets/vis/timeline/component/css/timeline.css +2 -0
  64. data/vendor/assets/vis/timeline/component/item/Item.js +81 -0
  65. data/vendor/assets/vis/timeline/component/item/ItemBox.js +302 -0
  66. data/vendor/assets/vis/timeline/component/item/ItemPoint.js +237 -0
  67. data/vendor/assets/vis/timeline/component/item/ItemRange.js +251 -0
  68. data/vendor/assets/vis/timeline/component/item/ItemRangeOverflow.js +91 -0
  69. data/vendor/assets/vis/util.js +673 -0
  70. data/vis-rails.gemspec +47 -0
  71. metadata +142 -0
@@ -0,0 +1,113 @@
1
+ /**
2
+ * A content panel can contain a groupset or an itemset, and can handle
3
+ * vertical scrolling
4
+ * @param {Component} [parent]
5
+ * @param {Component[]} [depends] Components on which this components depends
6
+ * (except for the parent)
7
+ * @param {Object} [options] Available parameters:
8
+ * {String | Number | function} [left]
9
+ * {String | Number | function} [top]
10
+ * {String | Number | function} [width]
11
+ * {String | Number | function} [height]
12
+ * {String | function} [className]
13
+ * @constructor ContentPanel
14
+ * @extends Panel
15
+ */
16
+ function ContentPanel(parent, depends, options) {
17
+ this.id = util.randomUUID();
18
+ this.parent = parent;
19
+ this.depends = depends;
20
+
21
+ this.options = options || {};
22
+ }
23
+
24
+ ContentPanel.prototype = new Component();
25
+
26
+ /**
27
+ * Set options. Will extend the current options.
28
+ * @param {Object} [options] Available parameters:
29
+ * {String | function} [className]
30
+ * {String | Number | function} [left]
31
+ * {String | Number | function} [top]
32
+ * {String | Number | function} [width]
33
+ * {String | Number | function} [height]
34
+ */
35
+ ContentPanel.prototype.setOptions = Component.prototype.setOptions;
36
+
37
+ /**
38
+ * Get the container element of the panel, which can be used by a child to
39
+ * add its own widgets.
40
+ * @returns {HTMLElement} container
41
+ */
42
+ ContentPanel.prototype.getContainer = function () {
43
+ return this.frame;
44
+ };
45
+
46
+ /**
47
+ * Repaint the component
48
+ * @return {Boolean} changed
49
+ */
50
+ ContentPanel.prototype.repaint = function () {
51
+ var changed = 0,
52
+ update = util.updateProperty,
53
+ asSize = util.option.asSize,
54
+ options = this.options,
55
+ frame = this.frame;
56
+ if (!frame) {
57
+ frame = document.createElement('div');
58
+ frame.className = 'content-panel';
59
+
60
+ var className = options.className;
61
+ if (className) {
62
+ if (typeof className == 'function') {
63
+ util.addClassName(frame, String(className()));
64
+ }
65
+ else {
66
+ util.addClassName(frame, String(className));
67
+ }
68
+ }
69
+
70
+ this.frame = frame;
71
+ changed += 1;
72
+ }
73
+ if (!frame.parentNode) {
74
+ if (!this.parent) {
75
+ throw new Error('Cannot repaint panel: no parent attached');
76
+ }
77
+ var parentContainer = this.parent.getContainer();
78
+ if (!parentContainer) {
79
+ throw new Error('Cannot repaint panel: parent has no container element');
80
+ }
81
+ parentContainer.appendChild(frame);
82
+ changed += 1;
83
+ }
84
+
85
+ changed += update(frame.style, 'top', asSize(options.top, '0px'));
86
+ changed += update(frame.style, 'left', asSize(options.left, '0px'));
87
+ changed += update(frame.style, 'width', asSize(options.width, '100%'));
88
+ changed += update(frame.style, 'height', asSize(options.height, '100%'));
89
+
90
+ return (changed > 0);
91
+ };
92
+
93
+ /**
94
+ * Reflow the component
95
+ * @return {Boolean} resized
96
+ */
97
+ ContentPanel.prototype.reflow = function () {
98
+ var changed = 0,
99
+ update = util.updateProperty,
100
+ frame = this.frame;
101
+
102
+ if (frame) {
103
+ changed += update(this, 'top', frame.offsetTop);
104
+ changed += update(this, 'left', frame.offsetLeft);
105
+ changed += update(this, 'width', frame.offsetWidth);
106
+ changed += update(this, 'height', frame.offsetHeight);
107
+ }
108
+ else {
109
+ changed += 1;
110
+ }
111
+
112
+ return (changed > 0);
113
+ };
@@ -0,0 +1,101 @@
1
+ /**
2
+ * A current time bar
3
+ * @param {Component} parent
4
+ * @param {Component[]} [depends] Components on which this components depends
5
+ * (except for the parent)
6
+ * @param {Object} [options] Available parameters:
7
+ * {Boolean} [showCurrentTime]
8
+ * @constructor CurrentTime
9
+ * @extends Component
10
+ */
11
+
12
+ function CurrentTime (parent, depends, options) {
13
+ this.id = util.randomUUID();
14
+ this.parent = parent;
15
+ this.depends = depends;
16
+
17
+ this.options = options || {};
18
+ this.defaultOptions = {
19
+ showCurrentTime: false
20
+ };
21
+ }
22
+
23
+ CurrentTime.prototype = new Component();
24
+
25
+ CurrentTime.prototype.setOptions = Component.prototype.setOptions;
26
+
27
+ /**
28
+ * Get the container element of the bar, which can be used by a child to
29
+ * add its own widgets.
30
+ * @returns {HTMLElement} container
31
+ */
32
+ CurrentTime.prototype.getContainer = function () {
33
+ return this.frame;
34
+ };
35
+
36
+ /**
37
+ * Repaint the component
38
+ * @return {Boolean} changed
39
+ */
40
+ CurrentTime.prototype.repaint = function () {
41
+ var bar = this.frame,
42
+ parent = this.parent,
43
+ parentContainer = parent.parent.getContainer();
44
+
45
+ if (!parent) {
46
+ throw new Error('Cannot repaint bar: no parent attached');
47
+ }
48
+
49
+ if (!parentContainer) {
50
+ throw new Error('Cannot repaint bar: parent has no container element');
51
+ }
52
+
53
+ if (!this.getOption('showCurrentTime')) {
54
+ if (bar) {
55
+ parentContainer.removeChild(bar);
56
+ delete this.frame;
57
+ }
58
+
59
+ return;
60
+ }
61
+
62
+ if (!bar) {
63
+ bar = document.createElement('div');
64
+ bar.className = 'currenttime';
65
+ bar.style.position = 'absolute';
66
+ bar.style.top = '0px';
67
+ bar.style.height = '100%';
68
+
69
+ parentContainer.appendChild(bar);
70
+ this.frame = bar;
71
+ }
72
+
73
+ if (!parent.conversion) {
74
+ parent._updateConversion();
75
+ }
76
+
77
+ var now = new Date();
78
+ var x = parent.toScreen(now);
79
+
80
+ bar.style.left = x + 'px';
81
+ bar.title = 'Current time: ' + now;
82
+
83
+ // start a timer to adjust for the new time
84
+ if (this.currentTimeTimer !== undefined) {
85
+ clearTimeout(this.currentTimeTimer);
86
+ delete this.currentTimeTimer;
87
+ }
88
+
89
+ var timeline = this;
90
+ var interval = 1 / parent.conversion.scale / 2;
91
+
92
+ if (interval < 30) {
93
+ interval = 30;
94
+ }
95
+
96
+ this.currentTimeTimer = setTimeout(function() {
97
+ timeline.repaint();
98
+ }, interval);
99
+
100
+ return false;
101
+ };
@@ -0,0 +1,255 @@
1
+ /**
2
+ * A custom time bar
3
+ * @param {Component} parent
4
+ * @param {Component[]} [depends] Components on which this components depends
5
+ * (except for the parent)
6
+ * @param {Object} [options] Available parameters:
7
+ * {Boolean} [showCustomTime]
8
+ * @constructor CustomTime
9
+ * @extends Component
10
+ */
11
+
12
+ function CustomTime (parent, depends, options) {
13
+ this.id = util.randomUUID();
14
+ this.parent = parent;
15
+ this.depends = depends;
16
+
17
+ this.options = options || {};
18
+ this.defaultOptions = {
19
+ showCustomTime: false
20
+ };
21
+
22
+ this.listeners = [];
23
+ this.customTime = new Date();
24
+ }
25
+
26
+ CustomTime.prototype = new Component();
27
+
28
+ CustomTime.prototype.setOptions = Component.prototype.setOptions;
29
+
30
+ /**
31
+ * Get the container element of the bar, which can be used by a child to
32
+ * add its own widgets.
33
+ * @returns {HTMLElement} container
34
+ */
35
+ CustomTime.prototype.getContainer = function () {
36
+ return this.frame;
37
+ };
38
+
39
+ /**
40
+ * Repaint the component
41
+ * @return {Boolean} changed
42
+ */
43
+ CustomTime.prototype.repaint = function () {
44
+ var bar = this.frame,
45
+ parent = this.parent,
46
+ parentContainer = parent.parent.getContainer();
47
+
48
+ if (!parent) {
49
+ throw new Error('Cannot repaint bar: no parent attached');
50
+ }
51
+
52
+ if (!parentContainer) {
53
+ throw new Error('Cannot repaint bar: parent has no container element');
54
+ }
55
+
56
+ if (!this.getOption('showCustomTime')) {
57
+ if (bar) {
58
+ parentContainer.removeChild(bar);
59
+ delete this.frame;
60
+ }
61
+
62
+ return;
63
+ }
64
+
65
+ if (!bar) {
66
+ bar = document.createElement('div');
67
+ bar.className = 'customtime';
68
+ bar.style.position = 'absolute';
69
+ bar.style.top = '0px';
70
+ bar.style.height = '100%';
71
+
72
+ parentContainer.appendChild(bar);
73
+
74
+ var drag = document.createElement('div');
75
+ drag.style.position = 'relative';
76
+ drag.style.top = '0px';
77
+ drag.style.left = '-10px';
78
+ drag.style.height = '100%';
79
+ drag.style.width = '20px';
80
+ bar.appendChild(drag);
81
+
82
+ this.frame = bar;
83
+
84
+ this.subscribe(this, 'movetime');
85
+ }
86
+
87
+ if (!parent.conversion) {
88
+ parent._updateConversion();
89
+ }
90
+
91
+ var x = parent.toScreen(this.customTime);
92
+
93
+ bar.style.left = x + 'px';
94
+ bar.title = 'Time: ' + this.customTime;
95
+
96
+ return false;
97
+ };
98
+
99
+ /**
100
+ * Set custom time.
101
+ * @param {Date} time
102
+ */
103
+ CustomTime.prototype._setCustomTime = function(time) {
104
+ this.customTime = new Date(time.valueOf());
105
+ this.repaint();
106
+ };
107
+
108
+ /**
109
+ * Retrieve the current custom time.
110
+ * @return {Date} customTime
111
+ */
112
+ CustomTime.prototype._getCustomTime = function() {
113
+ return new Date(this.customTime.valueOf());
114
+ };
115
+
116
+ /**
117
+ * Add listeners for mouse and touch events to the component
118
+ * @param {Component} component
119
+ */
120
+ CustomTime.prototype.subscribe = function (component, event) {
121
+ var me = this;
122
+ var listener = {
123
+ component: component,
124
+ event: event,
125
+ callback: function (event) {
126
+ me._onMouseDown(event, listener);
127
+ },
128
+ params: {}
129
+ };
130
+
131
+ component.on('mousedown', listener.callback);
132
+ me.listeners.push(listener);
133
+
134
+ };
135
+
136
+ /**
137
+ * Event handler
138
+ * @param {String} event name of the event, for example 'click', 'mousemove'
139
+ * @param {function} callback callback handler, invoked with the raw HTML Event
140
+ * as parameter.
141
+ */
142
+ CustomTime.prototype.on = function (event, callback) {
143
+ var bar = this.frame;
144
+ if (!bar) {
145
+ throw new Error('Cannot add event listener: no parent attached');
146
+ }
147
+
148
+ events.addListener(this, event, callback);
149
+ util.addEventListener(bar, event, callback);
150
+ };
151
+
152
+ /**
153
+ * Start moving horizontally
154
+ * @param {Event} event
155
+ * @param {Object} listener Listener containing the component and params
156
+ * @private
157
+ */
158
+ CustomTime.prototype._onMouseDown = function(event, listener) {
159
+ event = event || window.event;
160
+ var params = listener.params;
161
+
162
+ // only react on left mouse button down
163
+ var leftButtonDown = event.which ? (event.which == 1) : (event.button == 1);
164
+ if (!leftButtonDown) {
165
+ return;
166
+ }
167
+
168
+ // get mouse position
169
+ params.mouseX = util.getPageX(event);
170
+ params.moved = false;
171
+
172
+ params.customTime = this.customTime;
173
+
174
+ // add event listeners to handle moving the custom time bar
175
+ var me = this;
176
+ if (!params.onMouseMove) {
177
+ params.onMouseMove = function (event) {
178
+ me._onMouseMove(event, listener);
179
+ };
180
+ util.addEventListener(document, 'mousemove', params.onMouseMove);
181
+ }
182
+ if (!params.onMouseUp) {
183
+ params.onMouseUp = function (event) {
184
+ me._onMouseUp(event, listener);
185
+ };
186
+ util.addEventListener(document, 'mouseup', params.onMouseUp);
187
+ }
188
+
189
+ util.stopPropagation(event);
190
+ util.preventDefault(event);
191
+ };
192
+
193
+ /**
194
+ * Perform moving operating.
195
+ * This function activated from within the funcion CustomTime._onMouseDown().
196
+ * @param {Event} event
197
+ * @param {Object} listener
198
+ * @private
199
+ */
200
+ CustomTime.prototype._onMouseMove = function (event, listener) {
201
+ event = event || window.event;
202
+ var params = listener.params;
203
+ var parent = this.parent;
204
+
205
+ // calculate change in mouse position
206
+ var mouseX = util.getPageX(event);
207
+
208
+ if (params.mouseX === undefined) {
209
+ params.mouseX = mouseX;
210
+ }
211
+
212
+ var diff = mouseX - params.mouseX;
213
+
214
+ // if mouse movement is big enough, register it as a "moved" event
215
+ if (Math.abs(diff) >= 1) {
216
+ params.moved = true;
217
+ }
218
+
219
+ var x = parent.toScreen(params.customTime);
220
+ var xnew = x + diff;
221
+ var time = parent.toTime(xnew);
222
+ this._setCustomTime(time);
223
+
224
+ // fire a timechange event
225
+ events.trigger(this, 'timechange', {customTime: this.customTime});
226
+
227
+ util.preventDefault(event);
228
+ };
229
+
230
+ /**
231
+ * Stop moving operating.
232
+ * This function activated from within the function CustomTime._onMouseDown().
233
+ * @param {event} event
234
+ * @param {Object} listener
235
+ * @private
236
+ */
237
+ CustomTime.prototype._onMouseUp = function (event, listener) {
238
+ event = event || window.event;
239
+ var params = listener.params;
240
+
241
+ // remove event listeners here, important for Safari
242
+ if (params.onMouseMove) {
243
+ util.removeEventListener(document, 'mousemove', params.onMouseMove);
244
+ params.onMouseMove = null;
245
+ }
246
+ if (params.onMouseUp) {
247
+ util.removeEventListener(document, 'mouseup', params.onMouseUp);
248
+ params.onMouseUp = null;
249
+ }
250
+
251
+ if (params.moved) {
252
+ // fire a timechanged event
253
+ events.trigger(this, 'timechanged', {customTime: this.customTime});
254
+ }
255
+ };
@@ -0,0 +1,129 @@
1
+ /**
2
+ * @constructor Group
3
+ * @param {GroupSet} parent
4
+ * @param {Number | String} groupId
5
+ * @param {Object} [options] Options to set initial property values
6
+ * // TODO: describe available options
7
+ * @extends Component
8
+ */
9
+ function Group (parent, groupId, options) {
10
+ this.id = util.randomUUID();
11
+ this.parent = parent;
12
+
13
+ this.groupId = groupId;
14
+ this.itemset = null; // ItemSet
15
+ this.options = options || {};
16
+ this.options.top = 0;
17
+
18
+ this.props = {
19
+ label: {
20
+ width: 0,
21
+ height: 0
22
+ }
23
+ };
24
+
25
+ this.top = 0;
26
+ this.left = 0;
27
+ this.width = 0;
28
+ this.height = 0;
29
+ }
30
+
31
+ Group.prototype = new Component();
32
+
33
+ // TODO: comment
34
+ Group.prototype.setOptions = Component.prototype.setOptions;
35
+
36
+ /**
37
+ * Get the container element of the panel, which can be used by a child to
38
+ * add its own widgets.
39
+ * @returns {HTMLElement} container
40
+ */
41
+ Group.prototype.getContainer = function () {
42
+ return this.parent.getContainer();
43
+ };
44
+
45
+ /**
46
+ * Set item set for the group. The group will create a view on the itemset,
47
+ * filtered by the groups id.
48
+ * @param {DataSet | DataView} items
49
+ */
50
+ Group.prototype.setItems = function setItems(items) {
51
+ if (this.itemset) {
52
+ // remove current item set
53
+ this.itemset.hide();
54
+ this.itemset.setItems();
55
+
56
+ this.parent.controller.remove(this.itemset);
57
+ this.itemset = null;
58
+ }
59
+
60
+ if (items) {
61
+ var groupId = this.groupId;
62
+
63
+ var itemsetOptions = Object.create(this.options);
64
+ this.itemset = new ItemSet(this, null, itemsetOptions);
65
+ this.itemset.setRange(this.parent.range);
66
+
67
+ this.view = new DataView(items, {
68
+ filter: function (item) {
69
+ return item.group == groupId;
70
+ }
71
+ });
72
+ this.itemset.setItems(this.view);
73
+
74
+ this.parent.controller.add(this.itemset);
75
+ }
76
+ };
77
+
78
+ /**
79
+ * Set selected items by their id. Replaces the current selection.
80
+ * Unknown id's are silently ignored.
81
+ * @param {Array} [ids] An array with zero or more id's of the items to be
82
+ * selected. If ids is an empty array, all items will be
83
+ * unselected.
84
+ */
85
+ Group.prototype.setSelection = function setSelection(ids) {
86
+ if (this.itemset) this.itemset.setSelection(ids);
87
+ };
88
+
89
+ /**
90
+ * Get the selected items by their id
91
+ * @return {Array} ids The ids of the selected items
92
+ */
93
+ Group.prototype.getSelection = function getSelection() {
94
+ return this.itemset ? this.itemset.getSelection() : [];
95
+ };
96
+
97
+ /**
98
+ * Repaint the item
99
+ * @return {Boolean} changed
100
+ */
101
+ Group.prototype.repaint = function repaint() {
102
+ return false;
103
+ };
104
+
105
+ /**
106
+ * Reflow the item
107
+ * @return {Boolean} resized
108
+ */
109
+ Group.prototype.reflow = function reflow() {
110
+ var changed = 0,
111
+ update = util.updateProperty;
112
+
113
+ changed += update(this, 'top', this.itemset ? this.itemset.top : 0);
114
+ changed += update(this, 'height', this.itemset ? this.itemset.height : 0);
115
+
116
+ // TODO: reckon with the height of the group label
117
+
118
+ if (this.label) {
119
+ var inner = this.label.firstChild;
120
+ changed += update(this.props.label, 'width', inner.clientWidth);
121
+ changed += update(this.props.label, 'height', inner.clientHeight);
122
+ }
123
+ else {
124
+ changed += update(this.props.label, 'width', 0);
125
+ changed += update(this.props.label, 'height', 0);
126
+ }
127
+
128
+ return (changed > 0);
129
+ };