@plotly/d3
Version:
162 lines (136 loc) • 4.04 kB
JavaScript
import "../arrays/map";
import "../core/subclass";
import "../core/true";
import "../event/dispatch";
import "../event/timer";
import "../selection/selection";
import "../selection/transition";
import "../selection/interrupt";
function d3_transition(groups, ns, id) {
d3_subclass(groups, d3_transitionPrototype);
// Note: read-only!
groups.namespace = ns;
groups.id = id;
return groups;
}
var d3_transitionPrototype = [],
d3_transitionId = 0,
d3_transitionInheritId,
d3_transitionInherit;
d3_transitionPrototype.call = d3_selectionPrototype.call;
d3_transitionPrototype.empty = d3_selectionPrototype.empty;
d3_transitionPrototype.node = d3_selectionPrototype.node;
d3_transitionPrototype.size = d3_selectionPrototype.size;
d3.transition = function(selection, name) {
return selection && selection.transition
? (d3_transitionInheritId ? selection.transition(name) : selection)
: d3.selection().transition(selection);
};
d3.transition.prototype = d3_transitionPrototype;
import "select";
import "selectAll";
import "filter";
import "attr";
import "style";
import "text";
import "remove";
import "ease";
import "delay";
import "duration";
import "each";
import "subtransition";
import "tween";
function d3_transitionNamespace(name) {
return name == null ? "__transition__" : "__transition_" + name + "__";
}
function d3_transitionNode(node, i, ns, id, inherit) {
var lock = node[ns] || (node[ns] = {active: 0, count: 0}),
transition = lock[id],
time,
timer,
duration,
ease,
tweens;
function schedule(elapsed) {
var delay = transition.delay;
timer.t = delay + time;
if (delay <= elapsed) return start(elapsed - delay);
timer.c = start;
}
function start(elapsed) {
// Interrupt the active transition, if any.
var activeId = lock.active,
active = lock[activeId];
if (active) {
active.timer.c = null;
active.timer.t = NaN;
--lock.count;
delete lock[activeId];
active.event && active.event.interrupt.call(node, node.__data__, active.index);
}
// Cancel any pre-empted transitions. No interrupt event is dispatched
// because the cancelled transitions never started.
for (var cancelId in lock) {
if (+cancelId < id) {
var cancel = lock[cancelId];
cancel.timer.c = null;
cancel.timer.t = NaN;
--lock.count;
delete lock[cancelId];
}
}
// Defer tween invocation to end of current frame; see mbostock/d3#1576.
// Note that this transition may be canceled before then!
// This must be scheduled before the start event; see d3/d3-transition#16!
timer.c = tick;
d3_timer(function() {
if (timer.c && tick(elapsed || 1)) {
timer.c = null;
timer.t = NaN;
}
return 1;
}, 0, time);
// Start the transition.
lock.active = id;
transition.event && transition.event.start.call(node, node.__data__, i);
// Initialize the tweens.
tweens = [];
transition.tween.forEach(function(key, value) {
if (value = value.call(node, node.__data__, i)) {
tweens.push(value);
}
});
// Defer capture to allow tween initialization to set ease & duration.
ease = transition.ease;
duration = transition.duration;
}
function tick(elapsed) {
var t = elapsed / duration,
e = ease(t),
n = tweens.length;
while (n > 0) {
tweens[--n].call(node, e);
}
if (t >= 1) {
transition.event && transition.event.end.call(node, node.__data__, i);
if (--lock.count) delete lock[id];
else delete node[ns];
return 1;
}
}
if (!transition) {
time = inherit.time;
timer = d3_timer(schedule, 0, time);
transition = lock[id] = {
tween: new d3_Map,
time: time,
timer: timer,
delay: inherit.delay,
duration: inherit.duration,
ease: inherit.ease,
index: i
};
inherit = null; // allow gc
++lock.count;
}
}