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.
@@ -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.0";
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
- Decade : 315360000000,
249
- Lustrum : 157680000000,
250
- FullYear : 31536000000,
251
- Month : 2592000000,
252
- Week : 604800000,
253
- Date : 86400000,
254
- Hours : 3600000,
255
- Minutes : 60000,
256
- Seconds : 1000
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 : ['Seconds','Minutes','Hours','Date','Week','Month','FullYear','Lustrum','Decade'],
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
- // Return the first year of the decade a Date belongs to as an integer.
282
- // Decades are defined in the conventional (ie. 60s) sense,
283
- // instead of the more precise mathematical method that starts
284
- // with year one. For example, the current decade runs from 2010-2019.
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
- // Returns the first year of the five year "lustrum" a Date belongs to
291
- // as an integer. A lustrum is a fancy Roman word for a "five-year period."
292
- // You can read more about it [here](http://en.wikipedia.org/wiki/Lustrum).
293
- // This all means that if you pass in the year 2011 you'll get 2010 back.
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(intvl !== 'Week') date["set" + intvl](intvl === "Date" ? 1 : 0);
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
- date["set" + intvl](date["get" + intvl]() + 1);
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("flip", this.flip);
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.position().left - this.$(".TS-item").width() < 0;
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 = $(JST.card({card: this}));
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 || {});