timeline_setter 0.3.0 → 0.3.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.
- data/Rakefile +4 -4
- data/doc/doc.markdown +50 -27
- data/doc/timeline-setter.html +170 -119
- data/doc/twitter-demo.html +4 -57
- data/documentation/TimelineSetter/CLI.html +87 -78
- data/documentation/TimelineSetter/Parser.html +45 -31
- data/documentation/TimelineSetter/Timeline.html +70 -48
- data/documentation/TimelineSetter.html +6 -4
- data/documentation/_index.html +4 -4
- data/documentation/css/full_list.css +2 -0
- data/documentation/css/style.css +12 -10
- data/documentation/file.README.html +22 -18
- data/documentation/frames.html +1 -1
- data/documentation/index.html +22 -18
- data/documentation/js/app.js +4 -4
- data/documentation/js/full_list.js +29 -6
- data/documentation/method_list.html +19 -19
- data/documentation/top-level-namespace.html +5 -3
- data/index.html +42 -15
- data/lib/timeline_setter/cli.rb +2 -1
- data/lib/timeline_setter/timeline.rb +1 -1
- data/lib/timeline_setter/version.rb +1 -1
- data/public/javascripts/timeline-setter.js +117 -57
- data/public/javascripts/vendor/jquery-min.js +4 -16
- data/public/javascripts/vendor/jquery.js +9404 -0
- data/public/javascripts/vendor/underscore-min.js +26 -21
- data/public/javascripts/vendor/underscore.js +999 -0
- data/spec/test_data.csv +3 -3
- data/spec/timeline-debug.html +19 -0
- data/templates/timeline-markup.erb +25 -1
- data/timeline_setter.gemspec +11 -10
- metadata +9 -8
@@ -5,7 +5,7 @@
|
|
5
5
|
var TimelineSetter = window.TimelineSetter = (window.TimelineSetter || {});
|
6
6
|
|
7
7
|
// Current version of `TimelineSetter`
|
8
|
-
TimelineSetter.VERSION = "0.3.
|
8
|
+
TimelineSetter.VERSION = "0.3.1";
|
9
9
|
|
10
10
|
// Mixins
|
11
11
|
// ------
|
@@ -81,7 +81,7 @@
|
|
81
81
|
drag = {x: e.pageX};
|
82
82
|
e.type = "dragstart";
|
83
83
|
obj.el.trigger(e);
|
84
|
-
}
|
84
|
+
}
|
85
85
|
|
86
86
|
// The user is interacting; capture the offset and trigger a `dragging` event.
|
87
87
|
function mousemove(e){
|
@@ -93,7 +93,7 @@
|
|
93
93
|
});
|
94
94
|
drag = { x: (e.pageX || e.touches[0].pageX) };
|
95
95
|
obj.el.trigger(e);
|
96
|
-
}
|
96
|
+
}
|
97
97
|
|
98
98
|
// We're done tracking the movement set drag back to `null` for the next event.
|
99
99
|
function mouseup(e){
|
@@ -101,7 +101,7 @@
|
|
101
101
|
drag = null;
|
102
102
|
e.type = "dragend";
|
103
103
|
obj.el.trigger(e);
|
104
|
-
}
|
104
|
+
}
|
105
105
|
|
106
106
|
if (!touchInit) {
|
107
107
|
// Bind on mouse events if we have a mouse...
|
@@ -123,7 +123,7 @@
|
|
123
123
|
|
124
124
|
obj.el.bind("touchmove", mousemove);
|
125
125
|
obj.el.bind("touchend", mouseup);
|
126
|
-
}
|
126
|
+
}
|
127
127
|
};
|
128
128
|
|
129
129
|
|
@@ -140,11 +140,11 @@
|
|
140
140
|
if (safari){
|
141
141
|
var negative = delta < 0 ? -1 : 1;
|
142
142
|
delta = Math.log(Math.abs(delta)) * negative * 2;
|
143
|
-
}
|
143
|
+
}
|
144
144
|
e.type = "scrolled";
|
145
145
|
e.deltaX = delta;
|
146
146
|
obj.el.trigger(e);
|
147
|
-
}
|
147
|
+
}
|
148
148
|
|
149
149
|
obj.el.bind("mousewheel DOMMouseScroll", mousewheel);
|
150
150
|
};
|
@@ -221,6 +221,14 @@
|
|
221
221
|
Intervals.dateStr = function(timestamp, interval) {
|
222
222
|
var d = new Intervals.dateFormats(timestamp);
|
223
223
|
switch (interval) {
|
224
|
+
case "Millennium":
|
225
|
+
return d.year;
|
226
|
+
case "Quincentenary":
|
227
|
+
return d.year;
|
228
|
+
case "Century":
|
229
|
+
return d.year;
|
230
|
+
case "HalfCentury":
|
231
|
+
return d.year;
|
224
232
|
case "Decade":
|
225
233
|
return d.year;
|
226
234
|
case "Lustrum":
|
@@ -235,6 +243,10 @@
|
|
235
243
|
return d.date;
|
236
244
|
case "Hours":
|
237
245
|
return d.hourWithMinutes;
|
246
|
+
case "HalfHour":
|
247
|
+
return d.hourWithMinutes;
|
248
|
+
case "QuarterHour":
|
249
|
+
return d.hourWithMinutes;
|
238
250
|
case "Minutes":
|
239
251
|
return d.hourWithMinutes;
|
240
252
|
case "Seconds":
|
@@ -245,19 +257,51 @@
|
|
245
257
|
Intervals.prototype = {
|
246
258
|
// Sane estimates of date ranges for the `isAtLeastA` test.
|
247
259
|
INTERVALS : {
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
260
|
+
Millennium : 69379200000000, // 2200 years is the trigger
|
261
|
+
Quincentenary : 34689600000000, // 1100 years is the trigger
|
262
|
+
Century : 9460800000000, // 300 years is the trigger
|
263
|
+
HalfCentury : 3153600000000, // 100 years is the trigger
|
264
|
+
Decade : 315360000000,
|
265
|
+
Lustrum : 157680000000,
|
266
|
+
FullYear : 31536000000,
|
267
|
+
Month : 2592000000,
|
268
|
+
Week : 604800000,
|
269
|
+
Date : 86400000,
|
270
|
+
Hours : 3600000,
|
271
|
+
HalfHour : 1800000,
|
272
|
+
QuarterHour : 900000,
|
273
|
+
Minutes : 60000,
|
274
|
+
Seconds : 1000 // 1,000 millliseconds equals on second
|
257
275
|
},
|
258
276
|
|
259
277
|
// The order used when testing where exactly a timespan falls.
|
260
|
-
INTERVAL_ORDER : [
|
278
|
+
INTERVAL_ORDER : [
|
279
|
+
'Seconds',
|
280
|
+
'Minutes',
|
281
|
+
'QuarterHour',
|
282
|
+
'HalfHour',
|
283
|
+
'Hours',
|
284
|
+
'Date',
|
285
|
+
'Week',
|
286
|
+
'Month',
|
287
|
+
'FullYear',
|
288
|
+
'Lustrum',
|
289
|
+
'Decade',
|
290
|
+
'HalfCentury',
|
291
|
+
'Century',
|
292
|
+
'Quincentenary',
|
293
|
+
'Millennium'
|
294
|
+
],
|
295
|
+
|
296
|
+
// The year adjustment used for supra-year intervals.
|
297
|
+
YEAR_FRACTIONS : {
|
298
|
+
Millenium : 1000,
|
299
|
+
Quincentenary : 500,
|
300
|
+
Century : 100,
|
301
|
+
HalfCentury : 50,
|
302
|
+
Decade : 10,
|
303
|
+
Lustrum : 5
|
304
|
+
},
|
261
305
|
|
262
306
|
// A test to find the appropriate range of intervals, for example if a range of
|
263
307
|
// timestamps only spans hours this will return true when called with `"Hours"`.
|
@@ -278,22 +322,16 @@
|
|
278
322
|
return this.INTERVALS[this.INTERVAL_ORDER[this.idx]];
|
279
323
|
},
|
280
324
|
|
281
|
-
//
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
// And if you pass in the year 2010 or 2015 you'll get 2010 back.
|
286
|
-
getDecade : function(date) {
|
287
|
-
return (date.getFullYear() / 10 | 0) * 10;
|
325
|
+
// Floor the year to a given epoch.
|
326
|
+
getYearFloor : function(date, intvl){
|
327
|
+
var fudge = this.YEAR_FRACTIONS[intvl] || 1;
|
328
|
+
return (date.getFullYear() / fudge | 0) * fudge;
|
288
329
|
},
|
289
330
|
|
290
|
-
//
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
// And if you pass in the year 1997 you'll get 1995 back.
|
295
|
-
getLustrum : function(date) {
|
296
|
-
return (date.getFullYear() / 5 | 0) * 5;
|
331
|
+
// Return a date with the year set to the next interval in a given epoch.
|
332
|
+
getYearCeil : function(date, intvl){
|
333
|
+
if(this.YEAR_FRACTIONS[intvl]) return this.getYearFloor(date, intvl) + this.YEAR_FRACTIONS[intvl];
|
334
|
+
return date.getFullYear();
|
297
335
|
},
|
298
336
|
|
299
337
|
// Return a Date object rounded down to the previous Sunday, a.k.a. the first day of the week.
|
@@ -310,6 +348,23 @@
|
|
310
348
|
return thisDate;
|
311
349
|
},
|
312
350
|
|
351
|
+
// Return the half of the hour this date belongs to. Anything before 30 min.
|
352
|
+
// past the hour comes back as zero. Anything after comes back as 30.
|
353
|
+
getHalfHour: function(date) {
|
354
|
+
return date.getMinutes() > 30 ? 30 : 0;
|
355
|
+
},
|
356
|
+
|
357
|
+
// Return the quarter of the hour this date belongs to. Anything before 15 min.
|
358
|
+
// past the hour comes back as zero; 15-30 comes back as 15; 30-45 as 30;
|
359
|
+
// 45-60 as 45.
|
360
|
+
getQuarterHour: function(date) {
|
361
|
+
var minutes = date.getMinutes();
|
362
|
+
if (minutes < 15) return 0;
|
363
|
+
if (minutes < 30) return 15;
|
364
|
+
if (minutes < 45) return 30;
|
365
|
+
return 45;
|
366
|
+
},
|
367
|
+
|
313
368
|
// Zero out a date from the current interval down to seconds.
|
314
369
|
floor : function(ts){
|
315
370
|
var date = new Date(ts);
|
@@ -319,22 +374,22 @@
|
|
319
374
|
idx;
|
320
375
|
|
321
376
|
// Zero the special extensions, and adjust as idx necessary.
|
377
|
+
date.setFullYear(this.getYearFloor(date, intvl));
|
322
378
|
switch(intvl){
|
323
|
-
case 'Decade':
|
324
|
-
date.setFullYear(this.getDecade(date));
|
325
|
-
break;
|
326
|
-
case 'Lustrum':
|
327
|
-
date.setFullYear(this.getLustrum(date));
|
328
|
-
break;
|
329
379
|
case 'Week':
|
330
380
|
date.setDate(this.getWeekFloor(date).getDate());
|
331
381
|
idx = _.indexOf(this.INTERVAL_ORDER, 'Week');
|
382
|
+
case 'HalfHour':
|
383
|
+
date.setMinutes(this.getHalfHour(date));
|
384
|
+
case 'QuarterHour':
|
385
|
+
date.setMinutes(this.getQuarterHour(date));
|
332
386
|
}
|
333
387
|
|
334
388
|
// Zero out the rest
|
335
389
|
while(idx--){
|
336
390
|
intvl = this.INTERVAL_ORDER[idx];
|
337
|
-
if(
|
391
|
+
if (!(_.include(['Week', 'HalfHour', 'QuarterHour'].concat(_.keys(this.YEAR_FRACTIONS)), intvl)))
|
392
|
+
date["set" + intvl](intvl === "Date" ? 1 : 0);
|
338
393
|
}
|
339
394
|
|
340
395
|
return date.getTime();
|
@@ -344,18 +399,21 @@
|
|
344
399
|
ceil : function(ts){
|
345
400
|
var date = new Date(this.floor(ts));
|
346
401
|
var intvl = this.INTERVAL_ORDER[this.idx];
|
402
|
+
|
403
|
+
date.setFullYear(this.getYearCeil(date, intvl));
|
347
404
|
switch(intvl){
|
348
|
-
case 'Decade':
|
349
|
-
date.setFullYear(this.getDecade(date) + 10);
|
350
|
-
break;
|
351
|
-
case 'Lustrum':
|
352
|
-
date.setFullYear(this.getLustrum(date) + 5);
|
353
|
-
break;
|
354
405
|
case 'Week':
|
355
406
|
date.setTime(this.getWeekCeil(date).getTime());
|
356
407
|
break;
|
408
|
+
case 'HalfHour':
|
409
|
+
date.setMinutes(this.getHalfHour(date) + 30);
|
410
|
+
break;
|
411
|
+
case 'QuarterHour':
|
412
|
+
date.setMinutes(this.getQuarterHour(date) + 15);
|
413
|
+
break;
|
357
414
|
default:
|
358
|
-
|
415
|
+
if (!(_.include(['Week', 'HalfHour', 'QuarterHour'].concat(_.keys(this.YEAR_FRACTIONS)), intvl)))
|
416
|
+
date["set" + intvl](date["get" + intvl]() + 1);
|
359
417
|
}
|
360
418
|
return date.getTime();
|
361
419
|
},
|
@@ -470,9 +528,9 @@
|
|
470
528
|
// are the formatters we override.
|
471
529
|
//
|
472
530
|
// formatter : function(d, defaults) {
|
473
|
-
// defaults.months = ['enero', 'febrero', 'marzo',
|
474
|
-
// 'abril', 'mayo', 'junio', 'julio',
|
475
|
-
// 'agosto', 'septiembre', 'octubre',
|
531
|
+
// defaults.months = ['enero', 'febrero', 'marzo',
|
532
|
+
// 'abril', 'mayo', 'junio', 'julio',
|
533
|
+
// 'agosto', 'septiembre', 'octubre',
|
476
534
|
// 'noviembre', 'diciembre'];
|
477
535
|
// return defaults;
|
478
536
|
// }
|
@@ -540,12 +598,12 @@
|
|
540
598
|
this.series.push(this.bySid[card.series]);
|
541
599
|
}
|
542
600
|
var series = this.bySid[card.series];
|
543
|
-
series.add(card);
|
601
|
+
var crd = series.add(card);
|
544
602
|
|
545
603
|
this.bounds.extend(series.max());
|
546
604
|
this.bounds.extend(series.min());
|
547
605
|
|
548
|
-
this.trigger('cardAdd', card);
|
606
|
+
this.trigger('cardAdd', card, crd);
|
549
607
|
}
|
550
608
|
});
|
551
609
|
|
@@ -663,6 +721,7 @@
|
|
663
721
|
add : function(card){
|
664
722
|
var crd = new Card(card, this);
|
665
723
|
this.cards.push(crd);
|
724
|
+
return crd;
|
666
725
|
},
|
667
726
|
|
668
727
|
// The comparing function for `max` and `min`.
|
@@ -715,12 +774,13 @@
|
|
715
774
|
this.series.bind("hideNotch", this.toggleNotch);
|
716
775
|
this.series.bind("showNotch", this.toggleNotch);
|
717
776
|
this.timeline.bind("render", this.render);
|
718
|
-
this.timeline.bar.bind("
|
777
|
+
this.timeline.bar.bind("move", this.flip);
|
719
778
|
this.id = [
|
720
779
|
this.get('timestamp'),
|
721
780
|
this.get('description').split(/ /)[0].replace(/[^a-zA-Z\-]/g,"")
|
722
781
|
].join("-");
|
723
782
|
this.timeline.cards.push(this);
|
783
|
+
this.template = window.JST.card;
|
724
784
|
};
|
725
785
|
|
726
786
|
Card.prototype = _.extend(Card.prototype, {
|
@@ -750,7 +810,7 @@
|
|
750
810
|
var tRightEdge = this.timeline.$(".timeline_setter").offset().left + this.timeline.$(".timeline_setter").width();
|
751
811
|
var margin = this.el.css("margin-left") === this.originalMargin;
|
752
812
|
var flippable = this.$(".TS-item").width() < this.timeline.$(".timeline_setter").width() / 2;
|
753
|
-
var offTimeline = this.el.
|
813
|
+
var offTimeline = (this.el.offset().left - this.el.parent().offset().left) - this.$(".TS-item").width() < 0;
|
754
814
|
|
755
815
|
// If the card's right edge is more than the timeline's right edge and
|
756
816
|
// it's never been flipped before and it won't go off the timeline when
|
@@ -775,7 +835,7 @@
|
|
775
835
|
var that = this;
|
776
836
|
this.hideActiveCard();
|
777
837
|
if (!this.el) {
|
778
|
-
this.el = $(
|
838
|
+
this.el = $(this.template({card: this}));
|
779
839
|
|
780
840
|
// create a `this.$` scoped to its card.
|
781
841
|
queryable(this, this.el);
|
@@ -931,7 +991,7 @@
|
|
931
991
|
|
932
992
|
// The TimelineSetter JS API allows you to listen to certain
|
933
993
|
// timeline events, and activate cards programmatically.
|
934
|
-
// To take advantage of it, assign the timeline boot function to a variable
|
994
|
+
// To take advantage of it, assign the timeline boot function to a variable
|
935
995
|
// like so:
|
936
996
|
//
|
937
997
|
// var currentTimeline = TimelineSetter.Timeline.boot(
|
@@ -940,7 +1000,7 @@
|
|
940
1000
|
//
|
941
1001
|
// then call methods on the `currentTimeline.api` object
|
942
1002
|
//
|
943
|
-
// currentTimeline.api.onLoad(function() {
|
1003
|
+
// currentTimeline.api.onLoad(function() {
|
944
1004
|
// console.log("I'm ready");
|
945
1005
|
// });
|
946
1006
|
//
|
@@ -1006,8 +1066,8 @@
|
|
1006
1066
|
// and a formatter function for dates. All of these are optional.
|
1007
1067
|
//
|
1008
1068
|
// We also initialize a new API object for each timeline, accessible via the
|
1009
|
-
// timeline variable's `api` method (e.g. `currentTimeline.api`) and look for
|
1010
|
-
// how many timelines are globally on the page for keydown purposes. We'll only
|
1069
|
+
// timeline variable's `api` method (e.g. `currentTimeline.api`) and look for
|
1070
|
+
// how many timelines are globally on the page for keydown purposes. We'll only
|
1011
1071
|
// bind keydowns globally if there's only one timeline on the page.
|
1012
1072
|
Timeline.boot = function(data, config) {
|
1013
1073
|
var timeline = TimelineSetter.timeline = new Timeline(data, config || {});
|