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