Checkpoint immediate-mode implementation.

This commit is contained in:
Michael Bostock 2010-10-23 20:32:16 -07:00
Родитель 4ff256dd76
Коммит 3cfeb7c664
36 изменённых файлов: 1145 добавлений и 2469 удалений

Просмотреть файл

@ -8,12 +8,15 @@ SRC_FILES = \
src/date.js \
src/object.js \
src/start.js \
src/array.js \
src/blend.js \
src/range.js \
src/ns.js \
src/dispatch.js \
src/dispatcher.js \
src/dispatchers.js \
src/ease.js \
src/interpolate.js \
src/tween.js \
src/join.js \
src/rgb.js \
src/hsl.js \
src/linear.js \
@ -21,19 +24,11 @@ SRC_FILES = \
src/pow.js \
src/sqrt.js \
src/ordinal.js \
src/transform.js \
src/transform_append.js \
src/transform_attr.js \
src/transform_bind.js \
src/transform_data.js \
src/transform_remove.js \
src/transform_on.js \
src/transform_filter.js \
src/transform_select.js \
src/transform_selectAll.js \
src/transform_style.js \
src/transform_text.js \
src/transform_transition.js \
src/root.js \
src/select.js \
src/selectAll.js \
src/selection.js \
src/transition.js \
src/end.js
all: d3.js d3.min.js

599
d3.alt.js
Просмотреть файл

@ -1,599 +0,0 @@
(function(_) {
var d3 = _.d3 = {},
d3_root = d3_selection([[document]]);
d3.version = "0.1.0";
d3.ns = {
prefix: {
svg: "http://www.w3.org/2000/svg",
xhtml: "http://www.w3.org/1999/xhtml",
xlink: "http://www.w3.org/1999/xlink",
xml: "http://www.w3.org/XML/1998/namespace",
xmlns: "http://www.w3.org/2000/xmlns/"
},
qualify: function(name) {
var i = name.indexOf(":");
return i < 0 ? name : {
space: d3.ns.prefix[name.substring(0, i)],
local: name.substring(i + 1)
};
}
};
function d3_array(psuedoarray) {
return Array.prototype.slice.call(psuedoarray);
}
function d3_blend(arrays) {
return Array.prototype.concat.apply([], arrays);
}
function d3_dispatchers() {
var dispatchers = {},
type;
for (var i = 0, n = arguments.length; i < n; i++) {
type = arguments[i];
dispatchers[type] = d3_dispatcher(type);
}
return dispatchers;
}
function d3_dispatcher(type) {
var dispatcher = {},
listeners = [];
dispatcher.add = function(listener) {
for (var i = 0; i < listeners.length; i++) {
if (listeners[i].listener == listener) return dispatcher; // already registered
}
listeners.push({listener: listener, on: true});
return dispatcher;
};
dispatcher.remove = function(listener) {
for (var i = 0; i < listeners.length; i++) {
var l = listeners[i];
if (l.listener == listener) {
l.on = false;
listeners = listeners.slice(0, i).concat(listeners.slice(i + 1));
break;
}
}
return dispatcher;
};
dispatcher.dispatch = function() {
var ls = listeners; // defensive reference
for (var i = 0, n = ls.length; i < n; i++) {
var l = ls[i];
if (l.on) l.listener.apply(this, arguments);
}
};
return dispatcher;
};
d3.select = function(query) {
return typeof query == "string"
? d3_root.select(query)
: d3_selection([[query]]); // assume node
};
d3.selectAll = function(query) {
return typeof query == "string"
? d3_root.selectAll(query)
: d3_selection([d3_array(query)]); // assume node[]
};
function d3_selection(groups) {
var i = -1,
n = groups.length,
group;
function select(select) {
var subgroups = [],
subgroup,
subnode,
group,
node;
for (var j = 0, m = groups.length; j < m; j++) {
group = groups[j];
subgroups.push(subgroup = []);
subgroup.parentNode = group.parentNode;
subgroup.parentData = group.parentData;
for (var i = 0, n = group.length; i < n; i++) {
if (node = group[i]) {
subgroup.push(subnode = select(node));
if (subnode) subnode.__data__ = node.__data__;
}
}
}
return d3_selection(subgroups);
}
function selectAll(selectAll) {
var subgroups = [],
subgroup,
group,
node;
for (var j = 0, m = groups.length; j < m; j++) {
group = groups[j];
for (var i = 0, n = group.length; i < n; i++) {
if (node = group[i]) {
subgroups.push(subgroup = selectAll(node));
subgroup.parentNode = node;
subgroup.parentData = node.__data__;
}
}
}
return d3_selection(subgroups);
}
// TODO select(function)?
groups.select = function(query) {
return select(function(node) {
return node.querySelector(query);
});
};
// TODO selectAll(function)?
groups.selectAll = function(query) {
return selectAll(function(node) {
return d3_array(node.querySelectorAll(query));
});
};
// TODO data(null) for clearing data?
groups.data = function(data, join) {
var i = -1,
n = groups.length,
group,
enter = [],
update = [],
exit = [];
if (typeof join == "string") join = d3_join(join);
function bind(group, groupData) {
var i = 0,
n = group.length,
m = groupData.length,
n0 = Math.min(n, m),
n1 = Math.max(n, m),
updateNodes = [],
enterNodes = [],
exitNodes = [],
node,
nodeData;
function append(e) {
return group.parentNode.appendChild(e);
}
if (join) {
var nodeByKey = {},
exitData = [],
keys = [],
key;
for (i = 0; i < n; i++) {
nodeByKey[key = join.node(node = group[i])] = node;
keys.push(key);
}
for (i = 0; i < m; i++) {
node = nodeByKey[key = join.data(nodeData = groupData[i])];
if (node) {
node.__data__ = nodeData;
updateNodes[i] = node;
enterNodes[i] = exitNodes[i] = null;
} else {
enterNodes[i] = {appendChild: append, __data__: nodeData};
updateNodes[i] = exitNodes[i] = null;
}
delete nodeByKey[key];
}
for (i = 0; i < n; i++) {
if (keys[i] in nodeByKey) {
exitNodes[i] = group[i];
}
}
} else {
for (; i < n0; i++) {
node = updateNodes[i] = group[i];
node.__data__ = groupData[i];
enterNodes[i] = exitNodes[i] = null;
}
for (; i < m; i++) {
enterNodes[i] = {appendChild: append, __data__: groupData[i]};
updateNodes[i] = exitNodes[i] = null;
}
for (; i < n1; i++) {
exitNodes[i] = group[i];
enterNodes[i] = updateNodes[i] = null;
}
}
enter.push(enterNodes);
update.push(updateNodes);
exit.push(exitNodes);
}
if (typeof data == "function") {
while (++i < n) {
bind(group = groups[i], data.call(group.parentNode, group.parentData, i));
}
} else {
while (++i < n) {
bind(group = groups[i], data);
}
}
var selection = d3_selection(update);
selection.enter = function(name) {
return d3_selection(enter).append(name);
};
selection.exit = function() {
return d3_selection(exit);
};
return selection;
};
// TODO mask forEach? or rename for eachData?
// TODO offer the same semantics for map, reduce, etc.?
groups.each = function(callback) {
for (var j = 0, m = groups.length; j < m; j++) {
var group = groups[j];
for (var i = 0, n = group.length; i < n; i++) {
var node = group[i];
if (node) callback.call(node, node.__data__, i);
}
}
return groups;
};
groups.attr = function(name, value) {
name = d3.ns.qualify(name);
function attrNull() {
this.removeAttribute(name);
}
function attrNullNS() {
this.removeAttributeNS(name.space, name.local);
}
function attrConstant() {
this.setAttribute(name, value);
}
function attrConstantNS() {
this.setAttributeNS(name.space, name.local, value);
}
function attrFunction() {
var x = value.apply(this, arguments);
if (x == null) this.removeAttribute(name);
else this.setAttribute(name, x);
}
function attrFunctionNS() {
var x = value.apply(this, arguments);
if (x == null) this.removeAttributeNS(name.space, name.local);
else this.setAttributeNS(name.space, name.local, x);
}
return groups.each(value == null
? (name.local ? attrNullNS : attrNull) : (typeof value == "function"
? (name.local ? attrFunctionNS : attrFunction)
: (name.local ? attrConstantNS : attrConstant)));
};
groups.style = function(name, value, priority) {
if (arguments.length < 3) priority = null;
function styleNull() {
this.style.removeProperty(name);
}
function styleConstant() {
this.style.setProperty(name, value, priority);
}
function styleFunction() {
var x = value.apply(this, arguments);
if (x == null) this.style.removeProperty(name);
else this.style.setProperty(name, x, priority);
}
return groups.each(value == null
? styleNull : (typeof value == "function"
? styleFunction : styleConstant));
};
groups.text = function(value) {
function textNull() {
while (this.lastChild) this.removeChild(this.lastChild);
}
function textConstant() {
this.appendChild(document.createTextNode(value));
}
function textFunction() {
var x = value.apply(this, arguments);
if (x != null) this.appendChild(document.createTextNode(x));
}
groups.each(textNull);
return value == null ? groups
: groups.each(typeof value == "function"
? textFunction : textConstant);
};
groups.html = function(value) {
function htmlConstant() {
this.innerHTML = value;
}
function htmlFunction() {
this.innerHTML = value.apply(this, arguments);
}
return groups.each(typeof value == "function"
? htmlFunction : htmlConstant);
};
// TODO append(node)?
// TODO append(function)?
groups.append = function(name) {
name = d3.ns.qualify(name);
function append(node) {
return node.appendChild(document.createElement(name));
}
function appendNS(node) {
return node.appendChild(document.createElementNS(name.space, name.local));
}
return select(name.local ? appendNS : append);
};
// TODO remove(query)?
// TODO remove(node)?
// TODO remove(function)?
groups.remove = function() {
return select(function(node) {
var parent = node.parentNode;
parent.removeChild(node);
return parent;
});
};
// TODO event
// TODO on?
// TODO filter, slice?
groups.transition = function() {
return d3_transition(groups);
};
return groups;
}
d3.transition = function() {
return d3_root.transition();
};
// TODO namespace transitions; cancel collisions
// TODO easing
function d3_transition(groups) {
var transition = {},
tweens = {},
timeout = setTimeout(start, 1),
interval,
then = Date.now(),
event = d3_dispatchers("start", "end"),
stage = [],
delay = [],
duration = [],
durationMax;
function start() {
interval = setInterval(step, 24);
}
function step() {
var elapsed = Date.now() - then,
clear = true,
k = -1;
groups.each(function(d, i) {
if (stage[++k] == 2) return; // ended
var t = (elapsed - delay[k]) / duration[k]; // TODO easing
if (t >= 1) {
t = 1;
} else {
clear = false;
if (t < 0) return;
if (!stage[k]) {
stage[k] = 1;
event.start.dispatch.apply(this, arguments);
}
}
for (var key in tweens) tweens[key].call(this, t);
if (t == 1) {
stage[k] = 2;
event.end.dispatch.apply(this, arguments);
}
});
if (clear) clearInterval(interval);
}
transition.delay = function(value) {
var delayMin = Infinity,
k = -1;
if (typeof value == "function") {
groups.each(function(d, i) {
var x = delay[++k] = +value.apply(this, arguments);
if (x < delayMin) delayMin = x;
});
} else {
delayMin = +value;
groups.each(function(d, i) {
delay[++k] = delayMin;
});
}
clearTimeout(timeout);
timeout = setTimeout(start, delayMin);
return transition;
};
transition.duration = function(value) {
var k = -1;
if (typeof value == "function") {
durationMax = 0;
groups.each(function(d, i) {
var x = duration[++k] = +value.apply(this, arguments);
if (x > durationMax) durationMax = x;
});
} else {
durationMax = +value;
groups.each(function(d, i) {
duration[++k] = durationMax;
});
}
return transition;
};
// TODO register custom easing functions?
// transition.easing = function(value) {
// easing = value;
// return transition;
// };
transition.attr = function(name, value) {
var key = "attr." + name + ".",
k = -1;
function attrConstant(d, i) {
tweens[key + ++k] = attrTween(
this.getAttribute(name),
value);
}
function attrConstantNS(d, i) {
tweens[key + ++k] = attrTweenNS(
this.getAttributeNS(name.space, name.local),
value);
}
function attrFunction(d, i) {
tweens[key + ++k] = attrTween(
this.getAttribute(name),
value.apply(this, arguments));
}
function attrFunctionNS(d, i) {
tweens[key + ++k] = attrTweenNS(
this.getAttributeNS(name.space, name.local),
value.apply(this, arguments));
}
function attrTween(a, b) {
var interpolate = d3_interpolate(a, b);
return function(t) {
this.setAttribute(name, interpolate(t));
};
}
function attrTweenNS(a, b) {
var interpolate = d3_interpolate(a, b);
return function(t) {
this.setAttributeNS(name.space, name.local, interpolate(t));
};
}
name = d3.ns.qualify(name);
groups.each(typeof value == "function"
? (name.local ? attrFunctionNS : attrFunction)
: (name.local ? attrConstantNS : attrConstant));
return transition;
};
transition.style = function(name, value, priority) {
var key = "style." + name + ".",
k = -1;
function styleConstant(d, i) {
tweens[key + ++k] = styleTween(
window.getComputedStyle(this, null).getPropertyValue(name),
value);
}
function styleFunction(d, i) {
tweens[key + ++k] = styleTween(
window.getComputedStyle(this, null).getPropertyValue(name),
value.apply(this, arguments));
}
function styleTween(a, b) {
var interpolate = d3_interpolate(a, b);
return function(t) {
this.style.setProperty(name, interpolate(t), priority);
};
}
groups.each(typeof value == "function" ? styleFunction : styleConstant);
return transition;
};
// TODO inherit easing
transition.select = function(query) {
var k, t = d3_transition(groups.select(query));
k = -1; t.delay(function(d, i) { return delay[++k]; });
k = -1; t.duration(function(d, i) { return duration[++k]; });
return t;
};
// TODO inherit easing
transition.selectAll = function(query) {
var k, t = d3_transition(groups.selectAll(query));
k = -1; t.delay(function(d, i) { return delay[i ? k : ++k]; })
k = -1; t.duration(function(d, i) { return duration[i ? k : ++k]; });
return t;
};
transition.on = function(type, listener) {
event[type].add(listener);
return transition;
};
return transition.delay(0).duration(250);
}
function d3_interpolate(a, b) {
return function(t) {
return a * (1 - t) + b * t;
};
}
function d3_join(key) {
return {
node: function(node) {
return node.getAttribute(key);
},
data: function(data) {
return data[key];
}
};
}
})(this);

