rubyvis 0.6.0 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.travis.yml +13 -0
  4. data/Gemfile +8 -0
  5. data/Gemfile.lock +37 -0
  6. data/History.txt +6 -0
  7. data/LICENSE.txt +23 -0
  8. data/{README.txt → README.md} +15 -12
  9. data/Rakefile +4 -11
  10. data/lib/rubyvis.rb +1 -1
  11. data/lib/rubyvis/scale/quantitative.rb +14 -18
  12. data/lib/rubyvis/scene/svg_label.rb +1 -1
  13. data/rubyvis.gemspec +21 -0
  14. data/spec/anchor_spec.rb +2 -1
  15. data/spec/line_spec.rb +2 -2
  16. data/spec/scale_linear_datetime_spec.rb +23 -8
  17. data/spec/spec_helper.rb +2 -1
  18. metadata +31 -214
  19. data/.gemtest +0 -0
  20. data/vendor/protovis/protovis-r3.3.js +0 -287
  21. data/vendor/protovis/src/behavior/Behavior.js +0 -32
  22. data/vendor/protovis/src/behavior/Drag.js +0 -112
  23. data/vendor/protovis/src/behavior/Pan.js +0 -110
  24. data/vendor/protovis/src/behavior/Point.js +0 -157
  25. data/vendor/protovis/src/behavior/Resize.js +0 -104
  26. data/vendor/protovis/src/behavior/Select.js +0 -100
  27. data/vendor/protovis/src/behavior/Zoom.js +0 -85
  28. data/vendor/protovis/src/color/Color.js +0 -598
  29. data/vendor/protovis/src/color/Colors.js +0 -135
  30. data/vendor/protovis/src/color/Ramp.js +0 -17
  31. data/vendor/protovis/src/data/Arrays.js +0 -277
  32. data/vendor/protovis/src/data/Dom.js +0 -380
  33. data/vendor/protovis/src/data/Flatten.js +0 -146
  34. data/vendor/protovis/src/data/Histogram.js +0 -120
  35. data/vendor/protovis/src/data/LinearScale.js +0 -54
  36. data/vendor/protovis/src/data/LogScale.js +0 -142
  37. data/vendor/protovis/src/data/Nest.js +0 -257
  38. data/vendor/protovis/src/data/Numbers.js +0 -313
  39. data/vendor/protovis/src/data/Objects.js +0 -78
  40. data/vendor/protovis/src/data/OrdinalScale.js +0 -267
  41. data/vendor/protovis/src/data/QuantileScale.js +0 -180
  42. data/vendor/protovis/src/data/QuantitativeScale.js +0 -440
  43. data/vendor/protovis/src/data/RootScale.js +0 -55
  44. data/vendor/protovis/src/data/Scale.js +0 -86
  45. data/vendor/protovis/src/data/Transform.js +0 -109
  46. data/vendor/protovis/src/data/Tree.js +0 -124
  47. data/vendor/protovis/src/data/Vector.js +0 -118
  48. data/vendor/protovis/src/geo/Geo.js +0 -5
  49. data/vendor/protovis/src/geo/GeoScale.js +0 -307
  50. data/vendor/protovis/src/geo/LatLng.js +0 -23
  51. data/vendor/protovis/src/geo/Projection.js +0 -43
  52. data/vendor/protovis/src/geo/Projections.js +0 -117
  53. data/vendor/protovis/src/lang/Array.js +0 -112
  54. data/vendor/protovis/src/lang/init.js +0 -26
  55. data/vendor/protovis/src/layout/Arc.js +0 -178
  56. data/vendor/protovis/src/layout/Bullet.js +0 -164
  57. data/vendor/protovis/src/layout/Cluster.js +0 -205
  58. data/vendor/protovis/src/layout/Force.js +0 -309
  59. data/vendor/protovis/src/layout/Grid.js +0 -119
  60. data/vendor/protovis/src/layout/Hierarchy.js +0 -249
  61. data/vendor/protovis/src/layout/Horizon.js +0 -159
  62. data/vendor/protovis/src/layout/Indent.js +0 -83
  63. data/vendor/protovis/src/layout/Layout.js +0 -56
  64. data/vendor/protovis/src/layout/Matrix.js +0 -177
  65. data/vendor/protovis/src/layout/Network.js +0 -302
  66. data/vendor/protovis/src/layout/Pack.js +0 -323
  67. data/vendor/protovis/src/layout/Partition.js +0 -203
  68. data/vendor/protovis/src/layout/Rollup.js +0 -203
  69. data/vendor/protovis/src/layout/Stack.js +0 -391
  70. data/vendor/protovis/src/layout/Tree.js +0 -282
  71. data/vendor/protovis/src/layout/Treemap.js +0 -347
  72. data/vendor/protovis/src/mark/Anchor.js +0 -81
  73. data/vendor/protovis/src/mark/Area.js +0 -268
  74. data/vendor/protovis/src/mark/Bar.js +0 -93
  75. data/vendor/protovis/src/mark/Dot.js +0 -212
  76. data/vendor/protovis/src/mark/Ease.js +0 -150
  77. data/vendor/protovis/src/mark/Image.js +0 -154
  78. data/vendor/protovis/src/mark/Label.js +0 -155
  79. data/vendor/protovis/src/mark/Line.js +0 -195
  80. data/vendor/protovis/src/mark/Mark.js +0 -1237
  81. data/vendor/protovis/src/mark/Panel.js +0 -273
  82. data/vendor/protovis/src/mark/Rule.js +0 -143
  83. data/vendor/protovis/src/mark/Transient.js +0 -7
  84. data/vendor/protovis/src/mark/Transition.js +0 -195
  85. data/vendor/protovis/src/mark/Wedge.js +0 -244
  86. data/vendor/protovis/src/physics/BoundConstraint.js +0 -75
  87. data/vendor/protovis/src/physics/ChargeForce.js +0 -184
  88. data/vendor/protovis/src/physics/CollisionConstraint.js +0 -113
  89. data/vendor/protovis/src/physics/Constraint.js +0 -26
  90. data/vendor/protovis/src/physics/DragForce.js +0 -49
  91. data/vendor/protovis/src/physics/Force.js +0 -25
  92. data/vendor/protovis/src/physics/Particle.js +0 -81
  93. data/vendor/protovis/src/physics/PositionConstraint.js +0 -72
  94. data/vendor/protovis/src/physics/Quadtree.js +0 -195
  95. data/vendor/protovis/src/physics/Simulation.js +0 -159
  96. data/vendor/protovis/src/physics/SpringForce.js +0 -141
  97. data/vendor/protovis/src/pv-internals.js +0 -154
  98. data/vendor/protovis/src/pv.js +0 -95
  99. data/vendor/protovis/src/scene/SvgArea.js +0 -172
  100. data/vendor/protovis/src/scene/SvgBar.js +0 -28
  101. data/vendor/protovis/src/scene/SvgCurve.js +0 -354
  102. data/vendor/protovis/src/scene/SvgDot.js +0 -81
  103. data/vendor/protovis/src/scene/SvgImage.js +0 -45
  104. data/vendor/protovis/src/scene/SvgLabel.js +0 -46
  105. data/vendor/protovis/src/scene/SvgLine.js +0 -159
  106. data/vendor/protovis/src/scene/SvgPanel.js +0 -126
  107. data/vendor/protovis/src/scene/SvgRule.js +0 -26
  108. data/vendor/protovis/src/scene/SvgScene.js +0 -185
  109. data/vendor/protovis/src/scene/SvgWedge.js +0 -66
  110. data/vendor/protovis/src/text/DateFormat.js +0 -262
  111. data/vendor/protovis/src/text/Format.js +0 -78
  112. data/vendor/protovis/src/text/NumberFormat.js +0 -227
  113. data/vendor/protovis/src/text/TimeFormat.js +0 -115
@@ -1,26 +0,0 @@
1
- pv.SvgScene.rule = function(scenes) {
2
- var e = scenes.$g.firstChild;
3
- for (var i = 0; i < scenes.length; i++) {
4
- var s = scenes[i];
5
-
6
- /* visible */
7
- if (!s.visible) continue;
8
- var stroke = s.strokeStyle;
9
- if (!stroke.opacity) continue;
10
-
11
- e = this.expect(e, "line", {
12
- "shape-rendering": s.antialias ? null : "crispEdges",
13
- "pointer-events": s.events,
14
- "cursor": s.cursor,
15
- "x1": s.left,
16
- "y1": s.top,
17
- "x2": s.left + s.width,
18
- "y2": s.top + s.height,
19
- "stroke": stroke.color,
20
- "stroke-opacity": stroke.opacity,
21
- "stroke-width": s.lineWidth / this.scale
22
- });
23
- e = this.append(e, scenes, i);
24
- }
25
- return e;
26
- };
@@ -1,185 +0,0 @@
1
- /**
2
- * @private
3
- * @namespace
4
- */
5
- pv.Scene = pv.SvgScene = {
6
- /* Various namespaces. */
7
- svg: "http://www.w3.org/2000/svg",
8
- xmlns: "http://www.w3.org/2000/xmlns",
9
- xlink: "http://www.w3.org/1999/xlink",
10
- xhtml: "http://www.w3.org/1999/xhtml",
11
-
12
- /** The pre-multipled scale, based on any enclosing transforms. */
13
- scale: 1,
14
-
15
- /** The set of supported events. */
16
- events: [
17
- "DOMMouseScroll", // for Firefox
18
- "mousewheel",
19
- "mousedown",
20
- "mouseup",
21
- "mouseover",
22
- "mouseout",
23
- "mousemove",
24
- "click",
25
- "dblclick"
26
- ],
27
-
28
- /** Implicit values for SVG and CSS properties. */
29
- implicit: {
30
- svg: {
31
- "shape-rendering": "auto",
32
- "pointer-events": "painted",
33
- "x": 0,
34
- "y": 0,
35
- "dy": 0,
36
- "text-anchor": "start",
37
- "transform": "translate(0,0)",
38
- "fill": "none",
39
- "fill-opacity": 1,
40
- "stroke": "none",
41
- "stroke-opacity": 1,
42
- "stroke-width": 1.5,
43
- "stroke-linejoin": "miter"
44
- },
45
- css: {
46
- "font": "10px sans-serif"
47
- }
48
- }
49
- };
50
-
51
- /**
52
- * Updates the display for the specified array of scene nodes.
53
- *
54
- * @param scenes {array} an array of scene nodes.
55
- */
56
- pv.SvgScene.updateAll = function(scenes) {
57
- if (scenes.length
58
- && scenes[0].reverse
59
- && (scenes.type != "line")
60
- && (scenes.type != "area")) {
61
- var reversed = pv.extend(scenes);
62
- for (var i = 0, j = scenes.length - 1; j >= 0; i++, j--) {
63
- reversed[i] = scenes[j];
64
- }
65
- scenes = reversed;
66
- }
67
- this.removeSiblings(this[scenes.type](scenes));
68
- };
69
-
70
- /**
71
- * Creates a new SVG element of the specified type.
72
- *
73
- * @param type {string} an SVG element type, such as "rect".
74
- * @returns a new SVG element.
75
- */
76
- pv.SvgScene.create = function(type) {
77
- return document.createElementNS(this.svg, type);
78
- };
79
-
80
- /**
81
- * Expects the element <i>e</i> to be the specified type. If the element does
82
- * not exist, a new one is created. If the element does exist but is the wrong
83
- * type, it is replaced with the specified element.
84
- *
85
- * @param e the current SVG element.
86
- * @param type {string} an SVG element type, such as "rect".
87
- * @param attributes an optional attribute map.
88
- * @param style an optional style map.
89
- * @returns a new SVG element.
90
- */
91
- pv.SvgScene.expect = function(e, type, attributes, style) {
92
- if (e) {
93
- if (e.tagName == "a") e = e.firstChild;
94
- if (e.tagName != type) {
95
- var n = this.create(type);
96
- e.parentNode.replaceChild(n, e);
97
- e = n;
98
- }
99
- } else {
100
- e = this.create(type);
101
- }
102
- for (var name in attributes) {
103
- var value = attributes[name];
104
- if (value == this.implicit.svg[name]) value = null;
105
- if (value == null) e.removeAttribute(name);
106
- else e.setAttribute(name, value);
107
- }
108
- for (var name in style) {
109
- var value = style[name];
110
- if (value == this.implicit.css[name]) value = null;
111
- if (value == null) e.style.removeProperty(name);
112
- else e.style[name] = value;
113
- }
114
- return e;
115
- };
116
-
117
- /** TODO */
118
- pv.SvgScene.append = function(e, scenes, index) {
119
- e.$scene = {scenes:scenes, index:index};
120
- e = this.title(e, scenes[index]);
121
- if (!e.parentNode) scenes.$g.appendChild(e);
122
- return e.nextSibling;
123
- };
124
-
125
- /**
126
- * Applies a title tooltip to the specified element <tt>e</tt>, using the
127
- * <tt>title</tt> property of the specified scene node <tt>s</tt>. Note that
128
- * this implementation does not create an SVG <tt>title</tt> element as a child
129
- * of <tt>e</tt>; although this is the recommended standard, it is only
130
- * supported in Opera. Instead, an anchor element is created around the element
131
- * <tt>e</tt>, and the <tt>xlink:title</tt> attribute is set accordingly.
132
- *
133
- * @param e an SVG element.
134
- * @param s a scene node.
135
- */
136
- pv.SvgScene.title = function(e, s) {
137
- var a = e.parentNode;
138
- if (a && (a.tagName != "a")) a = null;
139
- if (s.title) {
140
- if (!a) {
141
- a = this.create("a");
142
- if (e.parentNode) e.parentNode.replaceChild(a, e);
143
- a.appendChild(e);
144
- }
145
- a.setAttributeNS(this.xlink, "title", s.title);
146
- return a;
147
- }
148
- if (a) a.parentNode.replaceChild(e, a);
149
- return e;
150
- };
151
-
152
- /** TODO */
153
- pv.SvgScene.dispatch = pv.listener(function(e) {
154
- var t = e.target.$scene;
155
- if (t) {
156
- var type = e.type;
157
-
158
- /* Fixes for mousewheel support on Firefox & Opera. */
159
- switch (type) {
160
- case "DOMMouseScroll": {
161
- type = "mousewheel";
162
- e.wheel = -480 * e.detail;
163
- break;
164
- }
165
- case "mousewheel": {
166
- e.wheel = (window.opera ? 12 : 1) * e.wheelDelta;
167
- break;
168
- }
169
- }
170
-
171
- if (pv.Mark.dispatch(type, t.scenes, t.index)) e.preventDefault();
172
- }
173
- });
174
-
175
- /** @private Remove siblings following element <i>e</i>. */
176
- pv.SvgScene.removeSiblings = function(e) {
177
- while (e) {
178
- var n = e.nextSibling;
179
- e.parentNode.removeChild(e);
180
- e = n;
181
- }
182
- };
183
-
184
- /** @private Do nothing when rendering undefined mark types. */
185
- pv.SvgScene.undefined = function() {};
@@ -1,66 +0,0 @@
1
- pv.SvgScene.wedge = function(scenes) {
2
- var e = scenes.$g.firstChild;
3
- for (var i = 0; i < scenes.length; i++) {
4
- var s = scenes[i];
5
-
6
- /* visible */
7
- if (!s.visible) continue;
8
- var fill = s.fillStyle, stroke = s.strokeStyle;
9
- if (!fill.opacity && !stroke.opacity) continue;
10
-
11
- /* points */
12
- var r1 = s.innerRadius, r2 = s.outerRadius, a = Math.abs(s.angle), p;
13
- if (a >= 2 * Math.PI) {
14
- if (r1) {
15
- p = "M0," + r2
16
- + "A" + r2 + "," + r2 + " 0 1,1 0," + (-r2)
17
- + "A" + r2 + "," + r2 + " 0 1,1 0," + r2
18
- + "M0," + r1
19
- + "A" + r1 + "," + r1 + " 0 1,1 0," + (-r1)
20
- + "A" + r1 + "," + r1 + " 0 1,1 0," + r1
21
- + "Z";
22
- } else {
23
- p = "M0," + r2
24
- + "A" + r2 + "," + r2 + " 0 1,1 0," + (-r2)
25
- + "A" + r2 + "," + r2 + " 0 1,1 0," + r2
26
- + "Z";
27
- }
28
- } else {
29
- var sa = Math.min(s.startAngle, s.endAngle),
30
- ea = Math.max(s.startAngle, s.endAngle),
31
- c1 = Math.cos(sa), c2 = Math.cos(ea),
32
- s1 = Math.sin(sa), s2 = Math.sin(ea);
33
- if (r1) {
34
- p = "M" + r2 * c1 + "," + r2 * s1
35
- + "A" + r2 + "," + r2 + " 0 "
36
- + ((a < Math.PI) ? "0" : "1") + ",1 "
37
- + r2 * c2 + "," + r2 * s2
38
- + "L" + r1 * c2 + "," + r1 * s2
39
- + "A" + r1 + "," + r1 + " 0 "
40
- + ((a < Math.PI) ? "0" : "1") + ",0 "
41
- + r1 * c1 + "," + r1 * s1 + "Z";
42
- } else {
43
- p = "M" + r2 * c1 + "," + r2 * s1
44
- + "A" + r2 + "," + r2 + " 0 "
45
- + ((a < Math.PI) ? "0" : "1") + ",1 "
46
- + r2 * c2 + "," + r2 * s2 + "L0,0Z";
47
- }
48
- }
49
-
50
- e = this.expect(e, "path", {
51
- "shape-rendering": s.antialias ? null : "crispEdges",
52
- "pointer-events": s.events,
53
- "cursor": s.cursor,
54
- "transform": "translate(" + s.left + "," + s.top + ")",
55
- "d": p,
56
- "fill": fill.color,
57
- "fill-rule": "evenodd",
58
- "fill-opacity": fill.opacity || null,
59
- "stroke": stroke.color,
60
- "stroke-opacity": stroke.opacity || null,
61
- "stroke-width": stroke.opacity ? s.lineWidth / this.scale : null
62
- });
63
- e = this.append(e, scenes, i);
64
- }
65
- return e;
66
- };
@@ -1,262 +0,0 @@
1
- /**
2
- * Constructs a new date format with the specified string pattern.
3
- *
4
- * @class The format string is in the same format expected by the
5
- * <tt>strftime</tt> function in C. The following conversion specifications are
6
- * supported:<ul>
7
- *
8
- * <li>%a - abbreviated weekday name.</li>
9
- * <li>%A - full weekday name.</li>
10
- * <li>%b - abbreviated month names.</li>
11
- * <li>%B - full month names.</li>
12
- * <li>%c - locale's appropriate date and time.</li>
13
- * <li>%C - century number.</li>
14
- * <li>%d - day of month [01,31] (zero padded).</li>
15
- * <li>%D - same as %m/%d/%y.</li>
16
- * <li>%e - day of month [ 1,31] (space padded).</li>
17
- * <li>%h - same as %b.</li>
18
- * <li>%H - hour (24-hour clock) [00,23] (zero padded).</li>
19
- * <li>%I - hour (12-hour clock) [01,12] (zero padded).</li>
20
- * <li>%m - month number [01,12] (zero padded).</li>
21
- * <li>%M - minute [0,59] (zero padded).</li>
22
- * <li>%n - newline character.</li>
23
- * <li>%p - locale's equivalent of a.m. or p.m.</li>
24
- * <li>%r - same as %I:%M:%S %p.</li>
25
- * <li>%R - same as %H:%M.</li>
26
- * <li>%S - second [00,61] (zero padded).</li>
27
- * <li>%t - tab character.</li>
28
- * <li>%T - same as %H:%M:%S.</li>
29
- * <li>%x - same as %m/%d/%y.</li>
30
- * <li>%X - same as %I:%M:%S %p.</li>
31
- * <li>%y - year with century [00,99] (zero padded).</li>
32
- * <li>%Y - year including century.</li>
33
- * <li>%% - %.</li>
34
- *
35
- * </ul>The following conversion specifications are currently <i>unsupported</i>
36
- * for formatting:<ul>
37
- *
38
- * <li>%j - day number [1,366].</li>
39
- * <li>%u - weekday number [1,7].</li>
40
- * <li>%U - week number [00,53].</li>
41
- * <li>%V - week number [01,53].</li>
42
- * <li>%w - weekday number [0,6].</li>
43
- * <li>%W - week number [00,53].</li>
44
- * <li>%Z - timezone name or abbreviation.</li>
45
- *
46
- * </ul>In addition, the following conversion specifications are currently
47
- * <i>unsupported</i> for parsing:<ul>
48
- *
49
- * <li>%a - day of week, either abbreviated or full name.</li>
50
- * <li>%A - same as %a.</li>
51
- * <li>%c - locale's appropriate date and time.</li>
52
- * <li>%C - century number.</li>
53
- * <li>%D - same as %m/%d/%y.</li>
54
- * <li>%I - hour (12-hour clock) [1,12].</li>
55
- * <li>%n - any white space.</li>
56
- * <li>%p - locale's equivalent of a.m. or p.m.</li>
57
- * <li>%r - same as %I:%M:%S %p.</li>
58
- * <li>%R - same as %H:%M.</li>
59
- * <li>%t - same as %n.</li>
60
- * <li>%T - same as %H:%M:%S.</li>
61
- * <li>%x - locale's equivalent to %m/%d/%y.</li>
62
- * <li>%X - locale's equivalent to %I:%M:%S %p.</li>
63
- *
64
- * </ul>
65
- *
66
- * @see <a
67
- * href="http://www.opengroup.org/onlinepubs/007908799/xsh/strftime.html">strftime</a>
68
- * documentation.
69
- * @see <a
70
- * href="http://www.opengroup.org/onlinepubs/007908799/xsh/strptime.html">strptime</a>
71
- * documentation.
72
- * @extends pv.Format
73
- * @param {string} pattern the format pattern.
74
- */
75
- pv.Format.date = function(pattern) {
76
- var pad = pv.Format.pad;
77
-
78
- /** @private */
79
- function format(d) {
80
- return pattern.replace(/%[a-zA-Z0-9]/g, function(s) {
81
- switch (s) {
82
- case '%a': return [
83
- "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
84
- ][d.getDay()];
85
- case '%A': return [
86
- "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
87
- "Saturday"
88
- ][d.getDay()];
89
- case '%h':
90
- case '%b': return [
91
- "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
92
- "Oct", "Nov", "Dec"
93
- ][d.getMonth()];
94
- case '%B': return [
95
- "January", "February", "March", "April", "May", "June", "July",
96
- "August", "September", "October", "November", "December"
97
- ][d.getMonth()];
98
- case '%c': return d.toLocaleString();
99
- case '%C': return pad("0", 2, Math.floor(d.getFullYear() / 100) % 100);
100
- case '%d': return pad("0", 2, d.getDate());
101
- case '%x':
102
- case '%D': return pad("0", 2, d.getMonth() + 1)
103
- + "/" + pad("0", 2, d.getDate())
104
- + "/" + pad("0", 2, d.getFullYear() % 100);
105
- case '%e': return pad(" ", 2, d.getDate());
106
- case '%H': return pad("0", 2, d.getHours());
107
- case '%I': {
108
- var h = d.getHours() % 12;
109
- return h ? pad("0", 2, h) : 12;
110
- }
111
- // TODO %j: day of year as a decimal number [001,366]
112
- case '%m': return pad("0", 2, d.getMonth() + 1);
113
- case '%M': return pad("0", 2, d.getMinutes());
114
- case '%n': return "\n";
115
- case '%p': return d.getHours() < 12 ? "AM" : "PM";
116
- case '%T':
117
- case '%X':
118
- case '%r': {
119
- var h = d.getHours() % 12;
120
- return (h ? pad("0", 2, h) : 12)
121
- + ":" + pad("0", 2, d.getMinutes())
122
- + ":" + pad("0", 2, d.getSeconds())
123
- + " " + (d.getHours() < 12 ? "AM" : "PM");
124
- }
125
- case '%R': return pad("0", 2, d.getHours()) + ":" + pad("0", 2, d.getMinutes());
126
- case '%S': return pad("0", 2, d.getSeconds());
127
- case '%Q': return pad("0", 3, d.getMilliseconds());
128
- case '%t': return "\t";
129
- case '%u': {
130
- var w = d.getDay();
131
- return w ? w : 1;
132
- }
133
- // TODO %U: week number (sunday first day) [00,53]
134
- // TODO %V: week number (monday first day) [01,53] ... with weirdness
135
- case '%w': return d.getDay();
136
- // TODO %W: week number (monday first day) [00,53] ... with weirdness
137
- case '%y': return pad("0", 2, d.getFullYear() % 100);
138
- case '%Y': return d.getFullYear();
139
- // TODO %Z: timezone name or abbreviation
140
- case '%%': return "%";
141
- }
142
- return s;
143
- });
144
- }
145
-
146
- /**
147
- * Converts a date to a string using the associated formatting pattern.
148
- *
149
- * @function
150
- * @name pv.Format.date.prototype.format
151
- * @param {Date} date a date to format.
152
- * @returns {string} the formatted date as a string.
153
- */
154
- format.format = format;
155
-
156
- /**
157
- * Parses a date from a string using the associated formatting pattern.
158
- *
159
- * @function
160
- * @name pv.Format.date.prototype.parse
161
- * @param {string} s the string to parse as a date.
162
- * @returns {Date} the parsed date.
163
- */
164
- format.parse = function(s) {
165
- var year = 1970, month = 0, date = 1, hour = 0, minute = 0, second = 0;
166
- var fields = [function() {}];
167
-
168
- /* Register callbacks for each field in the format pattern. */
169
- var re = pv.Format.re(pattern).replace(/%[a-zA-Z0-9]/g, function(s) {
170
- switch (s) {
171
- // TODO %a: day of week, either abbreviated or full name
172
- // TODO %A: same as %a
173
- case '%b': {
174
- fields.push(function(x) { month = {
175
- Jan: 0, Feb: 1, Mar: 2, Apr: 3, May: 4, Jun: 5, Jul: 6, Aug: 7,
176
- Sep: 8, Oct: 9, Nov: 10, Dec: 11
177
- }[x]; });
178
- return "([A-Za-z]+)";
179
- }
180
- case '%h':
181
- case '%B': {
182
- fields.push(function(x) { month = {
183
- January: 0, February: 1, March: 2, April: 3, May: 4, June: 5,
184
- July: 6, August: 7, September: 8, October: 9, November: 10,
185
- December: 11
186
- }[x]; });
187
- return "([A-Za-z]+)";
188
- }
189
- // TODO %c: locale's appropriate date and time
190
- // TODO %C: century number[0,99]
191
- case '%e':
192
- case '%d': {
193
- fields.push(function(x) { date = x; });
194
- return "([0-9]+)";
195
- }
196
- // TODO %D: same as %m/%d/%y
197
- case '%I':
198
- case '%H': {
199
- fields.push(function(x) { hour = x; });
200
- return "([0-9]+)";
201
- }
202
- // TODO %j: day number [1,366]
203
- case '%m': {
204
- fields.push(function(x) { month = x - 1; });
205
- return "([0-9]+)";
206
- }
207
- case '%M': {
208
- fields.push(function(x) { minute = x; });
209
- return "([0-9]+)";
210
- }
211
- // TODO %n: any white space
212
- // TODO %p: locale's equivalent of a.m. or p.m.
213
- case '%p': { // TODO this is a hack
214
- fields.push(function(x) {
215
- if (hour == 12) {
216
- if (x == "am") hour = 0;
217
- } else if (x == "pm") {
218
- hour = Number(hour) + 12;
219
- }
220
- });
221
- return "(am|pm)";
222
- }
223
- // TODO %r: %I:%M:%S %p
224
- // TODO %R: %H:%M
225
- case '%S': {
226
- fields.push(function(x) { second = x; });
227
- return "([0-9]+)";
228
- }
229
- // TODO %t: any white space
230
- // TODO %T: %H:%M:%S
231
- // TODO %U: week number [00,53]
232
- // TODO %w: weekday [0,6]
233
- // TODO %W: week number [00, 53]
234
- // TODO %x: locale date (%m/%d/%y)
235
- // TODO %X: locale time (%I:%M:%S %p)
236
- case '%y': {
237
- fields.push(function(x) {
238
- x = Number(x);
239
- year = x + (((0 <= x) && (x < 69)) ? 2000
240
- : (((x >= 69) && (x < 100) ? 1900 : 0)));
241
- });
242
- return "([0-9]+)";
243
- }
244
- case '%Y': {
245
- fields.push(function(x) { year = x; });
246
- return "([0-9]+)";
247
- }
248
- case '%%': {
249
- fields.push(function() {});
250
- return "%";
251
- }
252
- }
253
- return s;
254
- });
255
-
256
- var match = s.match(re);
257
- if (match) match.forEach(function(m, i) { fields[i](m); });
258
- return new Date(year, month, date, hour, minute, second);
259
- };
260
-
261
- return format;
262
- };