toolkit/javascript/d3/src/core/transition.js
changeset 47 c0b4a8b5a012
equal deleted inserted replaced
46:efd9c589177a 47:c0b4a8b5a012
       
     1 function d3_transition(groups, id, time) {
       
     2   d3_arraySubclass(groups, d3_transitionPrototype);
       
     3 
       
     4   var tweens = {},
       
     5       event = d3.dispatch("start", "end"),
       
     6       ease = d3_transitionEase;
       
     7 
       
     8   groups.id = id;
       
     9 
       
    10   groups.time = time;
       
    11 
       
    12   groups.tween = function(name, tween) {
       
    13     if (arguments.length < 2) return tweens[name];
       
    14     if (tween == null) delete tweens[name];
       
    15     else tweens[name] = tween;
       
    16     return groups;
       
    17   };
       
    18 
       
    19   groups.ease = function(value) {
       
    20     if (!arguments.length) return ease;
       
    21     ease = typeof value === "function" ? value : d3.ease.apply(d3, arguments);
       
    22     return groups;
       
    23   };
       
    24 
       
    25   groups.each = function(type, listener) {
       
    26     if (arguments.length < 2) return d3_transition_each.call(groups, type);
       
    27     event.on(type, listener);
       
    28     return groups;
       
    29   };
       
    30 
       
    31   d3.timer(function(elapsed) {
       
    32     groups.each(function(d, i, j) {
       
    33       var tweened = [],
       
    34           node = this,
       
    35           delay = groups[j][i].delay,
       
    36           duration = groups[j][i].duration,
       
    37           lock = node.__transition__ || (node.__transition__ = {active: 0, count: 0});
       
    38 
       
    39       ++lock.count;
       
    40 
       
    41       delay <= elapsed ? start(elapsed) : d3.timer(start, delay, time);
       
    42 
       
    43       function start(elapsed) {
       
    44         if (lock.active > id) return stop();
       
    45         lock.active = id;
       
    46 
       
    47         for (var tween in tweens) {
       
    48           if (tween = tweens[tween].call(node, d, i)) {
       
    49             tweened.push(tween);
       
    50           }
       
    51         }
       
    52 
       
    53         event.start.call(node, d, i);
       
    54         if (!tick(elapsed)) d3.timer(tick, 0, time);
       
    55         return 1;
       
    56       }
       
    57 
       
    58       function tick(elapsed) {
       
    59         if (lock.active !== id) return stop();
       
    60 
       
    61         var t = (elapsed - delay) / duration,
       
    62             e = ease(t),
       
    63             n = tweened.length;
       
    64 
       
    65         while (n > 0) {
       
    66           tweened[--n].call(node, e);
       
    67         }
       
    68 
       
    69         if (t >= 1) {
       
    70           stop();
       
    71           d3_transitionInheritId = id;
       
    72           event.end.call(node, d, i);
       
    73           d3_transitionInheritId = 0;
       
    74           return 1;
       
    75         }
       
    76       }
       
    77 
       
    78       function stop() {
       
    79         if (!--lock.count) delete node.__transition__;
       
    80         return 1;
       
    81       }
       
    82     });
       
    83     return 1;
       
    84   }, 0, time);
       
    85 
       
    86   return groups;
       
    87 }
       
    88 
       
    89 var d3_transitionRemove = {};
       
    90 
       
    91 function d3_transitionNull(d, i, a) {
       
    92   return a != "" && d3_transitionRemove;
       
    93 }
       
    94 
       
    95 function d3_transitionTween(name, b) {
       
    96   var interpolate = d3_interpolateByName(name);
       
    97 
       
    98   function transitionFunction(d, i, a) {
       
    99     var v = b.call(this, d, i);
       
   100     return v == null
       
   101         ? a != "" && d3_transitionRemove
       
   102         : a != v && interpolate(a, v);
       
   103   }
       
   104 
       
   105   function transitionString(d, i, a) {
       
   106     return a != b && interpolate(a, b);
       
   107   }
       
   108 
       
   109   return typeof b === "function" ? transitionFunction
       
   110       : b == null ? d3_transitionNull
       
   111       : (b += "", transitionString);
       
   112 }
       
   113 
       
   114 var d3_transitionPrototype = [],
       
   115     d3_transitionId = 0,
       
   116     d3_transitionInheritId = 0,
       
   117     d3_transitionEase = d3.ease("cubic-in-out");
       
   118 
       
   119 d3_transitionPrototype.call = d3_selectionPrototype.call;
       
   120 
       
   121 d3.transition = function() {
       
   122   return d3_selectionRoot.transition();
       
   123 };
       
   124 
       
   125 d3.transition.prototype = d3_transitionPrototype;