vis-rails 2.0.0 → 2.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 +4 -4
- data/lib/vis/rails/version.rb +1 -1
- data/vendor/assets/javascripts/vis.js +26 -26
- metadata +16 -85
- data/vendor/assets/vis/DataSet.js +0 -926
- data/vendor/assets/vis/DataView.js +0 -283
- data/vendor/assets/vis/graph/Edge.js +0 -957
- data/vendor/assets/vis/graph/Graph.js +0 -2291
- data/vendor/assets/vis/graph/Groups.js +0 -80
- data/vendor/assets/vis/graph/Images.js +0 -41
- data/vendor/assets/vis/graph/Node.js +0 -966
- data/vendor/assets/vis/graph/Popup.js +0 -132
- data/vendor/assets/vis/graph/css/graph-manipulation.css +0 -128
- data/vendor/assets/vis/graph/css/graph-navigation.css +0 -66
- data/vendor/assets/vis/graph/dotparser.js +0 -829
- data/vendor/assets/vis/graph/graphMixins/ClusterMixin.js +0 -1143
- data/vendor/assets/vis/graph/graphMixins/HierarchicalLayoutMixin.js +0 -311
- data/vendor/assets/vis/graph/graphMixins/ManipulationMixin.js +0 -576
- data/vendor/assets/vis/graph/graphMixins/MixinLoader.js +0 -199
- data/vendor/assets/vis/graph/graphMixins/NavigationMixin.js +0 -205
- data/vendor/assets/vis/graph/graphMixins/SectorsMixin.js +0 -552
- data/vendor/assets/vis/graph/graphMixins/SelectionMixin.js +0 -648
- data/vendor/assets/vis/graph/graphMixins/physics/BarnesHut.js +0 -398
- data/vendor/assets/vis/graph/graphMixins/physics/HierarchialRepulsion.js +0 -64
- data/vendor/assets/vis/graph/graphMixins/physics/PhysicsMixin.js +0 -697
- data/vendor/assets/vis/graph/graphMixins/physics/Repulsion.js +0 -66
- data/vendor/assets/vis/graph/img/acceptDeleteIcon.png +0 -0
- data/vendor/assets/vis/graph/img/addNodeIcon.png +0 -0
- data/vendor/assets/vis/graph/img/backIcon.png +0 -0
- data/vendor/assets/vis/graph/img/connectIcon.png +0 -0
- data/vendor/assets/vis/graph/img/cross.png +0 -0
- data/vendor/assets/vis/graph/img/cross2.png +0 -0
- data/vendor/assets/vis/graph/img/deleteIcon.png +0 -0
- data/vendor/assets/vis/graph/img/downArrow.png +0 -0
- data/vendor/assets/vis/graph/img/editIcon.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 +0 -225
- data/vendor/assets/vis/graph3d/Graph3d.js +0 -3306
- data/vendor/assets/vis/module/exports.js +0 -65
- data/vendor/assets/vis/module/header.js +0 -24
- data/vendor/assets/vis/module/imports.js +0 -31
- data/vendor/assets/vis/shim.js +0 -252
- data/vendor/assets/vis/timeline/Range.js +0 -532
- data/vendor/assets/vis/timeline/TimeStep.js +0 -466
- data/vendor/assets/vis/timeline/Timeline.js +0 -851
- data/vendor/assets/vis/timeline/component/Component.js +0 -52
- data/vendor/assets/vis/timeline/component/CurrentTime.js +0 -128
- data/vendor/assets/vis/timeline/component/CustomTime.js +0 -182
- data/vendor/assets/vis/timeline/component/Group.js +0 -470
- data/vendor/assets/vis/timeline/component/ItemSet.js +0 -1332
- data/vendor/assets/vis/timeline/component/TimeAxis.js +0 -389
- data/vendor/assets/vis/timeline/component/css/animation.css +0 -33
- data/vendor/assets/vis/timeline/component/css/currenttime.css +0 -5
- data/vendor/assets/vis/timeline/component/css/customtime.css +0 -6
- data/vendor/assets/vis/timeline/component/css/item.css +0 -107
- data/vendor/assets/vis/timeline/component/css/itemset.css +0 -33
- data/vendor/assets/vis/timeline/component/css/labelset.css +0 -36
- data/vendor/assets/vis/timeline/component/css/panel.css +0 -71
- data/vendor/assets/vis/timeline/component/css/timeaxis.css +0 -48
- data/vendor/assets/vis/timeline/component/css/timeline.css +0 -2
- data/vendor/assets/vis/timeline/component/item/Item.js +0 -139
- data/vendor/assets/vis/timeline/component/item/ItemBox.js +0 -230
- data/vendor/assets/vis/timeline/component/item/ItemPoint.js +0 -190
- data/vendor/assets/vis/timeline/component/item/ItemRange.js +0 -262
- data/vendor/assets/vis/timeline/component/item/ItemRangeOverflow.js +0 -57
- data/vendor/assets/vis/timeline/img/delete.png +0 -0
- data/vendor/assets/vis/timeline/stack.js +0 -112
- data/vendor/assets/vis/util.js +0 -990
@@ -1,52 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* Prototype for visual components
|
3
|
-
* @param {{dom: Object, domProps: Object, emitter: Emitter, range: Range}} [body]
|
4
|
-
* @param {Object} [options]
|
5
|
-
*/
|
6
|
-
function Component (body, options) {
|
7
|
-
this.options = null;
|
8
|
-
this.props = null;
|
9
|
-
}
|
10
|
-
|
11
|
-
/**
|
12
|
-
* Set options for the component. The new options will be merged into the
|
13
|
-
* current options.
|
14
|
-
* @param {Object} options
|
15
|
-
*/
|
16
|
-
Component.prototype.setOptions = function(options) {
|
17
|
-
if (options) {
|
18
|
-
util.extend(this.options, options);
|
19
|
-
}
|
20
|
-
};
|
21
|
-
|
22
|
-
/**
|
23
|
-
* Repaint the component
|
24
|
-
* @return {boolean} Returns true if the component is resized
|
25
|
-
*/
|
26
|
-
Component.prototype.redraw = function() {
|
27
|
-
// should be implemented by the component
|
28
|
-
return false;
|
29
|
-
};
|
30
|
-
|
31
|
-
/**
|
32
|
-
* Destroy the component. Cleanup DOM and event listeners
|
33
|
-
*/
|
34
|
-
Component.prototype.destroy = function() {
|
35
|
-
// should be implemented by the component
|
36
|
-
};
|
37
|
-
|
38
|
-
/**
|
39
|
-
* Test whether the component is resized since the last time _isResized() was
|
40
|
-
* called.
|
41
|
-
* @return {Boolean} Returns true if the component is resized
|
42
|
-
* @protected
|
43
|
-
*/
|
44
|
-
Component.prototype._isResized = function() {
|
45
|
-
var resized = (this.props._previousWidth !== this.props.width ||
|
46
|
-
this.props._previousHeight !== this.props.height);
|
47
|
-
|
48
|
-
this.props._previousWidth = this.props.width;
|
49
|
-
this.props._previousHeight = this.props.height;
|
50
|
-
|
51
|
-
return resized;
|
52
|
-
};
|
@@ -1,128 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* A current time bar
|
3
|
-
* @param {{range: Range, dom: Object, domProps: Object}} body
|
4
|
-
* @param {Object} [options] Available parameters:
|
5
|
-
* {Boolean} [showCurrentTime]
|
6
|
-
* @constructor CurrentTime
|
7
|
-
* @extends Component
|
8
|
-
*/
|
9
|
-
|
10
|
-
function CurrentTime (body, options) {
|
11
|
-
this.body = body;
|
12
|
-
|
13
|
-
// default options
|
14
|
-
this.defaultOptions = {
|
15
|
-
showCurrentTime: true
|
16
|
-
};
|
17
|
-
this.options = util.extend({}, this.defaultOptions);
|
18
|
-
|
19
|
-
this._create();
|
20
|
-
|
21
|
-
this.setOptions(options);
|
22
|
-
}
|
23
|
-
|
24
|
-
CurrentTime.prototype = new Component();
|
25
|
-
|
26
|
-
/**
|
27
|
-
* Create the HTML DOM for the current time bar
|
28
|
-
* @private
|
29
|
-
*/
|
30
|
-
CurrentTime.prototype._create = function() {
|
31
|
-
var bar = document.createElement('div');
|
32
|
-
bar.className = 'currenttime';
|
33
|
-
bar.style.position = 'absolute';
|
34
|
-
bar.style.top = '0px';
|
35
|
-
bar.style.height = '100%';
|
36
|
-
|
37
|
-
this.bar = bar;
|
38
|
-
};
|
39
|
-
|
40
|
-
/**
|
41
|
-
* Destroy the CurrentTime bar
|
42
|
-
*/
|
43
|
-
CurrentTime.prototype.destroy = function () {
|
44
|
-
this.options.showCurrentTime = false;
|
45
|
-
this.redraw(); // will remove the bar from the DOM and stop refreshing
|
46
|
-
|
47
|
-
this.body = null;
|
48
|
-
};
|
49
|
-
|
50
|
-
/**
|
51
|
-
* Set options for the component. Options will be merged in current options.
|
52
|
-
* @param {Object} options Available parameters:
|
53
|
-
* {boolean} [showCurrentTime]
|
54
|
-
*/
|
55
|
-
CurrentTime.prototype.setOptions = function(options) {
|
56
|
-
if (options) {
|
57
|
-
// copy all options that we know
|
58
|
-
util.selectiveExtend(['showCurrentTime'], this.options, options);
|
59
|
-
}
|
60
|
-
};
|
61
|
-
|
62
|
-
/**
|
63
|
-
* Repaint the component
|
64
|
-
* @return {boolean} Returns true if the component is resized
|
65
|
-
*/
|
66
|
-
CurrentTime.prototype.redraw = function() {
|
67
|
-
if (this.options.showCurrentTime) {
|
68
|
-
var parent = this.body.dom.backgroundVertical;
|
69
|
-
if (this.bar.parentNode != parent) {
|
70
|
-
// attach to the dom
|
71
|
-
if (this.bar.parentNode) {
|
72
|
-
this.bar.parentNode.removeChild(this.bar);
|
73
|
-
}
|
74
|
-
parent.appendChild(this.bar);
|
75
|
-
|
76
|
-
this.start();
|
77
|
-
}
|
78
|
-
|
79
|
-
var now = new Date();
|
80
|
-
var x = this.body.util.toScreen(now);
|
81
|
-
|
82
|
-
this.bar.style.left = x + 'px';
|
83
|
-
this.bar.title = 'Current time: ' + now;
|
84
|
-
}
|
85
|
-
else {
|
86
|
-
// remove the line from the DOM
|
87
|
-
if (this.bar.parentNode) {
|
88
|
-
this.bar.parentNode.removeChild(this.bar);
|
89
|
-
}
|
90
|
-
this.stop();
|
91
|
-
}
|
92
|
-
|
93
|
-
return false;
|
94
|
-
};
|
95
|
-
|
96
|
-
/**
|
97
|
-
* Start auto refreshing the current time bar
|
98
|
-
*/
|
99
|
-
CurrentTime.prototype.start = function() {
|
100
|
-
var me = this;
|
101
|
-
|
102
|
-
function update () {
|
103
|
-
me.stop();
|
104
|
-
|
105
|
-
// determine interval to refresh
|
106
|
-
var scale = me.body.range.conversion(me.body.domProps.center.width).scale;
|
107
|
-
var interval = 1 / scale / 10;
|
108
|
-
if (interval < 30) interval = 30;
|
109
|
-
if (interval > 1000) interval = 1000;
|
110
|
-
|
111
|
-
me.redraw();
|
112
|
-
|
113
|
-
// start a timer to adjust for the new time
|
114
|
-
me.currentTimeTimer = setTimeout(update, interval);
|
115
|
-
}
|
116
|
-
|
117
|
-
update();
|
118
|
-
};
|
119
|
-
|
120
|
-
/**
|
121
|
-
* Stop auto refreshing the current time bar
|
122
|
-
*/
|
123
|
-
CurrentTime.prototype.stop = function() {
|
124
|
-
if (this.currentTimeTimer !== undefined) {
|
125
|
-
clearTimeout(this.currentTimeTimer);
|
126
|
-
delete this.currentTimeTimer;
|
127
|
-
}
|
128
|
-
};
|
@@ -1,182 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* A custom time bar
|
3
|
-
* @param {{range: Range, dom: Object}} body
|
4
|
-
* @param {Object} [options] Available parameters:
|
5
|
-
* {Boolean} [showCustomTime]
|
6
|
-
* @constructor CustomTime
|
7
|
-
* @extends Component
|
8
|
-
*/
|
9
|
-
|
10
|
-
function CustomTime (body, options) {
|
11
|
-
this.body = body;
|
12
|
-
|
13
|
-
// default options
|
14
|
-
this.defaultOptions = {
|
15
|
-
showCustomTime: false
|
16
|
-
};
|
17
|
-
this.options = util.extend({}, this.defaultOptions);
|
18
|
-
|
19
|
-
this.customTime = new Date();
|
20
|
-
this.eventParams = {}; // stores state parameters while dragging the bar
|
21
|
-
|
22
|
-
// create the DOM
|
23
|
-
this._create();
|
24
|
-
|
25
|
-
this.setOptions(options);
|
26
|
-
}
|
27
|
-
|
28
|
-
CustomTime.prototype = new Component();
|
29
|
-
|
30
|
-
/**
|
31
|
-
* Set options for the component. Options will be merged in current options.
|
32
|
-
* @param {Object} options Available parameters:
|
33
|
-
* {boolean} [showCustomTime]
|
34
|
-
*/
|
35
|
-
CustomTime.prototype.setOptions = function(options) {
|
36
|
-
if (options) {
|
37
|
-
// copy all options that we know
|
38
|
-
util.selectiveExtend(['showCustomTime'], this.options, options);
|
39
|
-
}
|
40
|
-
};
|
41
|
-
|
42
|
-
/**
|
43
|
-
* Create the DOM for the custom time
|
44
|
-
* @private
|
45
|
-
*/
|
46
|
-
CustomTime.prototype._create = function() {
|
47
|
-
var bar = document.createElement('div');
|
48
|
-
bar.className = 'customtime';
|
49
|
-
bar.style.position = 'absolute';
|
50
|
-
bar.style.top = '0px';
|
51
|
-
bar.style.height = '100%';
|
52
|
-
this.bar = bar;
|
53
|
-
|
54
|
-
var drag = document.createElement('div');
|
55
|
-
drag.style.position = 'relative';
|
56
|
-
drag.style.top = '0px';
|
57
|
-
drag.style.left = '-10px';
|
58
|
-
drag.style.height = '100%';
|
59
|
-
drag.style.width = '20px';
|
60
|
-
bar.appendChild(drag);
|
61
|
-
|
62
|
-
// attach event listeners
|
63
|
-
this.hammer = Hammer(bar, {
|
64
|
-
prevent_default: true
|
65
|
-
});
|
66
|
-
this.hammer.on('dragstart', this._onDragStart.bind(this));
|
67
|
-
this.hammer.on('drag', this._onDrag.bind(this));
|
68
|
-
this.hammer.on('dragend', this._onDragEnd.bind(this));
|
69
|
-
};
|
70
|
-
|
71
|
-
/**
|
72
|
-
* Destroy the CustomTime bar
|
73
|
-
*/
|
74
|
-
CustomTime.prototype.destroy = function () {
|
75
|
-
this.options.showCustomTime = false;
|
76
|
-
this.redraw(); // will remove the bar from the DOM
|
77
|
-
|
78
|
-
this.hammer.enable(false);
|
79
|
-
this.hammer = null;
|
80
|
-
|
81
|
-
this.body = null;
|
82
|
-
};
|
83
|
-
|
84
|
-
/**
|
85
|
-
* Repaint the component
|
86
|
-
* @return {boolean} Returns true if the component is resized
|
87
|
-
*/
|
88
|
-
CustomTime.prototype.redraw = function () {
|
89
|
-
if (this.options.showCustomTime) {
|
90
|
-
var parent = this.body.dom.backgroundVertical;
|
91
|
-
if (this.bar.parentNode != parent) {
|
92
|
-
// attach to the dom
|
93
|
-
if (this.bar.parentNode) {
|
94
|
-
this.bar.parentNode.removeChild(this.bar);
|
95
|
-
}
|
96
|
-
parent.appendChild(this.bar);
|
97
|
-
}
|
98
|
-
|
99
|
-
var x = this.body.util.toScreen(this.customTime);
|
100
|
-
|
101
|
-
this.bar.style.left = x + 'px';
|
102
|
-
this.bar.title = 'Time: ' + this.customTime;
|
103
|
-
}
|
104
|
-
else {
|
105
|
-
// remove the line from the DOM
|
106
|
-
if (this.bar.parentNode) {
|
107
|
-
this.bar.parentNode.removeChild(this.bar);
|
108
|
-
}
|
109
|
-
}
|
110
|
-
|
111
|
-
return false;
|
112
|
-
};
|
113
|
-
|
114
|
-
/**
|
115
|
-
* Set custom time.
|
116
|
-
* @param {Date} time
|
117
|
-
*/
|
118
|
-
CustomTime.prototype.setCustomTime = function(time) {
|
119
|
-
this.customTime = new Date(time.valueOf());
|
120
|
-
this.redraw();
|
121
|
-
};
|
122
|
-
|
123
|
-
/**
|
124
|
-
* Retrieve the current custom time.
|
125
|
-
* @return {Date} customTime
|
126
|
-
*/
|
127
|
-
CustomTime.prototype.getCustomTime = function() {
|
128
|
-
return new Date(this.customTime.valueOf());
|
129
|
-
};
|
130
|
-
|
131
|
-
/**
|
132
|
-
* Start moving horizontally
|
133
|
-
* @param {Event} event
|
134
|
-
* @private
|
135
|
-
*/
|
136
|
-
CustomTime.prototype._onDragStart = function(event) {
|
137
|
-
this.eventParams.dragging = true;
|
138
|
-
this.eventParams.customTime = this.customTime;
|
139
|
-
|
140
|
-
event.stopPropagation();
|
141
|
-
event.preventDefault();
|
142
|
-
};
|
143
|
-
|
144
|
-
/**
|
145
|
-
* Perform moving operating.
|
146
|
-
* @param {Event} event
|
147
|
-
* @private
|
148
|
-
*/
|
149
|
-
CustomTime.prototype._onDrag = function (event) {
|
150
|
-
if (!this.eventParams.dragging) return;
|
151
|
-
|
152
|
-
var deltaX = event.gesture.deltaX,
|
153
|
-
x = this.body.util.toScreen(this.eventParams.customTime) + deltaX,
|
154
|
-
time = this.body.util.toTime(x);
|
155
|
-
|
156
|
-
this.setCustomTime(time);
|
157
|
-
|
158
|
-
// fire a timechange event
|
159
|
-
this.body.emitter.emit('timechange', {
|
160
|
-
time: new Date(this.customTime.valueOf())
|
161
|
-
});
|
162
|
-
|
163
|
-
event.stopPropagation();
|
164
|
-
event.preventDefault();
|
165
|
-
};
|
166
|
-
|
167
|
-
/**
|
168
|
-
* Stop moving operating.
|
169
|
-
* @param {event} event
|
170
|
-
* @private
|
171
|
-
*/
|
172
|
-
CustomTime.prototype._onDragEnd = function (event) {
|
173
|
-
if (!this.eventParams.dragging) return;
|
174
|
-
|
175
|
-
// fire a timechanged event
|
176
|
-
this.body.emitter.emit('timechanged', {
|
177
|
-
time: new Date(this.customTime.valueOf())
|
178
|
-
});
|
179
|
-
|
180
|
-
event.stopPropagation();
|
181
|
-
event.preventDefault();
|
182
|
-
};
|
@@ -1,470 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* @constructor Group
|
3
|
-
* @param {Number | String} groupId
|
4
|
-
* @param {Object} data
|
5
|
-
* @param {ItemSet} itemSet
|
6
|
-
*/
|
7
|
-
function Group (groupId, data, itemSet) {
|
8
|
-
this.groupId = groupId;
|
9
|
-
|
10
|
-
this.itemSet = itemSet;
|
11
|
-
|
12
|
-
this.dom = {};
|
13
|
-
this.props = {
|
14
|
-
label: {
|
15
|
-
width: 0,
|
16
|
-
height: 0
|
17
|
-
}
|
18
|
-
};
|
19
|
-
this.className = null;
|
20
|
-
|
21
|
-
this.items = {}; // items filtered by groupId of this group
|
22
|
-
this.visibleItems = []; // items currently visible in window
|
23
|
-
this.orderedItems = { // items sorted by start and by end
|
24
|
-
byStart: [],
|
25
|
-
byEnd: []
|
26
|
-
};
|
27
|
-
|
28
|
-
this._create();
|
29
|
-
|
30
|
-
this.setData(data);
|
31
|
-
}
|
32
|
-
|
33
|
-
/**
|
34
|
-
* Create DOM elements for the group
|
35
|
-
* @private
|
36
|
-
*/
|
37
|
-
Group.prototype._create = function() {
|
38
|
-
var label = document.createElement('div');
|
39
|
-
label.className = 'vlabel';
|
40
|
-
this.dom.label = label;
|
41
|
-
|
42
|
-
var inner = document.createElement('div');
|
43
|
-
inner.className = 'inner';
|
44
|
-
label.appendChild(inner);
|
45
|
-
this.dom.inner = inner;
|
46
|
-
|
47
|
-
var foreground = document.createElement('div');
|
48
|
-
foreground.className = 'group';
|
49
|
-
foreground['timeline-group'] = this;
|
50
|
-
this.dom.foreground = foreground;
|
51
|
-
|
52
|
-
this.dom.background = document.createElement('div');
|
53
|
-
this.dom.background.className = 'group';
|
54
|
-
|
55
|
-
this.dom.axis = document.createElement('div');
|
56
|
-
this.dom.axis.className = 'group';
|
57
|
-
|
58
|
-
// create a hidden marker to detect when the Timelines container is attached
|
59
|
-
// to the DOM, or the style of a parent of the Timeline is changed from
|
60
|
-
// display:none is changed to visible.
|
61
|
-
this.dom.marker = document.createElement('div');
|
62
|
-
this.dom.marker.style.visibility = 'hidden';
|
63
|
-
this.dom.marker.innerHTML = '?';
|
64
|
-
this.dom.background.appendChild(this.dom.marker);
|
65
|
-
};
|
66
|
-
|
67
|
-
/**
|
68
|
-
* Set the group data for this group
|
69
|
-
* @param {Object} data Group data, can contain properties content and className
|
70
|
-
*/
|
71
|
-
Group.prototype.setData = function(data) {
|
72
|
-
// update contents
|
73
|
-
var content = data && data.content;
|
74
|
-
if (content instanceof Element) {
|
75
|
-
this.dom.inner.appendChild(content);
|
76
|
-
}
|
77
|
-
else if (content != undefined) {
|
78
|
-
this.dom.inner.innerHTML = content;
|
79
|
-
}
|
80
|
-
else {
|
81
|
-
this.dom.inner.innerHTML = this.groupId;
|
82
|
-
}
|
83
|
-
|
84
|
-
if (!this.dom.inner.firstChild) {
|
85
|
-
util.addClassName(this.dom.inner, 'hidden');
|
86
|
-
}
|
87
|
-
else {
|
88
|
-
util.removeClassName(this.dom.inner, 'hidden');
|
89
|
-
}
|
90
|
-
|
91
|
-
// update className
|
92
|
-
var className = data && data.className || null;
|
93
|
-
if (className != this.className) {
|
94
|
-
if (this.className) {
|
95
|
-
util.removeClassName(this.dom.label, className);
|
96
|
-
util.removeClassName(this.dom.foreground, className);
|
97
|
-
util.removeClassName(this.dom.background, className);
|
98
|
-
util.removeClassName(this.dom.axis, className);
|
99
|
-
}
|
100
|
-
util.addClassName(this.dom.label, className);
|
101
|
-
util.addClassName(this.dom.foreground, className);
|
102
|
-
util.addClassName(this.dom.background, className);
|
103
|
-
util.addClassName(this.dom.axis, className);
|
104
|
-
}
|
105
|
-
};
|
106
|
-
|
107
|
-
/**
|
108
|
-
* Get the width of the group label
|
109
|
-
* @return {number} width
|
110
|
-
*/
|
111
|
-
Group.prototype.getLabelWidth = function() {
|
112
|
-
return this.props.label.width;
|
113
|
-
};
|
114
|
-
|
115
|
-
|
116
|
-
/**
|
117
|
-
* Repaint this group
|
118
|
-
* @param {{start: number, end: number}} range
|
119
|
-
* @param {{item: number, axis: number}} margin
|
120
|
-
* @param {boolean} [restack=false] Force restacking of all items
|
121
|
-
* @return {boolean} Returns true if the group is resized
|
122
|
-
*/
|
123
|
-
Group.prototype.redraw = function(range, margin, restack) {
|
124
|
-
var resized = false;
|
125
|
-
|
126
|
-
this.visibleItems = this._updateVisibleItems(this.orderedItems, this.visibleItems, range);
|
127
|
-
|
128
|
-
// force recalculation of the height of the items when the marker height changed
|
129
|
-
// (due to the Timeline being attached to the DOM or changed from display:none to visible)
|
130
|
-
var markerHeight = this.dom.marker.clientHeight;
|
131
|
-
if (markerHeight != this.lastMarkerHeight) {
|
132
|
-
this.lastMarkerHeight = markerHeight;
|
133
|
-
|
134
|
-
util.forEach(this.items, function (item) {
|
135
|
-
item.dirty = true;
|
136
|
-
if (item.displayed) item.redraw();
|
137
|
-
});
|
138
|
-
|
139
|
-
restack = true;
|
140
|
-
}
|
141
|
-
|
142
|
-
// reposition visible items vertically
|
143
|
-
if (this.itemSet.options.stack) { // TODO: ugly way to access options...
|
144
|
-
stack.stack(this.visibleItems, margin, restack);
|
145
|
-
}
|
146
|
-
else { // no stacking
|
147
|
-
stack.nostack(this.visibleItems, margin);
|
148
|
-
}
|
149
|
-
|
150
|
-
// recalculate the height of the group
|
151
|
-
var height;
|
152
|
-
var visibleItems = this.visibleItems;
|
153
|
-
if (visibleItems.length) {
|
154
|
-
var min = visibleItems[0].top;
|
155
|
-
var max = visibleItems[0].top + visibleItems[0].height;
|
156
|
-
util.forEach(visibleItems, function (item) {
|
157
|
-
min = Math.min(min, item.top);
|
158
|
-
max = Math.max(max, (item.top + item.height));
|
159
|
-
});
|
160
|
-
height = (max - min) + margin.axis + margin.item;
|
161
|
-
}
|
162
|
-
else {
|
163
|
-
height = margin.axis + margin.item;
|
164
|
-
}
|
165
|
-
height = Math.max(height, this.props.label.height);
|
166
|
-
|
167
|
-
// calculate actual size and position
|
168
|
-
var foreground = this.dom.foreground;
|
169
|
-
this.top = foreground.offsetTop;
|
170
|
-
this.left = foreground.offsetLeft;
|
171
|
-
this.width = foreground.offsetWidth;
|
172
|
-
resized = util.updateProperty(this, 'height', height) || resized;
|
173
|
-
|
174
|
-
// recalculate size of label
|
175
|
-
resized = util.updateProperty(this.props.label, 'width', this.dom.inner.clientWidth) || resized;
|
176
|
-
resized = util.updateProperty(this.props.label, 'height', this.dom.inner.clientHeight) || resized;
|
177
|
-
|
178
|
-
// apply new height
|
179
|
-
foreground.style.height = height + 'px';
|
180
|
-
this.dom.label.style.height = height + 'px';
|
181
|
-
|
182
|
-
// update vertical position of items after they are re-stacked and the height of the group is calculated
|
183
|
-
for (var i = 0, ii = this.visibleItems.length; i < ii; i++) {
|
184
|
-
var item = this.visibleItems[i];
|
185
|
-
item.repositionY();
|
186
|
-
}
|
187
|
-
|
188
|
-
return resized;
|
189
|
-
};
|
190
|
-
|
191
|
-
/**
|
192
|
-
* Show this group: attach to the DOM
|
193
|
-
*/
|
194
|
-
Group.prototype.show = function() {
|
195
|
-
if (!this.dom.label.parentNode) {
|
196
|
-
this.itemSet.dom.labelSet.appendChild(this.dom.label);
|
197
|
-
}
|
198
|
-
|
199
|
-
if (!this.dom.foreground.parentNode) {
|
200
|
-
this.itemSet.dom.foreground.appendChild(this.dom.foreground);
|
201
|
-
}
|
202
|
-
|
203
|
-
if (!this.dom.background.parentNode) {
|
204
|
-
this.itemSet.dom.background.appendChild(this.dom.background);
|
205
|
-
}
|
206
|
-
|
207
|
-
if (!this.dom.axis.parentNode) {
|
208
|
-
this.itemSet.dom.axis.appendChild(this.dom.axis);
|
209
|
-
}
|
210
|
-
};
|
211
|
-
|
212
|
-
/**
|
213
|
-
* Hide this group: remove from the DOM
|
214
|
-
*/
|
215
|
-
Group.prototype.hide = function() {
|
216
|
-
var label = this.dom.label;
|
217
|
-
if (label.parentNode) {
|
218
|
-
label.parentNode.removeChild(label);
|
219
|
-
}
|
220
|
-
|
221
|
-
var foreground = this.dom.foreground;
|
222
|
-
if (foreground.parentNode) {
|
223
|
-
foreground.parentNode.removeChild(foreground);
|
224
|
-
}
|
225
|
-
|
226
|
-
var background = this.dom.background;
|
227
|
-
if (background.parentNode) {
|
228
|
-
background.parentNode.removeChild(background);
|
229
|
-
}
|
230
|
-
|
231
|
-
var axis = this.dom.axis;
|
232
|
-
if (axis.parentNode) {
|
233
|
-
axis.parentNode.removeChild(axis);
|
234
|
-
}
|
235
|
-
};
|
236
|
-
|
237
|
-
/**
|
238
|
-
* Add an item to the group
|
239
|
-
* @param {Item} item
|
240
|
-
*/
|
241
|
-
Group.prototype.add = function(item) {
|
242
|
-
this.items[item.id] = item;
|
243
|
-
item.setParent(this);
|
244
|
-
|
245
|
-
if (item instanceof ItemRange && this.visibleItems.indexOf(item) == -1) {
|
246
|
-
var range = this.itemSet.body.range; // TODO: not nice accessing the range like this
|
247
|
-
this._checkIfVisible(item, this.visibleItems, range);
|
248
|
-
}
|
249
|
-
};
|
250
|
-
|
251
|
-
/**
|
252
|
-
* Remove an item from the group
|
253
|
-
* @param {Item} item
|
254
|
-
*/
|
255
|
-
Group.prototype.remove = function(item) {
|
256
|
-
delete this.items[item.id];
|
257
|
-
item.setParent(this.itemSet);
|
258
|
-
|
259
|
-
// remove from visible items
|
260
|
-
var index = this.visibleItems.indexOf(item);
|
261
|
-
if (index != -1) this.visibleItems.splice(index, 1);
|
262
|
-
|
263
|
-
// TODO: also remove from ordered items?
|
264
|
-
};
|
265
|
-
|
266
|
-
/**
|
267
|
-
* Remove an item from the corresponding DataSet
|
268
|
-
* @param {Item} item
|
269
|
-
*/
|
270
|
-
Group.prototype.removeFromDataSet = function(item) {
|
271
|
-
this.itemSet.removeItem(item.id);
|
272
|
-
};
|
273
|
-
|
274
|
-
/**
|
275
|
-
* Reorder the items
|
276
|
-
*/
|
277
|
-
Group.prototype.order = function() {
|
278
|
-
var array = util.toArray(this.items);
|
279
|
-
this.orderedItems.byStart = array;
|
280
|
-
this.orderedItems.byEnd = this._constructByEndArray(array);
|
281
|
-
|
282
|
-
stack.orderByStart(this.orderedItems.byStart);
|
283
|
-
stack.orderByEnd(this.orderedItems.byEnd);
|
284
|
-
};
|
285
|
-
|
286
|
-
/**
|
287
|
-
* Create an array containing all items being a range (having an end date)
|
288
|
-
* @param {Item[]} array
|
289
|
-
* @returns {ItemRange[]}
|
290
|
-
* @private
|
291
|
-
*/
|
292
|
-
Group.prototype._constructByEndArray = function(array) {
|
293
|
-
var endArray = [];
|
294
|
-
|
295
|
-
for (var i = 0; i < array.length; i++) {
|
296
|
-
if (array[i] instanceof ItemRange) {
|
297
|
-
endArray.push(array[i]);
|
298
|
-
}
|
299
|
-
}
|
300
|
-
return endArray;
|
301
|
-
};
|
302
|
-
|
303
|
-
/**
|
304
|
-
* Update the visible items
|
305
|
-
* @param {{byStart: Item[], byEnd: Item[]}} orderedItems All items ordered by start date and by end date
|
306
|
-
* @param {Item[]} visibleItems The previously visible items.
|
307
|
-
* @param {{start: number, end: number}} range Visible range
|
308
|
-
* @return {Item[]} visibleItems The new visible items.
|
309
|
-
* @private
|
310
|
-
*/
|
311
|
-
Group.prototype._updateVisibleItems = function(orderedItems, visibleItems, range) {
|
312
|
-
var initialPosByStart,
|
313
|
-
newVisibleItems = [],
|
314
|
-
i;
|
315
|
-
|
316
|
-
// first check if the items that were in view previously are still in view.
|
317
|
-
// this handles the case for the ItemRange that is both before and after the current one.
|
318
|
-
if (visibleItems.length > 0) {
|
319
|
-
for (i = 0; i < visibleItems.length; i++) {
|
320
|
-
this._checkIfVisible(visibleItems[i], newVisibleItems, range);
|
321
|
-
}
|
322
|
-
}
|
323
|
-
|
324
|
-
// If there were no visible items previously, use binarySearch to find a visible ItemPoint or ItemRange (based on startTime)
|
325
|
-
if (newVisibleItems.length == 0) {
|
326
|
-
initialPosByStart = this._binarySearch(orderedItems, range, false);
|
327
|
-
}
|
328
|
-
else {
|
329
|
-
initialPosByStart = orderedItems.byStart.indexOf(newVisibleItems[0]);
|
330
|
-
}
|
331
|
-
|
332
|
-
// use visible search to find a visible ItemRange (only based on endTime)
|
333
|
-
var initialPosByEnd = this._binarySearch(orderedItems, range, true);
|
334
|
-
|
335
|
-
// if we found a initial ID to use, trace it up and down until we meet an invisible item.
|
336
|
-
if (initialPosByStart != -1) {
|
337
|
-
for (i = initialPosByStart; i >= 0; i--) {
|
338
|
-
if (this._checkIfInvisible(orderedItems.byStart[i], newVisibleItems, range)) {break;}
|
339
|
-
}
|
340
|
-
for (i = initialPosByStart + 1; i < orderedItems.byStart.length; i++) {
|
341
|
-
if (this._checkIfInvisible(orderedItems.byStart[i], newVisibleItems, range)) {break;}
|
342
|
-
}
|
343
|
-
}
|
344
|
-
|
345
|
-
// if we found a initial ID to use, trace it up and down until we meet an invisible item.
|
346
|
-
if (initialPosByEnd != -1) {
|
347
|
-
for (i = initialPosByEnd; i >= 0; i--) {
|
348
|
-
if (this._checkIfInvisible(orderedItems.byEnd[i], newVisibleItems, range)) {break;}
|
349
|
-
}
|
350
|
-
for (i = initialPosByEnd + 1; i < orderedItems.byEnd.length; i++) {
|
351
|
-
if (this._checkIfInvisible(orderedItems.byEnd[i], newVisibleItems, range)) {break;}
|
352
|
-
}
|
353
|
-
}
|
354
|
-
|
355
|
-
return newVisibleItems;
|
356
|
-
};
|
357
|
-
|
358
|
-
/**
|
359
|
-
* This function does a binary search for a visible item. The user can select either the this.orderedItems.byStart or .byEnd
|
360
|
-
* arrays. This is done by giving a boolean value true if you want to use the byEnd.
|
361
|
-
* This is done to be able to select the correct if statement (we do not want to check if an item is visible, we want to check
|
362
|
-
* if the time we selected (start or end) is within the current range).
|
363
|
-
*
|
364
|
-
* The trick is that every interval has to either enter the screen at the initial load or by dragging. The case of the ItemRange that is
|
365
|
-
* before and after the current range is handled by simply checking if it was in view before and if it is again. For all the rest,
|
366
|
-
* either the start OR end time has to be in the range.
|
367
|
-
*
|
368
|
-
* @param {{byStart: Item[], byEnd: Item[]}} orderedItems
|
369
|
-
* @param {{start: number, end: number}} range
|
370
|
-
* @param {Boolean} byEnd
|
371
|
-
* @returns {number}
|
372
|
-
* @private
|
373
|
-
*/
|
374
|
-
Group.prototype._binarySearch = function(orderedItems, range, byEnd) {
|
375
|
-
var array = [];
|
376
|
-
var byTime = byEnd ? 'end' : 'start';
|
377
|
-
if (byEnd == true) {array = orderedItems.byEnd; }
|
378
|
-
else {array = orderedItems.byStart;}
|
379
|
-
|
380
|
-
var interval = range.end - range.start;
|
381
|
-
|
382
|
-
var found = false;
|
383
|
-
var low = 0;
|
384
|
-
var high = array.length;
|
385
|
-
var guess = Math.floor(0.5*(high+low));
|
386
|
-
var newGuess;
|
387
|
-
|
388
|
-
if (high == 0) {guess = -1;}
|
389
|
-
else if (high == 1) {
|
390
|
-
if ((array[guess].data[byTime] > range.start - interval) && (array[guess].data[byTime] < range.end)) {
|
391
|
-
guess = 0;
|
392
|
-
}
|
393
|
-
else {
|
394
|
-
guess = -1;
|
395
|
-
}
|
396
|
-
}
|
397
|
-
else {
|
398
|
-
high -= 1;
|
399
|
-
while (found == false) {
|
400
|
-
if ((array[guess].data[byTime] > range.start - interval) && (array[guess].data[byTime] < range.end)) {
|
401
|
-
found = true;
|
402
|
-
}
|
403
|
-
else {
|
404
|
-
if (array[guess].data[byTime] < range.start - interval) { // it is too small --> increase low
|
405
|
-
low = Math.floor(0.5*(high+low));
|
406
|
-
}
|
407
|
-
else { // it is too big --> decrease high
|
408
|
-
high = Math.floor(0.5*(high+low));
|
409
|
-
}
|
410
|
-
newGuess = Math.floor(0.5*(high+low));
|
411
|
-
// not in list;
|
412
|
-
if (guess == newGuess) {
|
413
|
-
guess = -1;
|
414
|
-
found = true;
|
415
|
-
}
|
416
|
-
else {
|
417
|
-
guess = newGuess;
|
418
|
-
}
|
419
|
-
}
|
420
|
-
}
|
421
|
-
}
|
422
|
-
return guess;
|
423
|
-
};
|
424
|
-
|
425
|
-
/**
|
426
|
-
* this function checks if an item is invisible. If it is NOT we make it visible
|
427
|
-
* and add it to the global visible items. If it is, return true.
|
428
|
-
*
|
429
|
-
* @param {Item} item
|
430
|
-
* @param {Item[]} visibleItems
|
431
|
-
* @param {{start:number, end:number}} range
|
432
|
-
* @returns {boolean}
|
433
|
-
* @private
|
434
|
-
*/
|
435
|
-
Group.prototype._checkIfInvisible = function(item, visibleItems, range) {
|
436
|
-
if (item.isVisible(range)) {
|
437
|
-
if (!item.displayed) item.show();
|
438
|
-
item.repositionX();
|
439
|
-
if (visibleItems.indexOf(item) == -1) {
|
440
|
-
visibleItems.push(item);
|
441
|
-
}
|
442
|
-
return false;
|
443
|
-
}
|
444
|
-
else {
|
445
|
-
return true;
|
446
|
-
}
|
447
|
-
};
|
448
|
-
|
449
|
-
/**
|
450
|
-
* this function is very similar to the _checkIfInvisible() but it does not
|
451
|
-
* return booleans, hides the item if it should not be seen and always adds to
|
452
|
-
* the visibleItems.
|
453
|
-
* this one is for brute forcing and hiding.
|
454
|
-
*
|
455
|
-
* @param {Item} item
|
456
|
-
* @param {Array} visibleItems
|
457
|
-
* @param {{start:number, end:number}} range
|
458
|
-
* @private
|
459
|
-
*/
|
460
|
-
Group.prototype._checkIfVisible = function(item, visibleItems, range) {
|
461
|
-
if (item.isVisible(range)) {
|
462
|
-
if (!item.displayed) item.show();
|
463
|
-
// reposition item horizontally
|
464
|
-
item.repositionX();
|
465
|
-
visibleItems.push(item);
|
466
|
-
}
|
467
|
-
else {
|
468
|
-
if (item.displayed) item.hide();
|
469
|
-
}
|
470
|
-
};
|