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,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
|
+
};
|