d3-transition
Advanced tools
Comparing version 0.2.5 to 0.2.6
(function (global, factory) { | ||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-selection'), require('d3-interpolate'), require('d3-dispatch'), require('d3-timer'), require('d3-ease')) : | ||
typeof define === 'function' && define.amd ? define(['exports', 'd3-selection', 'd3-interpolate', 'd3-dispatch', 'd3-timer', 'd3-ease'], factory) : | ||
(factory((global.d3_transition = global.d3_transition || {}),global.d3_selection,global.d3_interpolate,global.d3_dispatch,global.d3_timer,global.d3_ease)); | ||
}(this, function (exports,d3Selection,d3Interpolate,d3Dispatch,d3Timer,d3Ease) { 'use strict'; | ||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-selection'), require('d3-dispatch'), require('d3-timer'), require('d3-interpolate'), require('d3-color'), require('d3-ease')) : | ||
typeof define === 'function' && define.amd ? define(['exports', 'd3-selection', 'd3-dispatch', 'd3-timer', 'd3-interpolate', 'd3-color', 'd3-ease'], factory) : | ||
(factory((global.d3_transition = global.d3_transition || {}),global.d3_selection,global.d3_dispatch,global.d3_timer,global.d3_interpolate,global.d3_color,global.d3_ease)); | ||
}(this, function (exports,d3Selection,d3Dispatch,d3Timer,d3Interpolate,d3Color,d3Ease) { 'use strict'; | ||
var version = "0.2.6"; | ||
var emptyOn = d3Dispatch.dispatch("start", "end", "interrupt"); | ||
@@ -12,9 +14,13 @@ var emptyTween = []; | ||
var SCHEDULED = 1; | ||
var STARTED = 2; | ||
function schedule(node, key, id, index, group, timing) { | ||
var schedules = node[key]; | ||
if (!schedules) node[key] = schedules = {active: null, pending: []}; | ||
else if (has(node, key, id)) return; | ||
start(node, key, { | ||
id: id, | ||
var STARTING = 2; | ||
var STARTED = 3; | ||
var ENDING = 4; | ||
var ENDED = 5; | ||
function schedule(node, name, id, index, group, timing) { | ||
var schedules = node.__transition; | ||
if (!schedules) node.__transition = {}; | ||
else if (id in schedules) return; | ||
create(node, id, { | ||
name: name, | ||
index: index, // For context during callback. | ||
@@ -33,31 +39,22 @@ group: group, // For context during callback. | ||
function has(node, key, id) { | ||
var schedules = node[key]; | ||
if (!schedules) return; | ||
var schedule = schedules.active; | ||
if (schedule && schedule.id === id) return schedule; | ||
var pending = schedules.pending, i = pending.length; | ||
while (--i >= 0) if ((schedule = pending[i]).id === id) return schedule; | ||
} | ||
function init(node, key, id) { | ||
var schedule = has(node, key, id); | ||
if (!schedule || schedule.state > CREATED) throw new Error("too late"); | ||
function init(node, id) { | ||
var schedule = node.__transition; | ||
if (!schedule || !(schedule = schedule[id]) || schedule.state > CREATED) throw new Error("too late"); | ||
return schedule; | ||
} | ||
function set(node, key, id) { | ||
var schedule = has(node, key, id); | ||
if (!schedule || schedule.state > SCHEDULED) throw new Error("too late"); | ||
function set(node, id) { | ||
var schedule = node.__transition; | ||
if (!schedule || !(schedule = schedule[id]) || schedule.state > STARTING) throw new Error("too late"); | ||
return schedule; | ||
} | ||
function get(node, key, id) { | ||
var schedule = has(node, key, id); | ||
if (!schedule) throw new Error("too late"); | ||
function get(node, id) { | ||
var schedule = node.__transition; | ||
if (!schedule || !(schedule = schedule[id])) throw new Error("too late"); | ||
return schedule; | ||
} | ||
function start(node, key, self) { | ||
var schedules = node[key], | ||
function create(node, id, self) { | ||
var schedules = node.__transition, | ||
tween; | ||
@@ -67,3 +64,3 @@ | ||
// Note the actual delay is not known until the first callback! | ||
schedules.pending.push(self); | ||
schedules[id] = self; | ||
self.timer = d3Timer.timer(schedule, 0, self.time); | ||
@@ -80,26 +77,27 @@ | ||
function start(elapsed) { | ||
var interrupted = schedules.active, | ||
pending = schedules.pending, | ||
i, j, n, o; | ||
var i, j, n, o; | ||
// Interrupt the active transition, if any. | ||
// Dispatch the interrupt event. | ||
if (interrupted) { | ||
interrupted.timer.stop(); | ||
interrupted.on.call("interrupt", node, node.__data__, interrupted.index, interrupted.group); | ||
} | ||
for (i in schedules) { | ||
o = schedules[i]; | ||
if (o.name !== self.name) continue; | ||
// Cancel any pre-empted transitions. No interrupt event is dispatched | ||
// because the cancelled transitions never started. Note that this also | ||
// removes this transition from the pending list! | ||
for (i = 0, j = -1, n = pending.length; i < n; ++i) { | ||
o = pending[i]; | ||
if (o.id < self.id) o.timer.stop(); | ||
else if (o.id > self.id) pending[++j] = o; | ||
// Interrupt the active transition, if any. | ||
// Dispatch the interrupt event. | ||
if (o.state === STARTED) { | ||
o.state = ENDED; | ||
o.timer.stop(); | ||
o.on.call("interrupt", node, node.__data__, o.index, o.group); | ||
delete schedules[i]; | ||
} | ||
// Cancel any pre-empted transitions. No interrupt event is dispatched | ||
// because the cancelled transitions never started. Note that this also | ||
// removes this transition from the pending list! | ||
else if (+i < id) { | ||
o.state = ENDED; | ||
o.timer.stop(); | ||
delete schedules[i]; | ||
} | ||
} | ||
pending.length = j + 1; | ||
// Mark this transition as active. | ||
schedules.active = self; | ||
// Defer the first tick to end of the current frame; see mbostock/d3#1576. | ||
@@ -110,3 +108,3 @@ // Note the transition may be canceled after start and before the first tick! | ||
d3Timer.timeout(function() { | ||
if (schedules.active === self) { | ||
if (self.state === STARTED) { | ||
self.timer.restart(tick, self.delay, self.time); | ||
@@ -119,3 +117,5 @@ tick(elapsed); | ||
// Note this must be done before the tween are initialized. | ||
self.state = STARTING; | ||
self.on.call("start", node, node.__data__, self.index, self.group); | ||
if (self.state !== STARTING) return; // interrupted | ||
self.state = STARTED; | ||
@@ -134,16 +134,17 @@ | ||
function tick(elapsed) { | ||
var t = elapsed / self.duration, | ||
e = t >= 1 ? 1 : self.ease.call(null, t), | ||
i, n; | ||
var t = elapsed < self.duration ? self.ease.call(null, elapsed / self.duration) : (self.state = ENDING, 1), | ||
i = -1, | ||
n = tween.length; | ||
for (i = 0, n = tween.length; i < n; ++i) { | ||
tween[i].call(null, e); | ||
while (++i < n) { | ||
tween[i].call(null, t); | ||
} | ||
// Dispatch the end event. | ||
if (t >= 1) { | ||
if (self.state === ENDING) { | ||
self.state = ENDED; | ||
self.timer.stop(); | ||
self.on.call("end", node, node.__data__, self.index, self.group); | ||
schedules.active = null; | ||
if (!schedules.pending.length) delete node[key]; | ||
self.timer.stop(); | ||
for (i in schedules) if (+i !== id) return void delete schedules[id]; | ||
delete node.__transition; | ||
} | ||
@@ -153,6 +154,30 @@ } | ||
function tweenFunction(key, id, name, value) { | ||
function selection_interrupt(name) { | ||
name = name == null ? null : name + ""; | ||
return this.each(function() { | ||
var schedules = this.__transition, | ||
schedule, | ||
active, | ||
empty = true, | ||
i; | ||
if (!schedules) return; | ||
for (i in schedules) { | ||
if ((schedule = schedules[i]).name !== name) { empty = false; continue; } | ||
active = schedule.state === STARTED; | ||
schedule.state = ENDED; | ||
schedule.timer.stop(); | ||
if (active) schedule.on.call("interrupt", this, this.__data__, schedule.index, schedule.group); | ||
delete schedules[i]; | ||
} | ||
if (empty) delete this.__transition; | ||
}); | ||
} | ||
function tweenFunction(id, name, value) { | ||
var tween0, tween1; | ||
return function() { | ||
var schedule = set(this, key, id), | ||
var schedule = set(this, id), | ||
tween = schedule.tween; | ||
@@ -179,4 +204,3 @@ | ||
function transition_tween(name, value) { | ||
var key = this._key, | ||
id = this._id; | ||
var id = this._id; | ||
@@ -186,3 +210,3 @@ name += ""; | ||
if (arguments.length < 2) { | ||
var tween = get(this.node(), key, id).tween; | ||
var tween = get(this.node(), id).tween; | ||
for (var i = 0, n = tween.length, t; i < n; ++i) { | ||
@@ -197,19 +221,26 @@ if ((t = tween[i]).name === name) { | ||
if (typeof value !== "function") throw new Error; | ||
return this.each(tweenFunction(key, id, name, value)); | ||
return this.each(tweenFunction(id, name, value)); | ||
} | ||
function tweenValue(transition, name, value) { | ||
var key = transition._key, | ||
id = transition._id; | ||
var id = transition._id; | ||
transition.each(function() { | ||
var schedule = set(this, key, id), v = value.apply(this, arguments); | ||
(schedule.value || (schedule.value = {}))[name] = v == null ? null : v + ""; | ||
var schedule = set(this, id); | ||
(schedule.value || (schedule.value = {}))[name] = value.apply(this, arguments); | ||
}); | ||
return function(node) { | ||
return get(node, key, id).value[name]; | ||
return get(node, id).value[name]; | ||
}; | ||
} | ||
function interpolate(a, b) { | ||
var c; | ||
return (typeof b === "number" ? d3Interpolate.interpolateNumber | ||
: b instanceof d3Color.color ? d3Interpolate.interpolateRgb | ||
: (c = d3Color.color(b)) ? (b = c, d3Interpolate.interpolateRgb) | ||
: d3Interpolate.interpolateString)(a, b); | ||
} | ||
function attrRemove(name) { | ||
@@ -278,7 +309,7 @@ return function() { | ||
function transition_attr(name, value) { | ||
var fullname = d3Selection.namespace(name), i = fullname === "transform" ? d3Interpolate.interpolateTransformSvg : d3Interpolate.interpolate; | ||
var fullname = d3Selection.namespace(name), i = fullname === "transform" ? d3Interpolate.interpolateTransformSvg : interpolate; | ||
return this.attrTween(name, typeof value === "function" | ||
? (fullname.local ? attrFunctionNS : attrFunction)(fullname, i, tweenValue(this, "attr." + name, value)) | ||
: value == null ? (fullname.local ? attrRemoveNS : attrRemove)(fullname) | ||
: (fullname.local ? attrConstantNS : attrConstant)(fullname, i, value + "")); | ||
: (fullname.local ? attrConstantNS : attrConstant)(fullname, i, value)); | ||
} | ||
@@ -318,11 +349,11 @@ | ||
function delayFunction(key, id, value) { | ||
function delayFunction(id, value) { | ||
return function() { | ||
init(this, key, id).delay = +value.apply(this, arguments); | ||
init(this, id).delay = +value.apply(this, arguments); | ||
}; | ||
} | ||
function delayConstant(key, id, value) { | ||
function delayConstant(id, value) { | ||
return value = +value, function() { | ||
init(this, key, id).delay = value; | ||
init(this, id).delay = value; | ||
}; | ||
@@ -332,4 +363,3 @@ } | ||
function transition_delay(value) { | ||
var key = this._key, | ||
id = this._id; | ||
var id = this._id; | ||
@@ -339,15 +369,15 @@ return arguments.length | ||
? delayFunction | ||
: delayConstant)(key, id, value)) | ||
: get(this.node(), key, id).delay; | ||
: delayConstant)(id, value)) | ||
: get(this.node(), id).delay; | ||
} | ||
function durationFunction(key, id, value) { | ||
function durationFunction(id, value) { | ||
return function() { | ||
set(this, key, id).duration = +value.apply(this, arguments); | ||
set(this, id).duration = +value.apply(this, arguments); | ||
}; | ||
} | ||
function durationConstant(key, id, value) { | ||
function durationConstant(id, value) { | ||
return value = +value, function() { | ||
set(this, key, id).duration = value; | ||
set(this, id).duration = value; | ||
}; | ||
@@ -357,4 +387,3 @@ } | ||
function transition_duration(value) { | ||
var key = this._key, | ||
id = this._id; | ||
var id = this._id; | ||
@@ -364,10 +393,10 @@ return arguments.length | ||
? durationFunction | ||
: durationConstant)(key, id, value)) | ||
: get(this.node(), key, id).duration; | ||
: durationConstant)(id, value)) | ||
: get(this.node(), id).duration; | ||
} | ||
function easeConstant(key, id, value) { | ||
function easeConstant(id, value) { | ||
if (typeof value !== "function") throw new Error; | ||
return function() { | ||
set(this, key, id).ease = value; | ||
set(this, id).ease = value; | ||
}; | ||
@@ -377,8 +406,7 @@ } | ||
function transition_ease(value) { | ||
var key = this._key, | ||
id = this._id; | ||
var id = this._id; | ||
return arguments.length | ||
? this.each(easeConstant(key, id, value)) | ||
: get(this.node(), key, id).ease; | ||
? this.each(easeConstant(id, value)) | ||
: get(this.node(), id).ease; | ||
} | ||
@@ -397,8 +425,9 @@ | ||
return new Transition(subgroups, this._parents, this._key, this._id); | ||
return new Transition(subgroups, this._parents, this._name, this._id); | ||
} | ||
function transition_merge(selection) { | ||
function transition_merge(transition) { | ||
if (transition._id !== this._id) throw new Error; | ||
for (var groups0 = this._groups, groups1 = selection._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) { | ||
for (var groups0 = this._groups, groups1 = transition._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) { | ||
for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) { | ||
@@ -415,6 +444,6 @@ if (node = group0[i] || group1[i]) { | ||
return new Transition(merges, this._parents, this._key, this._id); | ||
return new Transition(merges, this._parents, this._name, this._id); | ||
} | ||
function start$1(name) { | ||
function start(name) { | ||
return (name + "").trim().split(/^|\s+/).every(function(t) { | ||
@@ -427,7 +456,7 @@ var i = t.indexOf("."); | ||
function onFunction(key, id, name, listener) { | ||
function onFunction(id, name, listener) { | ||
if (typeof listener !== "function") throw new Error; | ||
var on0, on1, sit = start$1(name) ? init : set; | ||
var on0, on1, sit = start(name) ? init : set; | ||
return function() { | ||
var schedule = sit(this, key, id), | ||
var schedule = sit(this, id), | ||
on = schedule.on; | ||
@@ -445,14 +474,14 @@ | ||
function transition_on(name, listener) { | ||
var key = this._key, | ||
id = this._id; | ||
var id = this._id; | ||
return arguments.length < 2 | ||
? get(this.node(), key, id).on.on(name) | ||
: this.each(onFunction(key, id, name, listener)); | ||
? get(this.node(), id).on.on(name) | ||
: this.each(onFunction(id, name, listener)); | ||
} | ||
function removeFunction(key) { | ||
function removeFunction(id) { | ||
return function() { | ||
var parent = this.parentNode; | ||
if (parent && !this[key].pending.length) parent.removeChild(this); | ||
for (var i in this.__transition) if (+i !== id) return; | ||
if (parent) parent.removeChild(this); | ||
}; | ||
@@ -462,7 +491,7 @@ } | ||
function transition_remove() { | ||
return this.on("end.remove", removeFunction(this._key)); | ||
return this.on("end.remove", removeFunction(this._id)); | ||
} | ||
function transition_select(select) { | ||
var key = this._key, | ||
var name = this._name, | ||
id = this._id; | ||
@@ -477,3 +506,3 @@ | ||
subgroup[i] = subnode; | ||
schedule(subgroup[i], key, id, i, subgroup, get(node, key, id)); | ||
schedule(subgroup[i], name, id, i, subgroup, get(node, id)); | ||
} | ||
@@ -483,7 +512,7 @@ } | ||
return new Transition(subgroups, this._parents, key, id); | ||
return new Transition(subgroups, this._parents, name, id); | ||
} | ||
function transition_selectAll(select) { | ||
var key = this._key, | ||
var name = this._name, | ||
id = this._id; | ||
@@ -496,5 +525,5 @@ | ||
if (node = group[i]) { | ||
for (var children = select.call(node, node.__data__, i, group), child, inherit = get(node, key, id), k = 0, l = children.length; k < l; ++k) { | ||
for (var children = select.call(node, node.__data__, i, group), child, inherit = get(node, id), k = 0, l = children.length; k < l; ++k) { | ||
if (child = children[k]) { | ||
schedule(child, key, id, k, children, inherit); | ||
schedule(child, name, id, k, children, inherit); | ||
} | ||
@@ -508,3 +537,3 @@ } | ||
return new Transition(subgroups, parents, key, id); | ||
return new Transition(subgroups, parents, name, id); | ||
} | ||
@@ -565,3 +594,3 @@ | ||
function transition_style(name, value, priority) { | ||
var i = (name += "") === "transform" ? d3Interpolate.interpolateTransformCss : d3Interpolate.interpolate; | ||
var i = (name += "") === "transform" ? d3Interpolate.interpolateTransformCss : interpolate; | ||
return value == null ? this | ||
@@ -572,3 +601,3 @@ .styleTween(name, styleRemove(name, i)) | ||
? styleFunction(name, i, tweenValue(this, "style." + name, value)) | ||
: styleConstant(name, i, value + ""), priority); | ||
: styleConstant(name, i, value), priority); | ||
} | ||
@@ -589,3 +618,3 @@ | ||
function transition_styleTween(name, value, priority) { | ||
var key = "style." + name; | ||
var key = "style." + (name += ""); | ||
return arguments.length < 2 | ||
@@ -616,3 +645,3 @@ ? (key = this.tween(key)) && key._value | ||
function transition_transition() { | ||
var key = this._key, | ||
var name = this._name, | ||
id0 = this._id, | ||
@@ -624,4 +653,4 @@ id1 = newId(); | ||
if (node = group[i]) { | ||
var inherit = get(node, key, id0); | ||
schedule(node, key, id1, i, group, { | ||
var inherit = get(node, id0); | ||
schedule(node, name, id1, i, group, { | ||
time: inherit.time + inherit.delay + inherit.duration, | ||
@@ -636,3 +665,3 @@ delay: 0, | ||
return new Transition(groups, this._parents, key, id1); | ||
return new Transition(groups, this._parents, name, id1); | ||
} | ||
@@ -642,6 +671,6 @@ | ||
function Transition(groups, parents, key, id) { | ||
function Transition(groups, parents, name, id) { | ||
this._groups = groups; | ||
this._parents = parents; | ||
this._key = key; | ||
this._name = name; | ||
this._id = id; | ||
@@ -658,6 +687,2 @@ } | ||
function namekey(name) { | ||
return name ? "__transition" + name : "__transition"; | ||
} | ||
var selection_prototype = d3Selection.selection.prototype; | ||
@@ -692,24 +717,2 @@ | ||
function selection_interrupt(name) { | ||
var key = namekey(name); | ||
return this.each(function() { | ||
var schedule = this[key]; | ||
if (schedule) { | ||
var pending = schedule.pending, | ||
active = schedule.active, | ||
i, n; | ||
if (active) { | ||
active.on.call("interrupt", this, this.__data__, active.index, active.group); // TODO try-catch? | ||
schedule.active = null; | ||
active.timer.stop(); | ||
} | ||
for (i = 0, n = pending.length; i < n; ++i) { | ||
pending[i].timer.stop(); | ||
} | ||
pending.length = 0; | ||
delete this[key]; | ||
} | ||
}); | ||
} | ||
var defaultTiming = { | ||
@@ -723,10 +726,9 @@ time: null, // Set on use. | ||
function selection_transition(name) { | ||
var key, | ||
id, | ||
var id, | ||
timing; | ||
if (name instanceof Transition) { | ||
key = name._key, id = name._id, timing = get(name.node(), key, id); | ||
id = name._id, timing = get(name.node(), id), name = name._name; | ||
} else { | ||
key = namekey(name), id = newId(), (timing = defaultTiming).time = d3Timer.now(); | ||
id = newId(), (timing = defaultTiming).time = d3Timer.now(), name = name == null ? null : name + ""; | ||
} | ||
@@ -737,3 +739,3 @@ | ||
if (node = group[i]) { | ||
schedule(node, key, id, i, group, timing); | ||
schedule(node, name, id, i, group, timing); | ||
} | ||
@@ -743,3 +745,3 @@ } | ||
return new Transition(groups, this._parents, key, id); | ||
return new Transition(groups, this._parents, name, id); | ||
} | ||
@@ -753,9 +755,18 @@ | ||
function active(node, name) { | ||
var key = namekey(name), active = node[key]; | ||
if (!active || !(active = active.active)) return null; | ||
return new Transition([[node]], root, key, active.id); | ||
var schedules = node.__transition, | ||
schedule, | ||
i; | ||
if (schedules) { | ||
name = name == null ? null : name + ""; | ||
for (i in schedules) { | ||
if ((schedule = schedules[i]).state > SCHEDULED && schedule.name === name) { | ||
return new Transition([[node]], root, name, +i); | ||
} | ||
} | ||
} | ||
return null; | ||
} | ||
var version = "0.2.5"; | ||
exports.version = version; | ||
@@ -762,0 +773,0 @@ exports.transition = transition; |
@@ -1,1 +0,1 @@ | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("d3-selection"),require("d3-interpolate"),require("d3-dispatch"),require("d3-timer"),require("d3-ease")):"function"==typeof define&&define.amd?define(["exports","d3-selection","d3-interpolate","d3-dispatch","d3-timer","d3-ease"],e):e(t.d3_transition=t.d3_transition||{},t.d3_selection,t.d3_interpolate,t.d3_dispatch,t.d3_timer,t.d3_ease)}(this,function(t,e,n,r,i,o){"use strict";function u(t,e,n,r,i,o){var u=t[e];if(u){if(a(t,e,n))return}else t[e]=u={active:null,pending:[]};f(t,e,{id:n,index:r,group:i,on:at,tween:st,time:o.time,delay:o.delay,duration:o.duration,ease:o.ease,timer:null,state:lt})}function a(t,e,n){var r=t[e];if(r){var i=r.active;if(i&&i.id===n)return i;for(var o=r.pending,u=o.length;--u>=0;)if((i=o[u]).id===n)return i}}function s(t,e,n){var r=a(t,e,n);if(!r||r.state>lt)throw new Error("too late");return r}function l(t,e,n){var r=a(t,e,n);if(!r||r.state>ct)throw new Error("too late");return r}function c(t,e,n){var r=a(t,e,n);if(!r)throw new Error("too late");return r}function f(t,e,n){function r(t){n.state=ct,n.delay<=t?o(t-n.delay):n.timer.restart(o,n.delay,n.time)}function o(e){var r,o,l,c,f=s.active,h=s.pending;for(f&&(f.timer.stop(),f.on.call("interrupt",t,t.__data__,f.index,f.group)),r=0,o=-1,l=h.length;l>r;++r)c=h[r],c.id<n.id?c.timer.stop():c.id>n.id&&(h[++o]=c);for(h.length=o+1,s.active=n,i.timeout(function(){s.active===n&&(n.timer.restart(u,n.delay,n.time),u(e))}),n.on.call("start",t,t.__data__,n.index,n.group),n.state=ft,a=new Array(l=n.tween.length),r=0,o=-1;l>r;++r)(c=n.tween[r].value.call(t,t.__data__,n.index,n.group))&&(a[++o]=c);a.length=o+1}function u(r){var i,o,u=r/n.duration,l=u>=1?1:n.ease.call(null,u);for(i=0,o=a.length;o>i;++i)a[i].call(null,l);u>=1&&(n.on.call("end",t,t.__data__,n.index,n.group),s.active=null,s.pending.length||delete t[e],n.timer.stop())}var a,s=t[e];s.pending.push(n),n.timer=i.timer(r,0,n.time)}function h(t,e,n,r){var i,o;return function(){var u=l(this,t,e),a=u.tween;if(a!==i){o=(i=a).slice();for(var s={name:n,value:r},c=0,f=o.length;f>c;++c)if(o[c].name===n){o[c]=s;break}c===f&&o.push(s)}u.tween=o}}function d(t,e){var n=this._key,r=this._id;if(t+="",arguments.length<2){for(var i,o=c(this.node(),n,r).tween,u=0,a=o.length;a>u;++u)if((i=o[u]).name===t)return i.value;return null}if("function"!=typeof e)throw new Error;return this.each(h(n,r,t,e))}function p(t,e,n){var r=t._key,i=t._id;return t.each(function(){var t=l(this,r,i),o=n.apply(this,arguments);(t.value||(t.value={}))[e]=null==o?null:o+""}),function(t){return c(t,r,i).value[e]}}function v(t){return function(){this.removeAttribute(t)}}function _(t){return function(){this.removeAttributeNS(t.space,t.local)}}function y(t,e,n){var r,i;return function(){var o=this.getAttribute(t);return o===n?null:o===r?i:i=e(r=o,n)}}function g(t,e,n){var r,i;return function(){var o=this.getAttributeNS(t.space,t.local);return o===n?null:o===r?i:i=e(r=o,n)}}function w(t,e,n){var r,i,o;return function(){var u,a=n(this);return null==a?void this.removeAttribute(t):(u=this.getAttribute(t),u===a?null:u===r&&a===i?o:o=e(r=u,i=a))}}function m(t,e,n){var r,i,o;return function(){var u,a=n(this);return null==a?void this.removeAttributeNS(t.space,t.local):(u=this.getAttributeNS(t.space,t.local),u===a?null:u===r&&a===i?o:o=e(r=u,i=a))}}function A(t,r){var i=e.namespace(t),o="transform"===i?n.interpolateTransformSvg:n.interpolate;return this.attrTween(t,"function"==typeof r?(i.local?m:w)(i,o,p(this,"attr."+t,r)):null==r?(i.local?_:v)(i):(i.local?g:y)(i,o,r+""))}function k(t,e){function n(){var n=this,r=e.apply(n,arguments);return r&&function(e){n.setAttributeNS(t.space,t.local,r(e))}}return n._value=e,n}function x(t,e){function n(){var n=this,r=e.apply(n,arguments);return r&&function(e){n.setAttribute(t,r(e))}}return n._value=e,n}function b(t,n){var r="attr."+t;if(arguments.length<2)return(r=this.tween(r))&&r._value;if("function"!=typeof n)throw new Error;var i=e.namespace(t);return this.tween(r,(i.local?k:x)(i,n))}function P(t,e,n){return function(){s(this,t,e).delay=+n.apply(this,arguments)}}function S(t,e,n){return n=+n,function(){s(this,t,e).delay=n}}function C(t){var e=this._key,n=this._id;return arguments.length?this.each(("function"==typeof t?P:S)(e,n,t)):c(this.node(),e,n).delay}function E(t,e,n){return function(){l(this,t,e).duration=+n.apply(this,arguments)}}function T(t,e,n){return n=+n,function(){l(this,t,e).duration=n}}function N(t){var e=this._key,n=this._id;return arguments.length?this.each(("function"==typeof t?E:T)(e,n,t)):c(this.node(),e,n).duration}function q(t,e,n){if("function"!=typeof n)throw new Error;return function(){l(this,t,e).ease=n}}function V(t){var e=this._key,n=this._id;return arguments.length?this.each(q(e,n,t)):c(this.node(),e,n).ease}function z(t){"function"!=typeof t&&(t=e.matcher(t));for(var n=this._groups,r=n.length,i=new Array(r),o=0;r>o;++o)for(var u,a=n[o],s=a.length,l=i[o]=new Array(s),c=0;s>c;++c)(u=a[c])&&t.call(u,u.__data__,c,a)&&(l[c]=u);return new tt(i,this._parents,this._key,this._id)}function O(t){for(var e=this._groups,n=t._groups,r=e.length,i=n.length,o=Math.min(r,i),u=new Array(r),a=0;o>a;++a)for(var s,l=e[a],c=n[a],f=l.length,h=u[a]=new Array(f),d=0;f>d;++d)(s=l[d]||c[d])&&(h[d]=s);for(;r>a;++a)u[a]=e[a];return new tt(u,this._parents,this._key,this._id)}function j(t){return(t+"").trim().split(/^|\s+/).every(function(t){var e=t.indexOf(".");return e>=0&&(t=t.slice(0,e)),!t||"start"===t})}function I(t,e,n,r){if("function"!=typeof r)throw new Error;var i,o,u=j(n)?s:l;return function(){var a=u(this,t,e),s=a.on;s!==i&&(o=(i=s).copy()).on(n,r),a.on=o}}function M(t,e){var n=this._key,r=this._id;return arguments.length<2?c(this.node(),n,r).on.on(t):this.each(I(n,r,t,e))}function B(t){return function(){var e=this.parentNode;e&&!this[t].pending.length&&e.removeChild(this)}}function D(){return this.on("end.remove",B(this._key))}function F(t){var n=this._key,r=this._id;"function"!=typeof t&&(t=e.selector(t));for(var i=this._groups,o=i.length,a=new Array(o),s=0;o>s;++s)for(var l,f,h=i[s],d=h.length,p=a[s]=new Array(d),v=0;d>v;++v)(l=h[v])&&(f=t.call(l,l.__data__,v,h))&&("__data__"in l&&(f.__data__=l.__data__),p[v]=f,u(p[v],n,r,v,p,c(l,n,r)));return new tt(a,this._parents,n,r)}function G(t){var n=this._key,r=this._id;"function"!=typeof t&&(t=e.selectorAll(t));for(var i=this._groups,o=i.length,a=[],s=[],l=0;o>l;++l)for(var f,h=i[l],d=h.length,p=0;d>p;++p)if(f=h[p]){for(var v,_=t.call(f,f.__data__,p,h),y=c(f,n,r),g=0,w=_.length;w>g;++g)(v=_[g])&&u(v,n,r,g,_,y);a.push(_),s.push(f)}return new tt(a,s,n,r)}function H(){return new ht(this._groups,this._parents)}function J(t,n){var r,i,o;return function(){var u=e.window(this).getComputedStyle(this,null),a=u.getPropertyValue(t),s=(this.style.removeProperty(t),u.getPropertyValue(t));return a===s?null:a===r&&s===i?o:o=n(r=a,i=s)}}function K(t){return function(){this.style.removeProperty(t)}}function L(t,n,r){var i,o;return function(){var u=e.window(this).getComputedStyle(this,null).getPropertyValue(t);return u===r?null:u===i?o:o=n(i=u,r)}}function Q(t,n,r){var i,o,u;return function(){var a=e.window(this).getComputedStyle(this,null),s=a.getPropertyValue(t),l=r(this);return null==l&&(this.style.removeProperty(t),l=a.getPropertyValue(t)),s===l?null:s===i&&l===o?u:u=n(i=s,o=l)}}function R(t,e,r){var i="transform"==(t+="")?n.interpolateTransformCss:n.interpolate;return null==e?this.styleTween(t,J(t,i)).on("end.style."+t,K(t)):this.styleTween(t,"function"==typeof e?Q(t,i,p(this,"style."+t,e)):L(t,i,e+""),r)}function U(t,e,n){function r(){var r=this,i=e.apply(r,arguments);return i&&function(e){r.style.setProperty(t,i(e),n)}}if("function"!=typeof e)throw new Error;return r._value=e,r}function W(t,e,n){var r="style."+t;return arguments.length<2?(r=this.tween(r))&&r._value:this.tween(r,U(t,e,null==n?"":n))}function X(t){return function(){this.textContent=t}}function Y(t){return function(){var e=t(this);this.textContent=null==e?"":e}}function Z(t){return this.tween("text","function"==typeof t?Y(p(this,"text",t)):X(null==t?"":t+""))}function $(){for(var t=this._key,e=this._id,n=nt(),r=this._groups,i=r.length,o=0;i>o;++o)for(var a,s=r[o],l=s.length,f=0;l>f;++f)if(a=s[f]){var h=c(a,t,e);u(a,t,n,f,s,{time:h.time+h.delay+h.duration,delay:0,duration:h.duration,ease:h.ease})}return new tt(r,this._parents,t,n)}function tt(t,e,n,r){this._groups=t,this._parents=e,this._key=n,this._id=r}function et(t){return e.selection().transition(t)}function nt(){return++dt}function rt(t){return t?"__transition"+t:"__transition"}function it(t){var e=rt(t);return this.each(function(){var t=this[e];if(t){var n,r,i=t.pending,o=t.active;for(o&&(o.on.call("interrupt",this,this.__data__,o.index,o.group),t.active=null,o.timer.stop()),n=0,r=i.length;r>n;++n)i[n].timer.stop();i.length=0,delete this[e]}})}function ot(t){var e,n,r;t instanceof tt?(e=t._key,n=t._id,r=c(t.node(),e,n)):(e=rt(t),n=nt(),(r=vt).time=i.now());for(var o=this._groups,a=o.length,s=0;a>s;++s)for(var l,f=o[s],h=f.length,d=0;h>d;++d)(l=f[d])&&u(l,e,n,d,f,r);return new tt(o,this._parents,e,n)}function ut(t,e){var n=rt(e),r=t[n];return r&&(r=r.active)?new tt([[t]],_t,n,r.id):null}var at=r.dispatch("start","end","interrupt"),st=[],lt=0,ct=1,ft=2,ht=e.selection.prototype.constructor,dt=0,pt=e.selection.prototype;tt.prototype=et.prototype={constructor:tt,select:F,selectAll:G,filter:z,merge:O,selection:H,transition:$,call:pt.call,nodes:pt.nodes,node:pt.node,size:pt.size,empty:pt.empty,each:pt.each,on:M,attr:A,attrTween:b,style:R,styleTween:W,text:Z,remove:D,tween:d,delay:C,duration:N,ease:V};var vt={time:null,delay:0,duration:250,ease:o.easeCubicInOut};e.selection.prototype.interrupt=it,e.selection.prototype.transition=ot;var _t=[null],yt="0.2.5";t.version=yt,t.transition=et,t.active=ut}); | ||
!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("d3-selection"),require("d3-dispatch"),require("d3-timer"),require("d3-interpolate"),require("d3-color"),require("d3-ease")):"function"==typeof define&&define.amd?define(["exports","d3-selection","d3-dispatch","d3-timer","d3-interpolate","d3-color","d3-ease"],n):n(t.d3_transition=t.d3_transition||{},t.d3_selection,t.d3_dispatch,t.d3_timer,t.d3_interpolate,t.d3_color,t.d3_ease)}(this,function(t,n,e,r,i,o,a){"use strict";function u(t,n,e,r,i,o){var a=t.__transition;if(a){if(e in a)return}else t.__transition={};c(t,e,{name:n,index:r,group:i,on:st,tween:lt,time:o.time,delay:o.delay,duration:o.duration,ease:o.ease,timer:null,state:ft})}function s(t,n){var e=t.__transition;if(!e||!(e=e[n])||e.state>ft)throw new Error("too late");return e}function l(t,n){var e=t.__transition;if(!e||!(e=e[n])||e.state>ht)throw new Error("too late");return e}function f(t,n){var e=t.__transition;if(!e||!(e=e[n]))throw new Error("too late");return e}function c(t,n,e){function i(t){e.state=ct,e.delay<=t?o(t-e.delay):e.timer.restart(o,e.delay,e.time)}function o(i){var o,l,f,c;for(o in s)c=s[o],c.name===e.name&&(c.state===dt?(c.state=pt,c.timer.stop(),c.on.call("interrupt",t,t.__data__,c.index,c.group),delete s[o]):n>+o&&(c.state=pt,c.timer.stop(),delete s[o]));if(r.timeout(function(){e.state===dt&&(e.timer.restart(a,e.delay,e.time),a(i))}),e.state=ht,e.on.call("start",t,t.__data__,e.index,e.group),e.state===ht){for(e.state=dt,u=new Array(f=e.tween.length),o=0,l=-1;f>o;++o)(c=e.tween[o].value.call(t,t.__data__,e.index,e.group))&&(u[++l]=c);u.length=l+1}}function a(r){for(var i=r<e.duration?e.ease.call(null,r/e.duration):(e.state=_t,1),o=-1,a=u.length;++o<a;)u[o].call(null,i);if(e.state===_t){e.state=pt,e.timer.stop(),e.on.call("end",t,t.__data__,e.index,e.group);for(o in s)if(+o!==n)return void delete s[n];delete t.__transition}}var u,s=t.__transition;s[n]=e,e.timer=r.timer(i,0,e.time)}function h(t){return t=null==t?null:t+"",this.each(function(){var n,e,r,i=this.__transition,o=!0;if(i){for(r in i)(n=i[r]).name===t?(e=n.state===dt,n.state=pt,n.timer.stop(),e&&n.on.call("interrupt",this,this.__data__,n.index,n.group),delete i[r]):o=!1;o&&delete this.__transition}})}function d(t,n,e){var r,i;return function(){var o=l(this,t),a=o.tween;if(a!==r){i=(r=a).slice();for(var u={name:n,value:e},s=0,f=i.length;f>s;++s)if(i[s].name===n){i[s]=u;break}s===f&&i.push(u)}o.tween=i}}function _(t,n){var e=this._id;if(t+="",arguments.length<2){for(var r,i=f(this.node(),e).tween,o=0,a=i.length;a>o;++o)if((r=i[o]).name===t)return r.value;return null}if("function"!=typeof n)throw new Error;return this.each(d(e,t,n))}function p(t,n,e){var r=t._id;return t.each(function(){var t=l(this,r);(t.value||(t.value={}))[n]=e.apply(this,arguments)}),function(t){return f(t,r).value[n]}}function v(t,n){var e;return("number"==typeof n?i.interpolateNumber:n instanceof o.color?i.interpolateRgb:(e=o.color(n))?(n=e,i.interpolateRgb):i.interpolateString)(t,n)}function y(t){return function(){this.removeAttribute(t)}}function m(t){return function(){this.removeAttributeNS(t.space,t.local)}}function g(t,n,e){var r,i;return function(){var o=this.getAttribute(t);return o===e?null:o===r?i:i=n(r=o,e)}}function w(t,n,e){var r,i;return function(){var o=this.getAttributeNS(t.space,t.local);return o===e?null:o===r?i:i=n(r=o,e)}}function A(t,n,e){var r,i,o;return function(){var a,u=e(this);return null==u?void this.removeAttribute(t):(a=this.getAttribute(t),a===u?null:a===r&&u===i?o:o=n(r=a,i=u))}}function b(t,n,e){var r,i,o;return function(){var a,u=e(this);return null==u?void this.removeAttributeNS(t.space,t.local):(a=this.getAttributeNS(t.space,t.local),a===u?null:a===r&&u===i?o:o=n(r=a,i=u))}}function x(t,e){var r=n.namespace(t),o="transform"===r?i.interpolateTransformSvg:v;return this.attrTween(t,"function"==typeof e?(r.local?b:A)(r,o,p(this,"attr."+t,e)):null==e?(r.local?m:y)(r):(r.local?w:g)(r,o,e))}function S(t,n){function e(){var e=this,r=n.apply(e,arguments);return r&&function(n){e.setAttributeNS(t.space,t.local,r(n))}}return e._value=n,e}function E(t,n){function e(){var e=this,r=n.apply(e,arguments);return r&&function(n){e.setAttribute(t,r(n))}}return e._value=n,e}function P(t,e){var r="attr."+t;if(arguments.length<2)return(r=this.tween(r))&&r._value;if("function"!=typeof e)throw new Error;var i=n.namespace(t);return this.tween(r,(i.local?S:E)(i,e))}function C(t,n){return function(){s(this,t).delay=+n.apply(this,arguments)}}function N(t,n){return n=+n,function(){s(this,t).delay=n}}function T(t){var n=this._id;return arguments.length?this.each(("function"==typeof t?C:N)(n,t)):f(this.node(),n).delay}function q(t,n){return function(){l(this,t).duration=+n.apply(this,arguments)}}function V(t,n){return n=+n,function(){l(this,t).duration=n}}function z(t){var n=this._id;return arguments.length?this.each(("function"==typeof t?q:V)(n,t)):f(this.node(),n).duration}function O(t,n){if("function"!=typeof n)throw new Error;return function(){l(this,t).ease=n}}function R(t){var n=this._id;return arguments.length?this.each(O(n,t)):f(this.node(),n).ease}function j(t){"function"!=typeof t&&(t=n.matcher(t));for(var e=this._groups,r=e.length,i=new Array(r),o=0;r>o;++o)for(var a,u=e[o],s=u.length,l=i[o]=new Array(s),f=0;s>f;++f)(a=u[f])&&t.call(a,a.__data__,f,u)&&(l[f]=a);return new et(i,this._parents,this._name,this._id)}function k(t){if(t._id!==this._id)throw new Error;for(var n=this._groups,e=t._groups,r=n.length,i=e.length,o=Math.min(r,i),a=new Array(r),u=0;o>u;++u)for(var s,l=n[u],f=e[u],c=l.length,h=a[u]=new Array(c),d=0;c>d;++d)(s=l[d]||f[d])&&(h[d]=s);for(;r>u;++u)a[u]=n[u];return new et(a,this._parents,this._name,this._id)}function I(t){return(t+"").trim().split(/^|\s+/).every(function(t){var n=t.indexOf(".");return n>=0&&(t=t.slice(0,n)),!t||"start"===t})}function M(t,n,e){if("function"!=typeof e)throw new Error;var r,i,o=I(n)?s:l;return function(){var a=o(this,t),u=a.on;u!==r&&(i=(r=u).copy()).on(n,e),a.on=i}}function B(t,n){var e=this._id;return arguments.length<2?f(this.node(),e).on.on(t):this.each(M(e,t,n))}function D(t){return function(){var n=this.parentNode;for(var e in this.__transition)if(+e!==t)return;n&&n.removeChild(this)}}function F(){return this.on("end.remove",D(this._id))}function G(t){var e=this._name,r=this._id;"function"!=typeof t&&(t=n.selector(t));for(var i=this._groups,o=i.length,a=new Array(o),s=0;o>s;++s)for(var l,c,h=i[s],d=h.length,_=a[s]=new Array(d),p=0;d>p;++p)(l=h[p])&&(c=t.call(l,l.__data__,p,h))&&("__data__"in l&&(c.__data__=l.__data__),_[p]=c,u(_[p],e,r,p,_,f(l,r)));return new et(a,this._parents,e,r)}function H(t){var e=this._name,r=this._id;"function"!=typeof t&&(t=n.selectorAll(t));for(var i=this._groups,o=i.length,a=[],s=[],l=0;o>l;++l)for(var c,h=i[l],d=h.length,_=0;d>_;++_)if(c=h[_]){for(var p,v=t.call(c,c.__data__,_,h),y=f(c,r),m=0,g=v.length;g>m;++m)(p=v[m])&&u(p,e,r,m,v,y);a.push(v),s.push(c)}return new et(a,s,e,r)}function J(){return new vt(this._groups,this._parents)}function K(t,e){var r,i,o;return function(){var a=n.window(this).getComputedStyle(this,null),u=a.getPropertyValue(t),s=(this.style.removeProperty(t),a.getPropertyValue(t));return u===s?null:u===r&&s===i?o:o=e(r=u,i=s)}}function L(t){return function(){this.style.removeProperty(t)}}function Q(t,e,r){var i,o;return function(){var a=n.window(this).getComputedStyle(this,null).getPropertyValue(t);return a===r?null:a===i?o:o=e(i=a,r)}}function U(t,e,r){var i,o,a;return function(){var u=n.window(this).getComputedStyle(this,null),s=u.getPropertyValue(t),l=r(this);return null==l&&(this.style.removeProperty(t),l=u.getPropertyValue(t)),s===l?null:s===i&&l===o?a:a=e(i=s,o=l)}}function W(t,n,e){var r="transform"==(t+="")?i.interpolateTransformCss:v;return null==n?this.styleTween(t,K(t,r)).on("end.style."+t,L(t)):this.styleTween(t,"function"==typeof n?U(t,r,p(this,"style."+t,n)):Q(t,r,n),e)}function X(t,n,e){function r(){var r=this,i=n.apply(r,arguments);return i&&function(n){r.style.setProperty(t,i(n),e)}}if("function"!=typeof n)throw new Error;return r._value=n,r}function Y(t,n,e){var r="style."+(t+="");return arguments.length<2?(r=this.tween(r))&&r._value:this.tween(r,X(t,n,null==e?"":e))}function Z(t){return function(){this.textContent=t}}function $(t){return function(){var n=t(this);this.textContent=null==n?"":n}}function tt(t){return this.tween("text","function"==typeof t?$(p(this,"text",t)):Z(null==t?"":t+""))}function nt(){for(var t=this._name,n=this._id,e=it(),r=this._groups,i=r.length,o=0;i>o;++o)for(var a,s=r[o],l=s.length,c=0;l>c;++c)if(a=s[c]){var h=f(a,n);u(a,t,e,c,s,{time:h.time+h.delay+h.duration,delay:0,duration:h.duration,ease:h.ease})}return new et(r,this._parents,t,e)}function et(t,n,e,r){this._groups=t,this._parents=n,this._name=e,this._id=r}function rt(t){return n.selection().transition(t)}function it(){return++yt}function ot(t){var n,e;t instanceof et?(n=t._id,e=f(t.node(),n),t=t._name):(n=it(),(e=gt).time=r.now(),t=null==t?null:t+"");for(var i=this._groups,o=i.length,a=0;o>a;++a)for(var s,l=i[a],c=l.length,h=0;c>h;++h)(s=l[h])&&u(s,t,n,h,l,e);return new et(i,this._parents,t,n)}function at(t,n){var e,r,i=t.__transition;if(i){n=null==n?null:n+"";for(r in i)if((e=i[r]).state>ct&&e.name===n)return new et([[t]],wt,n,+r)}return null}var ut="0.2.6",st=e.dispatch("start","end","interrupt"),lt=[],ft=0,ct=1,ht=2,dt=3,_t=4,pt=5,vt=n.selection.prototype.constructor,yt=0,mt=n.selection.prototype;et.prototype=rt.prototype={constructor:et,select:G,selectAll:H,filter:j,merge:k,selection:J,transition:nt,call:mt.call,nodes:mt.nodes,node:mt.node,size:mt.size,empty:mt.empty,each:mt.each,on:B,attr:x,attrTween:P,style:W,styleTween:Y,text:tt,remove:F,tween:_,delay:T,duration:z,ease:R};var gt={time:null,delay:0,duration:250,ease:a.easeCubicInOut};n.selection.prototype.interrupt=h,n.selection.prototype.transition=ot;var wt=[null];t.version=ut,t.transition=rt,t.active=at}); |
@@ -0,3 +1,4 @@ | ||
export {version} from "./build/version"; | ||
import "./src/selection/index"; | ||
export {default as transition} from "./src/transition/index"; | ||
export {default as active} from "./src/active"; |
{ | ||
"name": "d3-transition", | ||
"version": "0.2.5", | ||
"version": "0.2.6", | ||
"description": "Animated transitions for D3 selections.", | ||
@@ -24,3 +24,3 @@ "keywords": [ | ||
"scripts": { | ||
"pretest": "mkdir -p build && node -e 'process.stdout.write(\"var version = \\\"\" + require(\"./package.json\").version + \"\\\"; export * from \\\"../index\\\"; export {version};\");' > build/bundle.js && rollup -f umd -g d3-interpolate:d3_interpolate,d3-ease:d3_ease,d3-dispatch:d3_dispatch,d3-selection:d3_selection,d3-timer:d3_timer -n d3_transition -o build/d3-transition.js -- build/bundle.js", | ||
"pretest": "mkdir -p build && node -e 'process.stdout.write(\"export var version = \\\"\" + require(\"./package.json\").version + \"\\\";\\n\");' > build/version.js && rollup -f umd -g d3-color:d3_color,d3-interpolate:d3_interpolate,d3-ease:d3_ease,d3-dispatch:d3_dispatch,d3-selection:d3_selection,d3-timer:d3_timer -n d3_transition -o build/d3-transition.js -- index.js", | ||
"test": "faucet `find test -name '*-test.js'` && eslint index.js src test", | ||
@@ -31,2 +31,3 @@ "prepublish": "npm run test && uglifyjs build/d3-transition.js -c -m -o build/d3-transition.min.js && rm -f build/d3-transition.zip && zip -j build/d3-transition.zip -- LICENSE README.md build/d3-transition.js build/d3-transition.min.js", | ||
"dependencies": { | ||
"d3-color": "~0.4.0", | ||
"d3-dispatch": "~0.4.0", | ||
@@ -33,0 +34,0 @@ "d3-ease": "~0.7.0", |
191
README.md
# d3-transition | ||
A transition is a [selection](https://github.com/d3/d3-selection)-like interface for animating changes to the DOM. Instead of applying changes instantaneously, transitions smoothly interpolate the DOM from its current state to the desired target state over a given duration. To start a transition, select elements, call [*selection*.transition](#selection_transition), and then apply the desired changes. For example: | ||
A transition is a [selection](https://github.com/d3/d3-selection)-like interface for animating changes to the DOM. Instead of applying changes instantaneously, transitions smoothly interpolate the DOM from its current state to the desired target state over a given duration. | ||
To apply a transition, select elements, call [*selection*.transition](#selection_transition), and then make the desired changes. For example: | ||
```js | ||
@@ -11,5 +13,5 @@ d3.select("body") | ||
Transitions support most selection methods (such as [*transition*.attr](#transition_attr) and [*transition*.style](#transition_style)), but not all methods are supported; for example, you must [append](https://github.com/d3/d3-selection#selection_append) elements or [bind data](https://github.com/d3/d3-selection#joining-data) before a transition starts. A [*transition*.remove](#transition_remove) operator is provided for convenient removal of elements when the transition ends. | ||
Transitions support most selection methods (such as [*transition*.attr](#transition_attr) and [*transition*.style](#transition_style) in place of [*selection*.attr](https://github.com/d3/d3-selection#selection_attr) and [*selection*.style](https://github.com/d3/d3-selection#selection_style)), but not all methods are supported; for example, you must [append](https://github.com/d3/d3-selection#selection_append) elements or [bind data](https://github.com/d3/d3-selection#joining-data) before a transition starts. A [*transition*.remove](#transition_remove) operator is provided for convenient removal of elements when the transition ends. | ||
To animate changes, transitions leverage a variety of [built-in interpolators](https://github.com/d3/d3-interpolate). [Colors](https://github.com/d3/d3-interpolate#interpolateRgb), [numbers](https://github.com/d3/d3-interpolate#interpolateNumber), and [transforms](https://github.com/d3/d3-interpolate#interpolateTransform) are automatically detected. [Strings](https://github.com/d3/d3-interpolate#interpolateString) with embedded numbers are also detected, as is common with many styles (such as padding or font sizes) and paths. To specify a custom interpolator, use [*transition*.attrTween](#transition_attrTween), [*transition*.styleTween](#transition_styleTween) or [*transition*.tween](#transition_tween). | ||
To compute intermediate state, transitions leverage a variety of [built-in interpolators](https://github.com/d3/d3-interpolate). [Colors](https://github.com/d3/d3-interpolate#interpolateRgb), [numbers](https://github.com/d3/d3-interpolate#interpolateNumber), and [transforms](https://github.com/d3/d3-interpolate#interpolateTransform) are automatically detected. [Strings](https://github.com/d3/d3-interpolate#interpolateString) with embedded numbers are also detected, as is common with many styles (such as padding or font sizes) and paths. To specify a custom interpolator, use [*transition*.attrTween](#transition_attrTween), [*transition*.styleTween](#transition_styleTween) or [*transition*.tween](#transition_tween). | ||
@@ -43,2 +45,3 @@ ## Installing | ||
* [Control Flow](#control-flow) | ||
* [The Life of a Transition](#the-life-of-a-transition) | ||
@@ -51,3 +54,3 @@ ### Selecting Elements | ||
Returns a new transition on the given *selection* with the specified *name*. If a *name* is not specified, the default empty name (“”) is used. The new transition is only exclusive with other transitions of the same name. | ||
Returns a new transition on the given *selection* with the specified *name*. If a *name* is not specified, null is used. The new transition is only exclusive with other transitions of the same name. | ||
@@ -70,10 +73,11 @@ If the *name* is a [transition](#transition) instance, the new transition has the same id, name and timing as the specified transition; however, if a transition with the same id already exists on a selected element, the existing transition is returned for that element. This can be used to synchronize a transition across multiple selections, or to re-select a transition for specific elements and modify its configuration. For example: | ||
Interrupts the active transition of the specified *name* on the selected elements, and cancels any pending transitions with the specified *name*, if any. If a name is not specified, the empty name (“”) is used. | ||
Interrupts the active transition of the specified *name* on the selected elements, and cancels any pending transitions with the specified *name*, if any. If a name is not specified, null is used. | ||
<a name="transition" href="#transition">#</a> d3.<b>transition</b>([<i>name</i>]) | ||
Returns a new transition on the root element, `document.documentElement`, with the specified *name*. If a *name* is not specified, the default empty name (“”) is used. The new transition is only exclusive with other transitions of the same name. The *name* may also be a [transition](#transition) instance; see [*selection*.transition](#selection_transition). This method is equivalent to: | ||
Returns a new transition on the root element, `document.documentElement`, with the specified *name*. If a *name* is not specified, null is used. The new transition is only exclusive with other transitions of the same name. The *name* may also be a [transition](#transition) instance; see [*selection*.transition](#selection_transition). This method is equivalent to: | ||
```js | ||
d3.selection().transition(name) | ||
d3.selection() | ||
.transition(name) | ||
``` | ||
@@ -122,7 +126,7 @@ | ||
<a name="transition_merge" href="#transition_merge">#</a> <i>transition</i>.<b>merge</b>(<i>selection</i>) | ||
<a name="transition_merge" href="#transition_merge">#</a> <i>transition</i>.<b>merge</b>(<i>other</i>) | ||
Returns a new transition merging this transition with the specified *selection* (or *transition*). The returned transition has the same number of groups, the same parents, the same name and the same id as this transition. Any missing (null) elements in this transition are filled with the corresponding element, if present (not null), from the specified *selection*. | ||
Returns a new transition merging this transition with the specified *other* transition, which must have the same id as this transition. The returned transition has the same number of groups, the same parents, the same name and the same id as this transition. Any missing (null) elements in this transition are filled with the corresponding element, if present (not null), from the *other* transition. | ||
This method is equivalent to deriving the selection for this transition via [*transition*.selection](#transition_selection), merging with the specified selection via [*selection*.merge](https://github.com/d3/d3-selection#selection_merge), and then creating a new transition via [*selection*.transition](#selection_transition): | ||
This method is equivalent to deriving the selection for this transition via [*transition*.selection](#transition_selection), merging with the selection likewise derived from the *other* transition via [*selection*.merge](https://github.com/d3/d3-selection#selection_merge), and then creating a new transition via [*selection*.transition](#selection_transition): | ||
@@ -132,3 +136,3 @@ ```js | ||
.selection() | ||
.merge(selection) | ||
.merge(other.selection()) | ||
.transition(transition) | ||
@@ -161,3 +165,3 @@ ``` | ||
Returns the active transition on the specified *node* with the specified *name*, if any. If no *name* is specified, the default empty name is used. Returns null if there is no such active transition on the specified node. This method is useful for creating chained transitions. For example, to initiate disco mode: | ||
Returns the active transition on the specified *node* with the specified *name*, if any. If no *name* is specified, null is used. Returns null if there is no such active transition on the specified node. This method is useful for creating chained transitions. For example, to initiate disco mode: | ||
@@ -179,70 +183,175 @@ ```js | ||
See [chained transitions](http://bl.ocks.org/mbostock/70d5541b547cc222aa02) for an example. | ||
### Modifying Elements | ||
… | ||
After selecting elements and creating a transition with [*selection*.transition](#selection_transition), use the transition’s transformation methods to affect document content. | ||
<a name="transition_attr" href="#transition_attr">#</a> <i>transition</i>.<b>attr</b>(<i>name</i>, <i>value</i>) | ||
… Note that unlike [*selection*.attr](https://github.com/d3/d3-selection#selection_attr), *value* is required. | ||
For each selected element, creates an [attribute tween](#transition_attrTween) for the attribute with the specified *name* to the specified target *value*. The starting value of the tween is the attribute’s value when the transition starts. The target *value* may be specified either as a constant or a function. If a function, it is immediately evaluated for each selected element, in order, being passed the current datum `d` and index `i`, with the `this` context as the current DOM element. | ||
If the target value is null, the attribute is removed when the transition starts. Otherwise, an interpolator is chosen based on the type of the target value, using the following algorithm: | ||
1. If *value* is a number, use [interpolateNumber](https://github.com/d3/d3-interpolate#interpolateNumber). | ||
2. If *value* is a [color](https://github.com/d3/d3-color#color) or a string coercible to a color, use [interpolateRgb](https://github.com/d3/d3-interpolate#interpolateRgb). | ||
3. Use [interpolateString](https://github.com/d3/d3-interpolate#interpolateString). | ||
To apply a different interpolator, use [*transition*.attrTween](#transition_attrTween). | ||
<a name="transition_attrTween" href="#transition_attrTween">#</a> <i>transition</i>.<b>attrTween</b>(<i>name</i>[, <i>value</i>]) | ||
… | ||
For each selected element, creates a [tween](#transition_tween) for the attribute with the specified *name* with the specified interpolator *value*. The *value* must be specified as a function that returns an [interpolator](https://github.com/d3/d3-interpolate). When the transition starts, the *value* function is evaluated for each selected element, in order, being passed the current datum `d` and index `i`, with the `this` context as the current DOM element. The returned interpolator is then invoked for each frame of the transition, in order, being passed the [eased](#transition_ease) time *t*, typically in the range [0, 1]. | ||
For example, to interpolate the fill attribute from red to blue: | ||
```js | ||
selection.attrTween("fill", function() { | ||
return d3.interpolateRgb("red", "blue"); | ||
}); | ||
``` | ||
Or to interpolate from the current fill to blue, like [*transition*.attr](#transition_attr): | ||
```js | ||
selection.attrTween("fill", function() { | ||
return d3.interpolateRgb(this.getAttribute("fill"), "blue"); | ||
}); | ||
``` | ||
Or to apply a custom rainbow interpolator: | ||
```js | ||
selection.attrTween("fill", function() { | ||
return function(t) { | ||
return "hsl(" + t * 360 + ",100%,50%)"; | ||
}; | ||
}); | ||
``` | ||
This method is useful to specify a custom interpolator, such as one that understands [SVG paths](http://bl.ocks.org/mbostock/3916621). A useful technique is *data interpolation*, where [d3.interpolateObject](https://github.com/d3/d3-interpolate#interpolateObject) is used to interpolate two data values, and the resulting value is then used (say, with a [shape](https://github.com/d3/d3-shape)) to compute the new attribute value. | ||
<a name="transition_style" href="#transition_style">#</a> <i>transition</i>.<b>style</b>(<i>name</i>, <i>value</i>[, <i>priority</i>]) | ||
… Note that unlike [*selection*.style](https://github.com/d3/d3-selection#selection_style), *value* is required. | ||
For each selected element, creates an [style tween](#transition_styleTween) for the style with the specified *name* to the specified target *value* with the specified *priority*. The starting value of the tween is the style’s computed value when the transition starts. The target *value* may be specified either as a constant or a function. If a function, it is immediately evaluated for each selected element, in order, being passed the current datum `d` and index `i`, with the `this` context as the current DOM element. | ||
If the target value is null, the style is removed when the transition starts. Otherwise, an interpolator is chosen based on the type of the target value, using the following algorithm: | ||
1. If *value* is a number, use [interpolateNumber](https://github.com/d3/d3-interpolate#interpolateNumber). | ||
2. If *value* is a [color](https://github.com/d3/d3-color#color) or a string coercible to a color, use [interpolateRgb](https://github.com/d3/d3-interpolate#interpolateRgb). | ||
3. Use [interpolateString](https://github.com/d3/d3-interpolate#interpolateString). | ||
To apply a different interpolator, use [*transition*.styleTween](#transition_styleTween). | ||
<a name="transition_styleTween" href="#transition_styleTween">#</a> <i>transition</i>.<b>styleTween</b>(<i>name</i>[, <i>value</i>[, <i>priority</i>]])) | ||
… | ||
For each selected element, creates a [tween](#transition_tween) for the style with the specified *name* with the specified interpolator *value* with the specified *priority*. The *value* must be specified as a function that returns an [interpolator](https://github.com/d3/d3-interpolate). When the transition starts, the *value* function is evaluated for each selected element, in order, being passed the current datum `d` and index `i`, with the `this` context as the current DOM element. The returned interpolator is then invoked for each frame of the transition, in order, being passed the [eased](#transition_ease) time *t*, typically in the range [0, 1]. | ||
For example, to interpolate the fill style from red to blue: | ||
```js | ||
selection.styleTween("fill", function() { | ||
return d3.interpolateRgb("red", "blue"); | ||
}); | ||
``` | ||
Or to interpolate from the current fill to blue, like [*transition*.style](#transition_style): | ||
```js | ||
selection.styleTween("fill", function() { | ||
return d3.interpolateRgb(getComputedStyle(this).getPropertyValue("fill"), "blue"); | ||
}); | ||
``` | ||
Or to apply a custom rainbow interpolator: | ||
```js | ||
selection.styleTween("fill", function() { | ||
return function(t) { | ||
return "hsl(" + t * 360 + ",100%,50%)"; | ||
}; | ||
}); | ||
``` | ||
This method is useful to specify a custom interpolator, such as with *data interpolation*, where [d3.interpolateObject](https://github.com/d3/d3-interpolate#interpolateObject) is used to interpolate two data values, and the resulting value is then used to compute the new style value. | ||
<a name="transition_text" href="#transition_text">#</a> <i>transition</i>.<b>text</b>(<i>value</i>) | ||
… Note that unlike [*selection*.text](https://github.com/d3/d3-selection#selection_text), *value* is required. | ||
For each selected element, sets the [text content](http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-textContent) to the specified target *value* when the transition starts. The *value* may be specified either as a constant or a function. If a function, it is immediately evaluated for each selected element, in order, being passed the current datum `d` and index `i`, with the `this` context as the current DOM element. The function’s return value is then used to set each element’s text content. A null value will clear the content. | ||
To interpolate text rather than to set it on start, use [*transition*.tween](#transition_tween) ([for example](http://bl.ocks.org/mbostock/7004f92cac972edef365)) or append a replacement element and cross-fade opacity ([for example](http://bl.ocks.org/mbostock/f7dcecb19c4af317e464)). Text is not interpolated by default because it is usually undesirable. | ||
<a name="transition_remove" href="#transition_remove">#</a> <i>transition</i>.<b>remove</b>() | ||
… | ||
For each selected element, [removes](https://github.com/d3/d3-selection#selection_remove) the element when the transition ends, as long as the element has no other active or pending transitions. If the element has other active or pending transitions, does nothing. | ||
<a name="transition_tween" href="#transition_tween">#</a> <i>transition</i>.<b>tween</b>(<i>name</i>[, <i>value</i>]) | ||
… | ||
For each selected element, creates a tween with the specified *name* with the specified *value* function. The *value* must be specified as a function that returns a function. When the transition starts, the *value* function is evaluated for each selected element, in order, being passed the current datum `d` and index `i`, with the `this` context as the current DOM element. The returned function is then invoked for each frame of the transition, in order, being passed the [eased](#transition_ease) time *t*, typically in the range [0, 1]. | ||
For example, to interpolate the fill attribute to blue, like [*transition*.attr](#transition_attr): | ||
```js | ||
selection.tween("attr.fill", function() { | ||
var node = this, i = d3.interpolateRgb(node.getAttribute("fill"), "blue"); | ||
return function(t) { | ||
node.setAttribute("fill", i(t)); | ||
}; | ||
}); | ||
``` | ||
This method is useful to specify a custom interpolator, or to perform side-effects, say to animate the [scroll offset](http://bl.ocks.org/mbostock/1649463). | ||
### Timing | ||
Transitions may have per-element [delays](#transition_delay) and [durations](#transition_duration) computed by functions of data or index; this lets you stagger a transition across a set elements. For example, sorting elements and staggering the reordering improves perception. See [Animated Transitions in Statistical Data Graphics](http://vis.berkeley.edu/papers/animated_transitions/) for recommendations. | ||
The [easing](#transition_ease), [delay](#transition_delay) and [duration](#transition_duration) of a transition is configurable. For example, a per-element delay can be used to [stagger the reordering](http://bl.ocks.org/mbostock/3885705) of elements, improving perception. See [Animated Transitions in Statistical Data Graphics](http://vis.berkeley.edu/papers/animated_transitions/) for recommendations. | ||
Transitions start automatically after the given delay. Note, however, that even a zero-delay transition starts asynchronously after one tick (~17ms); this delay gives you time to configure the transition before it starts. Transitions have a default [duration](#transition_duration) of 250ms. | ||
<a name="transition_delay" href="#transition_delay">#</a> <i>transition</i>.<b>delay</b>([<i>value</i>]) | ||
Transitions are partially exclusive: only one transition of a given name may be *active* on a given element at a given time. Multiple transitions with different names may be simultaneously active on the element, and multiple transitions with the same name may be scheduled on the element, provided they do not overlap in time. See [*transition*.transition](#transition_transition), for example. When a transition starts on a given element, it automatically interrupts any active transition and cancels any pending transitions that were scheduled before the starting transition. This allows new transitions to supersede old transitions (such as in response to a user event), even if the old transitions were delayed. To manually interrupt transitions, use [*selection*.interrupt](#selection_interrupt). To run transitions concurrently on a given element, give each transition a [unique name](#selection_transition). | ||
For each selected element, sets the transition delay to the specified *value* in milliseconds. The *value* may be specified either as a constant or a function. If a function, it is immediately evaluated for each selected element, in order, being passed the current datum `d` and index `i`, with the `this` context as the current DOM element. The function’s return value is then used to set each element’s transition delay. If a delay is not specified, it defaults to zero. | ||
If another transition is active on a given element, a new zero-delay transition will **not** immediately (synchronously) interrupt the active transition: the old transition does not get pre-empted until the new transition starts, so the old transition is given a final tick. (Within a tick, active transitions are invoked in the order they were scheduled.) Thus, the old transition may overwrite attribute or style values that were set synchronously when the new transition was created. Use [*selection*.interrupt](#selection_interrupt) to interrupt any active transition and prevent it from receiving its final tick. | ||
If a *value* is not specified, returns the current value of the delay for the first (non-null) element in the transition. This is generally useful only if you know that the transition contains exactly one element. | ||
For more on transitions, see [Working with Transitions](http://bost.ocks.org/mike/transition/). | ||
Setting the delay to a multiple of the index `i` is a convenient way to stagger transitions across a set of elements. For example: | ||
<a name="transition_delay" href="#transition_delay">#</a> <i>transition</i>.<b>delay</b>([<i>value</i>]) | ||
```js | ||
transition.delay(function(d, i) { return i * 10; }); | ||
``` | ||
… | ||
Of course, you can also compute the delay as a function of the data, or [sort the selection](https://github.com/d3/d3-selection#selection_sort) before computed an index-based delay. | ||
<a name="transition_duration" href="#transition_duration">#</a> <i>transition</i>.<b>duration</b>([<i>value</i>]) | ||
… | ||
For each selected element, sets the transition duration to the specified *value* in milliseconds. The *value* may be specified either as a constant or a function. If a function, it is immediately evaluated for each selected element, in order, being passed the current datum `d` and index `i`, with the `this` context as the current DOM element. The function’s return value is then used to set each element’s transition duration. If a duration is not specified, it defaults to 250ms. | ||
If a *value* is not specified, returns the current value of the duration for the first (non-null) element in the transition. This is generally useful only if you know that the transition contains exactly one element. | ||
<a name="transition_ease" href="#transition_ease">#</a> <i>transition</i>.<b>ease</b>([<i>value</i>]) | ||
… | ||
Specifies the transition [easing function](https://github.com/d3/d3-ease) for all selected elements. The *value* must be specified as a function. The easing function is invoked for each frame of the animation, being passed the normalized time *t* in the range [0, 1]; it must then return the eased time *tʹ* which is typically also in the range [0, 1]. A good easing function should return 0 if *t* = 0 and 1 if *t* = 1. If an easing function is not specified, it defaults to [d3.easeCubic](https://github.com/d3/d3-ease#easeCubic). | ||
If a *value* is not specified, returns the current easing function for the first (non-null) element in the transition. This is generally useful only if you know that the transition contains exactly one element. | ||
### Control Flow | ||
… | ||
For advanced usage, transitions provide methods for custom control flow. | ||
<a name="transition_on" href="#transition_on">#</a> <i>transition</i>.<b>on</b>(<i>typenames</i>[, <i>listener</i>]) | ||
… | ||
Adds or removes a *listener* to each selected element for the specified event *typenames*. The *typenames* is one of the following string event types: | ||
* `start` | ||
* `end` | ||
* `interrupt` | ||
* `start` - when the transition starts. | ||
* `end` - when the transition ends. | ||
* `interrupt` - when the transition is interrupted. | ||
See [The Life of a Transition](#the-life-of-a-transition) for more. Note that these are *not* native DOM events as implemented by [*selection*.on](https://github.com/d3/d3-selection#selection_on) and [*selection*.dispatch](https://github.com/d3/d3-selection#selection_dispatch), but transition events! | ||
The type may be optionally followed by a period (`.`) and a name; the optional name allows multiple callbacks to be registered to receive events of the same type, such as `start.foo` and `start.bar`. To specify multiple typenames, separate typenames with spaces, such as `interrupt end` or `start.foo start.bar`. | ||
When a specified transition event is dispatched on a selected node, the specified *listener* will be invoked for the transitioning element, being passed the current datum `d` and index `i`, with the `this` context as the current DOM element. Listeners always see the latest datum for their element, but the index is a property of the selection and is fixed when the listener is assigned; to update the index, re-assign the listener. | ||
If an event listener was previously registered for the same *typename* on a selected element, the old listener is removed before the new listener is added. To remove a listener, pass null as the *listener*. To remove all listeners for a given name, pass null as the *listener* and `.foo` as the *typename*, where `foo` is the name; to remove all listeners with no name, specify `.` as the *typename*. | ||
If a *listener* is not specified, returns the currently-assigned listener for the specified event *typename* on the first (non-null) selected element, if any. If multiple typenames are specified, the first matching listener is returned. | ||
<a name="transition_each" href="#transition_each">#</a> <i>transition</i>.<b>each</b>(<i>function</i>) | ||
@@ -293,1 +402,15 @@ | ||
Returns the total number of elements in this transition. Equivalent to [*selection*.size](https://github.com/d3/d3-selection#selection_size). | ||
### The Life of a Transition | ||
Immediately after creating a transition, such as by [*selection*.transition](#selection_transition) or [*transition*.transition](#transition_transition), you may configure the transition using methods such as [*transition*.delay](#transition_delay), [*transition*.duration](#transition_duration), [*transition*.attr](#transition_attr) and [*transition*.style](#transition_style). Methods that specify target values (such as *transition*.attr) are evaluated synchronously; however, methods that require the starting value for interpolation, such as [*transition*.attrTween](#transition_attrTween) and [*transition*.styleTween](#transition_styleTween), must be deferred until the transition starts. | ||
Shortly after creation, either at the end of the current frame or during the next frame, the transition is scheduled. At this point, the delay and `start` event listeners may no longer be changed. | ||
When the transition subsequently starts, it interrupts the active transition of the same name on the same element, if any, dispatching an `interrupt` event to registered listeners. (Note that interrupts happen on start, not creation, and thus even a zero-delay transition will not immediately interrupt the active transition: the old transition is given a final frame. Use [*selection*.interrupt](#selection_interrupt) to interrupt immediately.) The starting transition also cancels any pending transitions of the same name on the same element that were created before the starting transition. The transition then dispatches a `start` event to registered listeners. This is the last moment at which the transition may be modified: after starting, the transition’s timing, tweens, and listeners may no longer be changed. The transition initializes its tweens immediately after starting. | ||
During the frame the transition starts, but *after* all transitions starting this frame have been started, the transition invokes its tweens for the first time. Batching tween initialization, which typically involves reading from the DOM, improves performance by avoiding interleaved DOM reads and writes. | ||
For each frame that a transition is active, it invokes its tweens with an [eased](#transition_ease) *t*-value ranging from 0 to 1. Within each frame, the transition invokes its tweens in the order they were registered. | ||
When a transition ends, it invokes its tweens a final time with a (non-eased) *t*-value of 1. It then dispatches an `end` event to registered listeners. This is the last moment at which the transition may be inspected: after ending, the transition is deleted from the element, and its configuration is destroyed. (A transition’s configuration is also destroyed on interrupt or cancel.) |
@@ -1,2 +0,3 @@ | ||
import {Transition, namekey} from "./transition/index"; | ||
import {Transition} from "./transition/index"; | ||
import {SCHEDULED} from "./transition/schedule"; | ||
@@ -6,5 +7,16 @@ var root = [null]; | ||
export default function(node, name) { | ||
var key = namekey(name), active = node[key]; | ||
if (!active || !(active = active.active)) return null; | ||
return new Transition([[node]], root, key, active.id); | ||
var schedules = node.__transition, | ||
schedule, | ||
i; | ||
if (schedules) { | ||
name = name == null ? null : name + ""; | ||
for (i in schedules) { | ||
if ((schedule = schedules[i]).state > SCHEDULED && schedule.name === name) { | ||
return new Transition([[node]], root, name, +i); | ||
} | ||
} | ||
} | ||
return null; | ||
} |
@@ -1,23 +0,25 @@ | ||
import {namekey} from "../transition/index"; | ||
import {STARTED, ENDED} from "../transition/schedule"; | ||
export default function(name) { | ||
var key = namekey(name); | ||
name = name == null ? null : name + ""; | ||
return this.each(function() { | ||
var schedule = this[key]; | ||
if (schedule) { | ||
var pending = schedule.pending, | ||
active = schedule.active, | ||
i, n; | ||
if (active) { | ||
active.on.call("interrupt", this, this.__data__, active.index, active.group); // TODO try-catch? | ||
schedule.active = null; | ||
active.timer.stop(); | ||
} | ||
for (i = 0, n = pending.length; i < n; ++i) { | ||
pending[i].timer.stop(); | ||
} | ||
pending.length = 0; | ||
delete this[key]; | ||
var schedules = this.__transition, | ||
schedule, | ||
active, | ||
empty = true, | ||
i; | ||
if (!schedules) return; | ||
for (i in schedules) { | ||
if ((schedule = schedules[i]).name !== name) { empty = false; continue; } | ||
active = schedule.state === STARTED; | ||
schedule.state = ENDED; | ||
schedule.timer.stop(); | ||
if (active) schedule.on.call("interrupt", this, this.__data__, schedule.index, schedule.group); | ||
delete schedules[i]; | ||
} | ||
if (empty) delete this.__transition; | ||
}); | ||
} |
@@ -1,2 +0,2 @@ | ||
import {Transition, newId, namekey} from "../transition/index"; | ||
import {Transition, newId} from "../transition/index"; | ||
import schedule, {get} from "../transition/schedule"; | ||
@@ -14,10 +14,9 @@ import {easeCubicInOut} from "d3-ease"; | ||
export default function(name) { | ||
var key, | ||
id, | ||
var id, | ||
timing; | ||
if (name instanceof Transition) { | ||
key = name._key, id = name._id, timing = get(name.node(), key, id); | ||
id = name._id, timing = get(name.node(), id), name = name._name; | ||
} else { | ||
key = namekey(name), id = newId(), (timing = defaultTiming).time = now(); | ||
id = newId(), (timing = defaultTiming).time = now(), name = name == null ? null : name + ""; | ||
} | ||
@@ -28,3 +27,3 @@ | ||
if (node = group[i]) { | ||
schedule(node, key, id, i, group, timing); | ||
schedule(node, name, id, i, group, timing); | ||
} | ||
@@ -34,3 +33,3 @@ } | ||
return new Transition(groups, this._parents, key, id); | ||
return new Transition(groups, this._parents, name, id); | ||
} |
@@ -1,4 +0,5 @@ | ||
import {interpolate, interpolateTransformSvg as interpolateTransform} from "d3-interpolate"; | ||
import {interpolateTransformSvg as interpolateTransform} from "d3-interpolate"; | ||
import {namespace} from "d3-selection"; | ||
import {tweenValue} from "./tween"; | ||
import interpolate from "./interpolate"; | ||
@@ -72,3 +73,3 @@ function attrRemove(name) { | ||
: value == null ? (fullname.local ? attrRemoveNS : attrRemove)(fullname) | ||
: (fullname.local ? attrConstantNS : attrConstant)(fullname, i, value + "")); | ||
: (fullname.local ? attrConstantNS : attrConstant)(fullname, i, value)); | ||
} |
import {get, init} from "./schedule"; | ||
function delayFunction(key, id, value) { | ||
function delayFunction(id, value) { | ||
return function() { | ||
init(this, key, id).delay = +value.apply(this, arguments); | ||
init(this, id).delay = +value.apply(this, arguments); | ||
}; | ||
} | ||
function delayConstant(key, id, value) { | ||
function delayConstant(id, value) { | ||
return value = +value, function() { | ||
init(this, key, id).delay = value; | ||
init(this, id).delay = value; | ||
}; | ||
@@ -16,4 +16,3 @@ } | ||
export default function(value) { | ||
var key = this._key, | ||
id = this._id; | ||
var id = this._id; | ||
@@ -23,4 +22,4 @@ return arguments.length | ||
? delayFunction | ||
: delayConstant)(key, id, value)) | ||
: get(this.node(), key, id).delay; | ||
: delayConstant)(id, value)) | ||
: get(this.node(), id).delay; | ||
} |
import {get, set} from "./schedule"; | ||
function durationFunction(key, id, value) { | ||
function durationFunction(id, value) { | ||
return function() { | ||
set(this, key, id).duration = +value.apply(this, arguments); | ||
set(this, id).duration = +value.apply(this, arguments); | ||
}; | ||
} | ||
function durationConstant(key, id, value) { | ||
function durationConstant(id, value) { | ||
return value = +value, function() { | ||
set(this, key, id).duration = value; | ||
set(this, id).duration = value; | ||
}; | ||
@@ -16,4 +16,3 @@ } | ||
export default function(value) { | ||
var key = this._key, | ||
id = this._id; | ||
var id = this._id; | ||
@@ -23,4 +22,4 @@ return arguments.length | ||
? durationFunction | ||
: durationConstant)(key, id, value)) | ||
: get(this.node(), key, id).duration; | ||
: durationConstant)(id, value)) | ||
: get(this.node(), id).duration; | ||
} |
import {get, set} from "./schedule"; | ||
function easeConstant(key, id, value) { | ||
function easeConstant(id, value) { | ||
if (typeof value !== "function") throw new Error; | ||
return function() { | ||
set(this, key, id).ease = value; | ||
set(this, id).ease = value; | ||
}; | ||
@@ -11,8 +11,7 @@ } | ||
export default function(value) { | ||
var key = this._key, | ||
id = this._id; | ||
var id = this._id; | ||
return arguments.length | ||
? this.each(easeConstant(key, id, value)) | ||
: get(this.node(), key, id).ease; | ||
? this.each(easeConstant(id, value)) | ||
: get(this.node(), id).ease; | ||
} |
@@ -15,3 +15,3 @@ import {matcher} from "d3-selection"; | ||
return new Transition(subgroups, this._parents, this._key, this._id); | ||
return new Transition(subgroups, this._parents, this._name, this._id); | ||
} |
@@ -22,6 +22,6 @@ import {selection} from "d3-selection"; | ||
export function Transition(groups, parents, key, id) { | ||
export function Transition(groups, parents, name, id) { | ||
this._groups = groups; | ||
this._parents = parents; | ||
this._key = key; | ||
this._name = name; | ||
this._id = id; | ||
@@ -38,6 +38,2 @@ } | ||
export function namekey(name) { | ||
return name ? "__transition" + name : "__transition"; | ||
} | ||
var selection_prototype = selection.prototype; | ||
@@ -44,0 +40,0 @@ |
import {Transition} from "./index"; | ||
export default function(selection) { | ||
export default function(transition) { | ||
if (transition._id !== this._id) throw new Error; | ||
for (var groups0 = this._groups, groups1 = selection._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) { | ||
for (var groups0 = this._groups, groups1 = transition._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) { | ||
for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) { | ||
@@ -17,3 +18,3 @@ if (node = group0[i] || group1[i]) { | ||
return new Transition(merges, this._parents, this._key, this._id); | ||
return new Transition(merges, this._parents, this._name, this._id); | ||
} |
@@ -11,7 +11,7 @@ import {get, set, init} from "./schedule"; | ||
function onFunction(key, id, name, listener) { | ||
function onFunction(id, name, listener) { | ||
if (typeof listener !== "function") throw new Error; | ||
var on0, on1, sit = start(name) ? init : set; | ||
return function() { | ||
var schedule = sit(this, key, id), | ||
var schedule = sit(this, id), | ||
on = schedule.on; | ||
@@ -29,8 +29,7 @@ | ||
export default function(name, listener) { | ||
var key = this._key, | ||
id = this._id; | ||
var id = this._id; | ||
return arguments.length < 2 | ||
? get(this.node(), key, id).on.on(name) | ||
: this.each(onFunction(key, id, name, listener)); | ||
? get(this.node(), id).on.on(name) | ||
: this.each(onFunction(id, name, listener)); | ||
} |
@@ -1,5 +0,6 @@ | ||
function removeFunction(key) { | ||
function removeFunction(id) { | ||
return function() { | ||
var parent = this.parentNode; | ||
if (parent && !this[key].pending.length) parent.removeChild(this); | ||
for (var i in this.__transition) if (+i !== id) return; | ||
if (parent) parent.removeChild(this); | ||
}; | ||
@@ -9,3 +10,3 @@ } | ||
export default function() { | ||
return this.on("end.remove", removeFunction(this._key)); | ||
return this.on("end.remove", removeFunction(this._id)); | ||
} |
@@ -7,12 +7,15 @@ import {dispatch} from "d3-dispatch"; | ||
var CREATED = 0, | ||
SCHEDULED = 1, | ||
STARTED = 2; | ||
export var CREATED = 0; | ||
export var SCHEDULED = 1; | ||
export var STARTING = 2; | ||
export var STARTED = 3; | ||
export var ENDING = 4; | ||
export var ENDED = 5; | ||
export default function(node, key, id, index, group, timing) { | ||
var schedules = node[key]; | ||
if (!schedules) node[key] = schedules = {active: null, pending: []}; | ||
else if (has(node, key, id)) return; | ||
start(node, key, { | ||
id: id, | ||
export default function(node, name, id, index, group, timing) { | ||
var schedules = node.__transition; | ||
if (!schedules) node.__transition = {}; | ||
else if (id in schedules) return; | ||
create(node, id, { | ||
name: name, | ||
index: index, // For context during callback. | ||
@@ -31,31 +34,22 @@ group: group, // For context during callback. | ||
function has(node, key, id) { | ||
var schedules = node[key]; | ||
if (!schedules) return; | ||
var schedule = schedules.active; | ||
if (schedule && schedule.id === id) return schedule; | ||
var pending = schedules.pending, i = pending.length; | ||
while (--i >= 0) if ((schedule = pending[i]).id === id) return schedule; | ||
} | ||
export function init(node, key, id) { | ||
var schedule = has(node, key, id); | ||
if (!schedule || schedule.state > CREATED) throw new Error("too late"); | ||
export function init(node, id) { | ||
var schedule = node.__transition; | ||
if (!schedule || !(schedule = schedule[id]) || schedule.state > CREATED) throw new Error("too late"); | ||
return schedule; | ||
} | ||
export function set(node, key, id) { | ||
var schedule = has(node, key, id); | ||
if (!schedule || schedule.state > SCHEDULED) throw new Error("too late"); | ||
export function set(node, id) { | ||
var schedule = node.__transition; | ||
if (!schedule || !(schedule = schedule[id]) || schedule.state > STARTING) throw new Error("too late"); | ||
return schedule; | ||
} | ||
export function get(node, key, id) { | ||
var schedule = has(node, key, id); | ||
if (!schedule) throw new Error("too late"); | ||
export function get(node, id) { | ||
var schedule = node.__transition; | ||
if (!schedule || !(schedule = schedule[id])) throw new Error("too late"); | ||
return schedule; | ||
} | ||
function start(node, key, self) { | ||
var schedules = node[key], | ||
function create(node, id, self) { | ||
var schedules = node.__transition, | ||
tween; | ||
@@ -65,3 +59,3 @@ | ||
// Note the actual delay is not known until the first callback! | ||
schedules.pending.push(self); | ||
schedules[id] = self; | ||
self.timer = timer(schedule, 0, self.time); | ||
@@ -78,26 +72,27 @@ | ||
function start(elapsed) { | ||
var interrupted = schedules.active, | ||
pending = schedules.pending, | ||
i, j, n, o; | ||
var i, j, n, o; | ||
// Interrupt the active transition, if any. | ||
// Dispatch the interrupt event. | ||
if (interrupted) { | ||
interrupted.timer.stop(); | ||
interrupted.on.call("interrupt", node, node.__data__, interrupted.index, interrupted.group); | ||
} | ||
for (i in schedules) { | ||
o = schedules[i]; | ||
if (o.name !== self.name) continue; | ||
// Cancel any pre-empted transitions. No interrupt event is dispatched | ||
// because the cancelled transitions never started. Note that this also | ||
// removes this transition from the pending list! | ||
for (i = 0, j = -1, n = pending.length; i < n; ++i) { | ||
o = pending[i]; | ||
if (o.id < self.id) o.timer.stop(); | ||
else if (o.id > self.id) pending[++j] = o; | ||
// Interrupt the active transition, if any. | ||
// Dispatch the interrupt event. | ||
if (o.state === STARTED) { | ||
o.state = ENDED; | ||
o.timer.stop(); | ||
o.on.call("interrupt", node, node.__data__, o.index, o.group); | ||
delete schedules[i]; | ||
} | ||
// Cancel any pre-empted transitions. No interrupt event is dispatched | ||
// because the cancelled transitions never started. Note that this also | ||
// removes this transition from the pending list! | ||
else if (+i < id) { | ||
o.state = ENDED; | ||
o.timer.stop(); | ||
delete schedules[i]; | ||
} | ||
} | ||
pending.length = j + 1; | ||
// Mark this transition as active. | ||
schedules.active = self; | ||
// Defer the first tick to end of the current frame; see mbostock/d3#1576. | ||
@@ -108,3 +103,3 @@ // Note the transition may be canceled after start and before the first tick! | ||
timeout(function() { | ||
if (schedules.active === self) { | ||
if (self.state === STARTED) { | ||
self.timer.restart(tick, self.delay, self.time); | ||
@@ -117,3 +112,5 @@ tick(elapsed); | ||
// Note this must be done before the tween are initialized. | ||
self.state = STARTING; | ||
self.on.call("start", node, node.__data__, self.index, self.group); | ||
if (self.state !== STARTING) return; // interrupted | ||
self.state = STARTED; | ||
@@ -132,18 +129,19 @@ | ||
function tick(elapsed) { | ||
var t = elapsed / self.duration, | ||
e = t >= 1 ? 1 : self.ease.call(null, t), | ||
i, n; | ||
var t = elapsed < self.duration ? self.ease.call(null, elapsed / self.duration) : (self.state = ENDING, 1), | ||
i = -1, | ||
n = tween.length; | ||
for (i = 0, n = tween.length; i < n; ++i) { | ||
tween[i].call(null, e); | ||
while (++i < n) { | ||
tween[i].call(null, t); | ||
} | ||
// Dispatch the end event. | ||
if (t >= 1) { | ||
if (self.state === ENDING) { | ||
self.state = ENDED; | ||
self.timer.stop(); | ||
self.on.call("end", node, node.__data__, self.index, self.group); | ||
schedules.active = null; | ||
if (!schedules.pending.length) delete node[key]; | ||
self.timer.stop(); | ||
for (i in schedules) if (+i !== id) return void delete schedules[id]; | ||
delete node.__transition; | ||
} | ||
} | ||
} |
@@ -6,3 +6,3 @@ import {selector} from "d3-selection"; | ||
export default function(select) { | ||
var key = this._key, | ||
var name = this._name, | ||
id = this._id; | ||
@@ -17,3 +17,3 @@ | ||
subgroup[i] = subnode; | ||
schedule(subgroup[i], key, id, i, subgroup, get(node, key, id)); | ||
schedule(subgroup[i], name, id, i, subgroup, get(node, id)); | ||
} | ||
@@ -23,3 +23,3 @@ } | ||
return new Transition(subgroups, this._parents, key, id); | ||
return new Transition(subgroups, this._parents, name, id); | ||
} |
@@ -6,3 +6,3 @@ import {selectorAll} from "d3-selection"; | ||
export default function(select) { | ||
var key = this._key, | ||
var name = this._name, | ||
id = this._id; | ||
@@ -15,5 +15,5 @@ | ||
if (node = group[i]) { | ||
for (var children = select.call(node, node.__data__, i, group), child, inherit = get(node, key, id), k = 0, l = children.length; k < l; ++k) { | ||
for (var children = select.call(node, node.__data__, i, group), child, inherit = get(node, id), k = 0, l = children.length; k < l; ++k) { | ||
if (child = children[k]) { | ||
schedule(child, key, id, k, children, inherit); | ||
schedule(child, name, id, k, children, inherit); | ||
} | ||
@@ -27,3 +27,3 @@ } | ||
return new Transition(subgroups, parents, key, id); | ||
return new Transition(subgroups, parents, name, id); | ||
} |
@@ -1,4 +0,5 @@ | ||
import {interpolate, interpolateTransformCss as interpolateTransform} from "d3-interpolate"; | ||
import {interpolateTransformCss as interpolateTransform} from "d3-interpolate"; | ||
import {window} from "d3-selection"; | ||
import {tweenValue} from "./tween"; | ||
import interpolate from "./interpolate"; | ||
@@ -58,3 +59,3 @@ function styleRemove(name, interpolate) { | ||
? styleFunction(name, i, tweenValue(this, "style." + name, value)) | ||
: styleConstant(name, i, value + ""), priority); | ||
: styleConstant(name, i, value), priority); | ||
} |
@@ -14,3 +14,3 @@ function styleTween(name, value, priority) { | ||
export default function(name, value, priority) { | ||
var key = "style." + name; | ||
var key = "style." + (name += ""); | ||
return arguments.length < 2 | ||
@@ -17,0 +17,0 @@ ? (key = this.tween(key)) && key._value |
@@ -5,3 +5,3 @@ import {Transition, newId} from "./index"; | ||
export default function() { | ||
var key = this._key, | ||
var name = this._name, | ||
id0 = this._id, | ||
@@ -13,4 +13,4 @@ id1 = newId(); | ||
if (node = group[i]) { | ||
var inherit = get(node, key, id0); | ||
schedule(node, key, id1, i, group, { | ||
var inherit = get(node, id0); | ||
schedule(node, name, id1, i, group, { | ||
time: inherit.time + inherit.delay + inherit.duration, | ||
@@ -25,3 +25,3 @@ delay: 0, | ||
return new Transition(groups, this._parents, key, id1); | ||
return new Transition(groups, this._parents, name, id1); | ||
} |
import {get, set} from "./schedule"; | ||
function tweenFunction(key, id, name, value) { | ||
function tweenFunction(id, name, value) { | ||
var tween0, tween1; | ||
return function() { | ||
var schedule = set(this, key, id), | ||
var schedule = set(this, id), | ||
tween = schedule.tween; | ||
@@ -28,4 +28,3 @@ | ||
export default function(name, value) { | ||
var key = this._key, | ||
id = this._id; | ||
var id = this._id; | ||
@@ -35,3 +34,3 @@ name += ""; | ||
if (arguments.length < 2) { | ||
var tween = get(this.node(), key, id).tween; | ||
var tween = get(this.node(), id).tween; | ||
for (var i = 0, n = tween.length, t; i < n; ++i) { | ||
@@ -46,17 +45,16 @@ if ((t = tween[i]).name === name) { | ||
if (typeof value !== "function") throw new Error; | ||
return this.each(tweenFunction(key, id, name, value)); | ||
return this.each(tweenFunction(id, name, value)); | ||
} | ||
export function tweenValue(transition, name, value) { | ||
var key = transition._key, | ||
id = transition._id; | ||
var id = transition._id; | ||
transition.each(function() { | ||
var schedule = set(this, key, id), v = value.apply(this, arguments); | ||
(schedule.value || (schedule.value = {}))[name] = v == null ? null : v + ""; | ||
var schedule = set(this, id); | ||
(schedule.value || (schedule.value = {}))[name] = value.apply(this, arguments); | ||
}); | ||
return function(node) { | ||
return get(node, key, id).value[name]; | ||
return get(node, id).value[name]; | ||
}; | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
92081
33
1301
408
6
+ Addedd3-color@~0.4.0