vis-rails 0.0.4 → 0.0.5

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 (58) hide show
  1. checksums.yaml +5 -13
  2. data/lib/vis/rails/version.rb +1 -1
  3. data/vendor/assets/component/emitter.js +162 -0
  4. data/vendor/assets/javascripts/vis.js +1 -0
  5. data/vendor/assets/vis/DataSet.js +8 -2
  6. data/vendor/assets/vis/DataView.js +8 -4
  7. data/vendor/assets/vis/graph/Edge.js +210 -78
  8. data/vendor/assets/vis/graph/Graph.js +474 -652
  9. data/vendor/assets/vis/graph/Node.js +119 -82
  10. data/vendor/assets/vis/graph/css/graph-manipulation.css +128 -0
  11. data/vendor/assets/vis/graph/css/graph-navigation.css +62 -0
  12. data/vendor/assets/vis/graph/graphMixins/ClusterMixin.js +1141 -0
  13. data/vendor/assets/vis/graph/graphMixins/HierarchicalLayoutMixin.js +296 -0
  14. data/vendor/assets/vis/graph/graphMixins/ManipulationMixin.js +433 -0
  15. data/vendor/assets/vis/graph/graphMixins/MixinLoader.js +201 -0
  16. data/vendor/assets/vis/graph/graphMixins/NavigationMixin.js +173 -0
  17. data/vendor/assets/vis/graph/graphMixins/SectorsMixin.js +552 -0
  18. data/vendor/assets/vis/graph/graphMixins/SelectionMixin.js +558 -0
  19. data/vendor/assets/vis/graph/graphMixins/physics/BarnesHut.js +373 -0
  20. data/vendor/assets/vis/graph/graphMixins/physics/HierarchialRepulsion.js +64 -0
  21. data/vendor/assets/vis/graph/graphMixins/physics/PhysicsMixin.js +513 -0
  22. data/vendor/assets/vis/graph/graphMixins/physics/Repulsion.js +66 -0
  23. data/vendor/assets/vis/graph/img/acceptDeleteIcon.png +0 -0
  24. data/vendor/assets/vis/graph/img/addNodeIcon.png +0 -0
  25. data/vendor/assets/vis/graph/img/backIcon.png +0 -0
  26. data/vendor/assets/vis/graph/img/connectIcon.png +0 -0
  27. data/vendor/assets/vis/graph/img/cross.png +0 -0
  28. data/vendor/assets/vis/graph/img/cross2.png +0 -0
  29. data/vendor/assets/vis/graph/img/deleteIcon.png +0 -0
  30. data/vendor/assets/vis/graph/img/downArrow.png +0 -0
  31. data/vendor/assets/vis/graph/img/editIcon.png +0 -0
  32. data/vendor/assets/vis/graph/img/leftArrow.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/module/exports.js +0 -2
  36. data/vendor/assets/vis/module/header.js +2 -2
  37. data/vendor/assets/vis/module/imports.js +1 -2
  38. data/vendor/assets/vis/timeline/Controller.js +56 -45
  39. data/vendor/assets/vis/timeline/Range.js +68 -62
  40. data/vendor/assets/vis/timeline/Stack.js +11 -13
  41. data/vendor/assets/vis/timeline/TimeStep.js +43 -38
  42. data/vendor/assets/vis/timeline/Timeline.js +215 -93
  43. data/vendor/assets/vis/timeline/component/Component.js +19 -3
  44. data/vendor/assets/vis/timeline/component/CurrentTime.js +1 -1
  45. data/vendor/assets/vis/timeline/component/CustomTime.js +39 -120
  46. data/vendor/assets/vis/timeline/component/GroupSet.js +35 -1
  47. data/vendor/assets/vis/timeline/component/ItemSet.js +272 -9
  48. data/vendor/assets/vis/timeline/component/RootPanel.js +59 -47
  49. data/vendor/assets/vis/timeline/component/TimeAxis.js +10 -0
  50. data/vendor/assets/vis/timeline/component/css/item.css +53 -22
  51. data/vendor/assets/vis/timeline/component/item/Item.js +40 -5
  52. data/vendor/assets/vis/timeline/component/item/ItemBox.js +3 -1
  53. data/vendor/assets/vis/timeline/component/item/ItemPoint.js +3 -1
  54. data/vendor/assets/vis/timeline/component/item/ItemRange.js +67 -3
  55. data/vendor/assets/vis/timeline/component/item/ItemRangeOverflow.js +37 -9
  56. data/vendor/assets/vis/timeline/img/delete.png +0 -0
  57. data/vendor/assets/vis/util.js +169 -30
  58. metadata +39 -12
