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,281 @@
1
+ /**
2
+ * DataView
3
+ *
4
+ * a dataview offers a filtered view on a dataset or an other dataview.
5
+ *
6
+ * @param {DataSet | DataView} data
7
+ * @param {Object} [options] Available options: see method get
8
+ *
9
+ * @constructor DataView
10
+ */
11
+ function DataView (data, options) {
12
+ this.id = util.randomUUID();
13
+
14
+ this.data = null;
15
+ this.ids = {}; // ids of the items currently in memory (just contains a boolean true)
16
+ this.options = options || {};
17
+ this.fieldId = 'id'; // name of the field containing id
18
+ this.subscribers = {}; // event subscribers
19
+
20
+ var me = this;
21
+ this.listener = function () {
22
+ me._onEvent.apply(me, arguments);
23
+ };
24
+
25
+ this.setData(data);
26
+ }
27
+
28
+ // TODO: implement a function .config() to dynamically update things like configured filter
29
+ // and trigger changes accordingly
30
+
31
+ /**
32
+ * Set a data source for the view
33
+ * @param {DataSet | DataView} data
34
+ */
35
+ DataView.prototype.setData = function (data) {
36
+ var ids, dataItems, i, len;
37
+
38
+ if (this.data) {
39
+ // unsubscribe from current dataset
40
+ if (this.data.unsubscribe) {
41
+ this.data.unsubscribe('*', this.listener);
42
+ }
43
+
44
+ // trigger a remove of all items in memory
45
+ ids = [];
46
+ for (var id in this.ids) {
47
+ if (this.ids.hasOwnProperty(id)) {
48
+ ids.push(id);
49
+ }
50
+ }
51
+ this.ids = {};
52
+ this._trigger('remove', {items: ids});
53
+ }
54
+
55
+ this.data = data;
56
+
57
+ if (this.data) {
58
+ // update fieldId
59
+ this.fieldId = this.options.fieldId ||
60
+ (this.data && this.data.options && this.data.options.fieldId) ||
61
+ 'id';
62
+
63
+ // trigger an add of all added items
64
+ ids = this.data.getIds({filter: this.options && this.options.filter});
65
+ for (i = 0, len = ids.length; i < len; i++) {
66
+ id = ids[i];
67
+ this.ids[id] = true;
68
+ }
69
+ this._trigger('add', {items: ids});
70
+
71
+ // subscribe to new dataset
72
+ if (this.data.subscribe) {
73
+ this.data.subscribe('*', this.listener);
74
+ }
75
+ }
76
+ };
77
+
78
+ /**
79
+ * Get data from the data view
80
+ *
81
+ * Usage:
82
+ *
83
+ * get()
84
+ * get(options: Object)
85
+ * get(options: Object, data: Array | DataTable)
86
+ *
87
+ * get(id: Number)
88
+ * get(id: Number, options: Object)
89
+ * get(id: Number, options: Object, data: Array | DataTable)
90
+ *
91
+ * get(ids: Number[])
92
+ * get(ids: Number[], options: Object)
93
+ * get(ids: Number[], options: Object, data: Array | DataTable)
94
+ *
95
+ * Where:
96
+ *
97
+ * {Number | String} id The id of an item
98
+ * {Number[] | String{}} ids An array with ids of items
99
+ * {Object} options An Object with options. Available options:
100
+ * {String} [type] Type of data to be returned. Can
101
+ * be 'DataTable' or 'Array' (default)
102
+ * {Object.<String, String>} [convert]
103
+ * {String[]} [fields] field names to be returned
104
+ * {function} [filter] filter items
105
+ * {String | function} [order] Order the items by
106
+ * a field name or custom sort function.
107
+ * {Array | DataTable} [data] If provided, items will be appended to this
108
+ * array or table. Required in case of Google
109
+ * DataTable.
110
+ * @param args
111
+ */
112
+ DataView.prototype.get = function (args) {
113
+ var me = this;
114
+
115
+ // parse the arguments
116
+ var ids, options, data;
117
+ var firstType = util.getType(arguments[0]);
118
+ if (firstType == 'String' || firstType == 'Number' || firstType == 'Array') {
119
+ // get(id(s) [, options] [, data])
120
+ ids = arguments[0]; // can be a single id or an array with ids
121
+ options = arguments[1];
122
+ data = arguments[2];
123
+ }
124
+ else {
125
+ // get([, options] [, data])
126
+ options = arguments[0];
127
+ data = arguments[1];
128
+ }
129
+
130
+ // extend the options with the default options and provided options
131
+ var viewOptions = util.extend({}, this.options, options);
132
+
133
+ // create a combined filter method when needed
134
+ if (this.options.filter && options && options.filter) {
135
+ viewOptions.filter = function (item) {
136
+ return me.options.filter(item) && options.filter(item);
137
+ }
138
+ }
139
+
140
+ // build up the call to the linked data set
141
+ var getArguments = [];
142
+ if (ids != undefined) {
143
+ getArguments.push(ids);
144
+ }
145
+ getArguments.push(viewOptions);
146
+ getArguments.push(data);
147
+
148
+ return this.data && this.data.get.apply(this.data, getArguments);
149
+ };
150
+
151
+ /**
152
+ * Get ids of all items or from a filtered set of items.
153
+ * @param {Object} [options] An Object with options. Available options:
154
+ * {function} [filter] filter items
155
+ * {String | function} [order] Order the items by
156
+ * a field name or custom sort function.
157
+ * @return {Array} ids
158
+ */
159
+ DataView.prototype.getIds = function (options) {
160
+ var ids;
161
+
162
+ if (this.data) {
163
+ var defaultFilter = this.options.filter;
164
+ var filter;
165
+
166
+ if (options && options.filter) {
167
+ if (defaultFilter) {
168
+ filter = function (item) {
169
+ return defaultFilter(item) && options.filter(item);
170
+ }
171
+ }
172
+ else {
173
+ filter = options.filter;
174
+ }
175
+ }
176
+ else {
177
+ filter = defaultFilter;
178
+ }
179
+
180
+ ids = this.data.getIds({
181
+ filter: filter,
182
+ order: options && options.order
183
+ });
184
+ }
185
+ else {
186
+ ids = [];
187
+ }
188
+
189
+ return ids;
190
+ };
191
+
192
+ /**
193
+ * Event listener. Will propagate all events from the connected data set to
194
+ * the subscribers of the DataView, but will filter the items and only trigger
195
+ * when there are changes in the filtered data set.
196
+ * @param {String} event
197
+ * @param {Object | null} params
198
+ * @param {String} senderId
199
+ * @private
200
+ */
201
+ DataView.prototype._onEvent = function (event, params, senderId) {
202
+ var i, len, id, item,
203
+ ids = params && params.items,
204
+ data = this.data,
205
+ added = [],
206
+ updated = [],
207
+ removed = [];
208
+
209
+ if (ids && data) {
210
+ switch (event) {
211
+ case 'add':
212
+ // filter the ids of the added items
213
+ for (i = 0, len = ids.length; i < len; i++) {
214
+ id = ids[i];
215
+ item = this.get(id);
216
+ if (item) {
217
+ this.ids[id] = true;
218
+ added.push(id);
219
+ }
220
+ }
221
+
222
+ break;
223
+
224
+ case 'update':
225
+ // determine the event from the views viewpoint: an updated
226
+ // item can be added, updated, or removed from this view.
227
+ for (i = 0, len = ids.length; i < len; i++) {
228
+ id = ids[i];
229
+ item = this.get(id);
230
+
231
+ if (item) {
232
+ if (this.ids[id]) {
233
+ updated.push(id);
234
+ }
235
+ else {
236
+ this.ids[id] = true;
237
+ added.push(id);
238
+ }
239
+ }
240
+ else {
241
+ if (this.ids[id]) {
242
+ delete this.ids[id];
243
+ removed.push(id);
244
+ }
245
+ else {
246
+ // nothing interesting for me :-(
247
+ }
248
+ }
249
+ }
250
+
251
+ break;
252
+
253
+ case 'remove':
254
+ // filter the ids of the removed items
255
+ for (i = 0, len = ids.length; i < len; i++) {
256
+ id = ids[i];
257
+ if (this.ids[id]) {
258
+ delete this.ids[id];
259
+ removed.push(id);
260
+ }
261
+ }
262
+
263
+ break;
264
+ }
265
+
266
+ if (added.length) {
267
+ this._trigger('add', {items: added}, senderId);
268
+ }
269
+ if (updated.length) {
270
+ this._trigger('update', {items: updated}, senderId);
271
+ }
272
+ if (removed.length) {
273
+ this._trigger('remove', {items: removed}, senderId);
274
+ }
275
+ }
276
+ };
277
+
278
+ // copy subscription functionality from DataSet
279
+ DataView.prototype.subscribe = DataSet.prototype.subscribe;
280
+ DataView.prototype.unsubscribe = DataSet.prototype.unsubscribe;
281
+ DataView.prototype._trigger = DataSet.prototype._trigger;
@@ -0,0 +1,89 @@
1
+ /**
2
+ * An event bus can be used to emit events, and to subscribe to events
3
+ * @constructor EventBus
4
+ */
5
+ function EventBus() {
6
+ this.subscriptions = [];
7
+ }
8
+
9
+ /**
10
+ * Subscribe to an event
11
+ * @param {String | RegExp} event The event can be a regular expression, or
12
+ * a string with wildcards, like 'server.*'.
13
+ * @param {function} callback. Callback are called with three parameters:
14
+ * {String} event, {*} [data], {*} [source]
15
+ * @param {*} [target]
16
+ * @returns {String} id A subscription id
17
+ */
18
+ EventBus.prototype.on = function (event, callback, target) {
19
+ var regexp = (event instanceof RegExp) ?
20
+ event :
21
+ new RegExp(event.replace('*', '\\w+'));
22
+
23
+ var subscription = {
24
+ id: util.randomUUID(),
25
+ event: event,
26
+ regexp: regexp,
27
+ callback: (typeof callback === 'function') ? callback : null,
28
+ target: target
29
+ };
30
+
31
+ this.subscriptions.push(subscription);
32
+
33
+ return subscription.id;
34
+ };
35
+
36
+ /**
37
+ * Unsubscribe from an event
38
+ * @param {String | Object} filter Filter for subscriptions to be removed
39
+ * Filter can be a string containing a
40
+ * subscription id, or an object containing
41
+ * one or more of the fields id, event,
42
+ * callback, and target.
43
+ */
44
+ EventBus.prototype.off = function (filter) {
45
+ var i = 0;
46
+ while (i < this.subscriptions.length) {
47
+ var subscription = this.subscriptions[i];
48
+
49
+ var match = true;
50
+ if (filter instanceof Object) {
51
+ // filter is an object. All fields must match
52
+ for (var prop in filter) {
53
+ if (filter.hasOwnProperty(prop)) {
54
+ if (filter[prop] !== subscription[prop]) {
55
+ match = false;
56
+ }
57
+ }
58
+ }
59
+ }
60
+ else {
61
+ // filter is a string, filter on id
62
+ match = (subscription.id == filter);
63
+ }
64
+
65
+ if (match) {
66
+ this.subscriptions.splice(i, 1);
67
+ }
68
+ else {
69
+ i++;
70
+ }
71
+ }
72
+ };
73
+
74
+ /**
75
+ * Emit an event
76
+ * @param {String} event
77
+ * @param {*} [data]
78
+ * @param {*} [source]
79
+ */
80
+ EventBus.prototype.emit = function (event, data, source) {
81
+ for (var i =0; i < this.subscriptions.length; i++) {
82
+ var subscription = this.subscriptions[i];
83
+ if (subscription.regexp.test(event)) {
84
+ if (subscription.callback) {
85
+ subscription.callback(event, data, source);
86
+ }
87
+ }
88
+ }
89
+ };
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Event listener (singleton)
3
+ */
4
+ // TODO: replace usage of the event listener for the EventBus
5
+ var events = {
6
+ 'listeners': [],
7
+
8
+ /**
9
+ * Find a single listener by its object
10
+ * @param {Object} object
11
+ * @return {Number} index -1 when not found
12
+ */
13
+ 'indexOf': function (object) {
14
+ var listeners = this.listeners;
15
+ for (var i = 0, iMax = this.listeners.length; i < iMax; i++) {
16
+ var listener = listeners[i];
17
+ if (listener && listener.object == object) {
18
+ return i;
19
+ }
20
+ }
21
+ return -1;
22
+ },
23
+
24
+ /**
25
+ * Add an event listener
26
+ * @param {Object} object
27
+ * @param {String} event The name of an event, for example 'select'
28
+ * @param {function} callback The callback method, called when the
29
+ * event takes place
30
+ */
31
+ 'addListener': function (object, event, callback) {
32
+ var index = this.indexOf(object);
33
+ var listener = this.listeners[index];
34
+ if (!listener) {
35
+ listener = {
36
+ 'object': object,
37
+ 'events': {}
38
+ };
39
+ this.listeners.push(listener);
40
+ }
41
+
42
+ var callbacks = listener.events[event];
43
+ if (!callbacks) {
44
+ callbacks = [];
45
+ listener.events[event] = callbacks;
46
+ }
47
+
48
+ // add the callback if it does not yet exist
49
+ if (callbacks.indexOf(callback) == -1) {
50
+ callbacks.push(callback);
51
+ }
52
+ },
53
+
54
+ /**
55
+ * Remove an event listener
56
+ * @param {Object} object
57
+ * @param {String} event The name of an event, for example 'select'
58
+ * @param {function} callback The registered callback method
59
+ */
60
+ 'removeListener': function (object, event, callback) {
61
+ var index = this.indexOf(object);
62
+ var listener = this.listeners[index];
63
+ if (listener) {
64
+ var callbacks = listener.events[event];
65
+ if (callbacks) {
66
+ index = callbacks.indexOf(callback);
67
+ if (index != -1) {
68
+ callbacks.splice(index, 1);
69
+ }
70
+
71
+ // remove the array when empty
72
+ if (callbacks.length == 0) {
73
+ delete listener.events[event];
74
+ }
75
+ }
76
+
77
+ // count the number of registered events. remove listener when empty
78
+ var count = 0;
79
+ var events = listener.events;
80
+ for (var e in events) {
81
+ if (events.hasOwnProperty(e)) {
82
+ count++;
83
+ }
84
+ }
85
+ if (count == 0) {
86
+ delete this.listeners[index];
87
+ }
88
+ }
89
+ },
90
+
91
+ /**
92
+ * Remove all registered event listeners
93
+ */
94
+ 'removeAllListeners': function () {
95
+ this.listeners = [];
96
+ },
97
+
98
+ /**
99
+ * Trigger an event. All registered event handlers will be called
100
+ * @param {Object} object
101
+ * @param {String} event
102
+ * @param {Object} properties (optional)
103
+ */
104
+ 'trigger': function (object, event, properties) {
105
+ var index = this.indexOf(object);
106
+ var listener = this.listeners[index];
107
+ if (listener) {
108
+ var callbacks = listener.events[event];
109
+ if (callbacks) {
110
+ for (var i = 0, iMax = callbacks.length; i < iMax; i++) {
111
+ callbacks[i](properties);
112
+ }
113
+ }
114
+ }
115
+ }
116
+ };