Permalink
Browse files

Consistent timing for subtransitions.

It was previously possible for small differences in the reference time for
subtransitions. This could lead to tearing with expensive transitions, as some
transitions would have slightly different reference times than the others. This
is fixed by passing the reference time along explicitly when deriving a new
transition, either by the transition or selection operators.
  • Loading branch information...
1 parent c623877 commit 3f3569cc71ed074fa4b9f521f40f3fc489aabec9 @mbostock mbostock committed Oct 14, 2011
View
21 d3.js
@@ -10,7 +10,7 @@ try {
d3_style_setProperty.call(this, name, value + "", priority);
};
}
-d3 = {version: "2.4.3"}; // semver
+d3 = {version: "2.4.4"}; // semver
var d3_array = d3_arraySlice; // conversion for NodeLists
function d3_arrayCopy(pseudoarray) {
@@ -1824,7 +1824,7 @@ d3_selectionPrototype.transition = function() {
}
}
- return d3_transition(subgroups, d3_transitionInheritId || ++d3_transitionId);
+ return d3_transition(subgroups, d3_transitionInheritId || ++d3_transitionId, Date.now());
};
var d3_selectionRoot = d3_selection([[document]]);
@@ -1844,16 +1844,17 @@ d3.selectAll = function(selector) {
? d3_selectionRoot.selectAll(selector)
: d3_selection([d3_array(selector)]); // assume node[]
};
-function d3_transition(groups, id) {
+function d3_transition(groups, id, time) {
d3_arraySubclass(groups, d3_transitionPrototype);
var tweens = {},
event = d3.dispatch("start", "end"),
- ease = d3_transitionEase,
- then = Date.now();
+ ease = d3_transitionEase;
groups.id = id;
+ groups.time = time;
+
groups.tween = function(name, tween) {
if (arguments.length < 2) return tweens[name];
if (tween == null) delete tweens[name];
@@ -1883,7 +1884,7 @@ function d3_transition(groups, id) {
++lock.count;
- delay <= elapsed ? start(elapsed) : d3.timer(start, delay, then);
+ delay <= elapsed ? start(elapsed) : d3.timer(start, delay, time);
function start(elapsed) {
if (lock.active > id) return stop();
@@ -1896,7 +1897,7 @@ function d3_transition(groups, id) {
}
event.start.dispatch.call(node, d, i);
- if (!tick(elapsed)) d3.timer(tick, 0, then);
+ if (!tick(elapsed)) d3.timer(tick, 0, time);
return 1;
}
@@ -1926,7 +1927,7 @@ function d3_transition(groups, id) {
}
});
return 1;
- }, 0, then);
+ }, 0, time);
return groups;
}
@@ -1987,7 +1988,7 @@ d3_transitionPrototype.select = function(selector) {
}
}
- return d3_transition(subgroups, this.id).ease(this.ease());
+ return d3_transition(subgroups, this.id, this.time).ease(this.ease());
};
d3_transitionPrototype.selectAll = function(selector) {
var subgroups = [],
@@ -2009,7 +2010,7 @@ d3_transitionPrototype.selectAll = function(selector) {
}
}
- return d3_transition(subgroups, this.id).ease(this.ease());
+ return d3_transition(subgroups, this.id, this.time).ease(this.ease());
};
d3_transitionPrototype.attr = function(name, value) {
return this.attrTween(name, d3_transitionTween(value));
View
4 d3.min.js
2 additions, 2 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
2 package.json
@@ -1,6 +1,6 @@
{
"name": "d3",
- "version": "2.4.3",
+ "version": "2.4.4",
"description": "A small, free JavaScript library for manipulating documents based on data.",
"keywords": [
"dom",
View
2 src/core/core.js
@@ -1 +1 @@
-d3 = {version: "2.4.3"}; // semver
+d3 = {version: "2.4.4"}; // semver
View
2 src/core/selection-transition.js
@@ -10,5 +10,5 @@ d3_selectionPrototype.transition = function() {
}
}
- return d3_transition(subgroups, d3_transitionInheritId || ++d3_transitionId);
+ return d3_transition(subgroups, d3_transitionInheritId || ++d3_transitionId, Date.now());
};
View
2 src/core/transition-select.js
@@ -18,5 +18,5 @@ d3_transitionPrototype.select = function(selector) {
}
}
- return d3_transition(subgroups, this.id).ease(this.ease());
+ return d3_transition(subgroups, this.id, this.time).ease(this.ease());
};
View
2 src/core/transition-selectAll.js
@@ -18,5 +18,5 @@ d3_transitionPrototype.selectAll = function(selector) {
}
}
- return d3_transition(subgroups, this.id).ease(this.ease());
+ return d3_transition(subgroups, this.id, this.time).ease(this.ease());
};
View
13 src/core/transition.js
@@ -1,13 +1,14 @@
-function d3_transition(groups, id) {
+function d3_transition(groups, id, time) {
d3_arraySubclass(groups, d3_transitionPrototype);
var tweens = {},
event = d3.dispatch("start", "end"),
- ease = d3_transitionEase,
- then = Date.now();
+ ease = d3_transitionEase;
groups.id = id;
+ groups.time = time;
+
groups.tween = function(name, tween) {
if (arguments.length < 2) return tweens[name];
if (tween == null) delete tweens[name];
@@ -37,7 +38,7 @@ function d3_transition(groups, id) {
++lock.count;
- delay <= elapsed ? start(elapsed) : d3.timer(start, delay, then);
+ delay <= elapsed ? start(elapsed) : d3.timer(start, delay, time);
function start(elapsed) {
if (lock.active > id) return stop();
@@ -50,7 +51,7 @@ function d3_transition(groups, id) {
}
event.start.dispatch.call(node, d, i);
- if (!tick(elapsed)) d3.timer(tick, 0, then);
+ if (!tick(elapsed)) d3.timer(tick, 0, time);
return 1;
}
@@ -80,7 +81,7 @@ function d3_transition(groups, id) {
}
});
return 1;
- }, 0, then);
+ }, 0, time);
return groups;
}
View
36 test/core/transition-test-time.js
@@ -0,0 +1,36 @@
+require("../env");
+require("../../d3");
+
+var assert = require("assert");
+
+module.exports = {
+ topic: function() {
+ return d3.select("body").append("div").transition();
+ },
+ "is approximately equal to now": function(transition) {
+ var time = transition.time;
+ assert.inDelta(time, Date.now(), 20);
+ },
+ "increases monotonically across transitions": function(transition) {
+ var now = Date.now, then = Date.now();
+ try {
+ Date.now = function() { return ++then; };
+ var t0 = d3.select("body").append("div").transition(),
+ t1 = d3.select("body").append("div").transition();
+ assert.isTrue(t1.time > t0.time);
+ } finally {
+ Date.now = now;
+ }
+ },
+ "is inherited by subtransitions": function(transition) {
+ var now = Date.now, then = Date.now();
+ try {
+ Date.now = function() { return ++then; };
+ var t0 = d3.select("body").append("div").transition(),
+ t1 = t0.transition();
+ assert.equal(t1.time, t0.time);
+ } finally {
+ Date.now = now;
+ }
+ }
+};
View
3 test/core/transition-test.js
@@ -58,7 +58,8 @@ suite.addBatch({
"each": require("./transition-test-each"),
"call": require("./transition-test-call"),
"tween": require("./transition-test-tween"),
- "id": require("./transition-test-id")
+ "id": require("./transition-test-id"),
+ "time": require("./transition-test-time")
});

0 comments on commit 3f3569c

Please sign in to comment.