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,522 @@
|
|
1
|
+
/**
|
2
|
+
* A horizontal time axis
|
3
|
+
* @param {Component} parent
|
4
|
+
* @param {Component[]} [depends] Components on which this components depends
|
5
|
+
* (except for the parent)
|
6
|
+
* @param {Object} [options] See TimeAxis.setOptions for the available
|
7
|
+
* options.
|
8
|
+
* @constructor TimeAxis
|
9
|
+
* @extends Component
|
10
|
+
*/
|
11
|
+
function TimeAxis (parent, depends, options) {
|
12
|
+
this.id = util.randomUUID();
|
13
|
+
this.parent = parent;
|
14
|
+
this.depends = depends;
|
15
|
+
|
16
|
+
this.dom = {
|
17
|
+
majorLines: [],
|
18
|
+
majorTexts: [],
|
19
|
+
minorLines: [],
|
20
|
+
minorTexts: [],
|
21
|
+
redundant: {
|
22
|
+
majorLines: [],
|
23
|
+
majorTexts: [],
|
24
|
+
minorLines: [],
|
25
|
+
minorTexts: []
|
26
|
+
}
|
27
|
+
};
|
28
|
+
this.props = {
|
29
|
+
range: {
|
30
|
+
start: 0,
|
31
|
+
end: 0,
|
32
|
+
minimumStep: 0
|
33
|
+
},
|
34
|
+
lineTop: 0
|
35
|
+
};
|
36
|
+
|
37
|
+
this.options = options || {};
|
38
|
+
this.defaultOptions = {
|
39
|
+
orientation: 'bottom', // supported: 'top', 'bottom'
|
40
|
+
// TODO: implement timeaxis orientations 'left' and 'right'
|
41
|
+
showMinorLabels: true,
|
42
|
+
showMajorLabels: true
|
43
|
+
};
|
44
|
+
|
45
|
+
this.conversion = null;
|
46
|
+
this.range = null;
|
47
|
+
}
|
48
|
+
|
49
|
+
TimeAxis.prototype = new Component();
|
50
|
+
|
51
|
+
// TODO: comment options
|
52
|
+
TimeAxis.prototype.setOptions = Component.prototype.setOptions;
|
53
|
+
|
54
|
+
/**
|
55
|
+
* Set a range (start and end)
|
56
|
+
* @param {Range | Object} range A Range or an object containing start and end.
|
57
|
+
*/
|
58
|
+
TimeAxis.prototype.setRange = function (range) {
|
59
|
+
if (!(range instanceof Range) && (!range || !range.start || !range.end)) {
|
60
|
+
throw new TypeError('Range must be an instance of Range, ' +
|
61
|
+
'or an object containing start and end.');
|
62
|
+
}
|
63
|
+
this.range = range;
|
64
|
+
};
|
65
|
+
|
66
|
+
/**
|
67
|
+
* Convert a position on screen (pixels) to a datetime
|
68
|
+
* @param {int} x Position on the screen in pixels
|
69
|
+
* @return {Date} time The datetime the corresponds with given position x
|
70
|
+
*/
|
71
|
+
TimeAxis.prototype.toTime = function(x) {
|
72
|
+
var conversion = this.conversion;
|
73
|
+
return new Date(x / conversion.scale + conversion.offset);
|
74
|
+
};
|
75
|
+
|
76
|
+
/**
|
77
|
+
* Convert a datetime (Date object) into a position on the screen
|
78
|
+
* @param {Date} time A date
|
79
|
+
* @return {int} x The position on the screen in pixels which corresponds
|
80
|
+
* with the given date.
|
81
|
+
* @private
|
82
|
+
*/
|
83
|
+
TimeAxis.prototype.toScreen = function(time) {
|
84
|
+
var conversion = this.conversion;
|
85
|
+
return (time.valueOf() - conversion.offset) * conversion.scale;
|
86
|
+
};
|
87
|
+
|
88
|
+
/**
|
89
|
+
* Repaint the component
|
90
|
+
* @return {Boolean} changed
|
91
|
+
*/
|
92
|
+
TimeAxis.prototype.repaint = function () {
|
93
|
+
var changed = 0,
|
94
|
+
update = util.updateProperty,
|
95
|
+
asSize = util.option.asSize,
|
96
|
+
options = this.options,
|
97
|
+
orientation = this.getOption('orientation'),
|
98
|
+
props = this.props,
|
99
|
+
step = this.step;
|
100
|
+
|
101
|
+
var frame = this.frame;
|
102
|
+
if (!frame) {
|
103
|
+
frame = document.createElement('div');
|
104
|
+
this.frame = frame;
|
105
|
+
changed += 1;
|
106
|
+
}
|
107
|
+
frame.className = 'axis';
|
108
|
+
// TODO: custom className?
|
109
|
+
|
110
|
+
if (!frame.parentNode) {
|
111
|
+
if (!this.parent) {
|
112
|
+
throw new Error('Cannot repaint time axis: no parent attached');
|
113
|
+
}
|
114
|
+
var parentContainer = this.parent.getContainer();
|
115
|
+
if (!parentContainer) {
|
116
|
+
throw new Error('Cannot repaint time axis: parent has no container element');
|
117
|
+
}
|
118
|
+
parentContainer.appendChild(frame);
|
119
|
+
|
120
|
+
changed += 1;
|
121
|
+
}
|
122
|
+
|
123
|
+
var parent = frame.parentNode;
|
124
|
+
if (parent) {
|
125
|
+
var beforeChild = frame.nextSibling;
|
126
|
+
parent.removeChild(frame); // take frame offline while updating (is almost twice as fast)
|
127
|
+
|
128
|
+
var defaultTop = (orientation == 'bottom' && this.props.parentHeight && this.height) ?
|
129
|
+
(this.props.parentHeight - this.height) + 'px' :
|
130
|
+
'0px';
|
131
|
+
changed += update(frame.style, 'top', asSize(options.top, defaultTop));
|
132
|
+
changed += update(frame.style, 'left', asSize(options.left, '0px'));
|
133
|
+
changed += update(frame.style, 'width', asSize(options.width, '100%'));
|
134
|
+
changed += update(frame.style, 'height', asSize(options.height, this.height + 'px'));
|
135
|
+
|
136
|
+
// get characters width and height
|
137
|
+
this._repaintMeasureChars();
|
138
|
+
|
139
|
+
if (this.step) {
|
140
|
+
this._repaintStart();
|
141
|
+
|
142
|
+
step.first();
|
143
|
+
var xFirstMajorLabel = undefined;
|
144
|
+
var max = 0;
|
145
|
+
while (step.hasNext() && max < 1000) {
|
146
|
+
max++;
|
147
|
+
var cur = step.getCurrent(),
|
148
|
+
x = this.toScreen(cur),
|
149
|
+
isMajor = step.isMajor();
|
150
|
+
|
151
|
+
// TODO: lines must have a width, such that we can create css backgrounds
|
152
|
+
|
153
|
+
if (this.getOption('showMinorLabels')) {
|
154
|
+
this._repaintMinorText(x, step.getLabelMinor());
|
155
|
+
}
|
156
|
+
|
157
|
+
if (isMajor && this.getOption('showMajorLabels')) {
|
158
|
+
if (x > 0) {
|
159
|
+
if (xFirstMajorLabel == undefined) {
|
160
|
+
xFirstMajorLabel = x;
|
161
|
+
}
|
162
|
+
this._repaintMajorText(x, step.getLabelMajor());
|
163
|
+
}
|
164
|
+
this._repaintMajorLine(x);
|
165
|
+
}
|
166
|
+
else {
|
167
|
+
this._repaintMinorLine(x);
|
168
|
+
}
|
169
|
+
|
170
|
+
step.next();
|
171
|
+
}
|
172
|
+
|
173
|
+
// create a major label on the left when needed
|
174
|
+
if (this.getOption('showMajorLabels')) {
|
175
|
+
var leftTime = this.toTime(0),
|
176
|
+
leftText = step.getLabelMajor(leftTime),
|
177
|
+
widthText = leftText.length * (props.majorCharWidth || 10) + 10; // upper bound estimation
|
178
|
+
|
179
|
+
if (xFirstMajorLabel == undefined || widthText < xFirstMajorLabel) {
|
180
|
+
this._repaintMajorText(0, leftText);
|
181
|
+
}
|
182
|
+
}
|
183
|
+
|
184
|
+
this._repaintEnd();
|
185
|
+
}
|
186
|
+
|
187
|
+
this._repaintLine();
|
188
|
+
|
189
|
+
// put frame online again
|
190
|
+
if (beforeChild) {
|
191
|
+
parent.insertBefore(frame, beforeChild);
|
192
|
+
}
|
193
|
+
else {
|
194
|
+
parent.appendChild(frame)
|
195
|
+
}
|
196
|
+
}
|
197
|
+
|
198
|
+
return (changed > 0);
|
199
|
+
};
|
200
|
+
|
201
|
+
/**
|
202
|
+
* Start a repaint. Move all DOM elements to a redundant list, where they
|
203
|
+
* can be picked for re-use, or can be cleaned up in the end
|
204
|
+
* @private
|
205
|
+
*/
|
206
|
+
TimeAxis.prototype._repaintStart = function () {
|
207
|
+
var dom = this.dom,
|
208
|
+
redundant = dom.redundant;
|
209
|
+
|
210
|
+
redundant.majorLines = dom.majorLines;
|
211
|
+
redundant.majorTexts = dom.majorTexts;
|
212
|
+
redundant.minorLines = dom.minorLines;
|
213
|
+
redundant.minorTexts = dom.minorTexts;
|
214
|
+
|
215
|
+
dom.majorLines = [];
|
216
|
+
dom.majorTexts = [];
|
217
|
+
dom.minorLines = [];
|
218
|
+
dom.minorTexts = [];
|
219
|
+
};
|
220
|
+
|
221
|
+
/**
|
222
|
+
* End a repaint. Cleanup leftover DOM elements in the redundant list
|
223
|
+
* @private
|
224
|
+
*/
|
225
|
+
TimeAxis.prototype._repaintEnd = function () {
|
226
|
+
util.forEach(this.dom.redundant, function (arr) {
|
227
|
+
while (arr.length) {
|
228
|
+
var elem = arr.pop();
|
229
|
+
if (elem && elem.parentNode) {
|
230
|
+
elem.parentNode.removeChild(elem);
|
231
|
+
}
|
232
|
+
}
|
233
|
+
});
|
234
|
+
};
|
235
|
+
|
236
|
+
|
237
|
+
/**
|
238
|
+
* Create a minor label for the axis at position x
|
239
|
+
* @param {Number} x
|
240
|
+
* @param {String} text
|
241
|
+
* @private
|
242
|
+
*/
|
243
|
+
TimeAxis.prototype._repaintMinorText = function (x, text) {
|
244
|
+
// reuse redundant label
|
245
|
+
var label = this.dom.redundant.minorTexts.shift();
|
246
|
+
|
247
|
+
if (!label) {
|
248
|
+
// create new label
|
249
|
+
var content = document.createTextNode('');
|
250
|
+
label = document.createElement('div');
|
251
|
+
label.appendChild(content);
|
252
|
+
label.className = 'text minor';
|
253
|
+
this.frame.appendChild(label);
|
254
|
+
}
|
255
|
+
this.dom.minorTexts.push(label);
|
256
|
+
|
257
|
+
label.childNodes[0].nodeValue = text;
|
258
|
+
label.style.left = x + 'px';
|
259
|
+
label.style.top = this.props.minorLabelTop + 'px';
|
260
|
+
//label.title = title; // TODO: this is a heavy operation
|
261
|
+
};
|
262
|
+
|
263
|
+
/**
|
264
|
+
* Create a Major label for the axis at position x
|
265
|
+
* @param {Number} x
|
266
|
+
* @param {String} text
|
267
|
+
* @private
|
268
|
+
*/
|
269
|
+
TimeAxis.prototype._repaintMajorText = function (x, text) {
|
270
|
+
// reuse redundant label
|
271
|
+
var label = this.dom.redundant.majorTexts.shift();
|
272
|
+
|
273
|
+
if (!label) {
|
274
|
+
// create label
|
275
|
+
var content = document.createTextNode(text);
|
276
|
+
label = document.createElement('div');
|
277
|
+
label.className = 'text major';
|
278
|
+
label.appendChild(content);
|
279
|
+
this.frame.appendChild(label);
|
280
|
+
}
|
281
|
+
this.dom.majorTexts.push(label);
|
282
|
+
|
283
|
+
label.childNodes[0].nodeValue = text;
|
284
|
+
label.style.top = this.props.majorLabelTop + 'px';
|
285
|
+
label.style.left = x + 'px';
|
286
|
+
//label.title = title; // TODO: this is a heavy operation
|
287
|
+
};
|
288
|
+
|
289
|
+
/**
|
290
|
+
* Create a minor line for the axis at position x
|
291
|
+
* @param {Number} x
|
292
|
+
* @private
|
293
|
+
*/
|
294
|
+
TimeAxis.prototype._repaintMinorLine = function (x) {
|
295
|
+
// reuse redundant line
|
296
|
+
var line = this.dom.redundant.minorLines.shift();
|
297
|
+
|
298
|
+
if (!line) {
|
299
|
+
// create vertical line
|
300
|
+
line = document.createElement('div');
|
301
|
+
line.className = 'grid vertical minor';
|
302
|
+
this.frame.appendChild(line);
|
303
|
+
}
|
304
|
+
this.dom.minorLines.push(line);
|
305
|
+
|
306
|
+
var props = this.props;
|
307
|
+
line.style.top = props.minorLineTop + 'px';
|
308
|
+
line.style.height = props.minorLineHeight + 'px';
|
309
|
+
line.style.left = (x - props.minorLineWidth / 2) + 'px';
|
310
|
+
};
|
311
|
+
|
312
|
+
/**
|
313
|
+
* Create a Major line for the axis at position x
|
314
|
+
* @param {Number} x
|
315
|
+
* @private
|
316
|
+
*/
|
317
|
+
TimeAxis.prototype._repaintMajorLine = function (x) {
|
318
|
+
// reuse redundant line
|
319
|
+
var line = this.dom.redundant.majorLines.shift();
|
320
|
+
|
321
|
+
if (!line) {
|
322
|
+
// create vertical line
|
323
|
+
line = document.createElement('DIV');
|
324
|
+
line.className = 'grid vertical major';
|
325
|
+
this.frame.appendChild(line);
|
326
|
+
}
|
327
|
+
this.dom.majorLines.push(line);
|
328
|
+
|
329
|
+
var props = this.props;
|
330
|
+
line.style.top = props.majorLineTop + 'px';
|
331
|
+
line.style.left = (x - props.majorLineWidth / 2) + 'px';
|
332
|
+
line.style.height = props.majorLineHeight + 'px';
|
333
|
+
};
|
334
|
+
|
335
|
+
|
336
|
+
/**
|
337
|
+
* Repaint the horizontal line for the axis
|
338
|
+
* @private
|
339
|
+
*/
|
340
|
+
TimeAxis.prototype._repaintLine = function() {
|
341
|
+
var line = this.dom.line,
|
342
|
+
frame = this.frame,
|
343
|
+
options = this.options;
|
344
|
+
|
345
|
+
// line before all axis elements
|
346
|
+
if (this.getOption('showMinorLabels') || this.getOption('showMajorLabels')) {
|
347
|
+
if (line) {
|
348
|
+
// put this line at the end of all childs
|
349
|
+
frame.removeChild(line);
|
350
|
+
frame.appendChild(line);
|
351
|
+
}
|
352
|
+
else {
|
353
|
+
// create the axis line
|
354
|
+
line = document.createElement('div');
|
355
|
+
line.className = 'grid horizontal major';
|
356
|
+
frame.appendChild(line);
|
357
|
+
this.dom.line = line;
|
358
|
+
}
|
359
|
+
|
360
|
+
line.style.top = this.props.lineTop + 'px';
|
361
|
+
}
|
362
|
+
else {
|
363
|
+
if (line && line.parentElement) {
|
364
|
+
frame.removeChild(line.line);
|
365
|
+
delete this.dom.line;
|
366
|
+
}
|
367
|
+
}
|
368
|
+
};
|
369
|
+
|
370
|
+
/**
|
371
|
+
* Create characters used to determine the size of text on the axis
|
372
|
+
* @private
|
373
|
+
*/
|
374
|
+
TimeAxis.prototype._repaintMeasureChars = function () {
|
375
|
+
// calculate the width and height of a single character
|
376
|
+
// this is used to calculate the step size, and also the positioning of the
|
377
|
+
// axis
|
378
|
+
var dom = this.dom,
|
379
|
+
text;
|
380
|
+
|
381
|
+
if (!dom.measureCharMinor) {
|
382
|
+
text = document.createTextNode('0');
|
383
|
+
var measureCharMinor = document.createElement('DIV');
|
384
|
+
measureCharMinor.className = 'text minor measure';
|
385
|
+
measureCharMinor.appendChild(text);
|
386
|
+
this.frame.appendChild(measureCharMinor);
|
387
|
+
|
388
|
+
dom.measureCharMinor = measureCharMinor;
|
389
|
+
}
|
390
|
+
|
391
|
+
if (!dom.measureCharMajor) {
|
392
|
+
text = document.createTextNode('0');
|
393
|
+
var measureCharMajor = document.createElement('DIV');
|
394
|
+
measureCharMajor.className = 'text major measure';
|
395
|
+
measureCharMajor.appendChild(text);
|
396
|
+
this.frame.appendChild(measureCharMajor);
|
397
|
+
|
398
|
+
dom.measureCharMajor = measureCharMajor;
|
399
|
+
}
|
400
|
+
};
|
401
|
+
|
402
|
+
/**
|
403
|
+
* Reflow the component
|
404
|
+
* @return {Boolean} resized
|
405
|
+
*/
|
406
|
+
TimeAxis.prototype.reflow = function () {
|
407
|
+
var changed = 0,
|
408
|
+
update = util.updateProperty,
|
409
|
+
frame = this.frame,
|
410
|
+
range = this.range;
|
411
|
+
|
412
|
+
if (!range) {
|
413
|
+
throw new Error('Cannot repaint time axis: no range configured');
|
414
|
+
}
|
415
|
+
|
416
|
+
if (frame) {
|
417
|
+
changed += update(this, 'top', frame.offsetTop);
|
418
|
+
changed += update(this, 'left', frame.offsetLeft);
|
419
|
+
|
420
|
+
// calculate size of a character
|
421
|
+
var props = this.props,
|
422
|
+
showMinorLabels = this.getOption('showMinorLabels'),
|
423
|
+
showMajorLabels = this.getOption('showMajorLabels'),
|
424
|
+
measureCharMinor = this.dom.measureCharMinor,
|
425
|
+
measureCharMajor = this.dom.measureCharMajor;
|
426
|
+
if (measureCharMinor) {
|
427
|
+
props.minorCharHeight = measureCharMinor.clientHeight;
|
428
|
+
props.minorCharWidth = measureCharMinor.clientWidth;
|
429
|
+
}
|
430
|
+
if (measureCharMajor) {
|
431
|
+
props.majorCharHeight = measureCharMajor.clientHeight;
|
432
|
+
props.majorCharWidth = measureCharMajor.clientWidth;
|
433
|
+
}
|
434
|
+
|
435
|
+
var parentHeight = frame.parentNode ? frame.parentNode.offsetHeight : 0;
|
436
|
+
if (parentHeight != props.parentHeight) {
|
437
|
+
props.parentHeight = parentHeight;
|
438
|
+
changed += 1;
|
439
|
+
}
|
440
|
+
switch (this.getOption('orientation')) {
|
441
|
+
case 'bottom':
|
442
|
+
props.minorLabelHeight = showMinorLabels ? props.minorCharHeight : 0;
|
443
|
+
props.majorLabelHeight = showMajorLabels ? props.majorCharHeight : 0;
|
444
|
+
|
445
|
+
props.minorLabelTop = 0;
|
446
|
+
props.majorLabelTop = props.minorLabelTop + props.minorLabelHeight;
|
447
|
+
|
448
|
+
props.minorLineTop = -this.top;
|
449
|
+
props.minorLineHeight = Math.max(this.top + props.majorLabelHeight, 0);
|
450
|
+
props.minorLineWidth = 1; // TODO: really calculate width
|
451
|
+
|
452
|
+
props.majorLineTop = -this.top;
|
453
|
+
props.majorLineHeight = Math.max(this.top + props.minorLabelHeight + props.majorLabelHeight, 0);
|
454
|
+
props.majorLineWidth = 1; // TODO: really calculate width
|
455
|
+
|
456
|
+
props.lineTop = 0;
|
457
|
+
|
458
|
+
break;
|
459
|
+
|
460
|
+
case 'top':
|
461
|
+
props.minorLabelHeight = showMinorLabels ? props.minorCharHeight : 0;
|
462
|
+
props.majorLabelHeight = showMajorLabels ? props.majorCharHeight : 0;
|
463
|
+
|
464
|
+
props.majorLabelTop = 0;
|
465
|
+
props.minorLabelTop = props.majorLabelTop + props.majorLabelHeight;
|
466
|
+
|
467
|
+
props.minorLineTop = props.minorLabelTop;
|
468
|
+
props.minorLineHeight = Math.max(parentHeight - props.majorLabelHeight - this.top);
|
469
|
+
props.minorLineWidth = 1; // TODO: really calculate width
|
470
|
+
|
471
|
+
props.majorLineTop = 0;
|
472
|
+
props.majorLineHeight = Math.max(parentHeight - this.top);
|
473
|
+
props.majorLineWidth = 1; // TODO: really calculate width
|
474
|
+
|
475
|
+
props.lineTop = props.majorLabelHeight + props.minorLabelHeight;
|
476
|
+
|
477
|
+
break;
|
478
|
+
|
479
|
+
default:
|
480
|
+
throw new Error('Unkown orientation "' + this.getOption('orientation') + '"');
|
481
|
+
}
|
482
|
+
|
483
|
+
var height = props.minorLabelHeight + props.majorLabelHeight;
|
484
|
+
changed += update(this, 'width', frame.offsetWidth);
|
485
|
+
changed += update(this, 'height', height);
|
486
|
+
|
487
|
+
// calculate range and step
|
488
|
+
this._updateConversion();
|
489
|
+
|
490
|
+
var start = util.convert(range.start, 'Number'),
|
491
|
+
end = util.convert(range.end, 'Number'),
|
492
|
+
minimumStep = this.toTime((props.minorCharWidth || 10) * 5).valueOf()
|
493
|
+
-this.toTime(0).valueOf();
|
494
|
+
this.step = new TimeStep(new Date(start), new Date(end), minimumStep);
|
495
|
+
changed += update(props.range, 'start', start);
|
496
|
+
changed += update(props.range, 'end', end);
|
497
|
+
changed += update(props.range, 'minimumStep', minimumStep.valueOf());
|
498
|
+
}
|
499
|
+
|
500
|
+
return (changed > 0);
|
501
|
+
};
|
502
|
+
|
503
|
+
/**
|
504
|
+
* Calculate the scale and offset to convert a position on screen to the
|
505
|
+
* corresponding date and vice versa.
|
506
|
+
* After the method _updateConversion is executed once, the methods toTime
|
507
|
+
* and toScreen can be used.
|
508
|
+
* @private
|
509
|
+
*/
|
510
|
+
TimeAxis.prototype._updateConversion = function() {
|
511
|
+
var range = this.range;
|
512
|
+
if (!range) {
|
513
|
+
throw new Error('No range configured');
|
514
|
+
}
|
515
|
+
|
516
|
+
if (range.conversion) {
|
517
|
+
this.conversion = range.conversion(this.width);
|
518
|
+
}
|
519
|
+
else {
|
520
|
+
this.conversion = Range.conversion(range.start, range.end, this.width);
|
521
|
+
}
|
522
|
+
};
|
@@ -0,0 +1,59 @@
|
|
1
|
+
|
2
|
+
.vis.timeline .groupset {
|
3
|
+
position: absolute;
|
4
|
+
padding: 0;
|
5
|
+
margin: 0;
|
6
|
+
}
|
7
|
+
|
8
|
+
.vis.timeline .labels {
|
9
|
+
position: absolute;
|
10
|
+
top: 0;
|
11
|
+
left: 0;
|
12
|
+
width: 100%;
|
13
|
+
height: 100%;
|
14
|
+
|
15
|
+
padding: 0;
|
16
|
+
margin: 0;
|
17
|
+
|
18
|
+
border-right: 1px solid #bfbfbf;
|
19
|
+
box-sizing: border-box;
|
20
|
+
-moz-box-sizing: border-box;
|
21
|
+
}
|
22
|
+
|
23
|
+
.vis.timeline .labels .label-set {
|
24
|
+
position: absolute;
|
25
|
+
top: 0;
|
26
|
+
left: 0;
|
27
|
+
width: 100%;
|
28
|
+
height: 100%;
|
29
|
+
|
30
|
+
overflow: hidden;
|
31
|
+
|
32
|
+
border-top: none;
|
33
|
+
border-bottom: 1px solid #bfbfbf;
|
34
|
+
}
|
35
|
+
|
36
|
+
.vis.timeline .labels .label-set .label {
|
37
|
+
position: absolute;
|
38
|
+
left: 0;
|
39
|
+
top: 0;
|
40
|
+
width: 100%;
|
41
|
+
color: #4d4d4d;
|
42
|
+
}
|
43
|
+
|
44
|
+
.vis.timeline.top .labels .label-set .label,
|
45
|
+
.vis.timeline.top .groupset .itemset-axis {
|
46
|
+
border-top: 1px solid #bfbfbf;
|
47
|
+
border-bottom: none;
|
48
|
+
}
|
49
|
+
|
50
|
+
.vis.timeline.bottom .labels .label-set .label,
|
51
|
+
.vis.timeline.bottom .groupset .itemset-axis {
|
52
|
+
border-top: none;
|
53
|
+
border-bottom: 1px solid #bfbfbf;
|
54
|
+
}
|
55
|
+
|
56
|
+
.vis.timeline .labels .label-set .label .inner {
|
57
|
+
display: inline-block;
|
58
|
+
padding: 5px;
|
59
|
+
}
|
@@ -0,0 +1,93 @@
|
|
1
|
+
|
2
|
+
.vis.timeline .item {
|
3
|
+
position: absolute;
|
4
|
+
color: #1A1A1A;
|
5
|
+
border-color: #97B0F8;
|
6
|
+
background-color: #D5DDF6;
|
7
|
+
display: inline-block;
|
8
|
+
}
|
9
|
+
|
10
|
+
.vis.timeline .item.selected {
|
11
|
+
border-color: #FFC200;
|
12
|
+
background-color: #FFF785;
|
13
|
+
z-index: 999;
|
14
|
+
}
|
15
|
+
|
16
|
+
.vis.timeline .item.point.selected {
|
17
|
+
background-color: #FFF785;
|
18
|
+
z-index: 999;
|
19
|
+
}
|
20
|
+
.vis.timeline .item.point.selected .dot {
|
21
|
+
border-color: #FFC200;
|
22
|
+
}
|
23
|
+
|
24
|
+
.vis.timeline .item.cluster {
|
25
|
+
/* TODO: use another color or pattern? */
|
26
|
+
background: #97B0F8 url('img/cluster_bg.png');
|
27
|
+
color: white;
|
28
|
+
}
|
29
|
+
.vis.timeline .item.cluster.point {
|
30
|
+
border-color: #D5DDF6;
|
31
|
+
}
|
32
|
+
|
33
|
+
.vis.timeline .item.box {
|
34
|
+
text-align: center;
|
35
|
+
border-style: solid;
|
36
|
+
border-width: 1px;
|
37
|
+
border-radius: 5px;
|
38
|
+
-moz-border-radius: 5px; /* For Firefox 3.6 and older */
|
39
|
+
}
|
40
|
+
|
41
|
+
.vis.timeline .item.point {
|
42
|
+
background: none;
|
43
|
+
}
|
44
|
+
|
45
|
+
.vis.timeline .dot {
|
46
|
+
border: 5px solid #97B0F8;
|
47
|
+
position: absolute;
|
48
|
+
border-radius: 5px;
|
49
|
+
-moz-border-radius: 5px; /* For Firefox 3.6 and older */
|
50
|
+
}
|
51
|
+
|
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 {
|
61
|
+
border-style: solid;
|
62
|
+
border-width: 1px;
|
63
|
+
border-radius: 2px;
|
64
|
+
-moz-border-radius: 2px; /* For Firefox 3.6 and older */
|
65
|
+
}
|
66
|
+
|
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 {
|
78
|
+
position: relative;
|
79
|
+
display: inline-block;
|
80
|
+
}
|
81
|
+
|
82
|
+
.vis.timeline .item.line {
|
83
|
+
position: absolute;
|
84
|
+
width: 0;
|
85
|
+
border-left-width: 1px;
|
86
|
+
border-left-style: solid;
|
87
|
+
}
|
88
|
+
|
89
|
+
.vis.timeline .item .content {
|
90
|
+
margin: 5px;
|
91
|
+
white-space: nowrap;
|
92
|
+
overflow: hidden;
|
93
|
+
}
|