@@ -10,12 +10,29 @@ function RootPanel(container, options) {
10
10
  this.id = util.randomUUID();
11
11
  this.container = container;
12
12
 
13
+ // create functions to be used as DOM event listeners
14
+ var me = this;
15
+ this.hammer = null;
16
+
17
+ // create listeners for all interesting events, these events will be emitted
18
+ // via the controller
19
+ var events = [
20
+ 'touch', 'pinch', 'tap', 'doubletap', 'hold',
21
+ 'dragstart', 'drag', 'dragend',
22
+ 'mousewheel', 'DOMMouseScroll' // DOMMouseScroll is for Firefox
23
+ ];
24
+ this.listeners = {};
25
+ events.forEach(function (event) {
26
+ me.listeners[event] = function () {
27
+ var args = [event].concat(Array.prototype.slice.call(arguments, 0));
28
+ me.controller.emit.apply(me.controller, args);
29
+ };
30
+ });
31
+
13
32
  this.options = options || {};
14
33
  this.defaultOptions = {
15
34
  autoResize: true
16
35
  };
17
-
18
- this.listeners = {}; // event listeners
19
36
  }
20
37
 
21
38
  RootPanel.prototype = new Panel();
@@ -48,6 +65,8 @@ RootPanel.prototype.repaint = function () {
48
65
 
49
66
  this.frame = frame;
50
67
 
68
+ this._registerListeners();
69
+
51
70
  changed += 1;
52
71
  }
