source: Dev/branches/jQueryUI/client/d3/d3.time.js @ 249

Last change on this file since 249 was 249, checked in by hendrikvanantwerpen, 13 years ago

This one's for Subversion, because it's so close...

First widget (stripped down sequencer).
Seperated client and server code in two direcotry trees.

File size: 18.4 KB
RevLine 
[249]1(function(){d3.time = {};
2
3var d3_time = Date;
4d3.time.format = function(template) {
5  var n = template.length;
6
7  function format(date) {
8    var string = [],
9        i = -1,
10        j = 0,
11        c,
12        f;
13    while (++i < n) {
14      if (template.charCodeAt(i) == 37) {
15        string.push(
16            template.substring(j, i),
17            (f = d3_time_formats[c = template.charAt(++i)])
18            ? f(date) : c);
19        j = i + 1;
20      }
21    }
22    string.push(template.substring(j, i));
23    return string.join("");
24  }
25
26  format.parse = function(string) {
27    var date = new d3_time(1900, 0, 1),
28        i = d3_time_parse(date, template, string, 0);
29    if (i != string.length) return null;
30    if (date.hour12) {
31      var hours = date.getHours() % 12;
32      date.setHours(date.hour12pm ? hours + 12 : hours);
33    }
34    delete date.hour12;
35    delete date.hour12pm;
36    return date;
37  };
38
39  format.toString = function() {
40    return template;
41  };
42
43  return format;
44};
45
46function d3_time_parse(date, template, string, j) {
47  var c,
48      p,
49      i = 0,
50      n = template.length,
51      m = string.length;
52  while (i < n) {
53    if (j >= m) return -1;
54    c = template.charCodeAt(i++);
55    if (c == 37) {
56      p = d3_time_parsers[template.charAt(i++)];
57      if (!p || ((j = p(date, string, j)) < 0)) return -1;
58    } else if (c != string.charCodeAt(j++)) {
59      return -1;
60    }
61  }
62  return j;
63}
64
65var d3_time_zfill2 = d3.format("02d"),
66    d3_time_zfill3 = d3.format("03d"),
67    d3_time_zfill4 = d3.format("04d"),
68    d3_time_sfill2 = d3.format("2d");
69
70var d3_time_formats = {
71  a: function(d) { return d3_time_weekdays[d.getDay()].substring(0, 3); },
72  A: function(d) { return d3_time_weekdays[d.getDay()]; },
73  b: function(d) { return d3_time_months[d.getMonth()].substring(0, 3); },
74  B: function(d) { return d3_time_months[d.getMonth()]; },
75  c: d3.time.format("%a %b %e %H:%M:%S %Y"),
76  d: function(d) { return d3_time_zfill2(d.getDate()); },
77  e: function(d) { return d3_time_sfill2(d.getDate()); },
78  H: function(d) { return d3_time_zfill2(d.getHours()); },
79  I: function(d) { return d3_time_zfill2(d.getHours() % 12 || 12); },
80  j: d3_time_dayOfYear,
81  m: function(d) { return d3_time_zfill2(d.getMonth() + 1); },
82  M: function(d) { return d3_time_zfill2(d.getMinutes()); },
83  p: function(d) { return d.getHours() >= 12 ? "PM" : "AM"; },
84  S: function(d) { return d3_time_zfill2(d.getSeconds()); },
85  U: d3_time_weekNumberSunday,
86  w: function(d) { return d.getDay(); },
87  W: d3_time_weekNumberMonday,
88  x: d3.time.format("%m/%d/%y"),
89  X: d3.time.format("%H:%M:%S"),
90  y: function(d) { return d3_time_zfill2(d.getFullYear() % 100); },
91  Y: function(d) { return d3_time_zfill4(d.getFullYear() % 10000); },
92  Z: d3_time_zone,
93  "%": function(d) { return "%"; }
94};
95
96var d3_time_parsers = {
97  a: d3_time_parseWeekdayAbbrev,
98  A: d3_time_parseWeekday,
99  b: d3_time_parseMonthAbbrev,
100  B: d3_time_parseMonth,
101  c: d3_time_parseLocaleFull,
102  d: d3_time_parseDay,
103  e: d3_time_parseDay,
104  H: d3_time_parseHour24,
105  I: d3_time_parseHour12,
106  // j: function(d, s, i) { /*TODO day of year [001,366] */ return i; },
107  m: d3_time_parseMonthNumber,
108  M: d3_time_parseMinutes,
109  p: d3_time_parseAmPm,
110  S: d3_time_parseSeconds,
111  // U: function(d, s, i) { /*TODO week number (sunday) [00,53] */ return i; },
112  // w: function(d, s, i) { /*TODO weekday [0,6] */ return i; },
113  // W: function(d, s, i) { /*TODO week number (monday) [00,53] */ return i; },
114  x: d3_time_parseLocaleDate,
115  X: d3_time_parseLocaleTime,
116  y: d3_time_parseYear,
117  Y: d3_time_parseFullYear
118  // ,
119  // Z: function(d, s, i) { /*TODO time zone */ return i; },
120  // "%": function(d, s, i) { /*TODO literal % */ return i; }
121};
122
123// Note: weekday is validated, but does not set the date.
124function d3_time_parseWeekdayAbbrev(date, string, i) {
125  return string.substring(i, i += 3).toLowerCase() in d3_time_weekdayAbbrevLookup ? i : -1;
126}
127
128var d3_time_weekdayAbbrevLookup = {
129  sun: 3,
130  mon: 3,
131  tue: 3,
132  wed: 3,
133  thu: 3,
134  fri: 3,
135  sat: 3
136};
137
138// Note: weekday is validated, but does not set the date.
139function d3_time_parseWeekday(date, string, i) {
140  d3_time_weekdayRe.lastIndex = 0;
141  var n = d3_time_weekdayRe.exec(string.substring(i, i + 10));
142  return n ? i += n[0].length : -1;
143}
144
145var d3_time_weekdayRe = /^(?:Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday)/ig;
146
147var d3_time_weekdays = [
148  "Sunday",
149  "Monday",
150  "Tuesday",
151  "Wednesday",
152  "Thursday",
153  "Friday",
154  "Saturday"
155];
156
157function d3_time_parseMonthAbbrev(date, string, i) {
158  var n = d3_time_monthAbbrevLookup[string.substring(i, i += 3).toLowerCase()];
159  return n == null ? -1 : (date.setMonth(n), i);
160}
161
162var d3_time_monthAbbrevLookup = {
163  jan: 0,
164  feb: 1,
165  mar: 2,
166  apr: 3,
167  may: 4,
168  jun: 5,
169  jul: 6,
170  aug: 7,
171  sep: 8,
172  oct: 9,
173  nov: 10,
174  dec: 11
175};
176
177function d3_time_parseMonth(date, string, i) {
178  d3_time_monthRe.lastIndex = 0;
179  var n = d3_time_monthRe.exec(string.substring(i, i + 12));
180  return n ? (date.setMonth(d3_time_monthLookup[n[0].toLowerCase()]), i += n[0].length) : -1;
181}
182
183var d3_time_monthRe = /^(?:January|February|March|April|May|June|July|August|September|October|November|December)/ig;
184
185var d3_time_monthLookup = {
186  january: 0,
187  february: 1,
188  march: 2,
189  april: 3,
190  may: 4,
191  june: 5,
192  july: 6,
193  august: 7,
194  september: 8,
195  october: 9,
196  november: 10,
197  december: 11
198};
199
200var d3_time_months = [
201  "January",
202  "February",
203  "March",
204  "April",
205  "May",
206  "June",
207  "July",
208  "August",
209  "September",
210  "October",
211  "November",
212  "December"
213];
214
215function d3_time_parseLocaleFull(date, string, i) {
216  return d3_time_parse(date, d3_time_formats.c.toString(), string, i);
217}
218
219function d3_time_parseLocaleDate(date, string, i) {
220  return d3_time_parse(date, d3_time_formats.x.toString(), string, i);
221}
222
223function d3_time_parseLocaleTime(date, string, i) {
224  return d3_time_parse(date, d3_time_formats.X.toString(), string, i);
225}
226
227function d3_time_parseFullYear(date, string, i) {
228  d3_time_numberRe.lastIndex = 0;
229  var n = d3_time_numberRe.exec(string.substring(i, i + 4));
230  return n ? (date.setFullYear(n[0]), i += n[0].length) : -1;
231}
232
233function d3_time_parseYear(date, string, i) {
234  d3_time_numberRe.lastIndex = 0;
235  var n = d3_time_numberRe.exec(string.substring(i, i + 2));
236  return n ? (date.setFullYear(d3_time_century() + +n[0]), i += n[0].length) : -1;
237}
238
239function d3_time_century() {
240  return ~~(new Date().getFullYear() / 1000) * 1000;
241}
242
243function d3_time_parseMonthNumber(date, string, i) {
244  d3_time_numberRe.lastIndex = 0;
245  var n = d3_time_numberRe.exec(string.substring(i, i + 2));
246  return n ? (date.setMonth(n[0] - 1), i += n[0].length) : -1;
247}
248
249function d3_time_parseDay(date, string, i) {
250  d3_time_numberRe.lastIndex = 0;
251  var n = d3_time_numberRe.exec(string.substring(i, i + 2));
252  return n ? (date.setDate(+n[0]), i += n[0].length) : -1;
253}
254
255// Note: we don't validate that the hour is in the range [0,23].
256function d3_time_parseHour24(date, string, i) {
257  d3_time_numberRe.lastIndex = 0;
258  var n = d3_time_numberRe.exec(string.substring(i, i + 2));
259  return n ? (date.setHours(+n[0]), i += n[0].length) : -1;
260}
261
262// Note: we don't validate that the hour is in the range [1,12].
263function d3_time_parseHour12(date, string, i) {
264  date.hour12 = true;
265  return d3_time_parseHour24(date, string, i);
266}
267
268function d3_time_parseMinutes(date, string, i) {
269  d3_time_numberRe.lastIndex = 0;
270  var n = d3_time_numberRe.exec(string.substring(i, i + 2));
271  return n ? (date.setMinutes(+n[0]), i += n[0].length) : -1;
272}
273
274function d3_time_parseSeconds(date, string, i) {
275  d3_time_numberRe.lastIndex = 0;
276  var n = d3_time_numberRe.exec(string.substring(i, i + 2));
277  return n ? (date.setSeconds(+n[0]), i += n[0].length) : -1;
278}
279
280// Note: we don't look at the next directive.
281var d3_time_numberRe = /\s*\d+/;
282
283function d3_time_parseAmPm(date, string, i) {
284  var n = d3_time_amPmLookup[string.substring(i, i += 2).toLowerCase()];
285  return n == null ? -1 : (date.hour12pm = n, i);
286}
287
288var d3_time_amPmLookup = {
289  am: 0,
290  pm: 1
291};
292
293function d3_time_year(d) {
294  return new d3_time(d.getFullYear(), 0, 1);
295}
296
297function d3_time_dayOfYear(d) {
298  return d3_time_zfill3(1 + ~~((d - d3_time_year(d)) / 864e5));
299}
300
301function d3_time_weekNumberSunday(d) {
302  var d0 = d3_time_year(d);
303  return d3_time_zfill2(~~(((d - d0) / 864e5 + d0.getDay()) / 7));
304}
305
306function d3_time_weekNumberMonday(d) {
307  var d0 = d3_time_year(d);
308  return d3_time_zfill2(~~(((d - d0) / 864e5 + (d0.getDay() + 6) % 7) / 7));
309}
310
311// TODO table of time zone offset names?
312function d3_time_zone(d) {
313  var z = d.getTimezoneOffset(),
314      zs = z > 0 ? "-" : "+",
315      zh = ~~(Math.abs(z) / 60),
316      zm = Math.abs(z) % 60;
317  return zs + d3_time_zfill2(zh) + d3_time_zfill2(zm);
318}
319d3.time.format.utc = function(template) {
320  var local = d3.time.format(template);
321
322  function format(date) {
323    var utc = new d3_time_format_utc();
324    utc._ = date;
325    return local(utc);
326  }
327
328  format.parse = function(string) {
329    try {
330      d3_time = d3_time_format_utc;
331      var date = local.parse(string);
332      return date && date._;
333    } finally {
334      d3_time = Date;
335    }
336  };
337
338  format.toString = local.toString;
339
340  return format;
341};
342
343function d3_time_format_utc() {
344  this._ = new Date(Date.UTC.apply(this, arguments));
345}
346
347d3_time_format_utc.prototype = {
348  getDate: function() { return this._.getUTCDate(); },
349  getDay: function() { return this._.getUTCDay(); },
350  getFullYear: function() { return this._.getUTCFullYear(); },
351  getHours: function() { return this._.getUTCHours(); },
352  getMilliseconds: function() { return this._.getUTCMilliseconds(); },
353  getMinutes: function() { return this._.getUTCMinutes(); },
354  getMonth: function() { return this._.getUTCMonth(); },
355  getSeconds: function() { return this._.getUTCSeconds(); },
356  getTimezoneOffset: function() { return 0; },
357  valueOf: function() { return this._.getTime(); },
358  setDate: function(x) { this._.setUTCDate(x); },
359  setDay: function(x) { this._.setUTCDay(x); },
360  setFullYear: function(x) { this._.setUTCFullYear(x); },
361  setHours: function(x) { this._.setUTCHours(x); },
362  setMilliseconds: function(x) { this._.setUTCMilliseconds(x); },
363  setMinutes: function(x) { this._.setUTCMinutes(x); },
364  setMonth: function(x) { this._.setUTCMonth(x); },
365  setSeconds: function(x) { this._.setUTCSeconds(x); }
366};
367d3.time.format.iso = d3.time.format.utc("%Y-%m-%dT%H:%M:%SZ");
368function d3_time_range(floor, step, number) {
369  return function(t0, t1, dt) {
370    var time = floor(t0), times = [];
371    if (time < t0) step(time);
372    if (dt > 1) {
373      while (time < t1) {
374        var date = new Date(+time);
375        if (!(number(date) % dt)) times.push(date);
376        step(time);
377      }
378    } else {
379      while (time < t1) times.push(new Date(+time)), step(time);
380    }
381    return times;
382  };
383}
384d3.time.second = function(date) {
385  return new Date(~~(date / 1e3) * 1e3);
386};
387
388d3.time.second.utc = d3.time.second;
389d3.time.seconds = d3_time_range(d3.time.second, function(date) {
390  date.setTime(date.getTime() + 1e3);
391}, function(date) {
392  return date.getSeconds();
393});
394
395d3.time.seconds.utc = d3.time.seconds;
396d3.time.minute = function(date) {
397  return new Date(~~(date / 6e4) * 6e4);
398};
399
400d3.time.minute.utc = d3.time.minute;d3.time.minutes = d3_time_range(d3.time.minute, d3_time_minutesStep, function(date) {
401  return date.getMinutes();
402});
403
404d3.time.minutes.utc = d3_time_range(d3.time.minute, d3_time_minutesStep, function(date) {
405  return date.getUTCMinutes();
406});
407
408function d3_time_minutesStep(date) {
409  date.setTime(date.getTime() + 6e4); // assumes no leap seconds
410}
411d3.time.hour = function(date) {
412  var offset = date.getTimezoneOffset() / 60;
413  return new Date((~~(date / 36e5 - offset) + offset) * 36e5);
414};
415
416d3.time.hour.utc = function(date) {
417  return new Date(~~(date / 36e5) * 36e5);
418};
419d3.time.hours = d3_time_range(d3.time.hour, d3_time_hoursStep, function(date) {
420  return date.getHours();
421});
422
423d3.time.hours.utc = d3_time_range(d3.time.hour.utc, d3_time_hoursStep, function(date) {
424  return date.getUTCHours();
425});
426
427function d3_time_hoursStep(date) {
428  date.setTime(date.getTime() + 36e5);
429}
430d3.time.day = function(date) {
431  return new Date(date.getFullYear(), date.getMonth(), date.getDate());
432};
433
434d3.time.day.utc = function(date) {
435  return new Date(~~(date / 864e5) * 864e5);
436};
437d3.time.days = d3_time_range(d3.time.day, function(date) {
438  date.setDate(date.getDate() + 1);
439}, function(date) {
440  return date.getDate() - 1;
441});
442
443d3.time.days.utc = d3_time_range(d3.time.day.utc, function(date) {
444  date.setUTCDate(date.getUTCDate() + 1);
445}, function(date) {
446  return date.getUTCDate() - 1;
447});
448d3.time.week = function(date) {
449  (date = d3.time.day(date)).setDate(date.getDate() - date.getDay());
450  return date;
451};
452
453d3.time.week.utc = function(date) {
454  (date = d3.time.day.utc(date)).setUTCDate(date.getUTCDate() - date.getUTCDay());
455  return date;
456};
457d3.time.weeks = d3_time_range(d3.time.week, function(date) {
458  date.setDate(date.getDate() + 7);
459}, function(date) {
460  return ~~((date - new Date(date.getFullYear(), 0, 1)) / 6048e5);
461});
462
463d3.time.weeks.utc = d3_time_range(d3.time.week.utc, function(date) {
464  date.setUTCDate(date.getUTCDate() + 7);
465}, function(date) {
466  return ~~((date - Date.UTC(date.getUTCFullYear(), 0, 1)) / 6048e5);
467});
468d3.time.month = function(date) {
469  return new Date(date.getFullYear(), date.getMonth(), 1);
470};
471
472d3.time.month.utc = function(date) {
473  return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), 1));
474};
475d3.time.months = d3_time_range(d3.time.month, function(date) {
476  date.setMonth(date.getMonth() + 1);
477}, function(date) {
478  return date.getMonth();
479});
480
481d3.time.months.utc = d3_time_range(d3.time.month.utc, function(date) {
482  date.setUTCMonth(date.getUTCMonth() + 1);
483}, function(date) {
484  return date.getUTCMonth();
485});
486d3.time.year = function(date) {
487  return new Date(date.getFullYear(), 0, 1);
488};
489
490d3.time.year.utc = function(date) {
491  return new Date(Date.UTC(date.getUTCFullYear(), 0, 1));
492};
493d3.time.years = d3_time_range(d3.time.year, function(date) {
494  date.setFullYear(date.getFullYear() + 1);
495}, function(date) {
496  return date.getFullYear();
497});
498
499d3.time.years.utc = d3_time_range(d3.time.year.utc, function(date) {
500  date.setUTCFullYear(date.getUTCFullYear() + 1);
501}, function(date) {
502  return date.getUTCFullYear();
503});
504// TODO nice
505function d3_time_scale(methods, format) {
506  var linear = d3.scale.linear();
507
508  function scale(x) {
509    return linear(x);
510  }
511
512  scale.invert = function(x) {
513    return d3_time_scaleDate(linear.invert(x));
514  };
515
516  scale.domain = function(x) {
517    if (!arguments.length) return linear.domain().map(d3_time_scaleDate);
518    linear.domain(x);
519    return scale;
520  };
521
522  scale.ticks = function(m, k) {
523    var extent = d3_time_scaleExtent(scale.domain());
524    if (typeof m !== "function") {
525      var span = extent[1] - extent[0],
526          target = span / m,
527          i = d3.bisect(d3_time_scaleSteps, target, 1, d3_time_scaleSteps.length - 1);
528      if (Math.log(target / d3_time_scaleSteps[i - 1]) < Math.log(d3_time_scaleSteps[i] / target)) --i;
529      m = methods[i];
530      k = m[1];
531      m = m[0];
532    }
533    return m(extent[0], extent[1], k);
534  };
535
536  scale.tickFormat = function() {
537    return format;
538  };
539
540  // TOOD expose d3_scale_linear_rebind?
541  scale.range = d3.rebind(scale, linear.range);
542  scale.rangeRound = d3.rebind(scale, linear.rangeRound);
543  scale.interpolate = d3.rebind(scale, linear.interpolate);
544  scale.clamp = d3.rebind(scale, linear.clamp);
545
546  return scale;
547}
548
549// TODO expose d3_scaleExtent?
550function d3_time_scaleExtent(domain) {
551  var start = domain[0], stop = domain[domain.length - 1];
552  return start < stop ? [start, stop] : [stop, start];
553}
554
555function d3_time_scaleDate(t) {
556  return new Date(t);
557}
558
559function d3_time_scaleFormat(formats) {
560  return function(date) {
561    var i = formats.length - 1, f = formats[i];
562    while (!f[1](date)) f = formats[--i];
563    return f[0](date);
564  };
565}
566
567var d3_time_scaleSteps = [
568  1e3,    // 1-second
569  5e3,    // 5-second
570  15e3,   // 15-second
571  3e4,    // 30-second
572  6e4,    // 1-minute
573  3e5,    // 5-minute
574  9e5,    // 15-minute
575  18e5,   // 30-minute
576  36e5,   // 1-hour
577  108e5,  // 3-hour
578  216e5,  // 6-hour
579  432e5,  // 12-hour
580  864e5,  // 1-day
581  1728e5, // 2-day
582  6048e5, // 1-week
583  1728e6, // 1-month
584  7776e6, // 3-month
585  31536e6 // 1-year
586];
587
588var d3_time_scaleLocalMethods = [
589  [d3.time.seconds, 1],
590  [d3.time.seconds, 5],
591  [d3.time.seconds, 15],
592  [d3.time.seconds, 30],
593  [d3.time.minutes, 1],
594  [d3.time.minutes, 5],
595  [d3.time.minutes, 15],
596  [d3.time.minutes, 30],
597  [d3.time.hours, 1],
598  [d3.time.hours, 3],
599  [d3.time.hours, 6],
600  [d3.time.hours, 12],
601  [d3.time.days, 1],
602  [d3.time.days, 2],
603  [d3.time.weeks, 1],
604  [d3.time.months, 1],
605  [d3.time.months, 3],
606  [d3.time.years, 1]
607];
608
609var d3_time_scaleLocalFormats = [
610  [d3.time.format("%Y"), function(d) { return true; }],
611  [d3.time.format("%B"), function(d) { return d.getMonth(); }],
612  [d3.time.format("%b %d"), function(d) { return d.getDate() != 1; }],
613  [d3.time.format("%a %d"), function(d) { return d.getDay() && d.getDate() != 1; }],
614  [d3.time.format("%I %p"), function(d) { return d.getHours(); }],
615  [d3.time.format("%I:%M"), function(d) { return d.getMinutes(); }],
616  [d3.time.format(":%S"), function(d) { return d.getSeconds() || d.getMilliseconds(); }]
617];
618
619var d3_time_scaleLocalFormat = d3_time_scaleFormat(d3_time_scaleLocalFormats);
620
621d3.time.scale = function() {
622  return d3_time_scale(d3_time_scaleLocalMethods, d3_time_scaleLocalFormat);
623};
624var d3_time_scaleUTCMethods = [
625  [d3.time.seconds.utc, 1],
626  [d3.time.seconds.utc, 5],
627  [d3.time.seconds.utc, 15],
628  [d3.time.seconds.utc, 30],
629  [d3.time.minutes.utc, 1],
630  [d3.time.minutes.utc, 5],
631  [d3.time.minutes.utc, 15],
632  [d3.time.minutes.utc, 30],
633  [d3.time.hours.utc, 1],
634  [d3.time.hours.utc, 3],
635  [d3.time.hours.utc, 6],
636  [d3.time.hours.utc, 12],
637  [d3.time.days.utc, 1],
638  [d3.time.days.utc, 2],
639  [d3.time.weeks.utc, 1],
640  [d3.time.months.utc, 1],
641  [d3.time.months.utc, 3],
642  [d3.time.years.utc, 1]
643];
644
645var d3_time_scaleUTCFormats = [
646  [d3.time.format.utc("%Y"), function(d) { return true; }],
647  [d3.time.format.utc("%B"), function(d) { return d.getUTCMonth(); }],
648  [d3.time.format.utc("%b %d"), function(d) { return d.getUTCDate() != 1; }],
649  [d3.time.format.utc("%a %d"), function(d) { return d.getUTCDay() && d.getUTCDate() != 1; }],
650  [d3.time.format.utc("%I %p"), function(d) { return d.getUTCHours(); }],
651  [d3.time.format.utc("%I:%M"), function(d) { return d.getUTCMinutes(); }],
652  [d3.time.format.utc(":%S"), function(d) { return d.getUTCSeconds() || d.getUTCMilliseconds(); }]
653];
654
655var d3_time_scaleUTCFormat = d3_time_scaleFormat(d3_time_scaleUTCFormats);
656
657d3.time.scale.utc = function() {
658  return d3_time_scale(d3_time_scaleUTCMethods, d3_time_scaleUTCFormat);
659};
660})();
Note: See TracBrowser for help on using the repository browser.