Commit a83ff054 authored by Mike Bostock's avatar Mike Bostock
Browse files

Merge branch '3.3.3'

parents fc5a5864 e67138ac
{
"name": "d3",
"version": "3.3.2",
"version": "3.3.3",
"main": "d3.js",
"scripts": [
"d3.js"
......
......@@ -10,7 +10,7 @@
"animation",
"canvas"
],
"version": "3.3.2",
"version": "3.3.3",
"main": "index-browserify.js",
"scripts": [
"d3.js",
......
d3 = function() {
var d3 = {
version: "3.3.2"
version: "3.3.3"
};
if (!Date.now) Date.now = function() {
return +new Date();
......@@ -1088,13 +1088,9 @@ d3 = function() {
d3_mouse_bug44083 = !(ctm.f || ctm.e);
svg.remove();
}
if (d3_mouse_bug44083) {
point.x = e.pageX;
point.y = e.pageY;
} else {
point.x = e.clientX;
point.y = e.clientY;
}
if (e.changedTouches) e = e.changedTouches[0];
if (d3_mouse_bug44083) point.x = e.pageX, point.y = e.pageY; else point.x = e.clientX,
point.y = e.clientY;
point = point.matrixTransform(container.getScreenCTM().inverse());
return [ point.x, point.y ];
}
......@@ -1205,7 +1201,7 @@ d3 = function() {
x: 0,
y: 0,
k: 1
}, translate0, center, size = [ 960, 500 ], scaleExtent = d3_behavior_zoomInfinity, mousedown = "mousedown.zoom", mousemove = "mousemove.zoom", mouseup = "mouseup.zoom", mousewheelTimer, touchstart = "touchstart.zoom", touchmove = "touchmove.zoom", touchend = "touchend.zoom", touchtime, event = d3_eventDispatch(zoom, "zoomstart", "zoom", "zoomend"), x0, x1, y0, y1;
}, translate0, center, size = [ 960, 500 ], scaleExtent = d3_behavior_zoomInfinity, mousedown = "mousedown.zoom", mousemove = "mousemove.zoom", mouseup = "mouseup.zoom", mousewheelTimer, touchstart = "touchstart.zoom", touchtime, event = d3_eventDispatch(zoom, "zoomstart", "zoom", "zoomend"), x0, x1, y0, y1;
function zoom(g) {
g.on(mousedown, mousedowned).on(d3_behavior_zoomWheel + ".zoom", mousewheeled).on(mousemove, mousewheelreset).on("dblclick.zoom", dblclicked).on(touchstart, touchstarted);
}
......@@ -1355,21 +1351,24 @@ d3 = function() {
}
}
function touchstarted() {
var target = this, event_ = event.of(target, arguments), locations0, distance0 = 0, scale0, w = d3.select(d3_window).on(touchmove, moved).on(touchend, ended), t = d3.select(target).on(mousedown, null).on(touchstart, started), dragRestore = d3_event_dragSuppress();
var target = this, event_ = event.of(target, arguments), locations0 = {}, distance0 = 0, scale0, eventId = d3.event.changedTouches[0].identifier, touchmove = "touchmove.zoom-" + eventId, touchend = "touchend.zoom-" + eventId, w = d3.select(d3_window).on(touchmove, moved).on(touchend, ended), t = d3.select(target).on(mousedown, null).on(touchstart, started), dragRestore = d3_event_dragSuppress();
d3_selection_interrupt.call(target);
started();
zoomstarted(event_);
function relocate() {
var touches = d3.touches(target);
scale0 = view.k;
locations0 = {};
touches.forEach(function(t) {
locations0[t.identifier] = location(t);
if (t.identifier in locations0) locations0[t.identifier] = location(t);
});
return touches;
}
function started() {
var now = Date.now(), touches = relocate();
var changed = d3.event.changedTouches;
for (var i = 0, n = changed.length; i < n; ++i) {
locations0[changed[i].identifier] = null;
}
var touches = relocate(), now = Date.now();
if (touches.length === 1) {
if (now - touchtime < 500) {
var p = touches[0], l = locations0[p.identifier];
......@@ -1385,13 +1384,16 @@ d3 = function() {
}
}
function moved() {
var touches = d3.touches(target), p0 = touches[0], l0 = locations0[p0.identifier];
if (p1 = touches[1]) {
var p1, l1 = locations0[p1.identifier], scale1 = d3.event.scale;
if (scale1 == null) {
var distance1 = (distance1 = p1[0] - p0[0]) * distance1 + (distance1 = p1[1] - p0[1]) * distance1;
scale1 = distance0 && Math.sqrt(distance1 / distance0);
var touches = d3.touches(target), p0, l0, p1, l1;
for (var i = 0, n = touches.length; i < n; ++i, l1 = null) {
p1 = touches[i];
if (l1 = locations0[p1.identifier]) {
if (l0) break;
p0 = p1, l0 = l1;
}
}
if (l1) {
var distance1 = (distance1 = p1[0] - p0[0]) * distance1 + (distance1 = p1[1] - p0[1]) * distance1, scale1 = distance0 && Math.sqrt(distance1 / distance0);
p0 = [ (p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2 ];
l0 = [ (l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2 ];
scaleTo(scale1 * scale0);
......@@ -1402,13 +1404,18 @@ d3 = function() {
}
function ended() {
if (d3.event.touches.length) {
relocate();
} else {
w.on(touchmove, null).on(touchend, null);
t.on(mousedown, mousedowned).on(touchstart, touchstarted);
dragRestore();
zoomended(event_);
var changed = d3.event.changedTouches;
for (var i = 0, n = changed.length; i < n; ++i) {
delete locations0[changed[i].identifier];
}
for (var identifier in locations0) {
return void relocate();
}
}
w.on(touchmove, null).on(touchend, null);
t.on(mousedown, mousedowned).on(touchstart, touchstarted);
dragRestore();
zoomended(event_);
}
}
function mousewheeled() {
......@@ -8118,7 +8125,7 @@ d3 = function() {
g.selectAll(".extent,.e>rect,.w>rect").attr("height", yExtent[1] - yExtent[0]);
}
function brushstart() {
var target = this, eventTarget = d3.select(d3.event.target), event_ = event.of(target, arguments), g = d3.select(target), resizing = eventTarget.datum(), resizingX = !/^(n|s)$/.test(resizing) && x, resizingY = !/^(e|w)$/.test(resizing) && y, dragging = eventTarget.classed("extent"), dragRestore = d3_event_dragSuppress(), center, origin = mouse(), offset;
var target = this, eventTarget = d3.select(d3.event.target), event_ = event.of(target, arguments), g = d3.select(target), resizing = eventTarget.datum(), resizingX = !/^(n|s)$/.test(resizing) && x, resizingY = !/^(e|w)$/.test(resizing) && y, dragging = eventTarget.classed("extent"), dragRestore = d3_event_dragSuppress(), center, origin = d3.mouse(target), offset;
var w = d3.select(d3_window).on("keydown.brush", keydown).on("keyup.brush", keyup);
if (d3.event.changedTouches) {
w.on("touchmove.brush", brushmove).on("touchend.brush", brushend);
......@@ -8141,10 +8148,6 @@ d3 = function() {
type: "brushstart"
});
brushmove();
function mouse() {
var touches = d3.event.changedTouches;
return touches ? d3.touches(target, touches)[0] : d3.mouse(target);
}
function keydown() {
if (d3.event.keyCode == 32) {
if (!dragging) {
......@@ -8165,7 +8168,7 @@ d3 = function() {
}
}
function brushmove() {
var point = mouse(), moved = false;
var point = d3.mouse(target), moved = false;
if (offset) {
point[0] += offset[0];
point[1] += offset[1];
......@@ -8513,17 +8516,18 @@ d3 = function() {
H: 0,
M: 0,
S: 0,
L: 0
L: 0,
Z: null
}, i = d3_time_parse(d, template, string, 0);
if (i != string.length) return null;
if ("p" in d) d.H = d.H % 12 + d.p * 12;
var date = new d3_date();
var localZ = d.Z != null && d3_date !== d3_date_utc, date = new (localZ ? d3_date_utc : d3_date)();
if ("j" in d) date.setFullYear(d.y, 0, d.j); else if ("w" in d && ("W" in d || "U" in d)) {
date.setFullYear(d.y, 0, 1);
date.setFullYear(d.y, 0, "W" in d ? (d.w + 6) % 7 + d.W * 7 - (date.getDay() + 5) % 7 : d.w + d.U * 7 - (date.getDay() + 6) % 7);
} else date.setFullYear(d.y, d.m, d.d);
date.setHours(d.H, d.M, d.S, d.L);
return date;
date.setHours(d.H + Math.floor(d.Z / 100), d.M + d.Z % 100, d.S, d.L);
return localZ ? date._ : date;
};
format.toString = function() {
return template;
......@@ -8652,6 +8656,7 @@ d3 = function() {
X: d3_time_parseLocaleTime,
y: d3_time_parseYear,
Y: d3_time_parseFullYear,
Z: d3_time_parseZone,
"%": d3_time_parseLiteralPercent
};
function d3_time_parseWeekdayAbbrev(date, string, i) {
......@@ -8708,6 +8713,10 @@ d3 = function() {
var n = d3_time_numberRe.exec(string.substring(i, i + 2));
return n ? (date.y = d3_time_expandYear(+n[0]), i + n[0].length) : -1;
}
function d3_time_parseZone(date, string, i) {
return /^[+-]\d{4}$/.test(string = string.substring(i, i + 5)) ? (date.Z = +string,
i + 5) : -1;
}
function d3_time_expandYear(d) {
return d + (d > 68 ? 1900 : 2e3);
}
......
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "d3",
"version": "3.3.2",
"version": "3.3.3",
"description": "A small, free JavaScript library for manipulating documents based on data.",
"keywords": [
"dom",
......
......@@ -19,8 +19,6 @@ d3.behavior.zoom = function() {
mouseup = "mouseup.zoom",
mousewheelTimer,
touchstart = "touchstart.zoom",
touchmove = "touchmove.zoom",
touchend = "touchend.zoom",
touchtime, // time of last touchstart (to detect double-tap)
event = d3_eventDispatch(zoom, "zoomstart", "zoom", "zoomend"),
x0,
......@@ -186,9 +184,12 @@ d3.behavior.zoom = function() {
function touchstarted() {
var target = this,
event_ = event.of(target, arguments),
locations0, // touchstart locations
locations0 = {}, // touchstart locations
distance0 = 0, // distance² between initial touches
scale0, // scale when we started touching
eventId = d3.event.changedTouches[0].identifier,
touchmove = "touchmove.zoom-" + eventId,
touchend = "touchend.zoom-" + eventId,
w = d3.select(d3_window).on(touchmove, moved).on(touchend, ended),
t = d3.select(target).on(mousedown, null).on(touchstart, started), // prevent duplicate events
dragRestore = d3_event_dragSuppress();
......@@ -197,18 +198,26 @@ d3.behavior.zoom = function() {
started();
zoomstarted(event_);
// Updates locations of any touches in locations0.
function relocate() {
var touches = d3.touches(target);
scale0 = view.k;
locations0 = {};
touches.forEach(function(t) { locations0[t.identifier] = location(t); });
touches.forEach(function(t) {
if (t.identifier in locations0) locations0[t.identifier] = location(t);
});
return touches;
}
// Temporarily override touchstart while gesture is active.
function started() {
var now = Date.now(),
touches = relocate();
// Only track touches started on the target element.
var changed = d3.event.changedTouches;
for (var i = 0, n = changed.length; i < n; ++i) {
locations0[changed[i].identifier] = null;
}
var touches = relocate(),
now = Date.now();
if (touches.length === 1) {
if (now - touchtime < 500) { // dbltap
......@@ -228,16 +237,19 @@ d3.behavior.zoom = function() {
function moved() {
var touches = d3.touches(target),
p0 = touches[0],
l0 = locations0[p0.identifier];
if (p1 = touches[1]) {
var p1, l1 = locations0[p1.identifier],
scale1 = d3.event.scale;
if (scale1 == null) {
var distance1 = (distance1 = p1[0] - p0[0]) * distance1 + (distance1 = p1[1] - p0[1]) * distance1;
scale1 = distance0 && Math.sqrt(distance1 / distance0);
p0, l0,
p1, l1;
for (var i = 0, n = touches.length; i < n; ++i, l1 = null) {
p1 = touches[i];
if (l1 = locations0[p1.identifier]) {
if (l0) break;
p0 = p1, l0 = l1;
}
}
if (l1) {
var distance1 = (distance1 = p1[0] - p0[0]) * distance1 + (distance1 = p1[1] - p0[1]) * distance1,
scale1 = distance0 && Math.sqrt(distance1 / distance0);
p0 = [(p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2];
l0 = [(l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2];
scaleTo(scale1 * scale0);
......@@ -249,14 +261,24 @@ d3.behavior.zoom = function() {
}
function ended() {
// If there are any globally-active touches remaining, remove the ended
// touches from locations0.
if (d3.event.touches.length) {
relocate(); // locations may have detached due to rotation
} else {
w.on(touchmove, null).on(touchend, null);
t.on(mousedown, mousedowned).on(touchstart, touchstarted);
dragRestore();
zoomended(event_);
var changed = d3.event.changedTouches;
for (var i = 0, n = changed.length; i < n; ++i) {
delete locations0[changed[i].identifier];
}
// If locations0 is not empty, then relocate and continue listening for
// touchmove and touchend.
for (var identifier in locations0) {
return void relocate(); // locations may have detached due to rotation
}
}
// Otherwise, remove touchmove and touchend listeners.
w.on(touchmove, null).on(touchend, null);
t.on(mousedown, mousedowned).on(touchstart, touchstarted);
dragRestore();
zoomended(event_);
}
}
......
......@@ -24,13 +24,9 @@ function d3_mousePoint(container, e) {
d3_mouse_bug44083 = !(ctm.f || ctm.e);
svg.remove();
}
if (d3_mouse_bug44083) {
point.x = e.pageX;
point.y = e.pageY;
} else {
point.x = e.clientX;
point.y = e.clientY;
}
if (e.changedTouches) e = e.changedTouches[0];
if (d3_mouse_bug44083) point.x = e.pageX, point.y = e.pageY;
else point.x = e.clientX, point.y = e.clientY;
point = point.matrixTransform(container.getScreenCTM().inverse());
return [point.x, point.y];
}
......
d3 = (function(){
var d3 = {version: "3.3.2"}; // semver
var d3 = {version: "3.3.3"}; // semver
......@@ -154,7 +154,7 @@ d3.svg.brush = function() {
dragging = eventTarget.classed("extent"),
dragRestore = d3_event_dragSuppress(),
center,
origin = mouse(),
origin = d3.mouse(target),
offset;
var w = d3.select(d3_window)
......@@ -198,11 +198,6 @@ d3.svg.brush = function() {
event_({type: "brushstart"});
brushmove();
function mouse() {
var touches = d3.event.changedTouches;
return touches ? d3.touches(target, touches)[0] : d3.mouse(target);
}
function keydown() {
if (d3.event.keyCode == 32) {
if (!dragging) {
......@@ -225,7 +220,7 @@ d3.svg.brush = function() {
}
function brushmove() {
var point = mouse(),
var point = d3.mouse(target),
moved = false;
// Preserve the offset for thick resizers.
......
......@@ -31,14 +31,19 @@ function d3_time_format(template) {
}
format.parse = function(string) {
var d = {y: 1900, m: 0, d: 1, H: 0, M: 0, S: 0, L: 0},
var d = {y: 1900, m: 0, d: 1, H: 0, M: 0, S: 0, L: 0, Z: null},
i = d3_time_parse(d, template, string, 0);
if (i != string.length) return null;
// The am-pm flag is 0 for AM, and 1 for PM.
if ("p" in d) d.H = d.H % 12 + d.p * 12;
var date = new d3_date;
// If a time zone is specified, it is always relative to UTC;
// we need to use d3_date_utc if we aren’t already.
var localZ = d.Z != null && d3_date !== d3_date_utc,
date = new (localZ ? d3_date_utc : d3_date);
// Set year, month, date.
if ("j" in d) date.setFullYear(d.y, 0, d.j);
else if ("w" in d && ("W" in d || "U" in d)) {
date.setFullYear(d.y, 0, 1);
......@@ -46,8 +51,11 @@ function d3_time_format(template) {
? (d.w + 6) % 7 + d.W * 7 - (date.getDay() + 5) % 7
: d.w + d.U * 7 - (date.getDay() + 6) % 7);
} else date.setFullYear(d.y, d.m, d.d);
date.setHours(d.H, d.M, d.S, d.L);
return date;
// Set hours, minutes, seconds and milliseconds.
date.setHours(d.H + Math.floor(d.Z / 100), d.M + d.Z % 100, d.S, d.L);
return localZ ? date._ : date;
};
format.toString = function() {
......@@ -161,7 +169,7 @@ var d3_time_parsers = {
X: d3_time_parseLocaleTime,
y: d3_time_parseYear,
Y: d3_time_parseFullYear,
// Z: function(d, s, i) { /*TODO time zone */ return i; },
Z: d3_time_parseZone,
"%": d3_time_parseLiteralPercent
};
......@@ -231,6 +239,12 @@ function d3_time_parseYear(date, string, i) {
return n ? (date.y = d3_time_expandYear(+n[0]), i + n[0].length) : -1;
}
function d3_time_parseZone(date, string, i) {
return /^[+-]\d{4}$/.test(string = string.substring(i, i + 5))
? (date.Z = +string, i + 5)
: -1;
}
function d3_time_expandYear(d) {
return d + (d > 68 ? 1900 : 2000);
}
......
......@@ -284,6 +284,12 @@ suite.addBatch({
assert.deepEqual(p("% 02/03/1991"), local(1991, 1, 3));
assert.isNull(p("%% 03/10/2010"));
},
"parses timezone offset": function(format) {
var p = format("%m/%d/%Y %Z").parse;
assert.deepEqual(p("01/02/1990 +0000"), local(1990, 0, 1, 16));
assert.deepEqual(p("01/02/1990 +0100"), local(1990, 0, 1, 17));
assert.deepEqual(p("01/02/1990 -0100"), local(1990, 0, 1, 15));
},
"ignores optional padding modifier, skipping zeroes and spaces": function(format) {
var p = format("%-m/%0d/%_Y").parse;
assert.deepEqual(p("01/ 1/1990"), local(1990, 0, 1));
......
......@@ -211,6 +211,12 @@ suite.addBatch({
assert.deepEqual(p("12:00:00 pm"), utc(1900, 0, 1, 12, 0, 0));
assert.deepEqual(p("12:00:01 pm"), utc(1900, 0, 1, 12, 0, 1));
assert.deepEqual(p("11:59:59 PM"), utc(1900, 0, 1, 23, 59, 59));
},
"parses timezone offset": function(format) {
var p = format("%m/%d/%Y %Z").parse;
assert.deepEqual(p("01/02/1990 +0000"), utc(1990, 0, 2));
assert.deepEqual(p("01/02/1990 +0100"), utc(1990, 0, 2, 1));
assert.deepEqual(p("01/02/1990 -0100"), utc(1990, 0, 1, 23));
}
}
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment