rubyvis 0.6.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +16 -0
- data/.travis.yml +13 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +37 -0
- data/History.txt +6 -0
- data/LICENSE.txt +23 -0
- data/{README.txt → README.md} +15 -12
- data/Rakefile +4 -11
- data/lib/rubyvis.rb +1 -1
- data/lib/rubyvis/scale/quantitative.rb +14 -18
- data/lib/rubyvis/scene/svg_label.rb +1 -1
- data/rubyvis.gemspec +21 -0
- data/spec/anchor_spec.rb +2 -1
- data/spec/line_spec.rb +2 -2
- data/spec/scale_linear_datetime_spec.rb +23 -8
- data/spec/spec_helper.rb +2 -1
- metadata +31 -214
- data/.gemtest +0 -0
- data/vendor/protovis/protovis-r3.3.js +0 -287
- data/vendor/protovis/src/behavior/Behavior.js +0 -32
- data/vendor/protovis/src/behavior/Drag.js +0 -112
- data/vendor/protovis/src/behavior/Pan.js +0 -110
- data/vendor/protovis/src/behavior/Point.js +0 -157
- data/vendor/protovis/src/behavior/Resize.js +0 -104
- data/vendor/protovis/src/behavior/Select.js +0 -100
- data/vendor/protovis/src/behavior/Zoom.js +0 -85
- data/vendor/protovis/src/color/Color.js +0 -598
- data/vendor/protovis/src/color/Colors.js +0 -135
- data/vendor/protovis/src/color/Ramp.js +0 -17
- data/vendor/protovis/src/data/Arrays.js +0 -277
- data/vendor/protovis/src/data/Dom.js +0 -380
- data/vendor/protovis/src/data/Flatten.js +0 -146
- data/vendor/protovis/src/data/Histogram.js +0 -120
- data/vendor/protovis/src/data/LinearScale.js +0 -54
- data/vendor/protovis/src/data/LogScale.js +0 -142
- data/vendor/protovis/src/data/Nest.js +0 -257
- data/vendor/protovis/src/data/Numbers.js +0 -313
- data/vendor/protovis/src/data/Objects.js +0 -78
- data/vendor/protovis/src/data/OrdinalScale.js +0 -267
- data/vendor/protovis/src/data/QuantileScale.js +0 -180
- data/vendor/protovis/src/data/QuantitativeScale.js +0 -440
- data/vendor/protovis/src/data/RootScale.js +0 -55
- data/vendor/protovis/src/data/Scale.js +0 -86
- data/vendor/protovis/src/data/Transform.js +0 -109
- data/vendor/protovis/src/data/Tree.js +0 -124
- data/vendor/protovis/src/data/Vector.js +0 -118
- data/vendor/protovis/src/geo/Geo.js +0 -5
- data/vendor/protovis/src/geo/GeoScale.js +0 -307
- data/vendor/protovis/src/geo/LatLng.js +0 -23
- data/vendor/protovis/src/geo/Projection.js +0 -43
- data/vendor/protovis/src/geo/Projections.js +0 -117
- data/vendor/protovis/src/lang/Array.js +0 -112
- data/vendor/protovis/src/lang/init.js +0 -26
- data/vendor/protovis/src/layout/Arc.js +0 -178
- data/vendor/protovis/src/layout/Bullet.js +0 -164
- data/vendor/protovis/src/layout/Cluster.js +0 -205
- data/vendor/protovis/src/layout/Force.js +0 -309
- data/vendor/protovis/src/layout/Grid.js +0 -119
- data/vendor/protovis/src/layout/Hierarchy.js +0 -249
- data/vendor/protovis/src/layout/Horizon.js +0 -159
- data/vendor/protovis/src/layout/Indent.js +0 -83
- data/vendor/protovis/src/layout/Layout.js +0 -56
- data/vendor/protovis/src/layout/Matrix.js +0 -177
- data/vendor/protovis/src/layout/Network.js +0 -302
- data/vendor/protovis/src/layout/Pack.js +0 -323
- data/vendor/protovis/src/layout/Partition.js +0 -203
- data/vendor/protovis/src/layout/Rollup.js +0 -203
- data/vendor/protovis/src/layout/Stack.js +0 -391
- data/vendor/protovis/src/layout/Tree.js +0 -282
- data/vendor/protovis/src/layout/Treemap.js +0 -347
- data/vendor/protovis/src/mark/Anchor.js +0 -81
- data/vendor/protovis/src/mark/Area.js +0 -268
- data/vendor/protovis/src/mark/Bar.js +0 -93
- data/vendor/protovis/src/mark/Dot.js +0 -212
- data/vendor/protovis/src/mark/Ease.js +0 -150
- data/vendor/protovis/src/mark/Image.js +0 -154
- data/vendor/protovis/src/mark/Label.js +0 -155
- data/vendor/protovis/src/mark/Line.js +0 -195
- data/vendor/protovis/src/mark/Mark.js +0 -1237
- data/vendor/protovis/src/mark/Panel.js +0 -273
- data/vendor/protovis/src/mark/Rule.js +0 -143
- data/vendor/protovis/src/mark/Transient.js +0 -7
- data/vendor/protovis/src/mark/Transition.js +0 -195
- data/vendor/protovis/src/mark/Wedge.js +0 -244
- data/vendor/protovis/src/physics/BoundConstraint.js +0 -75
- data/vendor/protovis/src/physics/ChargeForce.js +0 -184
- data/vendor/protovis/src/physics/CollisionConstraint.js +0 -113
- data/vendor/protovis/src/physics/Constraint.js +0 -26
- data/vendor/protovis/src/physics/DragForce.js +0 -49
- data/vendor/protovis/src/physics/Force.js +0 -25
- data/vendor/protovis/src/physics/Particle.js +0 -81
- data/vendor/protovis/src/physics/PositionConstraint.js +0 -72
- data/vendor/protovis/src/physics/Quadtree.js +0 -195
- data/vendor/protovis/src/physics/Simulation.js +0 -159
- data/vendor/protovis/src/physics/SpringForce.js +0 -141
- data/vendor/protovis/src/pv-internals.js +0 -154
- data/vendor/protovis/src/pv.js +0 -95
- data/vendor/protovis/src/scene/SvgArea.js +0 -172
- data/vendor/protovis/src/scene/SvgBar.js +0 -28
- data/vendor/protovis/src/scene/SvgCurve.js +0 -354
- data/vendor/protovis/src/scene/SvgDot.js +0 -81
- data/vendor/protovis/src/scene/SvgImage.js +0 -45
- data/vendor/protovis/src/scene/SvgLabel.js +0 -46
- data/vendor/protovis/src/scene/SvgLine.js +0 -159
- data/vendor/protovis/src/scene/SvgPanel.js +0 -126
- data/vendor/protovis/src/scene/SvgRule.js +0 -26
- data/vendor/protovis/src/scene/SvgScene.js +0 -185
- data/vendor/protovis/src/scene/SvgWedge.js +0 -66
- data/vendor/protovis/src/text/DateFormat.js +0 -262
- data/vendor/protovis/src/text/Format.js +0 -78
- data/vendor/protovis/src/text/NumberFormat.js +0 -227
- 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
|
-
};
|