53
72
  if (!frame.parentNode) {
@@ -58,7 +77,8 @@ RootPanel.prototype.repaint = function () {
58
77
  changed += 1;
59
78
  }
60
79
 
61
- frame.className = 'vis timeline rootpanel ' + options.orientation;
80
+ frame.className = 'vis timeline rootpanel ' + options.orientation +
81
+ (options.editable ? ' editable' : '');
62
82
  var className = options.className;
63
83
  if (className) {
64
84
  util.addClassName(frame, util.option.asString(className));
@@ -69,7 +89,6 @@ RootPanel.prototype.repaint = function () {
69
89
  changed += update(frame.style, 'width', asSize(options.width, '100%'));
70
90
  changed += update(frame.style, 'height', asSize(options.height, '100%'));
71
91
 
72
- this._updateEventEmitters();
73
92
  this._updateWatch();
74
93
 
75
94
  return (changed > 0);
@@ -158,58 +177,51 @@ RootPanel.prototype._unwatch = function () {
158
177
  };
159
178
 
160
179
  /**
161
- * Event handler
162
- * @param {String} event name of the event, for example 'click', 'mousemove'
163
- * @param {function} callback callback handler, invoked with the raw HTML Event
164
- * as parameter.
180
+ * Set controller for this component, or remove current controller by passing
181
+ * null as parameter value.
182
+ * @param {Controller | null} controller
165
183
  */
166
- RootPanel.prototype.on = function (event, callback) {
167
- // register the listener at this component
168
- var arr = this.listeners[event];
169
- if (!arr) {
170
- arr = [];
171
- this.listeners[event] = arr;
172
- }
173
- arr.push(callback);
184
+ RootPanel.prototype.setController = function setController (controller) {
185
+ this.controller = controller || null;
174
186
 
175
- this._updateEventEmitters();
187
+ if (this.controller) {
188
+ this._registerListeners();
189
+ }
190
+ else {
191
+ this._unregisterListeners();
192
+ }
176
193
  };
177
194
 
178
195
  /**
179
- * Update the event listeners for all event emitters
196
+ * Register event emitters emitted by the rootpanel
180
197
  * @private
181
198
  */
182
- RootPanel.prototype._updateEventEmitters = function () {
183
- if (this.listeners) {
184
- var me = this;
185
- util.forEach(this.listeners, function (listeners, event) {
186
- if (!me.emitters) {
187
- me.emitters = {};
199
+ RootPanel.prototype._registerListeners = function () {
200
+ if (this.frame && this.controller && !this.hammer) {
201
+ this.hammer = Hammer(this.frame, {
202
+ prevent_default: true
203
+ });
204
+
205
+ for (var event in this.listeners) {
206
+ if (this.listeners.hasOwnProperty(event)) {
207
+ this.hammer.on(event, this.listeners[event]);
188
208
  }
189
- if (!(event in me.emitters)) {
190
- // create event
191
- var frame = me.frame;
192
- if (frame) {
193
- //console.log('Created a listener for event ' + event + ' on component ' + me.id); // TODO: cleanup logging
194
- var callback = function(event) {
195
- listeners.forEach(function (listener) {
196
- // TODO: filter on event target!
197
- listener(event);
198
- });
199
- };
200
- me.emitters[event] = callback;
201
-
202
- if (!me.hammer) {
203
- me.hammer = Hammer(frame, {
204
- prevent_default: true
205
- });
206
- }
207
- me.hammer.on(event, callback);
208
- }
209
+ }
210
+ }
211
+ };
212
+
213
+ /**
214
+ * Unregister event emitters from the rootpanel
215
+ * @private
216
+ */
217
+ RootPanel.prototype._unregisterListeners = function () {
218
+ if (this.hammer) {
219
+ for (var event in this.listeners) {
220
+ if (this.listeners.hasOwnProperty(event)) {
221
+ this.hammer.off(event, this.listeners[event]);
209
222
  }
210
- });
223
+ }
211
224
 
212
- // TODO: be able to delete event listeners
213
- // TODO: be able to move event listeners to a parent when available
225
+ this.hammer = null;
214
226
  }
215
227
  };
@@ -520,3 +520,13 @@ TimeAxis.prototype._updateConversion = function() {
520
520
  this.conversion = Range.conversion(range.start, range.end, this.width);
521
521
  }
522
522
  };
523
+
524
+ /**
525
+ * Snap a date to a rounded value.
526
+ * The snap intervals are dependent on the current scale and step.
527
+ * @param {Date} date the date to be snapped.
528
+ * @return {Date} snappedDate
529
+ */
530
+ TimeAxis.prototype.snap = function snap (date) {
531
+ return this.step.snap(date);
532
+ };
@@ -5,6 +5,7 @@
5
5
  border-color: #97B0F8;
6
6
  background-color: #D5DDF6;
7
7
  display: inline-block;
8
+ padding: 5px;
8
9
  }
9
10
 
10
11
  .vis.timeline .item.selected {
@@ -13,6 +14,10 @@
13
14
  z-index: 999;
14
15
  }
15
16
 
17
+ .vis.timeline.editable .item.selected {
18
+ cursor: move;
19
+ }
20
+
16
21
  .vis.timeline .item.point.selected {
17
22
  background-color: #FFF785;
18
23
  z-index: 999;
@@ -42,44 +47,37 @@
42
47
  background: none;
43
48
  }
44
49
 
45
- .vis.timeline .dot {
50
+ .vis.timeline .dot,
51
+ .vis.timeline .item.dot {
52
+ padding: 0;
46
53
  border: 5px solid #97B0F8;
47
54
  position: absolute;
48
55
  border-radius: 5px;
49
56
  -moz-border-radius: 5px; /* For Firefox 3.6 and older */
50
57
  }
51
58
 
52
- .vis.timeline .item.range {
53
- overflow: hidden;
54
- border-style: solid;
55
- border-width: 1px;
56
- border-radius: 2px;
57
- -moz-border-radius: 2px; /* For Firefox 3.6 and older */
58
- }
59
-
60
- .vis.timeline .item.rangeoverflow {
59
+ .vis.timeline .item.range,
60
+ .vis.timeline .item.rangeoverflow{
61
61
  border-style: solid;
62
62
  border-width: 1px;
63
63
  border-radius: 2px;
64
64
  -moz-border-radius: 2px; /* For Firefox 3.6 and older */
65
+ box-sizing: border-box;
65
66
  }
66
67
 
67
- .vis.timeline .item.range .drag-left, .vis.timeline .item.rangeoverflow .drag-left {
68
- cursor: w-resize;
69
- z-index: 1000;
70
- }
71
-
72
- .vis.timeline .item.range .drag-right, .vis.timeline .item.rangeoverflow .drag-right {
73
- cursor: e-resize;
74
- z-index: 1000;
75
- }
76
-
77
- .vis.timeline .item.range .content, .vis.timeline .item.rangeoverflow .content {
68
+ .vis.timeline .item.range .content,
69
+ .vis.timeline .item.rangeoverflow .content {
78
70
  position: relative;
79
71
  display: inline-block;
80
72
  }
81
73
 
74
+ .vis.timeline .item.range .content {
75
+ overflow: hidden;
76
+ max-width: 100%;
77
+ }
78
+
82
79
  .vis.timeline .item.line {
80
+ padding: 0;
83
81
  position: absolute;
84
82
  width: 0;
85
83
  border-left-width: 1px;
@@ -87,7 +85,40 @@
87
85
  }
88
86
 
89
87
  .vis.timeline .item .content {
90
- margin: 5px;
91
88
  white-space: nowrap;
92
89
  overflow: hidden;
93
90
  }
91
+
92
+ .vis.timeline .item .delete {
93
+ background: url('img/timeline/delete.png') no-repeat top center;
94
+ position: absolute;
95
+ width: 24px;
96
+ height: 24px;
97
+ top: 0;
98
+ right: -24px;
99
+ cursor: pointer;
100
+ }
101
+
102
+ .vis.timeline .item.range .drag-left,
103
+ .vis.timeline .item.rangeoverflow .drag-left {
104
+ position: absolute;
105
+ width: 24px;
106
+ height: 100%;
107
+ top: 0;
108
+ left: -4px;
109
+
110
+ cursor: w-resize;
111
+ z-index: 10000;
112
+ }
113
+
114
+ .vis.timeline .item.range .drag-right,
115
+ .vis.timeline .item.rangeoverflow .drag-right {
116
+ position: absolute;
117
+ width: 24px;
118
+ height: 100%;
119
+ top: 0;
120
+ right: -4px;
121
+
122
+ cursor: e-resize;
123
+ z-index: 10001; /* a little higher z-index than .drag-left */
124
+ }
@@ -20,6 +20,7 @@ function Item (parent, data, options, defaultOptions) {
20
20
  this.left = 0;
21
21
  this.width = 0;
22
22
  this.height = 0;
23
+ this.offset = 0;
23
24
  }
24
25
 
25
26
  /**
@@ -73,9 +74,43 @@ Item.prototype.reflow = function reflow() {
73
74
  };
74
75
 
75
76
  /**
76
- * Return the items width
77
- * @return {Integer} width
77
+ * Give the item a display offset in pixels
78
+ * @param {Number} offset Offset on screen in pixels
78
79
  */
79
- Item.prototype.getWidth = function getWidth() {
80
- return this.width;
81
- }
80
+ Item.prototype.setOffset = function setOffset(offset) {
81
+ this.offset = offset;
82
+ };
83
+
84
+ /**
85
+ * Repaint a delete button on the top right of the item when the item is selected
86
+ * @param {HTMLElement} anchor
87
+ * @private
88
+ */
89
+ Item.prototype._repaintDeleteButton = function (anchor) {
90
+ if (this.selected && this.options.editable && !this.dom.deleteButton) {
91
+ // create and show button
92
+ var parent = this.parent;
93
+ var id = this.id;
94
+
95
+ var deleteButton = document.createElement('div');
96
+ deleteButton.className = 'delete';
97
+ deleteButton.title = 'Delete this item';
98
+
99
+ Hammer(deleteButton, {
100
+ preventDefault: true
101
+ }).on('tap', function (event) {
102
+ parent.removeItem(id);
103
+ event.stopPropagation();
104
+ });
105
+
106
+ anchor.appendChild(deleteButton);
107
+ this.dom.deleteButton = deleteButton;
108
+ }
109
+ else if (!this.selected && this.dom.deleteButton) {
110
+ // remove button
111
+ if (this.dom.deleteButton.parentNode) {
112
+ this.dom.deleteButton.parentNode.removeChild(this.dom.deleteButton);
113
+ }
114
+ this.dom.deleteButton = null;
115
+ }
116
+ };
@@ -79,6 +79,8 @@ ItemBox.prototype.repaint = function repaint() {
79
79
  changed = true;
80
80
  }
81
81
 
82
+ this._repaintDeleteButton(dom.box);
83
+
82
84
  // update contents
83
85
  if (this.data.content != this.content) {
84
86
  this.content = this.data.content;
@@ -187,7 +189,7 @@ ItemBox.prototype.reflow = function reflow() {
187
189
  update = util.updateProperty;
188
190
  props = this.props;
189
191
  options = this.options;
190
- start = this.parent.toScreen(this.data.start);
192
+ start = this.parent.toScreen(this.data.start) + this.offset;
191
193
  align = options.align || this.defaultOptions.align;
192
194
  margin = options.margin && options.margin.axis || this.defaultOptions.margin.axis;
193
195
  orientation = options.orientation || this.defaultOptions.orientation;
@@ -73,6 +73,8 @@ ItemPoint.prototype.repaint = function repaint() {
73
73
  changed = true;
74
74
  }
75
75
 
76
+ this._repaintDeleteButton(dom.point);
77
+
76
78
  // update class
77
79
  var className = (this.data.className? ' ' + this.data.className : '') +
78
80
  (this.selected ? ' selected' : '');
@@ -157,7 +159,7 @@ ItemPoint.prototype.reflow = function reflow() {
157
159
  options = this.options;
158
160
  orientation = options.orientation || this.defaultOptions.orientation;
159
161
  margin = options.margin && options.margin.axis || this.defaultOptions.margin.axis;
160
- start = this.parent.toScreen(this.data.start);
162
+ start = this.parent.toScreen(this.data.start) + this.offset;
161
163
 
162
164
  changed += update(this, 'width', dom.point.offsetWidth);
163
165
  changed += update(this, 'height', dom.point.offsetHeight);
@@ -67,8 +67,12 @@ ItemRange.prototype.repaint = function repaint() {
67
67
  changed = true;
68
68
  }
69
69
 
70
+ this._repaintDeleteButton(dom.box);
71
+ this._repaintDragLeft();
72
+ this._repaintDragRight();
73
+
70
74
  // update class
71
- var className = (this.data.className? ' ' + this.data.className : '') +
75
+ var className = (this.data.className ? (' ' + this.data.className) : '') +
72
76
  (this.selected ? ' selected' : '');
73
77
  if (this.className != className) {
74
78
  this.className = className;
@@ -157,8 +161,8 @@ ItemRange.prototype.reflow = function reflow() {
157
161
  props = this.props;
158
162
  options = this.options;
159
163
  parent = this.parent;
160
- start = parent.toScreen(this.data.start);
161
- end = parent.toScreen(this.data.end);
164
+ start = parent.toScreen(this.data.start) + this.offset;
165
+ end = parent.toScreen(this.data.end) + this.offset;
162
166
  update = util.updateProperty;
163
167
  box = dom.box;
164
168
  parentWidth = parent.width;
@@ -249,3 +253,63 @@ ItemRange.prototype.reposition = function reposition() {
249
253
  dom.content.style.left = props.content.left + 'px';
250
254
  }
251
255
  };
256
+
257
+ /**
258
+ * Repaint a drag area on the left side of the range when the range is selected
259
+ * @private
260
+ */
261
+ ItemRange.prototype._repaintDragLeft = function () {
262
+ if (this.selected && this.options.editable && !this.dom.dragLeft) {
263
+ // create and show drag area
264
+ var dragLeft = document.createElement('div');
265
+ dragLeft.className = 'drag-left';
266
+ dragLeft.dragLeftItem = this;
267
+
268
+ // TODO: this should be redundant?
269
+ Hammer(dragLeft, {
270
+ preventDefault: true
271
+ }).on('drag', function () {
272
+ //console.log('drag left')
273
+ });
274
+
275
+ this.dom.box.appendChild(dragLeft);
276
+ this.dom.dragLeft = dragLeft;
277
+ }
278
+ else if (!this.selected && this.dom.dragLeft) {
279
+ // delete drag area
280
+ if (this.dom.dragLeft.parentNode) {
281
+ this.dom.dragLeft.parentNode.removeChild(this.dom.dragLeft);
282
+ }
283
+ this.dom.dragLeft = null;
284
+ }
285
+ };
286
+
287
+ /**
288
+ * Repaint a drag area on the right side of the range when the range is selected
289
+ * @private
290
+ */
291
+ ItemRange.prototype._repaintDragRight = function () {
292
+ if (this.selected && this.options.editable && !this.dom.dragRight) {
293
+ // create and show drag area
294
+ var dragRight = document.createElement('div');
295
+ dragRight.className = 'drag-right';
296
+ dragRight.dragRightItem = this;
297
+
298
+ // TODO: this should be redundant?
299
+ Hammer(dragRight, {
300
+ preventDefault: true
301
+ }).on('drag', function () {
302
+ //console.log('drag right')
303
+ });
304
+
305
+ this.dom.box.appendChild(dragRight);
306
+ this.dom.dragRight = dragRight;
307
+ }
308
+ else if (!this.selected && this.dom.dragRight) {
309
+ // delete drag area
310
+ if (this.dom.dragRight.parentNode) {
311
+ this.dom.dragRight.parentNode.removeChild(this.dom.dragRight);
312
+ }
313
+ this.dom.dragRight = null;
314
+ }
315
+ };