vis-rails 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
+ };