timeline_setter 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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 || {});