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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.gitmodules +3 -0
- data/.project +11 -0
- data/Gemfile +4 -0
- data/LICENSE +202 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/lib/vis/rails/engine.rb +6 -0
- data/lib/vis/rails/version.rb +5 -0
- data/lib/vis/rails.rb +7 -0
- data/vendor/assets/javascripts/vis.js +1 -0
- data/vendor/assets/stylesheets/vis.css +3 -0
- data/vendor/assets/vis/DataSet.js +936 -0
- data/vendor/assets/vis/DataView.js +281 -0
- data/vendor/assets/vis/EventBus.js +89 -0
- data/vendor/assets/vis/events.js +116 -0
- data/vendor/assets/vis/graph/ClusterMixin.js +1019 -0
- data/vendor/assets/vis/graph/Edge.js +620 -0
- data/vendor/assets/vis/graph/Graph.js +2111 -0
- data/vendor/assets/vis/graph/Groups.js +80 -0
- data/vendor/assets/vis/graph/Images.js +41 -0
- data/vendor/assets/vis/graph/NavigationMixin.js +245 -0
- data/vendor/assets/vis/graph/Node.js +978 -0
- data/vendor/assets/vis/graph/Popup.js +105 -0
- data/vendor/assets/vis/graph/SectorsMixin.js +547 -0
- data/vendor/assets/vis/graph/SelectionMixin.js +515 -0
- data/vendor/assets/vis/graph/dotparser.js +829 -0
- data/vendor/assets/vis/graph/img/downarrow.png +0 -0
- data/vendor/assets/vis/graph/img/leftarrow.png +0 -0
- data/vendor/assets/vis/graph/img/minus.png +0 -0
- data/vendor/assets/vis/graph/img/plus.png +0 -0
- data/vendor/assets/vis/graph/img/rightarrow.png +0 -0
- data/vendor/assets/vis/graph/img/uparrow.png +0 -0
- data/vendor/assets/vis/graph/img/zoomExtends.png +0 -0
- data/vendor/assets/vis/graph/shapes.js +225 -0
- data/vendor/assets/vis/module/exports.js +68 -0
- data/vendor/assets/vis/module/header.js +24 -0
- data/vendor/assets/vis/module/imports.js +32 -0
- data/vendor/assets/vis/shim.js +252 -0
- data/vendor/assets/vis/timeline/Controller.js +172 -0
- data/vendor/assets/vis/timeline/Range.js +553 -0
- data/vendor/assets/vis/timeline/Stack.js +192 -0
- data/vendor/assets/vis/timeline/TimeStep.js +449 -0
- data/vendor/assets/vis/timeline/Timeline.js +476 -0
- data/vendor/assets/vis/timeline/component/Component.js +148 -0
- data/vendor/assets/vis/timeline/component/ContentPanel.js +113 -0
- data/vendor/assets/vis/timeline/component/CurrentTime.js +101 -0
- data/vendor/assets/vis/timeline/component/CustomTime.js +255 -0
- data/vendor/assets/vis/timeline/component/Group.js +129 -0
- data/vendor/assets/vis/timeline/component/GroupSet.js +546 -0
- data/vendor/assets/vis/timeline/component/ItemSet.js +612 -0
- data/vendor/assets/vis/timeline/component/Panel.js +112 -0
- data/vendor/assets/vis/timeline/component/RootPanel.js +215 -0
- data/vendor/assets/vis/timeline/component/TimeAxis.js +522 -0
- data/vendor/assets/vis/timeline/component/css/currenttime.css +5 -0
- data/vendor/assets/vis/timeline/component/css/customtime.css +6 -0
- data/vendor/assets/vis/timeline/component/css/groupset.css +59 -0
- data/vendor/assets/vis/timeline/component/css/item.css +93 -0
- data/vendor/assets/vis/timeline/component/css/itemset.css +17 -0
- data/vendor/assets/vis/timeline/component/css/panel.css +14 -0
- data/vendor/assets/vis/timeline/component/css/timeaxis.css +41 -0
- data/vendor/assets/vis/timeline/component/css/timeline.css +2 -0
- data/vendor/assets/vis/timeline/component/item/Item.js +81 -0
- data/vendor/assets/vis/timeline/component/item/ItemBox.js +302 -0
- data/vendor/assets/vis/timeline/component/item/ItemPoint.js +237 -0
- data/vendor/assets/vis/timeline/component/item/ItemRange.js +251 -0
- data/vendor/assets/vis/timeline/component/item/ItemRangeOverflow.js +91 -0
- data/vendor/assets/vis/util.js +673 -0
- data/vis-rails.gemspec +47 -0
- 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
|
+
};
|