1387
d3.js поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

72
d3.min.js поставляемый
Просмотреть файл

@ -1,39 +1,33 @@
if(!Date.now)Date.now=function(){return+new Date};if(!Object.create)Object.create=function(C){function z(){}z.prototype=C;return new z};
(function(C){function z(a){return function(f){return 1-a(1-f)}}function O(a){return function(f){return 0.5*(f<0.5?a(2*f):2-a(2-2*f))}}function V(a){return a}function D(a){return function(f){return Math.pow(f,a)}}function W(a){return 1-Math.cos(a*Math.PI/2)}function X(a){return a?Math.pow(2,10*(a-1))-0.0010:0}function Y(a){return 1-Math.sqrt(1-a*a)}function Z(a){return a<1/2.75?7.5625*a*a:a<2/2.75?7.5625*(a-=1.5/2.75)*a+0.75:a<2.5/2.75?7.5625*(a-=2.25/2.75)*a+0.9375:7.5625*(a-=2.625/2.75)*a+0.984375}
function E(a){var f,d,g,e,b;if(e=/([a-z]+)\((.*)\)/i.exec(a)){b=e[2].split(",");switch(e[1]){case "hsl":return P(parseFloat(b[0]),parseFloat(b[1])/100,parseFloat(b[2])/100);case "rgb":return{r:F(b[0]),g:F(b[1]),b:F(b[2])}}}if(e=w[a])return e;if(a==null)return w.black;if(a.charAt(0)=="#"){if(a.length==4){f=a.charAt(1);f+=f;d=a.charAt(2);d+=d;g=a.charAt(3);g+=g}else if(a.length==7){f=a.substring(1,3);d=a.substring(3,5);g=a.substring(5,7)}f=parseInt(f,16);d=parseInt(d,16);g=parseInt(g,16)}return{r:f,
g:d,b:g}}function P(a,f,d){function g(c){if(c>360)c-=360;else if(c<0)c+=360;if(c<60)return e+(b-e)*c/60;if(c<180)return b;if(c<240)return e+(b-e)*(240-c)/60;return e}var e,b;a%=360;if(a<0)a+=360;f=f<0?0:f>1?1:f;d=d<0?0:d>1?1:d;b=d<=0.5?d*(1+f):d+f-d*f;e=2*d-b;return{r:Math.round(g(a+120)*255),g:Math.round(g(a)*255),b:Math.round(g(a-120)*255)}}function F(a){var f=parseFloat(a);return a.charAt(a.length-1)=="%"?Math.round(f*2.55):f}function Q(){function a(g,e){var b=Object.create(f);b.pop=g;b.data=function(c){var i,
h={impl:R,bind:$,value:c,actions:[],enterActions:[],exitActions:[]};e.push(h);i=a(b,h.actions);i.enter=a(b,h.enterActions);i.exit=a(b,h.exitActions);i.key=function(l,n){h.key={name:A.qualify(l),value:n};return i};return i};b.attr=function(c,i){e.push({impl:aa,bind:ba,name:A.qualify(c),value:i});return b};b.style=function(c,i,h){e.push({impl:ca,bind:da,name:c,value:i,priority:arguments.length<3?null:h});return b};b.append=function(c,i){var h={impl:ea,name:A.qualify(c),value:i,actions:[]};e.push(h);
return a(b,h.actions)};b.remove=function(c){e.push({impl:fa,selector:c});return b};b.text=function(c){e.push({impl:ga,value:c});return b};b.on=function(c){c={impl:ha,type:c,actions:[]};e.push(c);return a(b,c.actions)};b.bind=function(c,i){e.push({impl:ia,type:c,listener:i});return b};b.filter=function(c){c={impl:S,bind:S,filter:c,actions:[]};e.push(c);return a(b,c.actions)};b.select=function(c){c={impl:G,bind:ja,selector:c,actions:[]};e.push(c);return a(b,c.actions)};b.selectAll=function(c){c={impl:H,
bind:ka,selector:c,actions:[]};e.push(c);return a(b,c.actions)};b.transition=function(){var c,i={impl:la,actions:[],endActions:[],ease:j.ease("cubic-in-out"),delay:0,duration:250};e.push(i);c=a(b,i.actions);c.end=a(b,i.endActions);c.ease=function(h){i.ease=typeof h=="string"?j.ease(h):h;return c};c.delay=function(h){i.delay=h;return c};c.duration=function(h){i.duration=h;return c};return c};return b}var f={},d=[];f.select=function(g){g={impl:G,selector:g,actions:[]};d.push(g);return a(f,g.actions)};
f.selectAll=function(g){g={impl:H,selector:g,actions:[]};d.push(g);return a(f,g.actions)};f.apply=function(){k.unshift(null);u(d,[{node:document,index:0}]);k.shift();return f};return f}function u(a,f){var d=a.length,g;for(g=0;g<d;++g)a[g].impl(f,u)}function ea(a,f){var d=a.length,g=this.name,e=[],b,c,i;if(g.local)for(b=0;b<d;++b){e.push(i=Object.create(c=a[b]));i.node=(i.parent=c).node.appendChild(document.createElementNS(g.space,g.local))}else for(b=0;b<d;++b){e.push(i=Object.create(c=a[b]));i.node=
(i.parent=c).node.appendChild(document.createElement(g))}f(this.actions,e)}function aa(a){var f=a.length,d=this.name,g=this.value,e,b,c;if(d.local)if(g==null)for(e=0;e<f;++e)a[e].node.removeAttributeNS(d.space,d.local);else if(typeof g=="function")for(e=0;e<f;++e){k[0]=(b=a[e]).data;c=g.apply(b,k);c==null?b.node.removeAttributeNS(d.space,d.local):b.node.setAttributeNS(d.space,d.local,c)}else for(e=0;e<f;++e)a[e].node.setAttributeNS(d.space,d.local,g);else if(g==null)for(e=0;e<f;++e)a[e].node.removeAttribute(d);
else if(typeof g=="function")for(e=0;e<f;++e){k[0]=(b=a[e]).data;c=g.apply(b,k);c==null?b.node.removeAttribute(d):b.node.setAttribute(d,c)}else for(e=0;e<f;++e)a[e].node.setAttribute(d,g)}function ba(a){var f=a.length,d=this.name,g=this.bound||(this.bound=this.value),e="attr."+(d.local?d.space+":"+d.local:d),b,c;if(g&&g.bind){if(d.local)for(b=0;b<f;++b){(c=a[b]).value=c.node.getAttributeNS(d.space,d.local);c.name=d.space+":"+d.local;k[0]=c.data;c[e]=g.bind.apply(c,k);delete c.value;delete c.name}else for(b=
0;b<f;++b){(c=a[b]).value=c.node.getAttribute(d);c.name=d;k[0]=c.data;c[e]=g.bind.apply(c,k);delete c.value;delete c.name}this.value=function(){return this[e].apply(this,arguments)}}}function ia(a){function f(h,l){return function(n){var o=k;try{j.event=n;i[0]=l;e.apply(h,k=i)}finally{delete j.event;k=o}}}var d=a.length,g="on"+this.type,e=this.listener,b=0,c,i=k.slice();if(e)for(;b<d;++b){c=a[b];c.node[g]=f(c,c.data)}else for(;b<d;++b)a[b].node[g]=null}function R(a,f){var d=this.value,g=a.length,e,
b=this.key,c,i,h,l,n=[],o=[],p=[],q,s,m;if(typeof d=="function"){c=k.shift();d=d.apply(null,k);k.unshift(c)}e=d.length;if(b){c=b.name;i=b.value;q={};s={};m={};if(c.local)for(b=0;b<g;++b){if(l=a[b].node){h=l.getAttributeNS(c.space,c.local);if(h!=null)q[h]=l}}else for(b=0;b<g;++b)if(l=a[b].node){h=l.getAttribute(c);if(h!=null)q[h]=l}for(b=0;b<e;++b){k[0]=c=d[b];h=i.apply(null,k);if(h!=null){s[h]=c;m[h]=b}}for(h in s){c=s[h];b=m[h];(l=q[h])?o.push({node:l,data:c,key:h,index:b}):n.push({node:a.parent.node,
data:c,key:h,index:b})}for(h in q)h in s||p.push({node:q[h]})}else{h=e<g?e:g;for(b=0;b<h;++b){(l=a[b]).data=d[b];if(l.node)o.push(l);else{l.node=l.parent.node;n.push(l)}}for(h=b;h<e;++h)n.push({node:a.parent.node,data:d[h],index:h});for(h=b;h<g;++h)p.push(a[h])}f(this.enterActions,n);f(this.actions,o);f(this.exitActions,p)}function $(a,f){var d=a.length,g=this.bound||(this.bound=this.value),e,b,c;if(g&&g.bind){e=[];for(b=0;b<d;++b){k[0]=(c=a[b]).data;c.value=c.data;c.data_=g.bind.apply(c,k);delete c.value}this.value=
function(){k.unshift(null);for(b=0;b<d;++b){k[0]=(c=a[b]).data;e[b]=c.data_.apply(c,k)}k.shift();return e}}else R.call(this,a,f)}function fa(a){var f=a.length,d=this.selector,g,e,b,c,i;if(d==null)for(e=0;e<f;++e){i=a[e].node;i.parentNode.removeChild(i)}else for(e=0;e<f;++e){g=a[e].node.querySelectorAll(d);b=0;for(c=g.length;b<c;b++){i=g[b];i.parentNode.removeChild(i)}}}function ha(a){function f(l){return function(n){var o=k;try{k=h;j.event=n;for(c=0;c<g;++c)d[c].impl(l,u)}finally{delete j.event;k=
o}}}var d=this.actions,g=d.length,e=a.length,b="on"+this.type,c=0,i,h=k.slice();if(g)for(;c<e;++c){i=a[c];i.node[b]=f([i])}else for(;c<e;++c)a[c].node[b]=null}function S(a,f){var d=[],g=a.length,e=this.filter,b,c;for(b=0;b<g;++b){k[0]=(c=a[b]).data;e.apply(c,k)&&d.push(c)}f(this.actions,d)}function G(a,f){var d=[],g=a.length,e=this.selector,b,c,i,h;for(b=0;b<g;++b){h=(c=a[b]).node.querySelector(e);d.push(i=Object.create(c));i.parent=c;i.node=h}f(this.actions,d)}function ja(a,f){var d=this;G.call(this,
a,function(g,e){f(g,e);d.impl=function(b,c){c(g,e)}})}function H(a,f){var d=a.length,g=this.selector,e,b;k.unshift(null);for(e=0;e<d;++e){k[1]=(b=a[e]).data;if(b.node){var c=f,i=this.actions,h=b.node.querySelectorAll(g),l=[],n=0,o=h.length;for(l.parent=b;n<o;n++)l.push({node:h[n],index:n});c(i,l)}}k.shift()}function ka(a,f){var d=a.length,g,e;H.call(this,a,function(b,c){f(b,c.parent.selectAll=c)});this.impl=function(b,c){k.unshift(null);g=0;for(d=b.length;g<d;++g){k[1]=(e=b[g]).data;c(this.actions,
e.selectAll)}k.shift()}}function ca(a){var f=a.length,d=this.name,g=this.value,e=this.priority,b,c,i;if(g==null)for(b=0;b<f;++b)a[b].node.style.removeProperty(d);else if(typeof g=="function")for(b=0;b<f;++b){c=a[b];k[0]=c.data;i=g.apply(c,k);i==null?c.node.style.removeProperty(d):c.node.style.setProperty(d,i,e)}else for(b=0;b<f;++b)a[b].node.style.setProperty(d,g,e)}function da(a){var f=a.length,d=this.name,g=this.bound||(this.bound=this.value),e="style."+d,b,c;if(g&&g.bind){for(b=0;b<f;++b){(c=a[b]).value=
c.node.style.getPropertyValue(d);c.name=d;k[0]=c.data;c[e]=g.bind.apply(c,k);delete c.value;delete c.name}this.value=function(){return this[e].apply(this,arguments)}}}function ga(a){var f=a.length,d=this.value,g,e,b;if(typeof d=="function")for(g=0;g<f;++g){e=a[g];k[0]=e.data;b=d.apply(e,k);for(e=e.node;e.lastChild;)e.removeChild(e.lastChild);e.appendChild(document.createTextNode(b))}else for(g=0;g<f;++g){for(e=a[g].node;e.lastChild;)e.removeChild(e.lastChild);e.appendChild(document.createTextNode(d))}}
function la(a){function f(x){for(m=0;m<s;++m)(r=a[m]).node.interval=x}function d(){var x=k,v=a.filter(function(ma){return ma.node.interval==o}),B=v.length,I=Date.now(),y,T=true;try{k=J;for(m=0;m<B;++m){r=v[m];y=(I-c-r.delay)/l;if(!(y<0)){if(y>1)y=1;else T=false;j.time=n(y);for(t=0;t<p;++t)e[t].impl([r],u);if(y==1){for(t=0;t<q;++t)b[t].impl([r],u);r.delay=Infinity}}}}finally{delete j.time;k=x}T&&clearInterval(o)}function g(){var x=k,v=(Date.now()-c-i)/l,B=a.filter(function(I){return I.node.interval==
o});try{k=J;j.time=n(v<0?0:v>1?1:v);for(m=0;m<p;++m)e[m].impl(B,u)}finally{delete j.time;k=x}if(v>=1){clearInterval(o);try{k=J;for(m=0;m<q;++m)b[m].impl(B,u)}finally{k=x}}}var e=this.actions,b=this.endActions,c=Date.now(),i=this.delay,h=Infinity,l=this.duration,n=this.ease,o,p=e.length,q=b.length,s=a.length,m,t,r,K,J=k.slice();if(typeof i=="function"){for(m=0;m<s;++m){k[0]=(r=a[m]).data;K=r.delay=i.apply(r,k);if(K<h)h=K}setTimeout(function(){f(o=setInterval(d,24))},h)}else setTimeout(function(){f(o=
setInterval(g,24))},i);try{j.time=0;U(e,a)}finally{delete j.time}}function U(a,f){var d=a.length,g,e;for(e=0;e<d;++e){g=a[e];g.bind&&g.bind(f,U)}}var j=C.d3={};j.version="0.0.0";j.range=function(a,f,d){if(arguments.length==1){f=a;a=0}if(d==null)d=1;if((f-a)/d==Infinity)throw Error("infinite range");var g=[],e=-1,b;if(d<0)for(;(b=a+d*++e)>f;)g.push(b);else for(;(b=a+d*++e)<f;)g.push(b);return g};var A={prefix:{svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",
xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"},resolve:function(a){return A.prefix[a]||null},qualify:function(a){var f=a.indexOf(":");return f<0?a:{space:A.prefix[a.substring(0,f)],local:a.substring(f+1)}}};j.dispatch=function(a){var f={};a.on=function(d,g){for(var e=f[d]||(f[d]=[]),b=0;b<e.length;b++)if(e[b].handler==g)return a;e.push({handler:g,on:true});return a};a.off=function(d,g){var e=f[d];if(e)for(var b=0;b<e.length;b++){var c=e[b];if(c.handler==g){c.on=
false;e.splice(b,1);break}}return a};a.dispatch=function(d){var g=f[d.type];if(g){g=g.slice();for(var e=0;e<g.length;e++){var b=g[e];b.on&&b.handler.call(a,d)}}};return a};var na=D(2),oa=D(3),pa={linear:function(){return V},poly:D,quad:function(){return na},cubic:function(){return oa},sin:function(){return W},exp:function(){return X},circle:function(){return Y},elastic:function(a,f){var d;if(arguments.length<2)f=0.45;if(arguments.length<1){a=1;d=f/4}else d=f/(2*Math.PI)*Math.asin(1/a);return function(g){return 1+
a*Math.pow(2,10*-g)*Math.sin(-(g+d)*2*Math.PI/f)}},back:function(a){a||(a=1.70158);return function(f){return f*f*((a+1)*f-a)}},bounce:function(){return Z}},qa={"in":function(a){return a},out:z,"in-out":O,"out-int":function(a){return O(z(a))}};j.ease=function(a){var f=a.indexOf("-"),d=f>=0?a.substring(0,f):a;f=f>=0?a.substring(f+1):"in";return qa[f](pa[d].apply(null,Array.prototype.slice.call(arguments,1)))};j.interpolate=function(a,f){if(typeof f=="number")return j.interpolateNumber(+a,f);if(typeof f==
"string")return f in w||/^(#|rgb\(|hsl\()/.test(f)?j.interpolateRgb(String(a),f):j.interpolateString(String(a),f);if(f instanceof Array)return j.interpolateArray(a,f);return j.interpolateObject(a,f)};j.interpolateNumber=function(a,f){f-=a;return function(d){return a+f*d}};j.interpolateString=function(a,f){var d,g,e=0,b=[],c=[],i,h;for(g=0;d=L.exec(f);++g){d.index&&b.push(f.substring(e,d.index));c.push({i:b.length,x:d[0]});b.push(null);e=L.lastIndex}e<f.length&&b.push(f.substring(e));g=0;for(i=c.length;(d=
L.exec(a))&&g<i;++g){h=c[g];if(h.x==d[0]){if(h.i)if(b[h.i+1]==null){b[h.i-1]+=h.x;b.splice(h.i,1);for(d=g+1;d<i;++d)c[d].i--}else{b[h.i-1]+=h.x+b[h.i+1];b.splice(h.i,2);for(d=g+1;d<i;++d)c[d].i-=2}else if(b[h.i+1]==null)b[h.i]=h.x;else{b[h.i]=h.x+b[h.i+1];b.splice(h.i+1,1);for(d=g+1;d<i;++d)c[d].i--}c.splice(g,1);i--;g--}else h.x=j.interpolateNumber(parseFloat(d[0]),parseFloat(h.x))}for(;g<i;){h=c.pop();if(b[h.i+1]==null)b[h.i]=h.x;else{b[h.i]=h.x+b[h.i+1];b.splice(h.i+1,1)}i--}if(b.length==1)return b[0]==
null?c[0].x:function(){return f};return function(l){for(g=0;g<i;++g)b[(h=c[g]).i]=h.x(l);return b.join("")}};j.interpolateRgb=function(a,f){a=E(a);f=E(f);var d=a.r,g=a.g,e=a.b,b=f.r-d,c=f.g-g,i=f.b-e;return function(h){return"rgb("+Math.round(d+b*h)+","+Math.round(g+c*h)+","+Math.round(e+i*h)+")"}};j.interpolateArray=function(a,f){var d=[],g=[],e=a.length,b=f.length,c=Math.min(a.length,f.length),i;for(i=0;i<c;++i)d.push(j.interpolate(a[i],f[i]));for(;i<e;++i)g[i]=a[i];for(;i<b;++i)g[i]=f[i];return function(h){for(i=
0;i<c;++i)g[i]=d[i](h);return g}};j.interpolateObject=function(a,f){var d={},g={},e;for(e in a)if(e in f)d[e]=(e in M||/\bcolor\b/.test(e)?j.interpolateRgb:j.interpolate)(a[e],f[e]);else g[e]=a[e];for(e in f)e in a||(g[e]=f[e]);return function(b){for(e in d)g[e]=d[e](b);return g}};var L=/[-+]?(?:\d+\.\d+|\d+\.|\.\d+|\d+)(?:[eE][-]?\d+)?/g,M={background:1,fill:1,stroke:1};j.tween=function(a){return{bind:typeof a=="function"?function(){var f=this.value,d=this.name,g=a.apply(this,arguments),e=(d in M||
/\bcolor\b/.test(d)?j.interpolateRgb:j.interpolate)(f,g);return function(){return e(j.time)}}:function(){var f=this.value,d=this.name,g=(d in M||/\bcolor\b/.test(d)?j.interpolateRgb:j.interpolate)(f,a);return function(){return g(j.time)}}}};var w={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",
chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",
darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",
lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",
mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",
peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",
wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"},N;for(N in w)w[N]=E(w[N]);j.hsl=function(a,f,d){a=P(a,f,d);return"rgb("+a.r+","+a.g+","+a.b+")"};j.linear=function(){function a(h){return i((h-d)*c)}function f(h){var l=Math.min(d,g),n=Math.max(d,g),o=n-l,p=Math.pow(10,Math.floor(Math.log(o/h)/Math.LN10));h=h/(o/p);if(h<=0.15)p*=10;else if(h<=0.35)p*=5;else if(h<=0.75)p*=2;return{start:Math.ceil(l/p)*p,stop:Math.floor(n/p)*p+p*0.5,step:p}}var d=0,g=1,e=0,
b=1,c=1/(g-d),i=j.interpolate(e,b);a.invert=function(h){return(h-e)/c+d};a.domain=function(h){if(!arguments.length)return[d,g];d=h[0];g=h[1];c=1/(g-d);return a};a.range=function(h){if(!arguments.length)return[e,b];e=h[0];b=h[1];i=j.interpolate(e,b);return a};a.ticks=function(h){h=f(h);return j.range(h.start,h.stop,h.step)};a.tickFormat=function(h){var l=Math.max(0,-Math.floor(Math.log(f(h).step)/Math.LN10+0.01));return function(n){return n.toFixed(l)}};return a};j.log=function(){function a(d){return f(Math.log(d))}
var f=j.linear();a.invert=function(d){return Math.exp(f.invert(d))};a.domain=function(d){if(!arguments.length)return f.domain().map(Math.exp);f.domain(d.map(Math.log));return a};a.range=function(){var d=f.range.apply(f,arguments);return arguments.length?a:d};return a};j.pow=function(){function a(c){return Math.pow(c,e)}function f(c){return Math.pow(c,b)}function d(c){return g(a(c))}var g=j.linear(),e=1,b=1/e;d.invert=function(c){return f(g.invert(c))};d.domain=function(c){if(!arguments.length)return g.domain().map(f);
g.domain(c.map(a));return d};d.range=function(){var c=g.range.apply(g,arguments);return arguments.length?d:c};d.exponent=function(c){if(!arguments.length)return e;var i=d.domain();e=c;b=1/c;return d.domain(i)};return d};j.sqrt=function(){return j.pow().exponent(0.5)};j.ordinal=function(){function a(b){b=b in d?d[b]:d[b]=f.push(b)-1;return g[b%g.length]}var f=[],d={},g=[],e=0;a.domain=function(b){if(!arguments.length)return f;f=b;d={};for(var c=-1,i=-1,h=f.length;++c<h;){b=f[c];b in d||(d[b]=++i)}return a};
a.range=function(b){if(!arguments.length)return g;g=b;return a};a.rangePoints=function(b,c){if(arguments.length<2)c=0;var i=b[0],h=b[1],l=(h-i)/(f.length-1+c);g=f.length==1?[(i+h)/2]:j.range(i+l*c/2,h+l/2,l);e=0;return a};a.rangeBands=function(b,c){if(arguments.length<2)c=0;var i=b[0],h=b[1],l=(h-i)/(f.length+c);g=j.range(i+l*c,h,l);e=l*(1-c);return a};a.rangeBand=function(){return e};return a};var k=[];j.select=function(a){return Q().select(a)};j.selectAll=function(a){return Q().selectAll(a)}})(this);
if(!Date.now)Date.now=function(){return+new Date};if(!Object.create)Object.create=function(F){function E(){}E.prototype=F;return new E};
(function(F){function E(){var a={},c=[];a.add=function(e){for(var b=0;b<c.length;b++)if(c[b].listener==e)return a;c.push({listener:e,on:true});return a};a.remove=function(e){for(var b=0;b<c.length;b++){var d=c[b];if(d.listener==e){d.on=false;c=c.slice(0,b).concat(c.slice(b+1));break}}return a};a.dispatch=function(){for(var e=c,b=0,d=e.length;b<d;b++){var f=e[b];f.on&&f.listener.apply(this,arguments)}};return a}function Q(){for(var a={},c,e=0,b=arguments.length;e<b;e++){c=arguments[e];a[c]=E(c)}return a}
function N(a){return function(c){return 1-a(1-c)}}function O(a){return function(c){return 0.5*(c<0.5?a(2*c):2-a(2-2*c))}}function R(a){return a}function G(a){return function(c){return Math.pow(c,a)}}function S(a){return 1-Math.cos(a*Math.PI/2)}function T(a){return a?Math.pow(2,10*(a-1))-0.0010:0}function U(a){return 1-Math.sqrt(1-a*a)}function V(a){return a<1/2.75?7.5625*a*a:a<2/2.75?7.5625*(a-=1.5/2.75)*a+0.75:a<2.5/2.75?7.5625*(a-=2.25/2.75)*a+0.9375:7.5625*(a-=2.625/2.75)*a+0.984375}function W(a){return{node:function(c){return c.getAttribute(a)},
data:function(c){return c[a]}}}function H(a){var c,e,b,d,f;if(d=/([a-z]+)\((.*)\)/i.exec(a)){f=d[2].split(",");switch(d[1]){case "hsl":return P(parseFloat(f[0]),parseFloat(f[1])/100,parseFloat(f[2])/100);case "rgb":return{r:I(f[0]),g:I(f[1]),b:I(f[2])}}}if(d=C[a])return d;if(a==null)return C.black;if(a.charAt(0)=="#"){if(a.length==4){c=a.charAt(1);c+=c;e=a.charAt(2);e+=e;b=a.charAt(3);b+=b}else if(a.length==7){c=a.substring(1,3);e=a.substring(3,5);b=a.substring(5,7)}c=parseInt(c,16);e=parseInt(e,
16);b=parseInt(b,16)}return{r:c,g:e,b:b}}function P(a,c,e){function b(h){if(h>360)h-=360;else if(h<0)h+=360;if(h<60)return d+(f-d)*h/60;if(h<180)return f;if(h<240)return d+(f-d)*(240-h)/60;return d}var d,f;a%=360;if(a<0)a+=360;c=c<0?0:c>1?1:c;e=e<0?0:e>1?1:e;f=e<=0.5?e*(1+c):e+c-e*c;d=2*e-f;return{r:Math.round(b(a+120)*255),g:Math.round(b(a)*255),b:Math.round(b(a-120)*255)}}function I(a){var c=parseFloat(a);return a.charAt(a.length-1)=="%"?Math.round(c*2.55):c}function z(a){function c(b){for(var d=
[],f,h,i,g,n=0,q=a.length;n<q;n++){i=a[n];d.push(f=[]);f.parentNode=i.parentNode;f.parentData=i.parentData;for(var p=0,o=i.length;p<o;p++)if(g=i[p]){f.push(h=b(g));if(h)h.__data__=g.__data__}}return z(d)}function e(b){for(var d=[],f,h,i,g=0,n=a.length;g<n;g++){h=a[g];for(var q=0,p=h.length;q<p;q++)if(i=h[q]){d.push(f=b(i));f.parentNode=i;f.parentData=i.__data__}}return z(d)}a.select=function(b){return c(function(d){return d.querySelector(b)})};a.selectAll=function(b){return e(function(d){d=d.querySelectorAll(b);
return Array.prototype.slice.call(d)})};a.data=function(b,d){function f(o,k){function m(D){return o.parentNode.appendChild(D)}var j=0,r=o.length,x=k.length,y=Math.min(r,x),v=Math.max(r,x),w=[],t=[],s=[],u;if(d){v={};var A=[],B;for(j=0;j<r;j++){v[B=d.node(u=o[j])]=u;A.push(B)}for(j=0;j<x;j++){if(u=v[B=d.data(y=k[j])]){u.__data__=y;w[j]=u;t[j]=s[j]=null}else{t[j]={appendChild:m,__data__:y};w[j]=s[j]=null}delete v[B]}for(j=0;j<r;j++)if(A[j]in v)s[j]=o[j]}else{for(;j<y;j++){u=w[j]=o[j];u.__data__=k[j];
t[j]=s[j]=null}for(;j<x;j++){t[j]={appendChild:m,__data__:k[j]};w[j]=s[j]=null}for(;j<v;j++){s[j]=o[j];t[j]=w[j]=null}}n.push(t);q.push(w);p.push(s)}var h=-1,i=a.length,g,n=[],q=[],p=[];if(typeof d=="string")d=W(d);if(typeof b=="function")for(;++h<i;)f(g=a[h],b.call(g.parentNode,g.parentData,h));else for(;++h<i;)f(g=a[h],b);h=z(q);h.enter=function(o){return z(n).append(o)};h.exit=function(){return z(p)};return h};a.each=function(b){for(var d=0,f=a.length;d<f;d++)for(var h=a[d],i=0,g=h.length;i<g;i++){var n=
h[i];n&&b.call(n,n.__data__,i)}return a};a.attr=function(b,d){function f(){this.removeAttribute(b)}function h(){this.removeAttributeNS(b.space,b.local)}function i(){this.setAttribute(b,d)}function g(){this.setAttributeNS(b.space,b.local,d)}function n(){var p=d.apply(this,arguments);p==null?this.removeAttribute(b):this.setAttribute(b,p)}function q(){var p=d.apply(this,arguments);p==null?this.removeAttributeNS(b.space,b.local):this.setAttributeNS(b.space,b.local,p)}b=l.ns.qualify(b);return a.each(d==
null?b.local?h:f:typeof d=="function"?b.local?q:n:b.local?g:i)};a.style=function(b,d,f){function h(){this.style.removeProperty(b)}function i(){this.style.setProperty(b,d,f)}function g(){var n=d.apply(this,arguments);n==null?this.style.removeProperty(b):this.style.setProperty(b,n,f)}if(arguments.length<3)f=null;return a.each(d==null?h:typeof d=="function"?g:i)};a.text=function(b){function d(){this.appendChild(document.createTextNode(b))}function f(){var h=b.apply(this,arguments);h!=null&&this.appendChild(document.createTextNode(h))}
a.each(function(){for(;this.lastChild;)this.removeChild(this.lastChild)});return b==null?a:a.each(typeof b=="function"?f:d)};a.html=function(b){function d(){this.innerHTML=b}function f(){this.innerHTML=b.apply(this,arguments)}return a.each(typeof b=="function"?f:d)};a.append=function(b){function d(h){return h.appendChild(document.createElement(b))}function f(h){return h.appendChild(document.createElementNS(b.space,b.local))}b=l.ns.qualify(b);return c(b.local?f:d)};a.remove=function(){return c(function(b){var d=
b.parentNode;d.removeChild(b);return d})};a.transition=function(){return J(a)};return a}function J(a){function c(){h=setInterval(e,24)}function e(){var k=Date.now()-i,m=true,j=-1;a.each(function(){if(n[++j]!=2){var r=(k-q[j])/p[j];if(r>=1)r=1;else{m=false;if(r<0)return;if(!n[j]){n[j]=1;g.start.dispatch.apply(this,arguments)}}for(var x in d)d[x].call(this,r);if(r==1){n[j]=2;g.end.dispatch.apply(this,arguments)}}});m&&clearInterval(h)}var b={},d={},f=setTimeout(c,1),h,i=Date.now(),g=Q("start","end"),
n=[],q=[],p=[],o;b.delay=function(k){var m=Infinity,j=-1;if(typeof k=="function")a.each(function(){var r=q[++j]=+k.apply(this,arguments);if(r<m)m=r});else{m=+k;a.each(function(){q[++j]=m})}clearTimeout(f);f=setTimeout(c,m);return b};b.duration=function(k){var m=-1;if(typeof k=="function"){o=0;a.each(function(){var j=p[++m]=+k.apply(this,arguments);if(j>o)o=j})}else{o=+k;a.each(function(){p[++m]=o})}return b};b.attr=function(k,m){function j(){d[t+ ++s]=v(this.getAttribute(k),m)}function r(){d[t+ ++s]=
w(this.getAttributeNS(k.space,k.local),m)}function x(){d[t+ ++s]=v(this.getAttribute(k),m.apply(this,arguments))}function y(){d[t+ ++s]=w(this.getAttributeNS(k.space,k.local),m.apply(this,arguments))}function v(u,A){var B=l.interpolate(u,A);return function(D){this.setAttribute(k,B(D))}}function w(u,A){var B=l.interpolate(u,A);return function(D){this.setAttributeNS(k.space,k.local,B(D))}}var t="attr."+k+".",s=-1;k=l.ns.qualify(k);a.each(typeof m=="function"?k.local?y:x:k.local?r:j);return b};b.style=
function(k,m,j){function r(){d[v+ ++w]=y(window.getComputedStyle(this,null).getPropertyValue(k),m)}function x(){d[v+ ++w]=y(window.getComputedStyle(this,null).getPropertyValue(k),m.apply(this,arguments))}function y(t,s){var u=l.interpolate(t,s);return function(A){this.style.setProperty(k,u(A),j)}}var v="style."+k+".",w=-1;a.each(typeof m=="function"?x:r);return b};b.select=function(k){var m;k=J(a.select(k));m=-1;k.delay(function(){return q[++m]});m=-1;k.duration(function(){return p[++m]});return k};
b.selectAll=function(k){var m;k=J(a.selectAll(k));m=-1;k.delay(function(j,r){return q[r?m:++m]});m=-1;k.duration(function(j,r){return p[r?m:++m]});return k};b.on=function(k,m){g[k].add(m);return b};return b.delay(0).duration(250)}var l=F.d3={};l.version="0.1.0";l.range=function(a,c,e){if(arguments.length==1){c=a;a=0}if(e==null)e=1;if((c-a)/e==Infinity)throw Error("infinite range");var b=[],d=-1,f;if(e<0)for(;(f=a+e*++d)>c;)b.push(f);else for(;(f=a+e*++d)<c;)b.push(f);return b};l.ns={prefix:{svg:"http://www.w3.org/2000/svg",
xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"},qualify:function(a){var c=a.indexOf(":");return c<0?a:{space:l.ns.prefix[a.substring(0,c)],local:a.substring(c+1)}}};var X=G(2),Y=G(3),Z={linear:function(){return R},poly:G,quad:function(){return X},cubic:function(){return Y},sin:function(){return S},exp:function(){return T},circle:function(){return U},elastic:function(a,c){var e;if(arguments.length<
2)c=0.45;if(arguments.length<1){a=1;e=c/4}else e=c/(2*Math.PI)*Math.asin(1/a);return function(b){return 1+a*Math.pow(2,10*-b)*Math.sin(-(b+e)*2*Math.PI/c)}},back:function(a){a||(a=1.70158);return function(c){return c*c*((a+1)*c-a)}},bounce:function(){return V}},$={"in":function(a){return a},out:N,"in-out":O,"out-int":function(a){return O(N(a))}};l.ease=function(a){var c=a.indexOf("-"),e=c>=0?a.substring(0,c):a;c=c>=0?a.substring(c+1):"in";return $[c](Z[e].apply(null,Array.prototype.slice.call(arguments,
1)))};l.interpolate=function(a,c){if(typeof c=="number")return l.interpolateNumber(+a,c);if(typeof c=="string")return c in C||/^(#|rgb\(|hsl\()/.test(c)?l.interpolateRgb(String(a),c):l.interpolateString(String(a),c);if(c instanceof Array)return l.interpolateArray(a,c);return l.interpolateObject(a,c)};l.interpolateNumber=function(a,c){c-=a;return function(e){return a+c*e}};l.interpolateString=function(a,c){var e,b,d=0,f=[],h=[],i,g;for(b=0;e=K.exec(c);++b){e.index&&f.push(c.substring(d,e.index));h.push({i:f.length,
x:e[0]});f.push(null);d=K.lastIndex}d<c.length&&f.push(c.substring(d));b=0;for(i=h.length;(e=K.exec(a))&&b<i;++b){g=h[b];if(g.x==e[0]){if(g.i)if(f[g.i+1]==null){f[g.i-1]+=g.x;f.splice(g.i,1);for(e=b+1;e<i;++e)h[e].i--}else{f[g.i-1]+=g.x+f[g.i+1];f.splice(g.i,2);for(e=b+1;e<i;++e)h[e].i-=2}else if(f[g.i+1]==null)f[g.i]=g.x;else{f[g.i]=g.x+f[g.i+1];f.splice(g.i+1,1);for(e=b+1;e<i;++e)h[e].i--}h.splice(b,1);i--;b--}else g.x=l.interpolateNumber(parseFloat(e[0]),parseFloat(g.x))}for(;b<i;){g=h.pop();if(f[g.i+
1]==null)f[g.i]=g.x;else{f[g.i]=g.x+f[g.i+1];f.splice(g.i+1,1)}i--}if(f.length==1)return f[0]==null?h[0].x:function(){return c};return function(n){for(b=0;b<i;++b)f[(g=h[b]).i]=g.x(n);return f.join("")}};l.interpolateRgb=function(a,c){a=H(a);c=H(c);var e=a.r,b=a.g,d=a.b,f=c.r-e,h=c.g-b,i=c.b-d;return function(g){return"rgb("+Math.round(e+f*g)+","+Math.round(b+h*g)+","+Math.round(d+i*g)+")"}};l.interpolateArray=function(a,c){var e=[],b=[],d=a.length,f=c.length,h=Math.min(a.length,c.length),i;for(i=
0;i<h;++i)e.push(l.interpolate(a[i],c[i]));for(;i<d;++i)b[i]=a[i];for(;i<f;++i)b[i]=c[i];return function(g){for(i=0;i<h;++i)b[i]=e[i](g);return b}};l.interpolateObject=function(a,c){var e={},b={},d;for(d in a)if(d in c)e[d]=(d in aa||/\bcolor\b/.test(d)?l.interpolateRgb:l.interpolate)(a[d],c[d]);else b[d]=a[d];for(d in c)d in a||(b[d]=c[d]);return function(f){for(d in e)b[d]=e[d](f);return b}};var K=/[-+]?(?:\d+\.\d+|\d+\.|\.\d+|\d+)(?:[eE][-]?\d+)?/g,aa={background:1,fill:1,stroke:1},C={aliceblue:"#f0f8ff",
antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",
darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",
goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",
lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",
navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",
silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"},L;for(L in C)C[L]=H(C[L]);l.hsl=function(a,c,e){a=P(a,c,e);return"rgb("+a.r+","+a.g+","+a.b+")"};l.linear=function(){function a(g){return i((g-e)*h)}function c(g){var n=
Math.min(e,b),q=Math.max(e,b),p=q-n,o=Math.pow(10,Math.floor(Math.log(p/g)/Math.LN10));g=g/(p/o);if(g<=0.15)o*=10;else if(g<=0.35)o*=5;else if(g<=0.75)o*=2;return{start:Math.ceil(n/o)*o,stop:Math.floor(q/o)*o+o*0.5,step:o}}var e=0,b=1,d=0,f=1,h=1/(b-e),i=l.interpolate(d,f);a.invert=function(g){return(g-d)/h+e};a.domain=function(g){if(!arguments.length)return[e,b];e=g[0];b=g[1];h=1/(b-e);return a};a.range=function(g){if(!arguments.length)return[d,f];d=g[0];f=g[1];i=l.interpolate(d,f);return a};a.ticks=
function(g){g=c(g);return l.range(g.start,g.stop,g.step)};a.tickFormat=function(g){var n=Math.max(0,-Math.floor(Math.log(c(g).step)/Math.LN10+0.01));return function(q){return q.toFixed(n)}};return a};l.log=function(){function a(e){return c(Math.log(e))}var c=l.linear();a.invert=function(e){return Math.exp(c.invert(e))};a.domain=function(e){if(!arguments.length)return c.domain().map(Math.exp);c.domain(e.map(Math.log));return a};a.range=function(){var e=c.range.apply(c,arguments);return arguments.length?
a:e};return a};l.pow=function(){function a(h){return Math.pow(h,d)}function c(h){return Math.pow(h,f)}function e(h){return b(a(h))}var b=l.linear(),d=1,f=1/d;e.invert=function(h){return c(b.invert(h))};e.domain=function(h){if(!arguments.length)return b.domain().map(c);b.domain(h.map(a));return e};e.range=function(){var h=b.range.apply(b,arguments);return arguments.length?e:h};e.exponent=function(h){if(!arguments.length)return d;var i=e.domain();d=h;f=1/h;return e.domain(i)};return e};l.sqrt=function(){return l.pow().exponent(0.5)};
l.ordinal=function(){function a(f){f=f in e?e[f]:e[f]=c.push(f)-1;return b[f%b.length]}var c=[],e={},b=[],d=0;a.domain=function(f){if(!arguments.length)return c;c=f;e={};for(var h=-1,i=-1,g=c.length;++h<g;){f=c[h];f in e||(e[f]=++i)}return a};a.range=function(f){if(!arguments.length)return b;b=f;return a};a.rangePoints=function(f,h){if(arguments.length<2)h=0;var i=f[0],g=f[1],n=(g-i)/(c.length-1+h);b=c.length==1?[(i+g)/2]:l.range(i+n*h/2,g+n/2,n);d=0;return a};a.rangeBands=function(f,h){if(arguments.length<
2)h=0;var i=f[0],g=f[1],n=(g-i)/(c.length+h);b=l.range(i+n*h,g,n);d=n*(1-h);return a};a.rangeBand=function(){return d};return a};var M=z([[document]]);l.select=function(a){return typeof a=="string"?M.select(a):z([[a]])};l.selectAll=function(a){return typeof a=="string"?M.selectAll(a):z([Array.prototype.slice.call(a)])};l.transition=function(){return M.transition()}})(this);

