[76] | 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 | 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 | |
---|
| 96 | var 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. |
---|
| 124 | function d3_time_parseWeekdayAbbrev(date, string, i) { |
---|
| 125 | return string.substring(i, i += 3).toLowerCase() in d3_time_weekdayAbbrevLookup ? i : -1; |
---|
| 126 | } |
---|
| 127 | |
---|
| 128 | var 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. |
---|
| 139 | function 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 | |
---|
| 145 | var d3_time_weekdayRe = /^(?:Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday)/ig; |
---|
| 146 | |
---|
| 147 | var d3_time_weekdays = [ |
---|
| 148 | "Sunday", |
---|
| 149 | "Monday", |
---|
| 150 | "Tuesday", |
---|
| 151 | "Wednesday", |
---|
| 152 | "Thursday", |
---|
| 153 | "Friday", |
---|
| 154 | "Saturday" |
---|
| 155 | ]; |
---|
| 156 | |
---|
| 157 | function 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 | |
---|
| 162 | var 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 | |
---|
| 177 | function 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 | |
---|
| 183 | var d3_time_monthRe = /^(?:January|February|March|April|May|June|July|August|September|October|November|December)/ig; |
---|
| 184 | |
---|
| 185 | var 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 | |
---|
| 200 | var 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 | |
---|
| 215 | function d3_time_parseLocaleFull(date, string, i) { |
---|
| 216 | return d3_time_parse(date, d3_time_formats.c.toString(), string, i); |
---|
| 217 | } |
---|
| 218 | |
---|
| 219 | function d3_time_parseLocaleDate(date, string, i) { |
---|
| 220 | return d3_time_parse(date, d3_time_formats.x.toString(), string, i); |
---|
| 221 | } |
---|
| 222 | |
---|
| 223 | function d3_time_parseLocaleTime(date, string, i) { |
---|
| 224 | return d3_time_parse(date, d3_time_formats.X.toString(), string, i); |
---|
| 225 | } |
---|
| 226 | |
---|
| 227 | function 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 | |
---|
| 233 | function 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 | |
---|
| 239 | function d3_time_century() { |
---|
| 240 | return ~~(new Date().getFullYear() / 1000) * 1000; |
---|
| 241 | } |
---|
| 242 | |
---|
| 243 | function 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 | |
---|
| 249 | function 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]. |
---|
| 256 | function 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]. |
---|
| 263 | function d3_time_parseHour12(date, string, i) { |
---|
| 264 | date.hour12 = true; |
---|
| 265 | return d3_time_parseHour24(date, string, i); |
---|
| 266 | } |
---|
| 267 | |
---|
| 268 | function 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 | |
---|
| 274 | function 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. |
---|
| 281 | var d3_time_numberRe = /\s*\d+/; |
---|
| 282 | |
---|
| 283 | function 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 | |
---|
| 288 | var d3_time_amPmLookup = { |
---|
| 289 | am: 0, |
---|
| 290 | pm: 1 |
---|
| 291 | }; |
---|
| 292 | |
---|
| 293 | function d3_time_year(d) { |
---|
| 294 | return new d3_time(d.getFullYear(), 0, 1); |
---|
| 295 | } |
---|
| 296 | |
---|
| 297 | function d3_time_dayOfYear(d) { |
---|
| 298 | return d3_time_zfill3(1 + ~~((d - d3_time_year(d)) / 864e5)); |
---|
| 299 | } |
---|
| 300 | |
---|
| 301 | function d3_time_weekNumberSunday(d) { |
---|
| 302 | var d0 = d3_time_year(d); |
---|
| 303 | return d3_time_zfill2(~~(((d - d0) / 864e5 + d0.getDay()) / 7)); |
---|
| 304 | } |
---|
| 305 | |
---|
| 306 | function 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? |
---|
| 312 | function 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 | } |
---|
| 319 | d3.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 | |
---|
| 343 | function d3_time_format_utc() { |
---|
| 344 | this._ = new Date(Date.UTC.apply(this, arguments)); |
---|
| 345 | } |
---|
| 346 | |
---|
| 347 | d3_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 | }; |
---|
| 367 | d3.time.format.iso = d3.time.format.utc("%Y-%m-%dT%H:%M:%SZ"); |
---|
| 368 | function 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 | } |
---|
| 384 | d3.time.second = function(date) { |
---|
| 385 | return new Date(~~(date / 1e3) * 1e3); |
---|
| 386 | }; |
---|
| 387 | |
---|
| 388 | d3.time.second.utc = d3.time.second; |
---|
| 389 | d3.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 | |
---|
| 395 | d3.time.seconds.utc = d3.time.seconds; |
---|
| 396 | d3.time.minute = function(date) { |
---|
| 397 | return new Date(~~(date / 6e4) * 6e4); |
---|
| 398 | }; |
---|
| 399 | |
---|
| 400 | d3.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 | |
---|
| 404 | d3.time.minutes.utc = d3_time_range(d3.time.minute, d3_time_minutesStep, function(date) { |
---|
| 405 | return date.getUTCMinutes(); |
---|
| 406 | }); |
---|
| 407 | |
---|
| 408 | function d3_time_minutesStep(date) { |
---|
| 409 | date.setTime(date.getTime() + 6e4); // assumes no leap seconds |
---|
| 410 | } |
---|
| 411 | d3.time.hour = function(date) { |
---|
| 412 | var offset = date.getTimezoneOffset() / 60; |
---|
| 413 | return new Date((~~(date / 36e5 - offset) + offset) * 36e5); |
---|
| 414 | }; |
---|
| 415 | |
---|
| 416 | d3.time.hour.utc = function(date) { |
---|
| 417 | return new Date(~~(date / 36e5) * 36e5); |
---|
| 418 | }; |
---|
| 419 | d3.time.hours = d3_time_range(d3.time.hour, d3_time_hoursStep, function(date) { |
---|
| 420 | return date.getHours(); |
---|
| 421 | }); |
---|
| 422 | |
---|
| 423 | d3.time.hours.utc = d3_time_range(d3.time.hour.utc, d3_time_hoursStep, function(date) { |
---|
| 424 | return date.getUTCHours(); |
---|
| 425 | }); |
---|
| 426 | |
---|
| 427 | function d3_time_hoursStep(date) { |
---|
| 428 | date.setTime(date.getTime() + 36e5); |
---|
| 429 | } |
---|
| 430 | d3.time.day = function(date) { |
---|
| 431 | return new Date(date.getFullYear(), date.getMonth(), date.getDate()); |
---|
| 432 | }; |
---|
| 433 | |
---|
| 434 | d3.time.day.utc = function(date) { |
---|
| 435 | return new Date(~~(date / 864e5) * 864e5); |
---|
| 436 | }; |
---|
| 437 | d3.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 | |
---|
| 443 | d3.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 | }); |
---|
| 448 | d3.time.week = function(date) { |
---|
| 449 | (date = d3.time.day(date)).setDate(date.getDate() - date.getDay()); |
---|
| 450 | return date; |
---|
| 451 | }; |
---|
| 452 | |
---|
| 453 | d3.time.week.utc = function(date) { |
---|
| 454 | (date = d3.time.day.utc(date)).setUTCDate(date.getUTCDate() - date.getUTCDay()); |
---|
| 455 | return date; |
---|
| 456 | }; |
---|
| 457 | d3.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 | |
---|
| 463 | d3.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 | }); |
---|
| 468 | d3.time.month = function(date) { |
---|
| 469 | return new Date(date.getFullYear(), date.getMonth(), 1); |
---|
| 470 | }; |
---|
| 471 | |
---|
| 472 | d3.time.month.utc = function(date) { |
---|
| 473 | return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), 1)); |
---|
| 474 | }; |
---|
| 475 | d3.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 | |
---|
| 481 | d3.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 | }); |
---|
| 486 | d3.time.year = function(date) { |
---|
| 487 | return new Date(date.getFullYear(), 0, 1); |
---|
| 488 | }; |
---|
| 489 | |
---|
| 490 | d3.time.year.utc = function(date) { |
---|
| 491 | return new Date(Date.UTC(date.getUTCFullYear(), 0, 1)); |
---|
| 492 | }; |
---|
| 493 | d3.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 | |
---|
| 499 | d3.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 |
---|
| 505 | function 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? |
---|
| 550 | function d3_time_scaleExtent(domain) { |
---|
| 551 | var start = domain[0], stop = domain[domain.length - 1]; |
---|
| 552 | return start < stop ? [start, stop] : [stop, start]; |
---|
| 553 | } |
---|
| 554 | |
---|
| 555 | function d3_time_scaleDate(t) { |
---|
| 556 | return new Date(t); |
---|
| 557 | } |
---|
| 558 | |
---|
| 559 | function 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 | |
---|
| 567 | var 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 | |
---|
| 588 | var 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 | |
---|
| 609 | var 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 | |
---|
| 619 | var d3_time_scaleLocalFormat = d3_time_scaleFormat(d3_time_scaleLocalFormats); |
---|
| 620 | |
---|
| 621 | d3.time.scale = function() { |
---|
| 622 | return d3_time_scale(d3_time_scaleLocalMethods, d3_time_scaleLocalFormat); |
---|
| 623 | }; |
---|
| 624 | var 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 | |
---|
| 645 | var 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 | |
---|
| 655 | var d3_time_scaleUTCFormat = d3_time_scaleFormat(d3_time_scaleUTCFormats); |
---|
| 656 | |
---|
| 657 | d3.time.scale.utc = function() { |
---|
| 658 | return d3_time_scale(d3_time_scaleUTCMethods, d3_time_scaleUTCFormat); |
---|
| 659 | }; |
---|
| 660 | })(); |
---|