diff --git a/Makefile b/Makefile index 831214e5cd64d..dc7aa2127c6ad 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,9 @@ all: \ d3.geo.js \ d3.geo.min.js \ d3.csv.js \ - d3.csv.min.js + d3.csv.min.js \ + d3.time.js \ + d3.time.min.js .INTERMEDIATE d3.js: \ d3.core.js \ @@ -68,6 +70,10 @@ d3.csv.js: \ src/csv/parse.js \ src/csv/format.js +d3.time.js: \ + src/time/time.js \ + src/time/format.js + %.min.js: %.js Makefile src/externs.js @rm -f $@ $(JS_COMPILER) --js $< --js_output_file $@ diff --git a/d3.js b/d3.js index 393fa77362870..3d27e34f55909 100644 --- a/d3.js +++ b/d3.js @@ -1,4 +1,4 @@ -d3 = {version: "0.12.1"}; // semver +d3 = {version: "0.13.0"}; // semver if (!Date.now) Date.now = function() { return +new Date(); }; @@ -204,7 +204,7 @@ var d3_ease_mode = { "in": function(f) { return f; }, "out": d3_ease_reverse, "in-out": d3_ease_reflect, - "out-int": function(f) { return d3_ease_reflect(d3_ease_reverse(f)); } + "out-in": function(f) { return d3_ease_reflect(d3_ease_reverse(f)); } }; d3.ease = function(name) { diff --git a/d3.min.js b/d3.min.js index 04a45d48434c7..b9654b599d2f2 100644 --- a/d3.min.js +++ b/d3.min.js @@ -1,9 +1,9 @@ -(function(){var p=null;d3={version:"0.12.1"};if(!Date.now)Date.now=function(){return+new Date};if(!Object.create)Object.create=function(a){function d(){}d.prototype=a;return new d};function z(a){return Array.prototype.slice.call(a)}function C(a,d){d=z(arguments);d[0]=this;a.apply(this,d);return this}d3.range=function(a,d,e){if(arguments.length==1){d=a;a=0}if(e==p)e=1;if((d-a)/e==Infinity)throw Error("infinite range");var f=[],c=-1,b;if(e<0)for(;(b=a+e*++c)>d;)f.push(b);else for(;(b=a+e*++c)d;)f.push(b);else for(;(b=a+e*++c)=0?g.substring(i):(i=g.length,""),o=[];i>0;)o.push(g.substring(i-=3,i+3));g=o.reverse().join(",")+j}i=g.length;if(i=^]))?([+\- ])?(#)?(0)?([0-9]+)?(,)?(\.[0-9]+)?([a-zA-Z%])?/,H=G(2),I=G(3),fa={linear:function(){return J},poly:G,quad:function(){return H},cubic:function(){return I},sin:function(){return K},exp:function(){return aa},circle:function(){return ba},elastic:ca,back:da,bounce:function(){return ea}},ga={"in":function(a){return a},out:L,"in-out":M,"out-int":function(a){return M(L(a))}}; +var F=/(?:([^{])?([<>=^]))?([+\- ])?(#)?(0)?([0-9]+)?(,)?(\.[0-9]+)?([a-zA-Z%])?/,H=G(2),I=G(3),fa={linear:function(){return J},poly:G,quad:function(){return H},cubic:function(){return I},sin:function(){return K},exp:function(){return aa},circle:function(){return ba},elastic:ca,back:da,bounce:function(){return ea}},ga={"in":function(a){return a},out:L,"in-out":M,"out-in":function(a){return M(L(a))}}; d3.ease=function(a){var d=a.indexOf("-");return ga[d>=0?a.substring(d+1):"in"](fa[d>=0?a.substring(0,d):a].apply(p,Array.prototype.slice.call(arguments,1)))};function L(a){return function(d){return 1-a(1-d)}}function M(a){return function(d){return 0.5*(d<0.5?a(2*d):2-a(2-2*d))}}function J(a){return a}function G(a){return function(d){return Math.pow(d,a)}}function K(a){return 1-Math.cos(a*Math.PI/2)}function aa(a){return a?Math.pow(2,10*(a-1))-0.0010:0}function ba(a){return 1-Math.sqrt(1-a*a)} function ca(a,d){var e;if(arguments.length<2)d=0.45;if(arguments.length<1){a=1;e=d/4}else e=d/(2*Math.PI)*Math.asin(1/a);return function(f){return 1+a*Math.pow(2,10*-f)*Math.sin((f-e)*2*Math.PI/d)}}function da(a){a||(a=1.70158);return function(d){return d*d*((a+1)*d-a)}}function ea(a){return a<1/2.75?7.5625*a*a:a<2/2.75?7.5625*(a-=1.5/2.75)*a+0.75:a<2.5/2.75?7.5625*(a-=2.25/2.75)*a+0.9375:7.5625*(a-=2.625/2.75)*a+0.984375}d3.event=p; d3.interpolate=function(a,d){if(typeof d=="number")return d3.interpolateNumber(+a,d);if(typeof d=="string")return d in N||/^(#|rgb\(|hsl\()/.test(d)?d3.interpolateRgb(String(a),d):d3.interpolateString(String(a),d);if(d instanceof Array)return d3.interpolateArray(a,d);return d3.interpolateObject(a,d)};d3.interpolateNumber=function(a,d){d-=a;return function(e){return a+d*e}}; diff --git a/d3.time.js b/d3.time.js new file mode 100644 index 0000000000000..d9b6227faa02d --- /dev/null +++ b/d3.time.js @@ -0,0 +1,313 @@ +d3.time = {}; +d3.time.format = function(template) { + var n = template.length; + + function format(date) { + var string = [], + i = -1, + j = 0, + c, + f; + while (++i < n) { + if (template.charCodeAt(i) == 37) { + string.push( + template.substring(j, i), + (f = d3_time_formats[c = template.charAt(++i)]) + ? f(date) : c); + j = i + 1; + } + } + string.push(template.substring(j, i)); + return string.join(""); + } + + format.parse = function(string) { + var date = new Date(1900, 0, 1), + i = d3_time_parse(date, template, string, 0); + if (i != string.length) return null; + if (date.hour12) { + var hours = date.getHours() % 12; + date.setHours(date.hour12pm ? hours + 12 : hours); + } + delete date.hour12; + delete date.hour12pm; + return date; + }; + + format.toString = function() { + return template; + }; + + return format; +}; + +function d3_time_parse(date, template, string, j) { + var c, + p, + i = 0, + n = template.length, + m = string.length; + while (i < n) { + if (j >= m) return -1; + c = template.charCodeAt(i++); + if (c == 37) { + p = d3_time_parsers[template.charAt(i++)]; + if (!p || ((j = p(date, string, j)) < 0)) return -1; + } else if (c != string.charCodeAt(j++)) { + return -1; + } + } + return j; +} + +var d3_time_zfill2 = d3.format("02d"), + d3_time_zfill3 = d3.format("03d"), + d3_time_zfill4 = d3.format("04d"), + d3_time_sfill2 = d3.format(" 2d"); + +var d3_time_formats = { + "a": function(d) { return d3_time_weekdays[d.getDay()].substring(0, 3); }, + "A": function(d) { return d3_time_weekdays[d.getDay()]; }, + "b": function(d) { return d3_time_months[d.getMonth()].substring(0, 3); }, + "B": function(d) { return d3_time_months[d.getMonth()]; }, + "c": d3.time.format("%a %b %e %H:%M:%S %Y"), + "d": function(d) { return d3_time_zfill2(d.getDate()); }, + "e": function(d) { return d3_time_sfill2(d.getDate()); }, + "H": function(d) { return d3_time_zfill2(d.getHours()); }, + "I": function(d) { return d3_time_zfill2(d.getHours() % 12 || 12); }, + "j": d3_time_dayOfYear, + "m": function(d) { return d3_time_zfill2(d.getMonth() + 1); }, + "M": function(d) { return d3_time_zfill2(d.getMinutes()); }, + "p": function(d) { return d.getHours() >= 12 ? "PM" : "AM"; }, + "S": function(d) { return d3_time_zfill2(d.getSeconds()); }, + "U": d3_time_weekNumberSunday, + "w": function(d) { return d.getDay(); }, + "W": d3_time_weekNumberMonday, + "x": d3.time.format("%m/%d/%y"), + "X": d3.time.format("%H:%M:%S"), + "y": function(d) { return d3_time_zfill2(d.getYear() % 100); }, + "Y": function(d) { return d3_time_zfill4(d.getFullYear() % 10000); }, + "Z": d3_time_zone, + "%": function(d) { return "%"; } +}; + +var d3_time_parsers = { + "a": d3_time_parseWeekdayAbbrev, + "A": d3_time_parseWeekday, + "b": d3_time_parseMonthAbbrev, + "B": d3_time_parseMonth, + "c": d3_time_parseLocaleFull, + "d": d3_time_parseDay, + "e": d3_time_parseDay, + "H": d3_time_parseHour24, + "I": d3_time_parseHour12, + // "j": function(d, s, i) { /*TODO day of year [001,366] */ return i; }, + "m": d3_time_parseMonthNumber, + "M": d3_time_parseMinutes, + "p": d3_time_parseAmPm, + "S": d3_time_parseSeconds, + // "U": function(d, s, i) { /*TODO week number (sunday) [00,53] */ return i; }, + // "w": function(d, s, i) { /*TODO weekday [0,6] */ return i; }, + // "W": function(d, s, i) { /*TODO week number (monday) [00,53] */ return i; }, + "x": d3_time_parseLocaleDate, + "X": d3_time_parseLocaleTime, + "y": d3_time_parseYear, + "Y": d3_time_parseFullYear + // , + // "Z": function(d, s, i) { /*TODO time zone */ return i; }, + // "%": function(d, s, i) { /*TODO literal % */ return i; } +}; + +// Note: weekday is validated, but does not set the date. +function d3_time_parseWeekdayAbbrev(date, string, i) { + return string.substring(i, i += 3).toLowerCase() in d3_time_weekdayAbbrevLookup ? i : -1; +} + +var d3_time_weekdayAbbrevLookup = { + "sun": 3, + "mon": 3, + "tue": 3, + "wed": 3, + "thu": 3, + "fri": 3, + "sat": 3 +}; + +// Note: weekday is validated, but does not set the date. +function d3_time_parseWeekday(date, string, i) { + d3_time_weekdayRe.lastIndex = 0; + var n = d3_time_weekdayRe.exec(string.substring(i, i + 10)); + return n ? i += n[0].length : -1; +} + +var d3_time_weekdayRe = /^(?:Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday)/ig; + +var d3_time_weekdays = [ + "Sunday", + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday" +]; + +function d3_time_parseMonthAbbrev(date, string, i) { + var n = d3_time_monthAbbrevLookup[string.substring(i, i += 3).toLowerCase()]; + return n == null ? -1 : (date.setMonth(n), i); +} + +var d3_time_monthAbbrevLookup = { + "jan": 0, + "feb": 1, + "mar": 2, + "apr": 3, + "may": 4, + "jun": 5, + "jul": 6, + "aug": 7, + "sep": 8, + "oct": 9, + "nov": 10, + "dec": 11 +}; + +function d3_time_parseMonth(date, string, i) { + d3_time_monthRe.lastIndex = 0; + var n = d3_time_monthRe.exec(string.substring(i, i + 12)); + return n ? (date.setMonth(d3_time_monthLookup[n[0].toLowerCase()]), i += n[0].length) : -1; +} + +var d3_time_monthRe = /^(?:January|February|March|April|May|June|July|August|September|October|November|December)/ig; + +var d3_time_monthLookup = { + "january": 0, + "february": 1, + "march": 2, + "april": 3, + "may": 4, + "june": 5, + "july": 6, + "august": 7, + "september": 8, + "october": 9, + "november": 10, + "december": 11 +}; + +var d3_time_months = [ + "January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December" +]; + +function d3_time_parseLocaleFull(date, string, i) { + return d3_time_parse(date, d3_time_formats.c.toString(), string, i); +} + +function d3_time_parseLocaleDate(date, string, i) { + return d3_time_parse(date, d3_time_formats.x.toString(), string, i); +} + +function d3_time_parseLocaleTime(date, string, i) { + return d3_time_parse(date, d3_time_formats.X.toString(), string, i); +} + +function d3_time_parseFullYear(date, string, i) { + d3_time_number4Re.lastIndex = 0; + var n = d3_time_number4Re.exec(string.substring(i, i + 4)); + return n ? (date.setFullYear(n[0]), i += n[0].length) : -1; +} + +function d3_time_parseYear(date, string, i) { + d3_time_number2Re.lastIndex = 0; + var n = d3_time_number2Re.exec(string.substring(i, i + 2)); + return n ? (date.setFullYear(d3_time_century() + +n[0]), i += n[0].length) : -1; +} + +function d3_time_century() { + return ~~(new Date().getFullYear() / 1000) * 1000; +} + +function d3_time_parseMonthNumber(date, string, i) { + d3_time_number2Re.lastIndex = 0; + var n = d3_time_number2Re.exec(string.substring(i, i + 2)); + return n ? (date.setMonth(n[0] - 1), i += n[0].length) : -1; +} + +function d3_time_parseDay(date, string, i) { + d3_time_number2Re.lastIndex = 0; + var n = d3_time_number2Re.exec(string.substring(i, i + 2)); + return n ? (date.setDate(+n[0]), i += n[0].length) : -1; +} + +// Note: we don't validate that the hour is in the range [0,23]. +function d3_time_parseHour24(date, string, i) { + d3_time_number2Re.lastIndex = 0; + var n = d3_time_number2Re.exec(string.substring(i, i + 2)); + return n ? (date.setHours(+n[0]), i += n[0].length) : -1; +} + +// Note: we don't validate that the hour is in the range [1,12]. +function d3_time_parseHour12(date, string, i) { + date.hour12 = true; + return d3_time_parseHour24(date, string, i); +} + +function d3_time_parseMinutes(date, string, i) { + d3_time_number2Re.lastIndex = 0; + var n = d3_time_number2Re.exec(string.substring(i, i + 2)); + return n ? (date.setMinutes(+n[0]), i += n[0].length) : -1; +} + +function d3_time_parseSeconds(date, string, i) { + d3_time_number2Re.lastIndex = 0; + var n = d3_time_number2Re.exec(string.substring(i, i + 2)); + return n ? (date.setSeconds(+n[0]), i += n[0].length) : -1; +} + +// Note: we don't look at the next directive. +var d3_time_number2Re = /[\s\d]{1,2}/, + d3_time_number4Re = /[\s\d]{1,4}/; + +function d3_time_parseAmPm(date, string, i) { + var n = d3_time_amPmLookup[string.substring(i, i += 2).toLowerCase()]; + return n == null ? -1 : (date.hour12pm = n, i); +} + +var d3_time_amPmLookup = { + "am": 0, + "pm": 1 +}; + +function d3_time_dayOfYear(d) { + return d3_time_zfill3(1 + ~~((d - new Date(d.getFullYear(), 0, 1)) / 864e5)); +} + +function d3_time_weekNumberSunday(d) { + var d0 = new Date(d.getFullYear(), 0, 1); + return d3_time_zfill2(~~(((d - d0) / 864e5 + d0.getDay()) / 7)); +} + +function d3_time_weekNumberMonday(d) { + var d0 = new Date(d.getFullYear(), 0, 1); + return d3_time_zfill2(~~(((d - d0) / 864e5 + (d0.getDay() + 6) % 7) / 7)); +} + +// TODO table of time zone offset names? +function d3_time_zone(d) { + var z = d.getTimezoneOffset(), + zs = z > 0 ? "-" : "+", + zh = ~~(Math.abs(z) / 60), + zm = Math.abs(z) % 60; + return zs + d3_time_zfill2(zh) + d3_time_zfill2(zm); +} diff --git a/d3.time.min.js b/d3.time.min.js new file mode 100644 index 0000000000000..0a9c5f305e5d4 --- /dev/null +++ b/d3.time.min.js @@ -0,0 +1,10 @@ +(function(){d3.time={};d3.time.format=function(a){function b(e){for(var d=[],h=-1,i=0,j,m;++h=j)return-1;d=b.charCodeAt(h++);if(d==37){d=k[b.charAt(h++)];if(!d||(e=d(a,c,e))<0)return-1}else if(d!=c.charCodeAt(e++))return-1}return e} +var l=d3.format("02d"),n=d3.format("03d"),o=d3.format("04d"),p=d3.format(" 2d"),f={a:function(a){return q[a.getDay()].substring(0,3)},A:function(a){return q[a.getDay()]},b:function(a){return r[a.getMonth()].substring(0,3)},B:function(a){return r[a.getMonth()]},c:d3.time.format("%a %b %e %H:%M:%S %Y"),d:function(a){return l(a.getDate())},e:function(a){return p(a.getDate())},H:function(a){return l(a.getHours())},I:function(a){return l(a.getHours()%12||12)},j:s,m:function(a){return l(a.getMonth()+1)}, +M:function(a){return l(a.getMinutes())},p:function(a){return a.getHours()>=12?"PM":"AM"},S:function(a){return l(a.getSeconds())},U:t,w:function(a){return a.getDay()},W:u,x:d3.time.format("%m/%d/%y"),X:d3.time.format("%H:%M:%S"),y:function(a){return l(a.getYear()%100)},Y:function(a){return o(a.getFullYear()%1E4)},Z:v,"%":function(){return"%"}},k={a:w,A:x,b:y,B:z,c:A,d:B,e:B,H:C,I:D,m:E,M:F,p:G,S:H,x:I,X:J,y:K,Y:L};function w(a,b,c){return b.substring(c,c+=3).toLowerCase()in M?c:-1} +var M={sun:3,mon:3,tue:3,wed:3,thu:3,fri:3,sat:3};function x(a,b,c){N.lastIndex=0;return(a=N.exec(b.substring(c,c+10)))?c+a[0].length:-1}var N=/^(?:Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday)/ig,q=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];function y(a,b,c){b=O[b.substring(c,c+=3).toLowerCase()];return b==null?-1:(a.setMonth(b),c)}var O={jan:0,feb:1,mar:2,apr:3,may:4,jun:5,jul:6,aug:7,sep:8,oct:9,nov:10,dec:11}; +function z(a,b,c){P.lastIndex=0;return(b=P.exec(b.substring(c,c+12)))?(a.setMonth(Q[b[0].toLowerCase()]),c+b[0].length):-1}var P=/^(?:January|February|March|April|May|June|July|August|September|October|November|December)/ig,Q={january:0,february:1,march:2,april:3,may:4,june:5,july:6,august:7,september:8,october:9,november:10,december:11},r=["January","February","March","April","May","June","July","August","September","October","November","December"]; +function A(a,b,c){return g(a,f.k.toString(),b,c)}function I(a,b,c){return g(a,f.x.toString(),b,c)}function J(a,b,c){return g(a,f.i.toString(),b,c)}function L(a,b,c){R.lastIndex=0;return(b=R.exec(b.substring(c,c+4)))?(a.setFullYear(b[0]),c+b[0].length):-1}function K(a,b,c){S.lastIndex=0;return(b=S.exec(b.substring(c,c+2)))?(a.setFullYear(~~((new Date).getFullYear()/1E3)*1E3+ +b[0]),c+b[0].length):-1} +function E(a,b,c){S.lastIndex=0;return(b=S.exec(b.substring(c,c+2)))?(a.setMonth(b[0]-1),c+b[0].length):-1}function B(a,b,c){S.lastIndex=0;return(b=S.exec(b.substring(c,c+2)))?(a.setDate(+b[0]),c+b[0].length):-1}function C(a,b,c){S.lastIndex=0;return(b=S.exec(b.substring(c,c+2)))?(a.setHours(+b[0]),c+b[0].length):-1}function D(a,b,c){a.g=true;return C(a,b,c)}function F(a,b,c){S.lastIndex=0;return(b=S.exec(b.substring(c,c+2)))?(a.setMinutes(+b[0]),c+b[0].length):-1} +function H(a,b,c){S.lastIndex=0;return(b=S.exec(b.substring(c,c+2)))?(a.setSeconds(+b[0]),c+b[0].length):-1}var S=/[\s\d]{1,2}/,R=/[\s\d]{1,4}/;function G(a,b,c){b=T[b.substring(c,c+=2).toLowerCase()];return b==null?-1:(a.h=b,c)}var T={am:0,pm:1};function s(a){return n(1+~~((a-new Date(a.getFullYear(),0,1))/864E5))}function t(a){var b=new Date(a.getFullYear(),0,1);return l(~~(((a-b)/864E5+b.getDay())/7))} +function u(a){var b=new Date(a.getFullYear(),0,1);return l(~~(((a-b)/864E5+(b.getDay()+6)%7)/7))}function v(a){a=a.getTimezoneOffset();var b=Math.abs(a)%60;return(a>0?"-":"+")+l(~~(Math.abs(a)/60))+l(b)};})() diff --git a/examples/zoom/zoom.html b/examples/zoom/zoom.html index 1787208ff1ca5..977fb13be2193 100644 --- a/examples/zoom/zoom.html +++ b/examples/zoom/zoom.html @@ -5,6 +5,7 @@ Zoom +