| 4214 | } |
| 4215 | |
| 4216 | function create(node, id, self) { |
| 4217 | var schedules = node.__transition, |
| 4218 | tween; |
| 4219 | |
| 4220 | // Initialize the self timer when the transition is created. |
| 4221 | // Note the actual delay is not known until the first callback! |
| 4222 | schedules[id] = self; |
| 4223 | self.timer = timer(schedule, 0, self.time); |
| 4224 | |
| 4225 | function schedule(elapsed) { |
| 4226 | self.state = SCHEDULED; |
| 4227 | self.timer.restart(start, self.delay, self.time); |
| 4228 | |
| 4229 | // If the elapsed delay is less than our first sleep, start immediately. |
| 4230 | if (self.delay <= elapsed) start(elapsed - self.delay); |
| 4231 | } |
| 4232 | |
| 4233 | function start(elapsed) { |
| 4234 | var i, j, n, o; |
| 4235 | |
| 4236 | // If the state is not SCHEDULED, then we previously errored on start. |
| 4237 | if (self.state !== SCHEDULED) return stop(); |
| 4238 | |
| 4239 | for (i in schedules) { |
| 4240 | o = schedules[i]; |
| 4241 | if (o.name !== self.name) continue; |
| 4242 | |
| 4243 | // While this element already has a starting transition during this frame, |
| 4244 | // defer starting an interrupting transition until that transition has a |
| 4245 | // chance to tick (and possibly end); see d3/d3-transition#54! |
| 4246 | if (o.state === STARTED) return timeout(start); |
| 4247 | |
| 4248 | // Interrupt the active transition, if any. |
| 4249 | if (o.state === RUNNING) { |
| 4250 | o.state = ENDED; |
| 4251 | o.timer.stop(); |
| 4252 | o.on.call("interrupt", node, node.__data__, o.index, o.group); |
| 4253 | delete schedules[i]; |
| 4254 | } |
| 4255 | |
| 4256 | // Cancel any pre-empted transitions. |
| 4257 | else if (+i < id) { |
| 4258 | o.state = ENDED; |
| 4259 | o.timer.stop(); |
| 4260 | o.on.call("cancel", node, node.__data__, o.index, o.group); |
| 4261 | delete schedules[i]; |
| 4262 | } |
| 4263 | } |
| 4264 | |
| 4265 | // Defer the first tick to end of the current frame; see d3/d3#1576. |
| 4266 | // Note the transition may be canceled after start and before the first tick! |
| 4267 | // Note this must be scheduled before the start event; see d3/d3-transition#16! |
| 4268 | // Assuming this is successful, subsequent callbacks go straight to tick. |
| 4269 | timeout(function() { |
| 4270 | if (self.state === STARTED) { |
| 4271 | self.state = RUNNING; |
| 4272 | self.timer.restart(tick, self.delay, self.time); |
| 4273 | tick(elapsed); |