Просмотреть файл

@ -55,7 +55,7 @@ var vis = d3.select("body")
var rules = vis.selectAll("g.rule")
.data(d3.range(0, 1.05, .1))
.enter.append("svg:g")
.enter("svg:g")
.attr("class", "rule");
rules.append("svg:line")
@ -95,14 +95,12 @@ vis.append("svg:path")
vis.selectAll("circle.area")
.data(data)
.enter.append("svg:circle")
.enter("svg:circle")
.attr("class", "area")
.attr("cx", function(d) { return x(d.x); })
.attr("cy", function(d) { return y(d.y); })
.attr("r", 3.5);
vis.apply();
function line(points) {
var d = [],
i = 1,

Просмотреть файл

@ -33,9 +33,9 @@ var vis = d3.select("body")
var bars = vis.selectAll("g.bar")
.data(data)
.enter.append("svg:g")
.enter("svg:g")
.attr("class", "bar")
.attr("transform", function(d) { return "translate(0," + y(this.index) + ")"; });
.attr("transform", function(d, i) { return "translate(0," + y(i) + ")"; });
bars.append("svg:rect")
.attr("fill", "steelblue")
@ -57,11 +57,11 @@ bars.append("svg:text")
.attr("dx", -6)
.attr("dy", ".35em")
.attr("text-anchor", "end")
.text(function(d) { return String.fromCharCode(65 + this.index); });
.text(function(d, i) { return String.fromCharCode(65 + i); });
var rules = vis.selectAll("g.rule")
.data(x.ticks(10))
.enter.append("svg:g")
.enter("svg:g")
.attr("class", "rule")
.attr("transform", function(d) { return "translate(" + x(d) + ",0)"; });
@ -87,8 +87,6 @@ vis.append("svg:line")
.attr("y2", h)
.attr("stroke", "black");
vis.apply();
</script>
</body>
</html>

Просмотреть файл

@ -47,7 +47,7 @@ var w = 960,
var vis = d3.select("body")
.selectAll("svg")
.data(range(1990, 2011))
.enter.append("svg:svg")
.enter("svg:svg")
.attr("width", w)
.attr("height", h)
.attr("class", "RdYlGn")
@ -60,7 +60,7 @@ vis.append("svg:text")
vis.selectAll("rect.day")
.data(dates)
.enter.append("svg:rect")
.enter("svg:rect")
.attr("x", function(d) { return d.week * z; })
.attr("y", function(d) { return d.day * z; })
.attr("class", function(d) { return "day q" + color(data[d.Date]) + "-9"; })
@ -71,7 +71,7 @@ vis.selectAll("rect.day")
vis.selectAll("path.month")
.data(months)
.enter.append("svg:path")
.enter("svg:path")
.attr("class", "month")
.attr("d", function(d) {
return "M" + (d.firstWeek + 1) * z + "," + d.firstDay * z
@ -85,8 +85,6 @@ vis.selectAll("path.month")
+ "Z";
});
vis.apply();
function range(start, end, step) {
if (arguments.length < 3) {
step = 1;

Просмотреть файл

@ -47,7 +47,7 @@ var w = 960,
var vis = d3.select("body")
.selectAll("svg")
.data(range(1993, 2011))
.enter.append("svg:svg")
.enter("svg:svg")
.attr("width", w)
.attr("height", h)
.attr("class", "RdYlGn")
@ -60,7 +60,7 @@ vis.append("svg:text")
vis.selectAll("rect.day")
.data(dates)
.enter.append("svg:rect")
.enter("svg:rect")
.attr("x", function(d) { return d.week * z; })
.attr("y", function(d) { return d.day * z; })
.attr("class", function(d) { return "day q" + (8-color(data[d.Date])) + "-9"; })
@ -71,7 +71,7 @@ vis.selectAll("rect.day")
vis.selectAll("path.month")
.data(months)
.enter.append("svg:path")
.enter("svg:path")
.attr("class", "month")
.attr("d", function(d) {
return "M" + (d.firstWeek + 1) * z + "," + d.firstDay * z
@ -85,8 +85,6 @@ vis.selectAll("path.month")
+ "Z";
});
vis.apply();
function range(start, end, step) {
if (arguments.length < 3) {
step = 1;

Просмотреть файл

@ -30,7 +30,7 @@ rect {
<body>
<script type="text/javascript">
var data = range(100).map(function(i) {
var data = d3.range(100).map(function(i) {
return {x: i / 99, y: Math.random()};
});
@ -46,8 +46,8 @@ var vis = d3.select("body")
.attr("transform", "translate(" + p + "," + p + ")");
var rules = vis.selectAll("g.rule")
.data(range(11))
.enter.append("svg:g")
.data(d3.range(11))
.enter("svg:g")
.attr("class", "rule");
rules.append("svg:line")
@ -82,25 +82,17 @@ vis.append("svg:rect")
var dots = vis.selectAll("circle.dot")
.data(data)
.enter.append("svg:circle")
.enter("svg:circle")
.attr("class", "dot")
.attr("cx", function(d) { return d.x * w; })
.attr("cy", function(d) { return d.y * h; })
.attr("r", 27)
.attr("stroke-opacity", 1e-6)
.transition()
.delay(function() { return this.index * 3; })
.delay(function(d, i) { return 1000 + i * 3; })
.duration(750)
.attr("stroke-opacity", d3.tween(1))
.attr("r", d3.tween(4.5));
vis.apply();
function range(n) {
var array = [];
for (var i = 0; i < n; i++) array.push(i);
return array;
}
.attr("stroke-opacity", 1)
.attr("r", 4.5);
</script>
</body>

3
src/array.js Normal file
Просмотреть файл

@ -0,0 +1,3 @@
function d3_array(psuedoarray) {
return Array.prototype.slice.call(psuedoarray);
}

3
src/blend.js Normal file
Просмотреть файл

@ -0,0 +1,3 @@
function d3_blend(arrays) {
return Array.prototype.concat.apply([], arrays);
}

Просмотреть файл

@ -1,37 +0,0 @@
d3.dispatch = function(that) {
var types = {};
that.on = function(type, handler) {
var listeners = types[type] || (types[type] = []);
for (var i = 0; i < listeners.length; i++) {
if (listeners[i].handler == handler) return that; // already registered
}
listeners.push({handler: handler, on: true});
return that;
};
that.off = function(type, handler) {
var listeners = types[type];
if (listeners) for (var i = 0; i < listeners.length; i++) {
var l = listeners[i];
if (l.handler == handler) {
l.on = false;
listeners.splice(i, 1);
break;
}
}
return that;
};
that.dispatch = function(event) {
var listeners = types[event.type];
if (!listeners) return;
listeners = listeners.slice(); // defensive copy
for (var i = 0; i < listeners.length; i++) {
var l = listeners[i];
if (l.on) l.handler.call(that, event);
}
};
return that;
};

34
src/dispatcher.js Normal file
Просмотреть файл

@ -0,0 +1,34 @@
function d3_dispatcher(type) {
var dispatcher = {},
listeners = [];
dispatcher.add = function(listener) {
for (var i = 0; i < listeners.length; i++) {
if (listeners[i].listener == listener) return dispatcher; // already registered
}
listeners.push({listener: listener, on: true});
return dispatcher;
};
dispatcher.remove = function(listener) {
for (var i = 0; i < listeners.length; i++) {
var l = listeners[i];
if (l.listener == listener) {
l.on = false;
listeners = listeners.slice(0, i).concat(listeners.slice(i + 1));
break;
}
}
return dispatcher;
};
dispatcher.dispatch = function() {
var ls = listeners; // defensive reference
for (var i = 0, n = ls.length; i < n; i++) {
var l = ls[i];
if (l.on) l.listener.apply(this, arguments);
}
};
return dispatcher;
};

10
src/dispatchers.js Normal file
Просмотреть файл

@ -0,0 +1,10 @@
/** @param {...string} types */
function d3_dispatchers(types) {
var dispatchers = {},
type;
for (var i = 0, n = arguments.length; i < n; i++) {
type = arguments[i];
dispatchers[type] = d3_dispatcher(type);
}
return dispatchers;
}

10
src/join.js Normal file
Просмотреть файл

@ -0,0 +1,10 @@
function d3_join(key) {
return {
node: function(node) {
return node.getAttribute(key);
},
data: function(data) {
return data[key];
}
};
}

Просмотреть файл

@ -1,4 +1,4 @@
var ns = {
d3.ns = {
prefix: {
svg: "http://www.w3.org/2000/svg",
@ -8,14 +8,10 @@ var ns = {
xmlns: "http://www.w3.org/2000/xmlns/"
},
resolve: function(prefix) {
return ns.prefix[prefix] || null;
},
qualify: function(name) {
var i = name.indexOf(":");
return i < 0 ? name : {
space: ns.prefix[name.substring(0, i)],
space: d3.ns.prefix[name.substring(0, i)],
local: name.substring(i + 1)
};
}

1
src/root.js Normal file
Просмотреть файл

@ -0,0 +1 @@
var d3_root = d3_selection([[document]]);

5
src/select.js Normal file
Просмотреть файл

@ -0,0 +1,5 @@
d3.select = function(query) {
return typeof query == "string"
? d3_root.select(query)
: d3_selection([[query]]); // assume node
};

5
src/selectAll.js Normal file
Просмотреть файл

@ -0,0 +1,5 @@
d3.selectAll = function(query) {
return typeof query == "string"
? d3_root.selectAll(query)
: d3_selection([d3_array(query)]); // assume node[]
};

300
src/selection.js Normal file
Просмотреть файл

@ -0,0 +1,300 @@
function d3_selection(groups) {
var i = -1,
n = groups.length,
group;
function select(select) {
var subgroups = [],
subgroup,
subnode,
group,
node;
for (var j = 0, m = groups.length; j < m; j++) {
group = groups[j];
subgroups.push(subgroup = []);
subgroup.parentNode = group.parentNode;
subgroup.parentData = group.parentData;
for (var i = 0, n = group.length; i < n; i++) {
if (node = group[i]) {
subgroup.push(subnode = select(node));
if (subnode) subnode.__data__ = node.__data__;
}
}
}
return d3_selection(subgroups);
}
function selectAll(selectAll) {
var subgroups = [],
subgroup,
group,
node;
for (var j = 0, m = groups.length; j < m; j++) {
group = groups[j];
for (var i = 0, n = group.length; i < n; i++) {
if (node = group[i]) {
subgroups.push(subgroup = selectAll(node));
subgroup.parentNode = node;
subgroup.parentData = node.__data__;
}
}
}
return d3_selection(subgroups);
}
// TODO select(function)?
groups.select = function(query) {
return select(function(node) {
return node.querySelector(query);
});
};
// TODO selectAll(function)?
groups.selectAll = function(query) {
return selectAll(function(node) {
return d3_array(node.querySelectorAll(query));
});
};
// TODO data(null) for clearing data?
groups.data = function(data, join) {
var i = -1,
n = groups.length,
group,
enter = [],
update = [],
exit = [];
if (typeof join == "string") join = d3_join(join);
function bind(group, groupData) {
var i = 0,
n = group.length,
m = groupData.length,
n0 = Math.min(n, m),
n1 = Math.max(n, m),
updateNodes = [],
enterNodes = [],
exitNodes = [],
node,
nodeData;
function append(e) {
return group.parentNode.appendChild(e);
}
if (join) {
var nodeByKey = {},
exitData = [],
keys = [],
key;
for (i = 0; i < n; i++) {
nodeByKey[key = join.node(node = group[i])] = node;
keys.push(key);
}
for (i = 0; i < m; i++) {
node = nodeByKey[key = join.data(nodeData = groupData[i])];
if (node) {
node.__data__ = nodeData;
updateNodes[i] = node;
enterNodes[i] = exitNodes[i] = null;
} else {
enterNodes[i] = {appendChild: append, __data__: nodeData};
updateNodes[i] = exitNodes[i] = null;
}
delete nodeByKey[key];
}
for (i = 0; i < n; i++) {
if (keys[i] in nodeByKey) {
exitNodes[i] = group[i];
}
}
} else {
for (; i < n0; i++) {
node = updateNodes[i] = group[i];
node.__data__ = groupData[i];
enterNodes[i] = exitNodes[i] = null;
}
for (; i < m; i++) {
enterNodes[i] = {appendChild: append, __data__: groupData[i]};
updateNodes[i] = exitNodes[i] = null;
}
for (; i < n1; i++) {
exitNodes[i] = group[i];
enterNodes[i] = updateNodes[i] = null;
}
}
enter.push(enterNodes);
update.push(updateNodes);
exit.push(exitNodes);
}
if (typeof data == "function") {
while (++i < n) {
bind(group = groups[i], data.call(group.parentNode, group.parentData, i));
}
} else {
while (++i < n) {
bind(group = groups[i], data);
}
}
var selection = d3_selection(update);
selection.enter = function(name) {
return d3_selection(enter).append(name);
};
selection.exit = function() {
return d3_selection(exit);
};
return selection;
};
// TODO mask forEach? or rename for eachData?
// TODO offer the same semantics for map, reduce, etc.?
groups.each = function(callback) {
for (var j = 0, m = groups.length; j < m; j++) {
var group = groups[j];
for (var i = 0, n = group.length; i < n; i++) {
var node = group[i];
if (node) callback.call(node, node.__data__, i);
}
}
return groups;
};
groups.attr = function(name, value) {
name = d3.ns.qualify(name);
function attrNull() {
this.removeAttribute(name);
}
function attrNullNS() {
this.removeAttributeNS(name.space, name.local);
}
function attrConstant() {
this.setAttribute(name, value);
}
function attrConstantNS() {
this.setAttributeNS(name.space, name.local, value);
}
function attrFunction() {
var x = value.apply(this, arguments);
if (x == null) this.removeAttribute(name);
else this.setAttribute(name, x);
}
function attrFunctionNS() {
var x = value.apply(this, arguments);
if (x == null) this.removeAttributeNS(name.space, name.local);
else this.setAttributeNS(name.space, name.local, x);
}
return groups.each(value == null
? (name.local ? attrNullNS : attrNull) : (typeof value == "function"
? (name.local ? attrFunctionNS : attrFunction)
: (name.local ? attrConstantNS : attrConstant)));
};
groups.style = function(name, value, priority) {
if (arguments.length < 3) priority = null;
function styleNull() {
this.style.removeProperty(name);
}
function styleConstant() {
this.style.setProperty(name, value, priority);
}
function styleFunction() {
var x = value.apply(this, arguments);
if (x == null) this.style.removeProperty(name);
else this.style.setProperty(name, x, priority);
}
return groups.each(value == null
? styleNull : (typeof value == "function"
? styleFunction : styleConstant));
};
groups.text = function(value) {
function textNull() {
while (this.lastChild) this.removeChild(this.lastChild);
}
function textConstant() {
this.appendChild(document.createTextNode(value));
}
function textFunction() {
var x = value.apply(this, arguments);
if (x != null) this.appendChild(document.createTextNode(x));
}
groups.each(textNull);
return value == null ? groups
: groups.each(typeof value == "function"
? textFunction : textConstant);
};
groups.html = function(value) {
function htmlConstant() {
this.innerHTML = value;
}
function htmlFunction() {
this.innerHTML = value.apply(this, arguments);
}
return groups.each(typeof value == "function"
? htmlFunction : htmlConstant);
};
// TODO append(node)?
// TODO append(function)?
groups.append = function(name) {
name = d3.ns.qualify(name);
function append(node) {
return node.appendChild(document.createElement(name));
}
function appendNS(node) {
return node.appendChild(document.createElementNS(name.space, name.local));
}
return select(name.local ? appendNS : append);
};
// TODO remove(query)?
// TODO remove(node)?
// TODO remove(function)?
groups.remove = function() {
return select(function(node) {
var parent = node.parentNode;
parent.removeChild(node);
return parent;
});
};
// TODO event
// TODO on?
// TODO filter, slice?
groups.transition = function() {
return d3_transition(groups);
};
return groups;
}

Просмотреть файл

@ -1,3 +1,3 @@
(function(_) {
var d3 = _.d3 = {};
d3.version = "0.0.0"; // semver
d3.version = "0.1.0"; // semver

Просмотреть файл

@ -1,230 +0,0 @@
var d3_transform_stack = [];
function d3_transform() {
var transform = {},
actions = [];
// TODO reorder elements
// convenience method for replacing elements?
// how to insert new element at a given location?
// how to move elements around, sort, reverse or reorder?
// TODO value transforms
// how to inspect current attr/style/text value from transform?
// perhaps push/pop values for temporary change (e.g., :hover)?
// this.value retrieves current attr / style / text? or this.value()?
// TODO extensibility
// register hooks for transform extensibility outside the library?
// how to encapsulate higher level logic (e.g., bars, wedges, charts)?
// virtual nodes? map to canvas?
// TODO composition
// transform.apply(nodes) to transform specific nodes? (set root context)
// transform.transform(transform) to chain transforms?
// TODO selectors
// allow select / selectAll argument to be function
// allow select / selectAll argument to be node / nodes
// allow select / selectAll argument to be xpath
// allow selectParent?
// allow selectFirstChild, selectLastChild, selectChildren?
// allow selectNext, selectPrevious?
// TODO performance
// dispatch to different impl based on ns.qualify, typeof v === "function", etc.
// TODO transitions
// how to do staggered transition on line control points? (virtual nodes?)
function transform_scope(parent, actions) {
var scope = Object.create(transform);
scope.pop = parent;
scope.data = function(v) {
var subscope, action = {
impl: d3_transform_data,
bind: d3_transform_data_bind,
value: v,
actions: [],
enterActions: [],
exitActions: []
};
actions.push(action);
subscope = transform_scope(scope, action.actions);
subscope.enter = transform_scope(scope, action.enterActions);
subscope.exit = transform_scope(scope, action.exitActions);
subscope.key = function(n, v) {
action.key = {name: ns.qualify(n), value: v};
return subscope;
};
return subscope;
};
scope.attr = function(n, v) {
actions.push({
impl: d3_transform_attr,
bind: d3_transform_attr_bind,
name: ns.qualify(n),
value: v
});
return scope;
};
scope.style = function(n, v, p) {
actions.push({
impl: d3_transform_style,
bind: d3_transform_style_bind,
name: n,
value: v,
priority: arguments.length < 3 ? null : p
});
return scope;
};
scope.append = function(n, v) {
var action = {
impl: d3_transform_append,
name: ns.qualify(n),
value: v,
actions: []
};
actions.push(action);
return transform_scope(scope, action.actions);
};
scope.remove = function(s) {
actions.push({
impl: d3_transform_remove,
selector: s
});
return scope;
};
scope.text = function(v) {
actions.push({
impl: d3_transform_text,
// TODO d3_transform_text_bind
value: v
});
return scope;
};
scope.on = function(t) {
var action = {
impl: d3_transform_on,
type: t,
actions: []
};
actions.push(action);
return transform_scope(scope, action.actions);
};
scope.bind = function(t, f) {
actions.push({
impl: d3_transform_bind,
type: t,
listener: f
});
return scope;
};
scope.filter = function(f) {
var action = {
impl: d3_transform_filter,
bind: d3_transform_filter, // TODO is this right?
filter: f,
actions: []
};
actions.push(action);
return transform_scope(scope, action.actions);
};
scope.select = function(s) {
var action = {
impl: d3_transform_select,
bind: d3_transform_select_bind,
selector: s,
actions: []
};
actions.push(action);
return transform_scope(scope, action.actions);
};
scope.selectAll = function(s) {
var action = {
impl: d3_transform_selectAll,
bind: d3_transform_selectAll_bind,
selector: s,
actions: []
};
actions.push(action);
return transform_scope(scope, action.actions);
};
scope.transition = function() {
var subscope, action = {
impl: d3_transform_transition,
actions: [],
endActions: [],
ease: d3.ease("cubic-in-out"),
delay: 0,
duration: 250
};
actions.push(action);
subscope = transform_scope(scope, action.actions);
subscope.end = transform_scope(scope, action.endActions);
subscope.ease = function(x) {
action.ease = typeof x == "string" ? d3.ease(x) : x;
return subscope;
};
subscope.delay = function(x) {
action.delay = x;
return subscope;
};
subscope.duration = function(x) {
action.duration = x;
return subscope;
};
return subscope;
};
return scope;
}
transform.select = function(s) {
var action = {
impl: d3_transform_select,
selector: s,
actions: []
};
actions.push(action);
return transform_scope(transform, action.actions);
};
transform.selectAll = function(s) {
var action = {
impl: d3_transform_selectAll,
selector: s,
actions: []
};
actions.push(action);
return transform_scope(transform, action.actions);
};
transform.apply = function() {
d3_transform_stack.unshift(null);
d3_transform_impl(actions, [{node: document, index: 0}]);
d3_transform_stack.shift();
return transform;
};
return transform;
}
function d3_transform_impl(actions, nodes) {
var n = actions.length,
i; // current index
for (i = 0; i < n; ++i) actions[i].impl(nodes, d3_transform_impl);
}

Просмотреть файл

@ -1,20 +0,0 @@
function d3_transform_append(nodes, pass) {
var m = nodes.length,
n = this.name,
childNodes = [],
i, // current index
o, // current node
c; // current child
if (n.local) {
for (i = 0; i < m; ++i) {
childNodes.push(c = Object.create(o = nodes[i]));
c.node = (c.parent = o).node.appendChild(document.createElementNS(n.space, n.local));
}
} else {
for (i = 0; i < m; ++i) {
childNodes.push(c = Object.create(o = nodes[i]));
c.node = (c.parent = o).node.appendChild(document.createElement(n));
}
}
pass(this.actions, childNodes);
}

Просмотреть файл

@ -1,77 +0,0 @@
function d3_transform_attr(nodes) {
var m = nodes.length,
n = this.name,
v = this.value,
i, // current index
o, // current node
x; // current value (for value functions)
if (n.local) {
if (v == null) {
for (i = 0; i < m; ++i) {
nodes[i].node.removeAttributeNS(n.space, n.local);
}
} else if (typeof v == "function") {
for (i = 0; i < m; ++i) {
d3_transform_stack[0] = (o = nodes[i]).data;
x = v.apply(o, d3_transform_stack);
x == null
? o.node.removeAttributeNS(n.space, n.local)
: o.node.setAttributeNS(n.space, n.local, x);
}
} else {
for (i = 0; i < m; ++i) {
nodes[i].node.setAttributeNS(n.space, n.local, v);
}
}
} else if (v == null) {
for (i = 0; i < m; ++i) {
nodes[i].node.removeAttribute(n);
}
} else if (typeof v == "function") {
for (i = 0; i < m; ++i) {
d3_transform_stack[0] = (o = nodes[i]).data;
x = v.apply(o, d3_transform_stack);
x == null
? o.node.removeAttribute(n)
: o.node.setAttribute(n, x);
}
} else {
for (i = 0; i < m; ++i) {
nodes[i].node.setAttribute(n, v);
}
}
}
function d3_transform_attr_bind(nodes) {
var m = nodes.length,
n = this.name,
v = this.bound || (this.bound = this.value),
b = "attr." + (n.local ? n.space + ":" + n.local : n),
i, // current index
o, // current node
x; // current value (for value functions)
if (v && v.bind) {
if (n.local) {
for (i = 0; i < m; ++i) {
(o = nodes[i]).value = o.node.getAttributeNS(n.space, n.local);
o.name = n.space + ":" + n.local;
d3_transform_stack[0] = o.data;
o[b] = v.bind.apply(o, d3_transform_stack);
delete o.value;
delete o.name;
}
} else {
for (i = 0; i < m; ++i) {
(o = nodes[i]).value = o.node.getAttribute(n);
o.name = n;
d3_transform_stack[0] = o.data;
o[b] = v.bind.apply(o, d3_transform_stack);
delete o.value;
delete o.name;
}
}
this.value = function() {
return this[b].apply(this, arguments);
};
}
}

Просмотреть файл

@ -1,35 +0,0 @@
function d3_transform_bind(nodes) {
var m = nodes.length,
t = "on" + this.type,
l = this.listener,
i = 0, // current node index
o, // curent node
stack = d3_transform_stack.slice(); // stack snapshot
// TODO this overwrites any actions registered with .on!
// TODO using namespaced event handlers could fix this ^ issue.
if (l) {
for (; i < m; ++i) {
o = nodes[i];
o.node[t] = bind(o, o.data);
}
} else {
for (; i < m; ++i) {
nodes[i].node[t] = null; // clear any previously-registered actions
}
}
function bind(o, d) {
return function(e) {
var s = d3_transform_stack;
try {
d3.event = e;
stack[0] = d;
l.apply(o, d3_transform_stack = stack);
} finally {
delete d3.event;
d3_transform_stack = s;
}
};
}
}

Просмотреть файл

@ -1,153 +0,0 @@
function d3_transform_data(nodes, pass) {
var data = this.value,
m = nodes.length,
n, // data length
key = this.key,
kn, // key name
kv, // key value
k, // current key
i, // current index
j, // current index
d, // current datum
o, // current node
enterNodes = [],
updateNodes = [],
exitNodes = [],
nodesByKey, // map key -> node
dataByKey, // map key -> data
indexesByKey; // map key -> index
if (typeof data == "function") {
d = d3_transform_stack.shift();
data = data.apply(null, d3_transform_stack);
d3_transform_stack.unshift(d);
}
n = data.length;
if (key) {
kn = key.name;
kv = key.value;
nodesByKey = {};
dataByKey = {};
indexesByKey = {};
// compute map from key -> node
if (kn.local) {
for (i = 0; i < m; ++i) {
o = nodes[i].node;
if (o) {
k = o.getAttributeNS(kn.space, kn.local);
if (k != null) nodesByKey[k] = o;
}
}
} else {
for (i = 0; i < m; ++i) {
o = nodes[i].node;
if (o) {
k = o.getAttribute(kn);
if (k != null) nodesByKey[k] = o;
}
}
}
// compute map from key -> data
for (i = 0; i < n; ++i) {
d3_transform_stack[0] = d = data[i];
k = kv.apply(null, d3_transform_stack);
if (k != null) {
dataByKey[k] = d;
indexesByKey[k] = i;
}
}
// compute entering and updating nodes
for (k in dataByKey) {
d = dataByKey[k];
i = indexesByKey[k];
if (o = nodesByKey[k]) {
updateNodes.push({
node: o,
data: d,
key: k,
index: i
});
} else {
enterNodes.push({
node: nodes.parent.node,
data: d,
key: k,
index: i
});
}
}
// compute exiting nodes
for (k in nodesByKey) {
if (!(k in dataByKey)) {
exitNodes.push({node: nodesByKey[k]});
}
}
} else {
k = n < m ? n : m;
// compute updating nodes
for (i = 0; i < k; ++i) {
(o = nodes[i]).data = data[i];
if (o.node) {
updateNodes.push(o);
} else {
o.node = o.parent.node;
enterNodes.push(o);
}
}
// compute entering nodes
for (j = i; j < n; ++j) {
enterNodes.push({
node: nodes.parent.node,
data: data[j],
index: j
});
}
// compute exiting nodes
for (j = i; j < m; ++j) {
exitNodes.push(nodes[j]);
}
}
pass(this.enterActions, enterNodes);
pass(this.actions, updateNodes);
pass(this.exitActions, exitNodes);
}
function d3_transform_data_bind(nodes, pass) {
var m = nodes.length,
n = this.name,
v = this.bound || (this.bound = this.value),
d, // bound data
i, // current index
o, // current node
x; // current value (for value functions)
if (v && v.bind) {
d = [];
for (i = 0; i < m; ++i) {
d3_transform_stack[0] = (o = nodes[i]).data;
o.value = o.data;
o.data_ = v.bind.apply(o, d3_transform_stack);
delete o.value;
}
this.value = function() {
d3_transform_stack.unshift(null);
for (i = 0; i < m; ++i) {
d3_transform_stack[0] = (o = nodes[i]).data;
d[i] = o.data_.apply(o, d3_transform_stack);
}
d3_transform_stack.shift();
return d;
};
} else {
d3_transform_data.call(this, nodes, pass);
}
}

Просмотреть файл

@ -1,12 +0,0 @@
function d3_transform_filter(nodes, pass) {
var filteredNodes = [],
m = nodes.length,
f = this.filter,
i, // the node index
o; // current item
for (i = 0; i < m; ++i) {
d3_transform_stack[0] = (o = nodes[i]).data;
if (f.apply(o, d3_transform_stack)) filteredNodes.push(o);
}
pass(this.actions, filteredNodes);
}

Просмотреть файл

@ -1,36 +0,0 @@
function d3_transform_on(nodes) {
var actions = this.actions,
n = actions.length,
m = nodes.length,
t = "on" + this.type,
i = 0, // current index
o, // curent node
stack = d3_transform_stack.slice(); // stack snapshot
// TODO this overwrites any actions registered with .bind!
// TODO using namespaced event handlers could fix this ^ issue.
if (n) {
for (; i < m; ++i) {
o = nodes[i];
o.node[t] = bind([o]);
}
} else {
for (; i < m; ++i) {
nodes[i].node[t] = null; // clear any previously-registered actions
}
}
function bind(o) {
return function(e) {
var s = d3_transform_stack;
try {
d3_transform_stack = stack;
d3.event = e;
for (i = 0; i < n; ++i) actions[i].impl(o, d3_transform_impl);
} finally {
delete d3.event;
d3_transform_stack = s;
}
};
}
}

Просмотреть файл

@ -1,23 +0,0 @@
function d3_transform_remove(nodes) {
var m = nodes.length,
s = this.selector,
r, // the selected nodes (for selectors)
i, // current node index
j, // current selector index
k, // current selector length
o; // current node to remove
if (s == null) {
for (i = 0; i < m; ++i) {
o = nodes[i].node;
o.parentNode.removeChild(o);
}
} else {
for (i = 0; i < m; ++i) {
r = nodes[i].node.querySelectorAll(s);
for (j = 0, k = r.length; j < k; j++) {
o = r[j];
o.parentNode.removeChild(o);
}
}
}
}

Просмотреть файл

@ -1,31 +0,0 @@
d3.select = function(s) {
return d3_transform().select(s);
};
function d3_transform_select(nodes, pass) {
var selectedNodes = [],
m = nodes.length,
s = this.selector,
i, // the node index
o, // current item
p, // current node
c, // current selected item
e; // current selected node
for (i = 0; i < m; ++i) {
e = (p = (o = nodes[i]).node).querySelector(s);
selectedNodes.push(c = Object.create(o));
c.parent = o;
c.node = e;
}
pass(this.actions, selectedNodes);
}
function d3_transform_select_bind(nodes, pass) {
var action = this;
d3_transform_select.call(this, nodes, function(actions, selectedNodes) {
pass(actions, selectedNodes);
action.impl = function(nodes, pass) {
pass(actions, selectedNodes);
};
});
}

Просмотреть файл

@ -1,43 +0,0 @@
d3.selectAll = function(s) {
return d3_transform().selectAll(s);
};
function d3_transform_selectAll(nodes, pass) {
var m = nodes.length,
s = this.selector,
i, // the node index
o; // the current node
d3_transform_stack.unshift(null);
for (i = 0; i < m; ++i) {
d3_transform_stack[1] = (o = nodes[i]).data;
if (!o.node) continue; // TODO better error handling when `select` fails.
pass(this.actions, d3_transform_nodes(o.node.querySelectorAll(s), o));
}
d3_transform_stack.shift();
}
function d3_transform_selectAll_bind(nodes, pass) {
var m = nodes.length,
i, // the node index
o; // the current node
d3_transform_selectAll.call(this, nodes, function(actions, nodes) {
pass(actions, nodes.parent.selectAll = nodes);
});
this.impl = function(nodes, pass) {
d3_transform_stack.unshift(null);
for (i = 0, m = nodes.length; i < m; ++i) {
d3_transform_stack[1] = (o = nodes[i]).data;
pass(this.actions, o.selectAll);
}
d3_transform_stack.shift();
};
}
function d3_transform_nodes(x, o) {
var nodes = [],
i = 0,
n = x.length;
nodes.parent = o;
for (; i < n; i++) nodes.push({node: x[i], index: i});
return nodes;
}

Просмотреть файл

@ -1,50 +0,0 @@
function d3_transform_style(nodes) {
var m = nodes.length,
n = this.name,
v = this.value,
p = this.priority,
i, // current index
o, // current node
x; // current value (for value functions)
if (v == null) {
for (i = 0; i < m; ++i) {
nodes[i].node.style.removeProperty(n);
}
} else if (typeof v == "function") {
for (i = 0; i < m; ++i) {
o = nodes[i];
d3_transform_stack[0] = o.data;
x = v.apply(o, d3_transform_stack);
x == null
? o.node.style.removeProperty(n)
: o.node.style.setProperty(n, x, p);
}
} else {
for (i = 0; i < m; ++i) {
nodes[i].node.style.setProperty(n, v, p);
}
}
}
function d3_transform_style_bind(nodes) {
var m = nodes.length,
n = this.name,
v = this.bound || (this.bound = this.value),
b = "style." + n,
i, // current index
o, // current node
x; // current value (for value functions)
if (v && v.bind) {
for (i = 0; i < m; ++i) {
(o = nodes[i]).value = o.node.style.getPropertyValue(n);
o.name = n;
d3_transform_stack[0] = o.data;
o[b] = v.bind.apply(o, d3_transform_stack);
delete o.value;
delete o.name;
}
this.value = function() {
return this[b].apply(this, arguments);
};
}
}

Просмотреть файл

@ -1,23 +0,0 @@
function d3_transform_text(nodes) {
var m = nodes.length,
v = this.value,
i, // current node index
o, // current node
x; // current value (for value functions)
if (typeof v == "function") {
for (i = 0; i < m; ++i) {
o = nodes[i];
d3_transform_stack[0] = o.data;
x = v.apply(o, d3_transform_stack);
o = o.node;
while (o.lastChild) o.removeChild(o.lastChild);
o.appendChild(document.createTextNode(x));
}
} else {
for (i = 0; i < m; ++i) {
o = nodes[i].node;
while (o.lastChild) o.removeChild(o.lastChild);
o.appendChild(document.createTextNode(v));
}
}
}

Просмотреть файл

@ -1,112 +0,0 @@
function d3_transform_transition(nodes) {
var actions = this.actions,
endActions = this.endActions,
start = Date.now(),
delay = this.delay,
minDelay = Infinity,
duration = this.duration,
ease = this.ease,
interval,
n = actions.length,
k = endActions.length,
m = nodes.length,
i, // current index
j, // current index
o, // curent node
x, // current value
stack = d3_transform_stack.slice(); // stack snapshot
// If delay is a function, transition each node separately.
if (typeof delay == "function") {
for (i = 0; i < m; ++i) {
d3_transform_stack[0] = (o = nodes[i]).data;
x = o.delay = delay.apply(o, d3_transform_stack);
if (x < minDelay) minDelay = x;
}
setTimeout(function() {
bind(interval = setInterval(tickOne, 24));
}, minDelay);
} else {
setTimeout(function() {
bind(interval = setInterval(tickAll, 24));
}, delay);
}
// Bind the active transition to the node.
function bind(interval) {
for (i = 0; i < m; ++i) {
(o = nodes[i]).node.interval = interval;
}
}
// Compute the tween values.
try {
d3.time = 0;
d3_transform_transition_bind(actions, nodes);
} finally {
delete d3.time;
}
function tickOne() {
var s = d3_transform_stack,
a = nodes.filter(function(o) { return o.node.interval == interval; }),
m = a.length,
q = Date.now(),
t,
d = true;
try {
d3_transform_stack = stack;
for (i = 0; i < m; ++i) {
o = a[i];
t = (q - start - o.delay) / duration;
if (t < 0) continue;
if (t > 1) t = 1;
else d = false;
d3.time = ease(t);
for (j = 0; j < n; ++j) actions[j].impl([o], d3_transform_impl);
if (t == 1) {
for (j = 0; j < k; ++j) endActions[j].impl([o], d3_transform_impl);
o.delay = Infinity; // stop transitioning this node
}
}
} finally {
delete d3.time;
d3_transform_stack = s;
}
if (d) clearInterval(interval);
}
function tickAll() {
var s = d3_transform_stack,
t = (Date.now() - start - delay) / duration,
a = nodes.filter(function(o) { return o.node.interval == interval; });
try {
d3_transform_stack = stack;
d3.time = ease(t < 0 ? 0 : t > 1 ? 1 : t);
for (i = 0; i < n; ++i) actions[i].impl(a, d3_transform_impl);
} finally {
delete d3.time;
d3_transform_stack = s;
}
if (t >= 1) {
clearInterval(interval);
try {
d3_transform_stack = stack;
for (i = 0; i < k; ++i) endActions[i].impl(a, d3_transform_impl);
} finally {
d3_transform_stack = s;
}
}
}
}
function d3_transform_transition_bind(actions, nodes) {
var n = actions.length,
m = nodes.length,
a, // current action
i; // current index
for (i = 0; i < n; ++i) {
a = actions[i];
if (a.bind) a.bind(nodes, d3_transform_transition_bind);
}
}

190
src/transition.js Normal file
Просмотреть файл

@ -0,0 +1,190 @@
d3.transition = function() {
return d3_root.transition();
};
// TODO namespace transitions; cancel collisions
// TODO easing
function d3_transition(groups) {
var transition = {},
tweens = {},
timeout = setTimeout(start, 1),
interval,
then = Date.now(),
event = d3_dispatchers("start", "end"),
stage = [],
delay = [],
duration = [],
durationMax;
function start() {
interval = setInterval(step, 24);
}
function step() {
var elapsed = Date.now() - then,
clear = true,
k = -1;
groups.each(function(d, i) {
if (stage[++k] == 2) return; // ended
var t = (elapsed - delay[k]) / duration[k]; // TODO easing
if (t >= 1) {
t = 1;
} else {
clear = false;
if (t < 0) return;
if (!stage[k]) {
stage[k] = 1;
event.start.dispatch.apply(this, arguments);
}
}
for (var key in tweens) tweens[key].call(this, t);
if (t == 1) {
stage[k] = 2;
event.end.dispatch.apply(this, arguments);
}
});
if (clear) clearInterval(interval);
}
transition.delay = function(value) {
var delayMin = Infinity,
k = -1;
if (typeof value == "function") {
groups.each(function(d, i) {
var x = delay[++k] = +value.apply(this, arguments);
if (x < delayMin) delayMin = x;
});
} else {
delayMin = +value;
groups.each(function(d, i) {
delay[++k] = delayMin;
});
}
clearTimeout(timeout);
timeout = setTimeout(start, delayMin);
return transition;
};
transition.duration = function(value) {
var k = -1;
if (typeof value == "function") {
durationMax = 0;
groups.each(function(d, i) {
var x = duration[++k] = +value.apply(this, arguments);
if (x > durationMax) durationMax = x;
});
} else {
durationMax = +value;
groups.each(function(d, i) {
duration[++k] = durationMax;
});
}
return transition;
};
// TODO register custom easing functions?
// transition.easing = function(value) {
// easing = value;
// return transition;
// };
transition.attr = function(name, value) {
var key = "attr." + name + ".",
k = -1;
function attrConstant(d, i) {
tweens[key + ++k] = attrTween(
this.getAttribute(name),
value);
}
function attrConstantNS(d, i) {
tweens[key + ++k] = attrTweenNS(
this.getAttributeNS(name.space, name.local),
value);
}
function attrFunction(d, i) {
tweens[key + ++k] = attrTween(
this.getAttribute(name),
value.apply(this, arguments));
}
function attrFunctionNS(d, i) {
tweens[key + ++k] = attrTweenNS(
this.getAttributeNS(name.space, name.local),
value.apply(this, arguments));
}
function attrTween(a, b) {
var interpolate = d3.interpolate(a, b);
return function(t) {
this.setAttribute(name, interpolate(t));
};
}
function attrTweenNS(a, b) {
var interpolate = d3.interpolate(a, b);
return function(t) {
this.setAttributeNS(name.space, name.local, interpolate(t));
};
}
name = d3.ns.qualify(name);
groups.each(typeof value == "function"
? (name.local ? attrFunctionNS : attrFunction)
: (name.local ? attrConstantNS : attrConstant));
return transition;
};
transition.style = function(name, value, priority) {
var key = "style." + name + ".",
k = -1;
function styleConstant(d, i) {
tweens[key + ++k] = styleTween(
window.getComputedStyle(this, null).getPropertyValue(name),
value);
}
function styleFunction(d, i) {
tweens[key + ++k] = styleTween(
window.getComputedStyle(this, null).getPropertyValue(name),
value.apply(this, arguments));
}
function styleTween(a, b) {
var interpolate = d3.interpolate(a, b);
return function(t) {
this.style.setProperty(name, interpolate(t), priority);
};
}
groups.each(typeof value == "function" ? styleFunction : styleConstant);
return transition;
};
// TODO inherit easing
transition.select = function(query) {
var k, t = d3_transition(groups.select(query));
k = -1; t.delay(function(d, i) { return delay[++k]; });
k = -1; t.duration(function(d, i) { return duration[++k]; });
return t;
};
// TODO inherit easing
transition.selectAll = function(query) {
var k, t = d3_transition(groups.selectAll(query));
k = -1; t.delay(function(d, i) { return delay[i ? k : ++k]; })
k = -1; t.duration(function(d, i) { return duration[i ? k : ++k]; });
return t;
};
transition.on = function(type, listener) {
event[type].add(listener);
return transition;
};
return transition.delay(0).duration(250);
}

Просмотреть файл

@ -1,24 +0,0 @@
d3.tween = function(v) {
return {
bind: typeof v == "function" ? function() {
var a = this.value,
n = this.name,
b = v.apply(this, arguments),
i = (n in d3_interpolate_rgb || /\bcolor\b/.test(n)
? d3.interpolateRgb
: d3.interpolate)(a, b);
return function() {
return i(d3.time);
};
} : function() {
var a = this.value,
n = this.name,
i = (n in d3_interpolate_rgb || /\bcolor\b/.test(n)
? d3.interpolateRgb
: d3.interpolate)(a, v);
return function() {
return i(d3.time);
};
}
};
};