function d3_transition(groups, id, time) { d3_arraySubclass(groups, d3_transitionPrototype); var tweens = {}, event = d3.dispatch("start", "end"), 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]; else tweens[name] = tween; return groups; }; groups.ease = function(value) { if (!arguments.length) return ease; ease = typeof value === "function" ? value : d3.ease.apply(d3, arguments); return groups; }; groups.each = function(type, listener) { if (arguments.length < 2) return d3_transition_each.call(groups, type); event.on(type, listener); return groups; }; d3.timer(function(elapsed) { groups.each(function(d, i, j) { var tweened = [], node = this, delay = groups[j][i].delay, duration = groups[j][i].duration, lock = node.__transition__ || (node.__transition__ = {active: 0, count: 0}); ++lock.count; delay <= elapsed ? start(elapsed) : d3.timer(start, delay, time); function start(elapsed) { if (lock.active > id) return stop(); lock.active = id; for (var tween in tweens) { if (tween = tweens[tween].call(node, d, i)) { tweened.push(tween); } } event.start.call(node, d, i); if (!tick(elapsed)) d3.timer(tick, 0, time); return 1; } function tick(elapsed) { if (lock.active !== id) return stop(); var t = (elapsed - delay) / duration, e = ease(t), n = tweened.length; while (n > 0) { tweened[--n].call(node, e); } if (t >= 1) { stop(); d3_transitionInheritId = id; event.end.call(node, d, i); d3_transitionInheritId = 0; return 1; } } function stop() { if (!--lock.count) delete node.__transition__; return 1; } }); return 1; }, 0, time); return groups; } var d3_transitionRemove = {}; function d3_transitionNull(d, i, a) { return a != "" && d3_transitionRemove; } function d3_transitionTween(name, b) { var interpolate = d3_interpolateByName(name); function transitionFunction(d, i, a) { var v = b.call(this, d, i); return v == null ? a != "" && d3_transitionRemove : a != v && interpolate(a, v); } function transitionString(d, i, a) { return a != b && interpolate(a, b); } return typeof b === "function" ? transitionFunction : b == null ? d3_transitionNull : (b += "", transitionString); } var d3_transitionPrototype = [], d3_transitionId = 0, d3_transitionInheritId = 0, d3_transitionEase = d3.ease("cubic-in-out"); d3_transitionPrototype.call = d3_selectionPrototype.call; d3.transition = function() { return d3_selectionRoot.transition(); }; d3.transition.prototype = d3_transitionPrototype;