source: Dev/branches/jQueryUI/client/d3/d3.js @ 249

Last change on this file since 249 was 249, checked in by hendrikvanantwerpen, 13 years ago

This one's for Subversion, because it's so close...

First widget (stripped down sequencer).
Seperated client and server code in two direcotry trees.

File size: 91.4 KB
Line 
1(function(){d3 = {version: "1.29.1"}; // semver
2if (!Date.now) Date.now = function() {
3  return +new Date;
4};
5if (!Object.create) Object.create = function(o) {
6  /** @constructor */ function f() {}
7  f.prototype = o;
8  return new f;
9};
10var d3_array = d3_arraySlice; // conversion for NodeLists
11
12function d3_arrayCopy(psuedoarray) {
13  var i = -1, n = psuedoarray.length, array = [];
14  while (++i < n) array.push(psuedoarray[i]);
15  return array;
16}
17
18function d3_arraySlice(psuedoarray) {
19  return Array.prototype.slice.call(psuedoarray);
20}
21
22try {
23  d3_array(document.documentElement.childNodes)[0].nodeType;
24} catch(e) {
25  d3_array = d3_arrayCopy;
26}
27d3.functor = function(v) {
28  return typeof v === "function" ? v : function() { return v; };
29};
30// A getter-setter method that preserves the appropriate `this` context.
31d3.rebind = function(object, method) {
32  return function() {
33    var x = method.apply(object, arguments);
34    return arguments.length ? object : x;
35  };
36};
37d3.ascending = function(a, b) {
38  return a < b ? -1 : a > b ? 1 : 0;
39};
40d3.descending = function(a, b) {
41  return b < a ? -1 : b > a ? 1 : 0;
42};
43d3.min = function(array, f) {
44  var i = -1,
45      n = array.length,
46      a,
47      b;
48  if (arguments.length === 1) {
49    while (++i < n && ((a = array[i]) == null || a != a)) a = undefined;
50    while (++i < n) if ((b = array[i]) != null && a > b) a = b;
51  } else {
52    while (++i < n && ((a = f.call(array, array[i], i)) == null || a != a)) a = undefined;
53    while (++i < n) if ((b = f.call(array, array[i], i)) != null && a > b) a = b;
54  }
55  return a;
56};
57d3.max = function(array, f) {
58  var i = -1,
59      n = array.length,
60      a,
61      b;
62  if (arguments.length === 1) {
63    while (++i < n && ((a = array[i]) == null || a != a)) a = undefined;
64    while (++i < n) if ((b = array[i]) != null && b > a) a = b;
65  } else {
66    while (++i < n && ((a = f.call(array, array[i], i)) == null || a != a)) a = undefined;
67    while (++i < n) if ((b = f.call(array, array[i], i)) != null && b > a) a = b;
68  }
69  return a;
70};
71d3.sum = function(array, f) {
72  var s = 0,
73      n = array.length,
74      a,
75      i = -1;
76
77  if (arguments.length === 1) {
78    while (++i < n) if (!isNaN(a = +array[i])) s += a;
79  } else {
80    while (++i < n) if (!isNaN(a = +f.call(array, array[i], i))) s += a;
81  }
82
83  return s;
84};
85// R-7 per <http://en.wikipedia.org/wiki/Quantile>
86d3.quantile = function(values, p) {
87  var H = (values.length - 1) * p + 1,
88      h = Math.floor(H),
89      v = values[h - 1],
90      e = H - h;
91  return e ? v + e * (values[h] - v) : v;
92};
93d3.zip = function() {
94  if (!(n = arguments.length)) return [];
95  for (var i = -1, m = d3.min(arguments, d3_zipLength), zips = new Array(m); ++i < m;) {
96    for (var j = -1, n, zip = zips[i] = new Array(n); ++j < n;) {
97      zip[j] = arguments[j][i];
98    }
99  }
100  return zips;
101};
102
103function d3_zipLength(d) {
104  return d.length;
105}
106// Locate the insertion point for x in a to maintain sorted order. The
107// arguments lo and hi may be used to specify a subset of the array which should
108// be considered; by default the entire array is used. If x is already present
109// in a, the insertion point will be before (to the left of) any existing
110// entries. The return value is suitable for use as the first argument to
111// `array.splice` assuming that a is already sorted.
112//
113// The returned insertion point i partitions the array a into two halves so that
114// all v < x for v in a[lo:i] for the left side and all v >= x for v in a[i:hi]
115// for the right side.
116d3.bisectLeft = function(a, x, lo, hi) {
117  if (arguments.length < 3) lo = 0;
118  if (arguments.length < 4) hi = a.length;
119  while (lo < hi) {
120    var mid = (lo + hi) >> 1;
121    if (a[mid] < x) lo = mid + 1;
122    else hi = mid;
123  }
124  return lo;
125};
126
127// Similar to bisectLeft, but returns an insertion point which comes after (to
128// the right of) any existing entries of x in a.
129//
130// The returned insertion point i partitions the array into two halves so that
131// all v <= x for v in a[lo:i] for the left side and all v > x for v in a[i:hi]
132// for the right side.
133d3.bisect =
134d3.bisectRight = function(a, x, lo, hi) {
135  if (arguments.length < 3) lo = 0;
136  if (arguments.length < 4) hi = a.length;
137  while (lo < hi) {
138    var mid = (lo + hi) >> 1;
139    if (x < a[mid]) hi = mid;
140    else lo = mid + 1;
141  }
142  return lo;
143};
144d3.first = function(array, f) {
145  var i = 0,
146      n = array.length,
147      a = array[0],
148      b;
149  if (arguments.length === 1) f = d3.ascending;
150  while (++i < n) {
151    if (f.call(array, a, b = array[i]) > 0) {
152      a = b;
153    }
154  }
155  return a;
156};
157d3.last = function(array, f) {
158  var i = 0,
159      n = array.length,
160      a = array[0],
161      b;
162  if (arguments.length === 1) f = d3.ascending;
163  while (++i < n) {
164    if (f.call(array, a, b = array[i]) <= 0) {
165      a = b;
166    }
167  }
168  return a;
169};
170d3.nest = function() {
171  var nest = {},
172      keys = [],
173      sortKeys = [],
174      sortValues,
175      rollup;
176
177  function map(array, depth) {
178    if (depth >= keys.length) return rollup
179        ? rollup.call(nest, array) : (sortValues
180        ? array.sort(sortValues)
181        : array);
182
183    var i = -1,
184        n = array.length,
185        key = keys[depth++],
186        keyValue,
187        object,
188        o = {};
189
190    while (++i < n) {
191      if ((keyValue = key(object = array[i])) in o) {
192        o[keyValue].push(object);
193      } else {
194        o[keyValue] = [object];
195      }
196    }
197
198    for (keyValue in o) {
199      o[keyValue] = map(o[keyValue], depth);
200    }
201
202    return o;
203  }
204
205  function entries(map, depth) {
206    if (depth >= keys.length) return map;
207
208    var a = [],
209        sortKey = sortKeys[depth++],
210        key;
211
212    for (key in map) {
213      a.push({key: key, values: entries(map[key], depth)});
214    }
215
216    if (sortKey) a.sort(function(a, b) {
217      return sortKey(a.key, b.key);
218    });
219
220    return a;
221  }
222
223  nest.map = function(array) {
224    return map(array, 0);
225  };
226
227  nest.entries = function(array) {
228    return entries(map(array, 0), 0);
229  };
230
231  nest.key = function(d) {
232    keys.push(d);
233    return nest;
234  };
235
236  // Specifies the order for the most-recently specified key.
237  // Note: only applies to entries. Map keys are unordered!
238  nest.sortKeys = function(order) {
239    sortKeys[keys.length - 1] = order;
240    return nest;
241  };
242
243  // Specifies the order for leaf values.
244  // Applies to both maps and entries array.
245  nest.sortValues = function(order) {
246    sortValues = order;
247    return nest;
248  };
249
250  nest.rollup = function(f) {
251    rollup = f;
252    return nest;
253  };
254
255  return nest;
256};
257d3.keys = function(map) {
258  var keys = [];
259  for (var key in map) keys.push(key);
260  return keys;
261};
262d3.values = function(map) {
263  var values = [];
264  for (var key in map) values.push(map[key]);
265  return values;
266};
267d3.entries = function(map) {
268  var entries = [];
269  for (var key in map) entries.push({key: key, value: map[key]});
270  return entries;
271};
272d3.permute = function(array, indexes) {
273  var permutes = [],
274      i = -1,
275      n = indexes.length;
276  while (++i < n) permutes[i] = array[indexes[i]];
277  return permutes;
278};
279d3.merge = function(arrays) {
280  return Array.prototype.concat.apply([], arrays);
281};
282d3.split = function(array, f) {
283  var arrays = [],
284      values = [],
285      value,
286      i = -1,
287      n = array.length;
288  if (arguments.length < 2) f = d3_splitter;
289  while (++i < n) {
290    if (f.call(values, value = array[i], i)) {
291      values = [];
292    } else {
293      if (!values.length) arrays.push(values);
294      values.push(value);
295    }
296  }
297  return arrays;
298};
299
300function d3_splitter(d) {
301  return d == null;
302}
303function d3_collapse(s) {
304  return s.replace(/(^\s+)|(\s+$)/g, "").replace(/\s+/g, " ");
305}
306//
307// Note: assigning to the arguments array simultaneously changes the value of
308// the corresponding argument!
309//
310// TODO The `this` argument probably shouldn't be the first argument to the
311// callback, anyway, since it's redundant. However, that will require a major
312// version bump due to backwards compatibility, so I'm not changing it right
313// away.
314//
315function d3_call(callback) {
316  callback.apply(this, (arguments[0] = this, arguments));
317  return this;
318}
319/**
320 * @param {number} start
321 * @param {number=} stop
322 * @param {number=} step
323 */
324d3.range = function(start, stop, step) {
325  if (arguments.length === 1) { stop = start; start = 0; }
326  if (step == null) step = 1;
327  if ((stop - start) / step == Infinity) throw new Error("infinite range");
328  var range = [],
329       i = -1,
330       j;
331  if (step < 0) while ((j = start + step * ++i) > stop) range.push(j);
332  else while ((j = start + step * ++i) < stop) range.push(j);
333  return range;
334};
335d3.requote = function(s) {
336  return s.replace(d3_requote_re, "\\$&");
337};
338
339var d3_requote_re = /[\\\^\$\*\+\?\[\]\(\)\.\{\}]/g;
340d3.round = function(x, n) {
341  return n
342      ? Math.round(x * Math.pow(10, n)) * Math.pow(10, -n)
343      : Math.round(x);
344};
345d3.xhr = function(url, mime, callback) {
346  var req = new XMLHttpRequest;
347  if (arguments.length < 3) callback = mime;
348  else if (mime && req.overrideMimeType) req.overrideMimeType(mime);
349  req.open("GET", url, true);
350  req.onreadystatechange = function() {
351    if (req.readyState === 4) callback(req.status < 300 ? req : null);
352  };
353  req.send(null);
354};
355d3.text = function(url, mime, callback) {
356  function ready(req) {
357    callback(req && req.responseText);
358  }
359  if (arguments.length < 3) {
360    callback = mime;
361    mime = null;
362  }
363  d3.xhr(url, mime, ready);
364};
365d3.json = function(url, callback) {
366  d3.text(url, "application/json", function(text) {
367    callback(text ? JSON.parse(text) : null);
368  });
369};
370d3.html = function(url, callback) {
371  d3.text(url, "text/html", function(text) {
372    if (text != null) { // Treat empty string as valid HTML.
373      var range = document.createRange();
374      range.selectNode(document.body);
375      text = range.createContextualFragment(text);
376    }
377    callback(text);
378  });
379};
380d3.xml = function(url, mime, callback) {
381  function ready(req) {
382    callback(req && req.responseXML);
383  }
384  if (arguments.length < 3) {
385    callback = mime;
386    mime = null;
387  }
388  d3.xhr(url, mime, ready);
389};
390d3.ns = {
391
392  prefix: {
393    svg: "http://www.w3.org/2000/svg",
394    xhtml: "http://www.w3.org/1999/xhtml",
395    xlink: "http://www.w3.org/1999/xlink",
396    xml: "http://www.w3.org/XML/1998/namespace",
397    xmlns: "http://www.w3.org/2000/xmlns/"
398  },
399
400  qualify: function(name) {
401    var i = name.indexOf(":");
402    return i < 0 ? name : {
403      space: d3.ns.prefix[name.substring(0, i)],
404      local: name.substring(i + 1)
405    };
406  }
407
408};
409/** @param {...string} types */
410d3.dispatch = function(types) {
411  var dispatch = {},
412      type;
413  for (var i = 0, n = arguments.length; i < n; i++) {
414    type = arguments[i];
415    dispatch[type] = d3_dispatch(type);
416  }
417  return dispatch;
418};
419
420function d3_dispatch(type) {
421  var dispatch = {},
422      listeners = [];
423
424  dispatch.add = function(listener) {
425    for (var i = 0; i < listeners.length; i++) {
426      if (listeners[i].listener == listener) return dispatch; // already registered
427    }
428    listeners.push({listener: listener, on: true});
429    return dispatch;
430  };
431
432  dispatch.remove = function(listener) {
433    for (var i = 0; i < listeners.length; i++) {
434      var l = listeners[i];
435      if (l.listener == listener) {
436        l.on = false;
437        listeners = listeners.slice(0, i).concat(listeners.slice(i + 1));
438        break;
439      }
440    }
441    return dispatch;
442  };
443
444  dispatch.dispatch = function() {
445    var ls = listeners; // defensive reference
446    for (var i = 0, n = ls.length; i < n; i++) {
447      var l = ls[i];
448      if (l.on) l.listener.apply(this, arguments);
449    }
450  };
451
452  return dispatch;
453};
454// TODO align
455d3.format = function(specifier) {
456  var match = d3_format_re.exec(specifier),
457      fill = match[1] || " ",
458      sign = match[3] || "",
459      zfill = match[5],
460      width = +match[6],
461      comma = match[7],
462      precision = match[8],
463      type = match[9],
464      percentage = false,
465      integer = false;
466
467  if (precision) precision = precision.substring(1);
468
469  if (zfill) {
470    fill = "0"; // TODO align = "=";
471    if (comma) width -= Math.floor((width - 1) / 4);
472  }
473
474  switch (type) {
475    case "n": comma = true; type = "g"; break;
476    case "%": percentage = true; type = "f"; break;
477    case "p": percentage = true; type = "r"; break;
478    case "d": integer = true; precision = "0"; break;
479  }
480
481  type = d3_format_types[type] || d3_format_typeDefault;
482
483  return function(value) {
484    var number = percentage ? value * 100 : +value,
485        negative = (number < 0) && (number = -number) ? "\u2212" : sign;
486
487    // Return the empty string for floats formatted as ints.
488    if (integer && (number % 1)) return "";
489
490    // Convert the input value to the desired precision.
491    value = type(number, precision);
492
493    // If the fill character is 0, the sign and group is applied after the fill.
494    if (zfill) {
495      var length = value.length + negative.length;
496      if (length < width) value = new Array(width - length + 1).join(fill) + value;
497      if (comma) value = d3_format_group(value);
498      value = negative + value;
499    }
500
501    // Otherwise (e.g., space-filling), the sign and group is applied before.
502    else {
503      if (comma) value = d3_format_group(value);
504      value = negative + value;
505      var length = value.length;
506      if (length < width) value = new Array(width - length + 1).join(fill) + value;
507    }
508    if (percentage) value += "%";
509
510    return value;
511  };
512};
513
514// [[fill]align][sign][#][0][width][,][.precision][type]
515var d3_format_re = /(?:([^{])?([<>=^]))?([+\- ])?(#)?(0)?([0-9]+)?(,)?(\.[0-9]+)?([a-zA-Z%])?/;
516
517var d3_format_types = {
518  g: function(x, p) { return x.toPrecision(p); },
519  e: function(x, p) { return x.toExponential(p); },
520  f: function(x, p) { return x.toFixed(p); },
521  r: function(x, p) {
522    var n = 1 + Math.floor(1e-15 + Math.log(x) / Math.LN10);
523    return d3.round(x, p - n).toFixed(Math.max(0, p - n));
524  }
525};
526
527function d3_format_typeDefault(x) {
528  return x + "";
529}
530
531// Apply comma grouping for thousands.
532function d3_format_group(value) {
533  var i = value.lastIndexOf("."),
534      f = i >= 0 ? value.substring(i) : (i = value.length, ""),
535      t = [];
536  while (i > 0) t.push(value.substring(i -= 3, i + 3));
537  return t.reverse().join(",") + f;
538}
539/*
540 * TERMS OF USE - EASING EQUATIONS
541 *
542 * Open source under the BSD License.
543 *
544 * Copyright 2001 Robert Penner
545 * All rights reserved.
546 *
547 * Redistribution and use in source and binary forms, with or without
548 * modification, are permitted provided that the following conditions are met:
549 *
550 * - Redistributions of source code must retain the above copyright notice, this
551 *   list of conditions and the following disclaimer.
552 *
553 * - Redistributions in binary form must reproduce the above copyright notice,
554 *   this list of conditions and the following disclaimer in the documentation
555 *   and/or other materials provided with the distribution.
556 *
557 * - Neither the name of the author nor the names of contributors may be used to
558 *   endorse or promote products derived from this software without specific
559 *   prior written permission.
560 *
561 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
562 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
563 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
564 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
565 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
566 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
567 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
568 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
569 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
570 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
571 * POSSIBILITY OF SUCH DAMAGE.
572 */
573
574var d3_ease_quad = d3_ease_poly(2),
575    d3_ease_cubic = d3_ease_poly(3);
576
577var d3_ease = {
578  linear: function() { return d3_ease_linear; },
579  poly: d3_ease_poly,
580  quad: function() { return d3_ease_quad; },
581  cubic: function() { return d3_ease_cubic; },
582  sin: function() { return d3_ease_sin; },
583  exp: function() { return d3_ease_exp; },
584  circle: function() { return d3_ease_circle; },
585  elastic: d3_ease_elastic,
586  back: d3_ease_back,
587  bounce: function() { return d3_ease_bounce; }
588};
589
590var d3_ease_mode = {
591  "in": function(f) { return f; },
592  "out": d3_ease_reverse,
593  "in-out": d3_ease_reflect,
594  "out-in": function(f) { return d3_ease_reflect(d3_ease_reverse(f)); }
595};
596
597d3.ease = function(name) {
598  var i = name.indexOf("-"),
599      t = i >= 0 ? name.substring(0, i) : name,
600      m = i >= 0 ? name.substring(i + 1) : "in";
601  return d3_ease_mode[m](d3_ease[t].apply(null, Array.prototype.slice.call(arguments, 1)));
602};
603
604function d3_ease_reverse(f) {
605  return function(t) {
606    return 1 - f(1 - t);
607  };
608}
609
610function d3_ease_reflect(f) {
611  return function(t) {
612    return .5 * (t < .5 ? f(2 * t) : (2 - f(2 - 2 * t)));
613  };
614}
615
616function d3_ease_linear(t) {
617  return t;
618}
619
620function d3_ease_poly(e) {
621  return function(t) {
622    return Math.pow(t, e);
623  }
624}
625
626function d3_ease_sin(t) {
627  return 1 - Math.cos(t * Math.PI / 2);
628}
629
630function d3_ease_exp(t) {
631  return t ? Math.pow(2, 10 * (t - 1)) - 1e-3 : 0;
632}
633
634function d3_ease_circle(t) {
635  return 1 - Math.sqrt(1 - t * t);
636}
637
638function d3_ease_elastic(a, p) {
639  var s;
640  if (arguments.length < 2) p = 0.45;
641  if (arguments.length < 1) { a = 1; s = p / 4; }
642  else s = p / (2 * Math.PI) * Math.asin(1 / a);
643  return function(t) {
644    return 1 + a * Math.pow(2, 10 * -t) * Math.sin((t - s) * 2 * Math.PI / p);
645  };
646}
647
648function d3_ease_back(s) {
649  if (!s) s = 1.70158;
650  return function(t) {
651    return t * t * ((s + 1) * t - s);
652  };
653}
654
655function d3_ease_bounce(t) {
656  return t < 1 / 2.75 ? 7.5625 * t * t
657      : t < 2 / 2.75 ? 7.5625 * (t -= 1.5 / 2.75) * t + .75
658      : t < 2.5 / 2.75 ? 7.5625 * (t -= 2.25 / 2.75) * t + .9375
659      : 7.5625 * (t -= 2.625 / 2.75) * t + .984375;
660}
661d3.event = null;
662d3.interpolate = function(a, b) {
663  var i = d3.interpolators.length, f;
664  while (--i >= 0 && !(f = d3.interpolators[i](a, b)));
665  return f;
666};
667
668d3.interpolateNumber = function(a, b) {
669  b -= a;
670  return function(t) { return a + b * t; };
671};
672
673d3.interpolateRound = function(a, b) {
674  b -= a;
675  return function(t) { return Math.round(a + b * t); };
676};
677
678d3.interpolateString = function(a, b) {
679  var m, // current match
680      i, // current index
681      j, // current index (for coallescing)
682      s0 = 0, // start index of current string prefix
683      s1 = 0, // end index of current string prefix
684      s = [], // string constants and placeholders
685      q = [], // number interpolators
686      n, // q.length
687      o;
688
689  // Reset our regular expression!
690  d3_interpolate_number.lastIndex = 0;
691
692  // Find all numbers in b.
693  for (i = 0; m = d3_interpolate_number.exec(b); ++i) {
694    if (m.index) s.push(b.substring(s0, s1 = m.index));
695    q.push({i: s.length, x: m[0]});
696    s.push(null);
697    s0 = d3_interpolate_number.lastIndex;
698  }
699  if (s0 < b.length) s.push(b.substring(s0));
700
701  // Find all numbers in a.
702  for (i = 0, n = q.length; (m = d3_interpolate_number.exec(a)) && i < n; ++i) {
703    o = q[i];
704    if (o.x == m[0]) { // The numbers match, so coallesce.
705      if (o.i) {
706        if (s[o.i + 1] == null) { // This match is followed by another number.
707          s[o.i - 1] += o.x;
708          s.splice(o.i, 1);
709          for (j = i + 1; j < n; ++j) q[j].i--;
710        } else { // This match is followed by a string, so coallesce twice.
711          s[o.i - 1] += o.x + s[o.i + 1];
712          s.splice(o.i, 2);
713          for (j = i + 1; j < n; ++j) q[j].i -= 2;
714        }
715      } else {
716          if (s[o.i + 1] == null) { // This match is followed by another number.
717          s[o.i] = o.x;
718        } else { // This match is followed by a string, so coallesce twice.
719          s[o.i] = o.x + s[o.i + 1];
720          s.splice(o.i + 1, 1);
721          for (j = i + 1; j < n; ++j) q[j].i--;
722        }
723      }
724      q.splice(i, 1);
725      n--;
726      i--;
727    } else {
728      o.x = d3.interpolateNumber(parseFloat(m[0]), parseFloat(o.x));
729    }
730  }
731
732  // Remove any numbers in b not found in a.
733  while (i < n) {
734    o = q.pop();
735    if (s[o.i + 1] == null) { // This match is followed by another number.
736      s[o.i] = o.x;
737    } else { // This match is followed by a string, so coallesce twice.
738      s[o.i] = o.x + s[o.i + 1];
739      s.splice(o.i + 1, 1);
740    }
741    n--;
742  }
743
744  // Special optimization for only a single match.
745  if (s.length === 1) {
746    return s[0] == null ? q[0].x : function() { return b; };
747  }
748
749  // Otherwise, interpolate each of the numbers and rejoin the string.
750  return function(t) {
751    for (i = 0; i < n; ++i) s[(o = q[i]).i] = o.x(t);
752    return s.join("");
753  };
754};
755
756d3.interpolateRgb = function(a, b) {
757  a = d3.rgb(a);
758  b = d3.rgb(b);
759  var ar = a.r,
760      ag = a.g,
761      ab = a.b,
762      br = b.r - ar,
763      bg = b.g - ag,
764      bb = b.b - ab;
765  return function(t) {
766    return "rgb(" + Math.round(ar + br * t)
767        + "," + Math.round(ag + bg * t)
768        + "," + Math.round(ab + bb * t)
769        + ")";
770  };
771};
772
773// interpolates HSL space, but outputs RGB string (for compatibility)
774d3.interpolateHsl = function(a, b) {
775  a = d3.hsl(a);
776  b = d3.hsl(b);
777  var h0 = a.h,
778      s0 = a.s,
779      l0 = a.l,
780      h1 = b.h - h0,
781      s1 = b.s - s0,
782      l1 = b.l - l0;
783  return function(t) {
784    return d3_hsl_rgb(h0 + h1 * t, s0 + s1 * t, l0 + l1 * t).toString();
785  };
786};
787
788d3.interpolateArray = function(a, b) {
789  var x = [],
790      c = [],
791      na = a.length,
792      nb = b.length,
793      n0 = Math.min(a.length, b.length),
794      i;
795  for (i = 0; i < n0; ++i) x.push(d3.interpolate(a[i], b[i]));
796  for (; i < na; ++i) c[i] = a[i];
797  for (; i < nb; ++i) c[i] = b[i];
798  return function(t) {
799    for (i = 0; i < n0; ++i) c[i] = x[i](t);
800    return c;
801  };
802};
803
804d3.interpolateObject = function(a, b) {
805  var i = {},
806      c = {},
807      k;
808  for (k in a) {
809    if (k in b) {
810      i[k] = d3_interpolateByName(k)(a[k], b[k]);
811    } else {
812      c[k] = a[k];
813    }
814  }
815  for (k in b) {
816    if (!(k in a)) {
817      c[k] = b[k];
818    }
819  }
820  return function(t) {
821    for (k in i) c[k] = i[k](t);
822    return c;
823  };
824}
825
826var d3_interpolate_number = /[-+]?(?:\d+\.\d+|\d+\.|\.\d+|\d+)(?:[eE][-]?\d+)?/g,
827    d3_interpolate_rgb = {background: 1, fill: 1, stroke: 1};
828
829function d3_interpolateByName(n) {
830  return n in d3_interpolate_rgb || /\bcolor\b/.test(n)
831      ? d3.interpolateRgb
832      : d3.interpolate;
833}
834
835d3.interpolators = [
836  d3.interpolateObject,
837  function(a, b) { return (b instanceof Array) && d3.interpolateArray(a, b); },
838  function(a, b) { return (typeof b === "string") && d3.interpolateString(String(a), b); },
839  function(a, b) { return (b in d3_rgb_names || /^(#|rgb\(|hsl\()/.test(b)) && d3.interpolateRgb(String(a), b); },
840  function(a, b) { return (typeof b === "number") && d3.interpolateNumber(+a, b); }
841];
842function d3_uninterpolateNumber(a, b) {
843  b = 1 / (b - (a = +a));
844  return function(x) { return (x - a) * b; };
845}
846
847function d3_uninterpolateClamp(a, b) {
848  b = 1 / (b - (a = +a));
849  return function(x) { return Math.max(0, Math.min(1, (x - a) * b)); };
850}
851d3.rgb = function(r, g, b) {
852  return arguments.length === 1
853      ? d3_rgb_parse("" + r, d3_rgb, d3_hsl_rgb)
854      : d3_rgb(~~r, ~~g, ~~b);
855};
856
857function d3_rgb(r, g, b) {
858  return new d3_Rgb(r, g, b);
859}
860
861function d3_Rgb(r, g, b) {
862  this.r = r;
863  this.g = g;
864  this.b = b;
865}
866
867d3_Rgb.prototype.brighter = function(k) {
868  k = Math.pow(0.7, arguments.length ? k : 1);
869  var r = this.r,
870      g = this.g,
871      b = this.b,
872      i = 30;
873  if (!r && !g && !b) return d3_rgb(i, i, i);
874  if (r && r < i) r = i;
875  if (g && g < i) g = i;
876  if (b && b < i) b = i;
877  return d3_rgb(
878    Math.min(255, Math.floor(r / k)),
879    Math.min(255, Math.floor(g / k)),
880    Math.min(255, Math.floor(b / k)));
881};
882
883d3_Rgb.prototype.darker = function(k) {
884  k = Math.pow(0.7, arguments.length ? k : 1);
885  return d3_rgb(
886    Math.max(0, Math.floor(k * this.r)),
887    Math.max(0, Math.floor(k * this.g)),
888    Math.max(0, Math.floor(k * this.b)));
889};
890
891d3_Rgb.prototype.hsl = function() {
892  return d3_rgb_hsl(this.r, this.g, this.b);
893};
894
895d3_Rgb.prototype.toString = function() {
896  return "#" + d3_rgb_hex(this.r) + d3_rgb_hex(this.g) + d3_rgb_hex(this.b);
897};
898
899function d3_rgb_hex(v) {
900  return v < 0x10 ? "0" + v.toString(16) : v.toString(16);
901}
902
903function d3_rgb_parse(format, rgb, hsl) {
904  var r = 0, // red channel; int in [0, 255]
905      g = 0, // green channel; int in [0, 255]
906      b = 0, // blue channel; int in [0, 255]
907      m1, // CSS color specification match
908      m2, // CSS color specification type (e.g., rgb)
909      name;
910
911  /* Handle hsl, rgb. */
912  m1 = /([a-z]+)\((.*)\)/i.exec(format);
913  if (m1) {
914    m2 = m1[2].split(",");
915    switch (m1[1]) {
916      case "hsl": {
917        return hsl(
918          parseFloat(m2[0]), // degrees
919          parseFloat(m2[1]) / 100, // percentage
920          parseFloat(m2[2]) / 100 // percentage
921        );
922      }
923      case "rgb": {
924        return rgb(
925          d3_rgb_parseNumber(m2[0]),
926          d3_rgb_parseNumber(m2[1]),
927          d3_rgb_parseNumber(m2[2])
928        );
929      }
930    }
931  }
932
933  /* Named colors. */
934  if (name = d3_rgb_names[format]) return rgb(name.r, name.g, name.b);
935
936  /* Hexadecimal colors: #rgb and #rrggbb. */
937  if (format != null && format.charAt(0) === "#") {
938    if (format.length === 4) {
939      r = format.charAt(1); r += r;
940      g = format.charAt(2); g += g;
941      b = format.charAt(3); b += b;
942    } else if (format.length === 7) {
943      r = format.substring(1, 3);
944      g = format.substring(3, 5);
945      b = format.substring(5, 7);
946    }
947    r = parseInt(r, 16);
948    g = parseInt(g, 16);
949    b = parseInt(b, 16);
950  }
951
952  return rgb(r, g, b);
953}
954
955function d3_rgb_hsl(r, g, b) {
956  var min = Math.min(r /= 255, g /= 255, b /= 255),
957      max = Math.max(r, g, b),
958      d = max - min,
959      h,
960      s,
961      l = (max + min) / 2;
962  if (d) {
963    s = l < .5 ? d / (max + min) : d / (2 - max - min);
964    if (r == max) h = (g - b) / d + (g < b ? 6 : 0);
965    else if (g == max) h = (b - r) / d + 2;
966    else h = (r - g) / d + 4;
967    h *= 60;
968  } else {
969    s = h = 0;
970  }
971  return d3_hsl(h, s, l);
972}
973
974function d3_rgb_parseNumber(c) { // either integer or percentage
975  var f = parseFloat(c);
976  return c.charAt(c.length - 1) === "%" ? Math.round(f * 2.55) : f;
977}
978
979var d3_rgb_names = {
980  aliceblue: "#f0f8ff",
981  antiquewhite: "#faebd7",
982  aqua: "#00ffff",
983  aquamarine: "#7fffd4",
984  azure: "#f0ffff",
985  beige: "#f5f5dc",
986  bisque: "#ffe4c4",
987  black: "#000000",
988  blanchedalmond: "#ffebcd",
989  blue: "#0000ff",
990  blueviolet: "#8a2be2",
991  brown: "#a52a2a",
992  burlywood: "#deb887",
993  cadetblue: "#5f9ea0",
994  chartreuse: "#7fff00",
995  chocolate: "#d2691e",
996  coral: "#ff7f50",
997  cornflowerblue: "#6495ed",
998  cornsilk: "#fff8dc",
999  crimson: "#dc143c",
1000  cyan: "#00ffff",
1001  darkblue: "#00008b",
1002  darkcyan: "#008b8b",
1003  darkgoldenrod: "#b8860b",
1004  darkgray: "#a9a9a9",
1005  darkgreen: "#006400",
1006  darkgrey: "#a9a9a9",
1007  darkkhaki: "#bdb76b",
1008  darkmagenta: "#8b008b",
1009  darkolivegreen: "#556b2f",
1010  darkorange: "#ff8c00",
1011  darkorchid: "#9932cc",
1012  darkred: "#8b0000",
1013  darksalmon: "#e9967a",
1014  darkseagreen: "#8fbc8f",
1015  darkslateblue: "#483d8b",
1016  darkslategray: "#2f4f4f",
1017  darkslategrey: "#2f4f4f",
1018  darkturquoise: "#00ced1",
1019  darkviolet: "#9400d3",
1020  deeppink: "#ff1493",
1021  deepskyblue: "#00bfff",
1022  dimgray: "#696969",
1023  dimgrey: "#696969",
1024  dodgerblue: "#1e90ff",
1025  firebrick: "#b22222",
1026  floralwhite: "#fffaf0",
1027  forestgreen: "#228b22",
1028  fuchsia: "#ff00ff",
1029  gainsboro: "#dcdcdc",
1030  ghostwhite: "#f8f8ff",
1031  gold: "#ffd700",
1032  goldenrod: "#daa520",
1033  gray: "#808080",
1034  green: "#008000",
1035  greenyellow: "#adff2f",
1036  grey: "#808080",
1037  honeydew: "#f0fff0",
1038  hotpink: "#ff69b4",
1039  indianred: "#cd5c5c",
1040  indigo: "#4b0082",
1041  ivory: "#fffff0",
1042  khaki: "#f0e68c",
1043  lavender: "#e6e6fa",
1044  lavenderblush: "#fff0f5",
1045  lawngreen: "#7cfc00",
1046  lemonchiffon: "#fffacd",
1047  lightblue: "#add8e6",
1048  lightcoral: "#f08080",
1049  lightcyan: "#e0ffff",
1050  lightgoldenrodyellow: "#fafad2",
1051  lightgray: "#d3d3d3",
1052  lightgreen: "#90ee90",
1053  lightgrey: "#d3d3d3",
1054  lightpink: "#ffb6c1",
1055  lightsalmon: "#ffa07a",
1056  lightseagreen: "#20b2aa",
1057  lightskyblue: "#87cefa",
1058  lightslategray: "#778899",
1059  lightslategrey: "#778899",
1060  lightsteelblue: "#b0c4de",
1061  lightyellow: "#ffffe0",
1062  lime: "#00ff00",
1063  limegreen: "#32cd32",
1064  linen: "#faf0e6",
1065  magenta: "#ff00ff",
1066  maroon: "#800000",
1067  mediumaquamarine: "#66cdaa",
1068  mediumblue: "#0000cd",
1069  mediumorchid: "#ba55d3",
1070  mediumpurple: "#9370db",
1071  mediumseagreen: "#3cb371",
1072  mediumslateblue: "#7b68ee",
1073  mediumspringgreen: "#00fa9a",
1074  mediumturquoise: "#48d1cc",
1075  mediumvioletred: "#c71585",
1076  midnightblue: "#191970",
1077  mintcream: "#f5fffa",
1078  mistyrose: "#ffe4e1",
1079  moccasin: "#ffe4b5",
1080  navajowhite: "#ffdead",
1081  navy: "#000080",
1082  oldlace: "#fdf5e6",
1083  olive: "#808000",
1084  olivedrab: "#6b8e23",
1085  orange: "#ffa500",
1086  orangered: "#ff4500",
1087  orchid: "#da70d6",
1088  palegoldenrod: "#eee8aa",
1089  palegreen: "#98fb98",
1090  paleturquoise: "#afeeee",
1091  palevioletred: "#db7093",
1092  papayawhip: "#ffefd5",
1093  peachpuff: "#ffdab9",
1094  peru: "#cd853f",
1095  pink: "#ffc0cb",
1096  plum: "#dda0dd",
1097  powderblue: "#b0e0e6",
1098  purple: "#800080",
1099  red: "#ff0000",
1100  rosybrown: "#bc8f8f",
1101  royalblue: "#4169e1",
1102  saddlebrown: "#8b4513",
1103  salmon: "#fa8072",
1104  sandybrown: "#f4a460",
1105  seagreen: "#2e8b57",
1106  seashell: "#fff5ee",
1107  sienna: "#a0522d",
1108  silver: "#c0c0c0",
1109  skyblue: "#87ceeb",
1110  slateblue: "#6a5acd",
1111  slategray: "#708090",
1112  slategrey: "#708090",
1113  snow: "#fffafa",
1114  springgreen: "#00ff7f",
1115  steelblue: "#4682b4",
1116  tan: "#d2b48c",
1117  teal: "#008080",
1118  thistle: "#d8bfd8",
1119  tomato: "#ff6347",
1120  turquoise: "#40e0d0",
1121  violet: "#ee82ee",
1122  wheat: "#f5deb3",
1123  white: "#ffffff",
1124  whitesmoke: "#f5f5f5",
1125  yellow: "#ffff00",
1126  yellowgreen: "#9acd32"
1127};
1128
1129for (var d3_rgb_name in d3_rgb_names) {
1130  d3_rgb_names[d3_rgb_name] = d3_rgb_parse(
1131      d3_rgb_names[d3_rgb_name],
1132      d3_rgb,
1133      d3_hsl_rgb);
1134}
1135d3.hsl = function(h, s, l) {
1136  return arguments.length === 1
1137      ? d3_rgb_parse("" + h, d3_rgb_hsl, d3_hsl)
1138      : d3_hsl(+h, +s, +l);
1139};
1140
1141function d3_hsl(h, s, l) {
1142  return new d3_Hsl(h, s, l);
1143}
1144
1145function d3_Hsl(h, s, l) {
1146  this.h = h;
1147  this.s = s;
1148  this.l = l;
1149}
1150
1151d3_Hsl.prototype.brighter = function(k) {
1152  k = Math.pow(0.7, arguments.length ? k : 1);
1153  return d3_hsl(this.h, this.s, this.l / k);
1154};
1155
1156d3_Hsl.prototype.darker = function(k) {
1157  k = Math.pow(0.7, arguments.length ? k : 1);
1158  return d3_hsl(this.h, this.s, k * this.l);
1159};
1160
1161d3_Hsl.prototype.rgb = function() {
1162  return d3_hsl_rgb(this.h, this.s, this.l);
1163};
1164
1165d3_Hsl.prototype.toString = function() {
1166  return "hsl(" + this.h + "," + this.s * 100 + "%," + this.l * 100 + "%)";
1167};
1168
1169function d3_hsl_rgb(h, s, l) {
1170  var m1,
1171      m2;
1172
1173  /* Some simple corrections for h, s and l. */
1174  h = h % 360; if (h < 0) h += 360;
1175  s = s < 0 ? 0 : s > 1 ? 1 : s;
1176  l = l < 0 ? 0 : l > 1 ? 1 : l;
1177
1178  /* From FvD 13.37, CSS Color Module Level 3 */
1179  m2 = l <= .5 ? l * (1 + s) : l + s - l * s;
1180  m1 = 2 * l - m2;
1181
1182  function v(h) {
1183    if (h > 360) h -= 360;
1184    else if (h < 0) h += 360;
1185    if (h < 60) return m1 + (m2 - m1) * h / 60;
1186    if (h < 180) return m2;
1187    if (h < 240) return m1 + (m2 - m1) * (240 - h) / 60;
1188    return m1;
1189  }
1190
1191  function vv(h) {
1192    return Math.round(v(h) * 255);
1193  }
1194
1195  return d3_rgb(vv(h + 120), vv(h), vv(h - 120));
1196}
1197var d3_select = function(s, n) { return n.querySelector(s); },
1198    d3_selectAll = function(s, n) { return d3_array(n.querySelectorAll(s)); };
1199
1200// Use Sizzle, if available.
1201if (typeof Sizzle === "function") {
1202  d3_select = function(s, n) { return Sizzle(s, n)[0]; };
1203  d3_selectAll = function(s, n) { return Sizzle.uniqueSort(Sizzle(s, n)); };
1204}
1205
1206var d3_root = d3_selection([[document]]);
1207d3_root[0].parentNode = document.documentElement;
1208
1209// TODO fast singleton implementation!
1210d3.select = function(selector) {
1211  return typeof selector === "string"
1212      ? d3_root.select(selector)
1213      : d3_selection([[selector]]); // assume node
1214};
1215
1216d3.selectAll = function(selector) {
1217  return typeof selector === "string"
1218      ? d3_root.selectAll(selector)
1219      : d3_selection([d3_array(selector)]); // assume node[]
1220};
1221
1222function d3_selection(groups) {
1223
1224  function select(select) {
1225    var subgroups = [],
1226        subgroup,
1227        subnode,
1228        group,
1229        node;
1230    for (var j = 0, m = groups.length; j < m; j++) {
1231      group = groups[j];
1232      subgroups.push(subgroup = []);
1233      subgroup.parentNode = group.parentNode;
1234      for (var i = 0, n = group.length; i < n; i++) {
1235        if (node = group[i]) {
1236          subgroup.push(subnode = select(node));
1237          if (subnode && "__data__" in node) subnode.__data__ = node.__data__;
1238        } else {
1239          subgroup.push(null);
1240        }
1241      }
1242    }
1243    return d3_selection(subgroups);
1244  }
1245
1246  function selectAll(selectAll) {
1247    var subgroups = [],
1248        subgroup,
1249        group,
1250        node;
1251    for (var j = 0, m = groups.length; j < m; j++) {
1252      group = groups[j];
1253      for (var i = 0, n = group.length; i < n; i++) {
1254        if (node = group[i]) {
1255          subgroups.push(subgroup = selectAll(node));
1256          subgroup.parentNode = node;
1257        }
1258      }
1259    }
1260    return d3_selection(subgroups);
1261  }
1262
1263  // TODO select(function)?
1264  groups.select = function(selector) {
1265    return select(function(node) {
1266      return d3_select(selector, node);
1267    });
1268  };
1269
1270  // TODO selectAll(function)?
1271  groups.selectAll = function(selector) {
1272    return selectAll(function(node) {
1273      return d3_selectAll(selector, node);
1274    });
1275  };
1276
1277  // TODO preserve null elements to maintain index?
1278  groups.filter = function(filter) {
1279    var subgroups = [],
1280        subgroup,
1281        group,
1282        node;
1283    for (var j = 0, m = groups.length; j < m; j++) {
1284      group = groups[j];
1285      subgroups.push(subgroup = []);
1286      subgroup.parentNode = group.parentNode;
1287      for (var i = 0, n = group.length; i < n; i++) {
1288        if ((node = group[i]) && filter.call(node, node.__data__, i)) {
1289          subgroup.push(node);
1290        }
1291      }
1292    }
1293    return d3_selection(subgroups);
1294  };
1295
1296  groups.map = function(map) {
1297    var group,
1298        node;
1299    for (var j = 0, m = groups.length; j < m; j++) {
1300      group = groups[j];
1301      for (var i = 0, n = group.length; i < n; i++) {
1302        if (node = group[i]) node.__data__ = map.call(node, node.__data__, i);
1303      }
1304    }
1305    return groups;
1306  };
1307
1308  // TODO data(null) for clearing data?
1309  groups.data = function(data, join) {
1310    var enter = [],
1311        update = [],
1312        exit = [];
1313
1314    function bind(group, groupData) {
1315      var i = 0,
1316          n = group.length,
1317          m = groupData.length,
1318          n0 = Math.min(n, m),
1319          n1 = Math.max(n, m),
1320          updateNodes = [],
1321          enterNodes = [],
1322          exitNodes = [],
1323          node,
1324          nodeData;
1325
1326      if (join) {
1327        var nodeByKey = {},
1328            keys = [],
1329            key,
1330            j = groupData.length;
1331
1332        for (i = 0; i < n; i++) {
1333          key = join.call(node = group[i], node.__data__, i);
1334          if (key in nodeByKey) {
1335            exitNodes[j++] = node; // duplicate key
1336          } else {
1337            nodeByKey[key] = node;
1338          }
1339          keys.push(key);
1340        }
1341
1342        for (i = 0; i < m; i++) {
1343          node = nodeByKey[key = join.call(groupData, nodeData = groupData[i], i)];
1344          if (node) {
1345            node.__data__ = nodeData;
1346            updateNodes[i] = node;
1347            enterNodes[i] = exitNodes[i] = null;
1348          } else {
1349            enterNodes[i] = d3_selection_enterNode(nodeData);
1350            updateNodes[i] = exitNodes[i] = null;
1351          }
1352          delete nodeByKey[key];
1353        }
1354
1355        for (i = 0; i < n; i++) {
1356          if (keys[i] in nodeByKey) {
1357            exitNodes[i] = group[i];
1358          }
1359        }
1360      } else {
1361        for (; i < n0; i++) {
1362          node = group[i];
1363          nodeData = groupData[i];
1364          if (node) {
1365            node.__data__ = nodeData;
1366            updateNodes[i] = node;
1367            enterNodes[i] = exitNodes[i] = null;
1368          } else {
1369            enterNodes[i] = d3_selection_enterNode(nodeData);
1370            updateNodes[i] = exitNodes[i] = null;
1371          }
1372        }
1373        for (; i < m; i++) {
1374          enterNodes[i] = d3_selection_enterNode(groupData[i]);
1375          updateNodes[i] = exitNodes[i] = null;
1376        }
1377        for (; i < n1; i++) {
1378          exitNodes[i] = group[i];
1379          enterNodes[i] = updateNodes[i] = null;
1380        }
1381      }
1382
1383      enterNodes.parentNode
1384          = updateNodes.parentNode
1385          = exitNodes.parentNode
1386          = group.parentNode;
1387
1388      enter.push(enterNodes);
1389      update.push(updateNodes);
1390      exit.push(exitNodes);
1391    }
1392
1393    var i = -1,
1394        n = groups.length,
1395        group;
1396    if (typeof data === "function") {
1397      while (++i < n) {
1398        bind(group = groups[i], data.call(group, group.parentNode.__data__, i));
1399      }
1400    } else {
1401      while (++i < n) {
1402        bind(group = groups[i], data);
1403      }
1404    }
1405
1406    var selection = d3_selection(update);
1407    selection.enter = function() {
1408      return d3_selectionEnter(enter);
1409    };
1410    selection.exit = function() {
1411      return d3_selection(exit);
1412    };
1413    return selection;
1414  };
1415
1416  // TODO mask forEach? or rename for eachData?
1417  // TODO offer the same semantics for map, reduce, etc.?
1418  groups.each = function(callback) {
1419    for (var j = 0, m = groups.length; j < m; j++) {
1420      var group = groups[j];
1421      for (var i = 0, n = group.length; i < n; i++) {
1422        var node = group[i];
1423        if (node) callback.call(node, node.__data__, i);
1424      }
1425    }
1426    return groups;
1427  };
1428
1429  function first(callback) {
1430    for (var j = 0, m = groups.length; j < m; j++) {
1431      var group = groups[j];
1432      for (var i = 0, n = group.length; i < n; i++) {
1433        var node = group[i];
1434        if (node) return callback.call(node, node.__data__, i);
1435      }
1436    }
1437    return null;
1438  }
1439
1440  groups.empty = function() {
1441    return !first(function() { return true; });
1442  };
1443
1444  groups.node = function() {
1445    return first(function() { return this; });
1446  };
1447
1448  groups.attr = function(name, value) {
1449    name = d3.ns.qualify(name);
1450
1451    // If no value is specified, return the first value.
1452    if (arguments.length < 2) {
1453      return first(name.local
1454          ? function() { return this.getAttributeNS(name.space, name.local); }
1455          : function() { return this.getAttribute(name); });
1456    }
1457
1458    /** @this {Element} */
1459    function attrNull() {
1460      this.removeAttribute(name);
1461    }
1462
1463    /** @this {Element} */
1464    function attrNullNS() {
1465      this.removeAttributeNS(name.space, name.local);
1466    }
1467
1468    /** @this {Element} */
1469    function attrConstant() {
1470      this.setAttribute(name, value);
1471    }
1472
1473    /** @this {Element} */
1474    function attrConstantNS() {
1475      this.setAttributeNS(name.space, name.local, value);
1476    }
1477
1478    /** @this {Element} */
1479    function attrFunction() {
1480      var x = value.apply(this, arguments);
1481      if (x == null) this.removeAttribute(name);
1482      else this.setAttribute(name, x);
1483    }
1484
1485    /** @this {Element} */
1486    function attrFunctionNS() {
1487      var x = value.apply(this, arguments);
1488      if (x == null) this.removeAttributeNS(name.space, name.local);
1489      else this.setAttributeNS(name.space, name.local, x);
1490    }
1491
1492    return groups.each(value == null
1493        ? (name.local ? attrNullNS : attrNull) : (typeof value === "function"
1494        ? (name.local ? attrFunctionNS : attrFunction)
1495        : (name.local ? attrConstantNS : attrConstant)));
1496  };
1497
1498  groups.classed = function(name, value) {
1499    var re = new RegExp("(^|\\s+)" + d3.requote(name) + "(\\s+|$)", "g");
1500
1501    // If no value is specified, return the first value.
1502    if (arguments.length < 2) {
1503      return first(function() {
1504        if (c = this.classList) return c.contains(name);
1505        var c = this.className;
1506        re.lastIndex = 0;
1507        return re.test(c.baseVal != null ? c.baseVal : c);
1508      });
1509    }
1510
1511    /** @this {Element} */
1512    function classedAdd() {
1513      if (c = this.classList) return c.add(name);
1514      var c = this.className,
1515          cb = c.baseVal != null,
1516          cv = cb ? c.baseVal : c;
1517      re.lastIndex = 0;
1518      if (!re.test(cv)) {
1519        cv = d3_collapse(cv + " " + name);
1520        if (cb) c.baseVal = cv;
1521        else this.className = cv;
1522      }
1523    }
1524
1525    /** @this {Element} */
1526    function classedRemove() {
1527      if (c = this.classList) return c.remove(name);
1528      var c = this.className,
1529          cb = c.baseVal != null,
1530          cv = cb ? c.baseVal : c;
1531      cv = d3_collapse(cv.replace(re, " "));
1532      if (cb) c.baseVal = cv;
1533      else this.className = cv;
1534    }
1535
1536    /** @this {Element} */
1537    function classedFunction() {
1538      (value.apply(this, arguments)
1539          ? classedAdd
1540          : classedRemove).call(this);
1541    }
1542
1543    return groups.each(typeof value === "function"
1544        ? classedFunction : value
1545        ? classedAdd
1546        : classedRemove);
1547  };
1548
1549  groups.style = function(name, value, priority) {
1550    if (arguments.length < 3) priority = "";
1551
1552    // If no value is specified, return the first value.
1553    if (arguments.length < 2) {
1554      return first(function() {
1555        return window.getComputedStyle(this, null).getPropertyValue(name);
1556      });
1557    }
1558
1559    /** @this {Element} */
1560    function styleNull() {
1561      this.style.removeProperty(name);
1562    }
1563
1564    /** @this {Element} */
1565    function styleConstant() {
1566      this.style.setProperty(name, value, priority);
1567    }
1568
1569    /** @this {Element} */
1570    function styleFunction() {
1571      var x = value.apply(this, arguments);
1572      if (x == null) this.style.removeProperty(name);
1573      else this.style.setProperty(name, x, priority);
1574    }
1575
1576    return groups.each(value == null
1577        ? styleNull : (typeof value === "function"
1578        ? styleFunction : styleConstant));
1579  };
1580
1581  groups.property = function(name, value) {
1582    name = d3.ns.qualify(name);
1583
1584    // If no value is specified, return the first value.
1585    if (arguments.length < 2) {
1586      return first(function() {
1587        return this[name];
1588      });
1589    }
1590
1591    /** @this {Element} */
1592    function propertyNull() {
1593      delete this[name];
1594    }
1595
1596    /** @this {Element} */
1597    function propertyConstant() {
1598      this[name] = value;
1599    }
1600
1601    /** @this {Element} */
1602    function propertyFunction() {
1603      var x = value.apply(this, arguments);
1604      if (x == null) delete this[name];
1605      else this[name] = x;
1606    }
1607
1608    return groups.each(value == null
1609        ? propertyNull : (typeof value === "function"
1610        ? propertyFunction : propertyConstant));
1611  };
1612
1613  groups.text = function(value) {
1614
1615    // If no value is specified, return the first value.
1616    if (arguments.length < 1) {
1617      return first(function() {
1618        return this.textContent;
1619      });
1620    }
1621
1622    /** @this {Element} */
1623    function textConstant() {
1624      this.textContent = value;
1625    }
1626
1627    /** @this {Element} */
1628    function textFunction() {
1629      this.textContent = value.apply(this, arguments);
1630    }
1631
1632    return groups.each(typeof value === "function"
1633        ? textFunction : textConstant);
1634  };
1635
1636  groups.html = function(value) {
1637
1638    // If no value is specified, return the first value.
1639    if (arguments.length < 1) {
1640      return first(function() {
1641        return this.innerHTML;
1642      });
1643    }
1644
1645    /** @this {Element} */
1646    function htmlConstant() {
1647      this.innerHTML = value;
1648    }
1649
1650    /** @this {Element} */
1651    function htmlFunction() {
1652      this.innerHTML = value.apply(this, arguments);
1653    }
1654
1655    return groups.each(typeof value === "function"
1656        ? htmlFunction : htmlConstant);
1657  };
1658
1659  // TODO append(node)?
1660  // TODO append(function)?
1661  groups.append = function(name) {
1662    name = d3.ns.qualify(name);
1663
1664    function append(node) {
1665      return node.appendChild(document.createElement(name));
1666    }
1667
1668    function appendNS(node) {
1669      return node.appendChild(document.createElementNS(name.space, name.local));
1670    }
1671
1672    return select(name.local ? appendNS : append);
1673  };
1674
1675  // TODO insert(node, function)?
1676  // TODO insert(function, string)?
1677  // TODO insert(function, function)?
1678  groups.insert = function(name, before) {
1679    name = d3.ns.qualify(name);
1680
1681    function insert(node) {
1682      return node.insertBefore(
1683          document.createElement(name),
1684          d3_select(before, node));
1685    }
1686
1687    function insertNS(node) {
1688      return node.insertBefore(
1689          document.createElementNS(name.space, name.local),
1690          d3_select(before, node));
1691    }
1692
1693    return select(name.local ? insertNS : insert);
1694  };
1695
1696  // TODO remove(selector)?
1697  // TODO remove(node)?
1698  // TODO remove(function)?
1699  groups.remove = function() {
1700    return groups.each(function() {
1701      var parent = this.parentNode;
1702      if (parent) parent.removeChild(this);
1703    });
1704  };
1705
1706  groups.sort = function(comparator) {
1707    comparator = d3_selection_comparator.apply(this, arguments);
1708    for (var j = 0, m = groups.length; j < m; j++) {
1709      var group = groups[j];
1710      group.sort(comparator);
1711      for (var i = 1, n = group.length, prev = group[0]; i < n; i++) {
1712        var node = group[i];
1713        if (node) {
1714          if (prev) prev.parentNode.insertBefore(node, prev.nextSibling);
1715          prev = node;
1716        }
1717      }
1718    }
1719    return groups;
1720  };
1721
1722  // type can be namespaced, e.g., "click.foo"
1723  // listener can be null for removal
1724  groups.on = function(type, listener, capture) {
1725    if (arguments.length < 3) capture = false;
1726
1727    // parse the type specifier
1728    var i = type.indexOf("."),
1729        typo = i === -1 ? type : type.substring(0, i),
1730        name = "__on" + type;
1731
1732    // remove the old event listener, and add the new event listener
1733    return groups.each(function(d, i) {
1734      if (this[name]) this.removeEventListener(typo, this[name], capture);
1735      if (listener) this.addEventListener(typo, this[name] = l, capture);
1736
1737      // wrapped event listener that preserves i
1738      var node = this;
1739      function l(e) {
1740        var o = d3.event; // Events can be reentrant (e.g., focus).
1741        d3.event = e;
1742        try {
1743          listener.call(this, node.__data__, i);
1744        } finally {
1745          d3.event = o;
1746        }
1747      }
1748    });
1749  };
1750
1751  // TODO slice?
1752
1753  groups.transition = function() {
1754    return d3_transition(groups);
1755  };
1756
1757  groups.call = d3_call;
1758
1759  return groups;
1760}
1761
1762function d3_selectionEnter(groups) {
1763
1764  function select(select) {
1765    var subgroups = [],
1766        subgroup,
1767        subnode,
1768        group,
1769        node;
1770    for (var j = 0, m = groups.length; j < m; j++) {
1771      group = groups[j];
1772      subgroups.push(subgroup = []);
1773      subgroup.parentNode = group.parentNode;
1774      for (var i = 0, n = group.length; i < n; i++) {
1775        if (node = group[i]) {
1776          subgroup.push(subnode = select(group.parentNode));
1777          subnode.__data__ = node.__data__;
1778        } else {
1779          subgroup.push(null);
1780        }
1781      }
1782    }
1783    return d3_selection(subgroups);
1784  }
1785
1786  // TODO append(node)?
1787  // TODO append(function)?
1788  groups.append = function(name) {
1789    name = d3.ns.qualify(name);
1790
1791    function append(node) {
1792      return node.appendChild(document.createElement(name));
1793    }
1794
1795    function appendNS(node) {
1796      return node.appendChild(document.createElementNS(name.space, name.local));
1797    }
1798
1799    return select(name.local ? appendNS : append);
1800  };
1801
1802  // TODO insert(node, function)?
1803  // TODO insert(function, string)?
1804  // TODO insert(function, function)?
1805  groups.insert = function(name, before) {
1806    name = d3.ns.qualify(name);
1807
1808    function insert(node) {
1809      return node.insertBefore(
1810          document.createElement(name),
1811          d3_select(before, node));
1812    }
1813
1814    function insertNS(node) {
1815      return node.insertBefore(
1816          document.createElementNS(name.space, name.local),
1817          d3_select(before, node));
1818    }
1819
1820    return select(name.local ? insertNS : insert);
1821  };
1822
1823  return groups;
1824}
1825
1826function d3_selection_comparator(comparator) {
1827  if (!arguments.length) comparator = d3.ascending;
1828  return function(a, b) {
1829    return comparator(a && a.__data__, b && b.__data__);
1830  };
1831}
1832
1833function d3_selection_enterNode(data) {
1834  return {__data__: data};
1835}
1836d3.transition = d3_root.transition;
1837
1838var d3_transitionId = 0,
1839    d3_transitionInheritId = 0;
1840
1841function d3_transition(groups) {
1842  var transition = {},
1843      transitionId = d3_transitionInheritId || ++d3_transitionId,
1844      tweens = {},
1845      interpolators = [],
1846      remove = false,
1847      event = d3.dispatch("start", "end"),
1848      stage = [],
1849      delay = [],
1850      duration = [],
1851      durationMax,
1852      ease = d3.ease("cubic-in-out");
1853
1854  //
1855  // Be careful with concurrent transitions!
1856  //
1857  // Say transition A causes an exit. Before A finishes, a transition B is
1858  // created, and believes it only needs to do an update, because the elements
1859  // haven't been removed yet (which happens at the very end of the exit
1860  // transition).
1861  //
1862  // Even worse, what if either transition A or B has a staggered delay? Then,
1863  // some elements may be removed, while others remain. Transition B does not
1864  // know to enter the elements because they were still present at the time
1865  // the transition B was created (but not yet started).
1866  //
1867  // To prevent such confusion, we only trigger end events for transitions if
1868  // the transition ending is the only one scheduled for the given element.
1869  // Similarly, we only allow one transition to be active for any given
1870  // element, so that concurrent transitions do not overwrite each other's
1871  // properties.
1872  //
1873  // TODO Support transition namespaces, so that transitions can proceed
1874  // concurrently on the same element if needed. Hopefully, this is rare!
1875  //
1876
1877  groups.each(function() {
1878    (this.__transition__ || (this.__transition__ = {})).owner = transitionId;
1879  });
1880
1881  function step(elapsed) {
1882    var clear = true,
1883        k = -1;
1884    groups.each(function() {
1885      if (stage[++k] === 2) return; // ended
1886      var t = (elapsed - delay[k]) / duration[k],
1887          tx = this.__transition__,
1888          te, // ease(t)
1889          tk, // tween key
1890          ik = interpolators[k];
1891
1892      // Check if the (un-eased) time is outside the range [0,1].
1893      if (t < 1) {
1894        clear = false;
1895        if (t < 0) return;
1896      } else {
1897        t = 1;
1898      }
1899
1900      // Determine the stage of this transition.
1901      // 0 - Not yet started.
1902      // 1 - In progress.
1903      // 2 - Ended.
1904      if (stage[k]) {
1905        if (!tx || tx.active !== transitionId) {
1906          stage[k] = 2;
1907          return;
1908        }
1909      } else if (!tx || tx.active > transitionId) {
1910        stage[k] = 2;
1911        return;
1912      } else {
1913        stage[k] = 1;
1914        event.start.dispatch.apply(this, arguments);
1915        ik = interpolators[k] = {};
1916        tx.active = transitionId;
1917        for (tk in tweens) {
1918          if (te = tweens[tk].apply(this, arguments)) {
1919            ik[tk] = te;
1920          }
1921        }
1922      }
1923
1924      // Apply the interpolators!
1925      te = ease(t);
1926      for (tk in ik) ik[tk].call(this, te);
1927
1928      // Handle ending transitions.
1929      if (t === 1) {
1930        stage[k] = 2;
1931        if (tx.active === transitionId) {
1932          var owner = tx.owner;
1933          if (owner === transitionId) {
1934            delete this.__transition__;
1935            if (remove && this.parentNode) this.parentNode.removeChild(this);
1936          }
1937          d3_transitionInheritId = transitionId;
1938          event.end.dispatch.apply(this, arguments);
1939          d3_transitionInheritId = 0;
1940          tx.owner = owner;
1941        }
1942      }
1943    });
1944    return clear;
1945  }
1946
1947  transition.delay = function(value) {
1948    var delayMin = Infinity,
1949        k = -1;
1950    if (typeof value === "function") {
1951      groups.each(function(d, i) {
1952        var x = delay[++k] = +value.apply(this, arguments);
1953        if (x < delayMin) delayMin = x;
1954      });
1955    } else {
1956      delayMin = +value;
1957      groups.each(function(d, i) {
1958        delay[++k] = delayMin;
1959      });
1960    }
1961    d3_timer(step, delayMin);
1962    return transition;
1963  };
1964
1965  transition.duration = function(value) {
1966    var k = -1;
1967    if (typeof value === "function") {
1968      durationMax = 0;
1969      groups.each(function(d, i) {
1970        var x = duration[++k] = +value.apply(this, arguments);
1971        if (x > durationMax) durationMax = x;
1972      });
1973    } else {
1974      durationMax = +value;
1975      groups.each(function(d, i) {
1976        duration[++k] = durationMax;
1977      });
1978    }
1979    return transition;
1980  };
1981
1982  transition.ease = function(value) {
1983    ease = typeof value === "function" ? value : d3.ease.apply(d3, arguments);
1984    return transition;
1985  };
1986
1987  transition.attrTween = function(name, tween) {
1988
1989    /** @this {Element} */
1990    function attrTween(d, i) {
1991      var f = tween.call(this, d, i, this.getAttribute(name));
1992      return f && function(t) {
1993        this.setAttribute(name, f(t));
1994      };
1995    }
1996
1997    /** @this {Element} */
1998    function attrTweenNS(d, i) {
1999      var f = tween.call(this, d, i, this.getAttributeNS(name.space, name.local));
2000      return f && function(t) {
2001        this.setAttributeNS(name.space, name.local, f(t));
2002      };
2003    }
2004
2005    tweens["attr." + name] = name.local ? attrTweenNS : attrTween;
2006    return transition;
2007  };
2008
2009  transition.attr = function(name, value) {
2010    return transition.attrTween(name, d3_transitionTween(value));
2011  };
2012
2013  transition.styleTween = function(name, tween, priority) {
2014    if (arguments.length < 3) priority = null;
2015
2016    /** @this {Element} */
2017    function styleTween(d, i) {
2018      var f = tween.call(this, d, i, window.getComputedStyle(this, null).getPropertyValue(name));
2019      return f && function(t) {
2020        this.style.setProperty(name, f(t), priority);
2021      };
2022    }
2023
2024    tweens["style." + name] = styleTween;
2025    return transition;
2026  };
2027
2028  transition.style = function(name, value, priority) {
2029    if (arguments.length < 3) priority = null;
2030    return transition.styleTween(name, d3_transitionTween(value), priority);
2031  };
2032
2033  transition.text = function(value) {
2034    tweens.text = function(d, i) {
2035      this.textContent = typeof value === "function"
2036          ? value.call(this, d, i)
2037          : value;
2038    };
2039    return transition;
2040  };
2041
2042  transition.select = function(query) {
2043    var k, t = d3_transition(groups.select(query)).ease(ease);
2044    k = -1; t.delay(function(d, i) { return delay[++k]; });
2045    k = -1; t.duration(function(d, i) { return duration[++k]; });
2046    return t;
2047  };
2048
2049  transition.selectAll = function(query) {
2050    var k, t = d3_transition(groups.selectAll(query)).ease(ease);
2051    k = -1; t.delay(function(d, i) { return delay[i ? k : ++k]; })
2052    k = -1; t.duration(function(d, i) { return duration[i ? k : ++k]; });
2053    return t;
2054  };
2055
2056  transition.remove = function() {
2057    remove = true;
2058    return transition;
2059  };
2060
2061  transition.each = function(type, listener) {
2062    event[type].add(listener);
2063    return transition;
2064  };
2065
2066  transition.call = d3_call;
2067
2068  return transition.delay(0).duration(250);
2069}
2070
2071function d3_transitionTween(b) {
2072  return typeof b === "function"
2073      ? function(d, i, a) { var v = b.call(this, d, i) + ""; return a != v && d3.interpolate(a, v); }
2074      : (b = b + "", function(d, i, a) { return a != b && d3.interpolate(a, b); });
2075}
2076var d3_timer_queue = null,
2077    d3_timer_interval, // is an interval (or frame) active?
2078    d3_timer_timeout; // is a timeout active?
2079
2080// The timer will continue to fire until callback returns true.
2081d3.timer = function(callback) {
2082  d3_timer(callback, 0);
2083};
2084
2085function d3_timer(callback, delay) {
2086  var now = Date.now(),
2087      found = false,
2088      t0,
2089      t1 = d3_timer_queue;
2090
2091  if (!isFinite(delay)) return;
2092
2093  // See if the callback's already in the queue.
2094  while (t1) {
2095    if (t1.callback === callback) {
2096      t1.then = now;
2097      t1.delay = delay;
2098      found = true;
2099      break;
2100    }
2101    t0 = t1;
2102    t1 = t1.next;
2103  }
2104
2105  // Otherwise, add the callback to the queue.
2106  if (!found) d3_timer_queue = {
2107    callback: callback,
2108    then: now,
2109    delay: delay,
2110    next: d3_timer_queue
2111  };
2112
2113  // Start animatin'!
2114  if (!d3_timer_interval) {
2115    d3_timer_timeout = clearTimeout(d3_timer_timeout);
2116    d3_timer_interval = 1;
2117    d3_timer_frame(d3_timer_step);
2118  }
2119}
2120
2121function d3_timer_step() {
2122  var elapsed,
2123      now = Date.now(),
2124      t1 = d3_timer_queue;
2125
2126  while (t1) {
2127    elapsed = now - t1.then;
2128    if (elapsed > t1.delay) t1.flush = t1.callback(elapsed);
2129    t1 = t1.next;
2130  }
2131
2132  var delay = d3_timer_flush() - now;
2133  if (delay > 24) {
2134    if (isFinite(delay)) {
2135      clearTimeout(d3_timer_timeout);
2136      d3_timer_timeout = setTimeout(d3_timer_step, delay);
2137    }
2138    d3_timer_interval = 0;
2139  } else {
2140    d3_timer_interval = 1;
2141    d3_timer_frame(d3_timer_step);
2142  }
2143}
2144
2145d3.timer.flush = function() {
2146  var elapsed,
2147      now = Date.now(),
2148      t1 = d3_timer_queue;
2149
2150  while (t1) {
2151    elapsed = now - t1.then;
2152    if (!t1.delay) t1.flush = t1.callback(elapsed);
2153    t1 = t1.next;
2154  }
2155
2156  d3_timer_flush();
2157};
2158
2159// Flush after callbacks, to avoid concurrent queue modification.
2160function d3_timer_flush() {
2161  var t0 = null,
2162      t1 = d3_timer_queue,
2163      then = Infinity;
2164  while (t1) {
2165    if (t1.flush) {
2166      t1 = t0 ? t0.next = t1.next : d3_timer_queue = t1.next;
2167    } else {
2168      then = Math.min(then, t1.then + t1.delay);
2169      t1 = (t0 = t1).next;
2170    }
2171  }
2172  return then;
2173}
2174
2175var d3_timer_frame = window.requestAnimationFrame
2176    || window.webkitRequestAnimationFrame
2177    || window.mozRequestAnimationFrame
2178    || window.oRequestAnimationFrame
2179    || window.msRequestAnimationFrame
2180    || function(callback) { setTimeout(callback, 17); };
2181function d3_noop() {}
2182d3.scale = {};
2183
2184function d3_scaleExtent(domain) {
2185  var start = domain[0], stop = domain[domain.length - 1];
2186  return start < stop ? [start, stop] : [stop, start];
2187}
2188function d3_scale_nice(domain, nice) {
2189  var i0 = 0,
2190      i1 = domain.length - 1,
2191      x0 = domain[i0],
2192      x1 = domain[i1],
2193      dx;
2194
2195  if (x1 < x0) {
2196    dx = i0; i0 = i1; i1 = dx;
2197    dx = x0; x0 = x1; x1 = dx;
2198  }
2199
2200  nice = nice(x1 - x0);
2201  domain[i0] = nice.floor(x0);
2202  domain[i1] = nice.ceil(x1);
2203  return domain;
2204}
2205
2206function d3_scale_niceDefault() {
2207  return Math;
2208}
2209d3.scale.linear = function() {
2210  var domain = [0, 1],
2211      range = [0, 1],
2212      interpolate = d3.interpolate,
2213      clamp = false,
2214      output,
2215      input;
2216
2217  function rescale() {
2218    var linear = domain.length == 2 ? d3_scale_bilinear : d3_scale_polylinear,
2219        uninterpolate = clamp ? d3_uninterpolateClamp : d3_uninterpolateNumber;
2220    output = linear(domain, range, uninterpolate, interpolate);
2221    input = linear(range, domain, uninterpolate, d3.interpolate);
2222    return scale;
2223  }
2224
2225  function scale(x) {
2226    return output(x);
2227  }
2228
2229  // Note: requires range is coercible to number!
2230  scale.invert = function(y) {
2231    return input(y);
2232  };
2233
2234  scale.domain = function(x) {
2235    if (!arguments.length) return domain;
2236    domain = x.map(Number);
2237    return rescale();
2238  };
2239
2240  scale.range = function(x) {
2241    if (!arguments.length) return range;
2242    range = x;
2243    return rescale();
2244  };
2245
2246  scale.rangeRound = function(x) {
2247    return scale.range(x).interpolate(d3.interpolateRound);
2248  };
2249
2250  scale.clamp = function(x) {
2251    if (!arguments.length) return clamp;
2252    clamp = x;
2253    return rescale();
2254  };
2255
2256  scale.interpolate = function(x) {
2257    if (!arguments.length) return interpolate;
2258    interpolate = x;
2259    return rescale();
2260  };
2261
2262  scale.ticks = function(m) {
2263    return d3_scale_linearTicks(domain, m);
2264  };
2265
2266  scale.tickFormat = function(m) {
2267    return d3_scale_linearTickFormat(domain, m);
2268  };
2269
2270  scale.nice = function() {
2271    d3_scale_nice(domain, d3_scale_linearNice);
2272    return rescale();
2273  };
2274
2275  return rescale();
2276};
2277
2278function d3_scale_linearRebind(scale, linear) {
2279  scale.range = d3.rebind(scale, linear.range);
2280  scale.rangeRound = d3.rebind(scale, linear.rangeRound);
2281  scale.interpolate = d3.rebind(scale, linear.interpolate);
2282  scale.clamp = d3.rebind(scale, linear.clamp);
2283  return scale;
2284}
2285
2286function d3_scale_linearNice(dx) {
2287  dx = Math.pow(10, Math.round(Math.log(dx) / Math.LN10) - 1);
2288  return {
2289    floor: function(x) { return Math.floor(x / dx) * dx; },
2290    ceil: function(x) { return Math.ceil(x / dx) * dx; }
2291  };
2292}
2293
2294// TODO Dates? Ugh.
2295function d3_scale_linearTickRange(domain, m) {
2296  var extent = d3_scaleExtent(domain),
2297      span = extent[1] - extent[0],
2298      step = Math.pow(10, Math.floor(Math.log(span / m) / Math.LN10)),
2299      err = m / span * step;
2300
2301  // Filter ticks to get closer to the desired count.
2302  if (err <= .15) step *= 10;
2303  else if (err <= .35) step *= 5;
2304  else if (err <= .75) step *= 2;
2305
2306  // Round start and stop values to step interval.
2307  extent[0] = Math.ceil(extent[0] / step) * step;
2308  extent[1] = Math.floor(extent[1] / step) * step + step * .5; // inclusive
2309  extent[2] = step;
2310  return extent;
2311}
2312
2313function d3_scale_linearTicks(domain, m) {
2314  return d3.range.apply(d3, d3_scale_linearTickRange(domain, m));
2315}
2316
2317function d3_scale_linearTickFormat(domain, m) {
2318  return d3.format(",." + Math.max(0, -Math.floor(Math.log(d3_scale_linearTickRange(domain, m)[2]) / Math.LN10 + .01)) + "f");
2319}
2320function d3_scale_bilinear(domain, range, uninterpolate, interpolate) {
2321  var u = uninterpolate(domain[0], domain[1]),
2322      i = interpolate(range[0], range[1]);
2323  return function(x) {
2324    return i(u(x));
2325  };
2326}
2327function d3_scale_polylinear(domain, range, uninterpolate, interpolate) {
2328  var u = [],
2329      i = [],
2330      j = 0,
2331      n = domain.length;
2332
2333  while (++j < n) {
2334    u.push(uninterpolate(domain[j - 1], domain[j]));
2335    i.push(interpolate(range[j - 1], range[j]));
2336  }
2337
2338  return function(x) {
2339    var j = d3.bisect(domain, x, 1, domain.length - 1) - 1;
2340    return i[j](u[j](x));
2341  };
2342}
2343d3.scale.log = function() {
2344  var linear = d3.scale.linear(),
2345      log = d3_scale_log,
2346      pow = log.pow;
2347
2348  function scale(x) {
2349    return linear(log(x));
2350  }
2351
2352  scale.invert = function(x) {
2353    return pow(linear.invert(x));
2354  };
2355
2356  scale.domain = function(x) {
2357    if (!arguments.length) return linear.domain().map(pow);
2358    log = x[0] < 0 ? d3_scale_logn : d3_scale_log;
2359    pow = log.pow;
2360    linear.domain(x.map(log));
2361    return scale;
2362  };
2363
2364  scale.nice = function() {
2365    linear.domain(d3_scale_nice(linear.domain(), d3_scale_niceDefault));
2366    return scale;
2367  };
2368
2369  scale.ticks = function() {
2370    var extent = d3_scaleExtent(linear.domain()),
2371        ticks = [];
2372    if (extent.every(isFinite)) {
2373      var i = Math.floor(extent[0]),
2374          j = Math.ceil(extent[1]),
2375          u = pow(extent[0]),
2376          v = pow(extent[1]);
2377      if (log === d3_scale_logn) {
2378        ticks.push(pow(i));
2379        for (; i++ < j;) for (var k = 9; k > 0; k--) ticks.push(pow(i) * k);
2380      } else {
2381        for (; i < j; i++) for (var k = 1; k < 10; k++) ticks.push(pow(i) * k);
2382        ticks.push(pow(i));
2383      }
2384      for (i = 0; ticks[i] < u; i++) {} // strip small values
2385      for (j = ticks.length; ticks[j - 1] > v; j--) {} // strip big values
2386      ticks = ticks.slice(i, j);
2387    }
2388    return ticks;
2389  };
2390
2391  scale.tickFormat = function() {
2392    return d3_scale_logTickFormat;
2393  };
2394
2395  return d3_scale_linearRebind(scale, linear);
2396};
2397
2398function d3_scale_log(x) {
2399  return Math.log(x) / Math.LN10;
2400}
2401
2402function d3_scale_logn(x) {
2403  return -Math.log(-x) / Math.LN10;
2404}
2405
2406d3_scale_log.pow = function(x) {
2407  return Math.pow(10, x);
2408};
2409
2410d3_scale_logn.pow = function(x) {
2411  return -Math.pow(10, -x);
2412};
2413
2414function d3_scale_logTickFormat(d) {
2415  return d.toPrecision(1);
2416}
2417d3.scale.pow = function() {
2418  var linear = d3.scale.linear(),
2419      exponent = 1,
2420      powp = Number,
2421      powb = powp;
2422
2423  function scale(x) {
2424    return linear(powp(x));
2425  }
2426
2427  scale.invert = function(x) {
2428    return powb(linear.invert(x));
2429  };
2430
2431  scale.domain = function(x) {
2432    if (!arguments.length) return linear.domain().map(powb);
2433    powp = d3_scale_powPow(exponent);
2434    powb = d3_scale_powPow(1 / exponent);
2435    linear.domain(x.map(powp));
2436    return scale;
2437  };
2438
2439  scale.ticks = function(m) {
2440    return d3_scale_linearTicks(scale.domain(), m);
2441  };
2442
2443  scale.tickFormat = function(m) {
2444    return d3_scale_linearTickFormat(scale.domain(), m);
2445  };
2446
2447  scale.nice = function() {
2448    return scale.domain(d3_scale_nice(scale.domain(), d3_scale_linearNice));
2449  };
2450
2451  scale.exponent = function(x) {
2452    if (!arguments.length) return exponent;
2453    var domain = scale.domain();
2454    exponent = x;
2455    return scale.domain(domain);
2456  };
2457
2458  return d3_scale_linearRebind(scale, linear);
2459};
2460
2461function d3_scale_powPow(e) {
2462  return function(x) {
2463    return x < 0 ? -Math.pow(-x, e) : Math.pow(x, e);
2464  };
2465}
2466d3.scale.sqrt = function() {
2467  return d3.scale.pow().exponent(.5);
2468};
2469d3.scale.ordinal = function() {
2470  var domain = [],
2471      index = {},
2472      range = [],
2473      rangeBand = 0,
2474      rerange = d3_noop;
2475
2476  function scale(x) {
2477    var i = x in index ? index[x] : (index[x] = domain.push(x) - 1);
2478    return range[i % range.length];
2479  }
2480
2481  scale.domain = function(x) {
2482    if (!arguments.length) return domain;
2483    domain = x;
2484    index = {};
2485    var i = -1, j = -1, n = domain.length; while (++i < n) {
2486      x = domain[i];
2487      if (!(x in index)) index[x] = ++j;
2488    }
2489    rerange();
2490    return scale;
2491  };
2492
2493  scale.range = function(x) {
2494    if (!arguments.length) return range;
2495    range = x;
2496    rerange = d3_noop;
2497    return scale;
2498  };
2499
2500  scale.rangePoints = function(x, padding) {
2501    if (arguments.length < 2) padding = 0;
2502    (rerange = function() {
2503      var start = x[0],
2504          stop = x[1],
2505          step = (stop - start) / (domain.length - 1 + padding);
2506      range = domain.length == 1
2507          ? [(start + stop) / 2]
2508          : d3.range(start + step * padding / 2, stop + step / 2, step);
2509      rangeBand = 0;
2510    })();
2511    return scale;
2512  };
2513
2514  scale.rangeBands = function(x, padding) {
2515    if (arguments.length < 2) padding = 0;
2516    (rerange = function() {
2517      var start = x[0],
2518          stop = x[1],
2519          step = (stop - start) / (domain.length + padding);
2520      range = d3.range(start + step * padding, stop, step);
2521      rangeBand = step * (1 - padding);
2522    })();
2523    return scale;
2524  };
2525
2526  scale.rangeRoundBands = function(x, padding) {
2527    if (arguments.length < 2) padding = 0;
2528    (rerange = function() {
2529      var start = x[0],
2530          stop = x[1],
2531          diff = stop - start,
2532          step = Math.floor(diff / (domain.length + padding)),
2533          err = diff - (domain.length - padding) * step;
2534      range = d3.range(start + Math.round(err / 2), stop, step);
2535      rangeBand = Math.round(step * (1 - padding));
2536    })();
2537    return scale;
2538  };
2539
2540  scale.rangeBand = function() {
2541    return rangeBand;
2542  };
2543
2544  return scale;
2545};
2546/*
2547 * This product includes color specifications and designs developed by Cynthia
2548 * Brewer (http://colorbrewer.org/). See lib/colorbrewer for more information.
2549 */
2550
2551d3.scale.category10 = function() {
2552  return d3.scale.ordinal().range(d3_category10);
2553};
2554
2555d3.scale.category20 = function() {
2556  return d3.scale.ordinal().range(d3_category20);
2557};
2558
2559d3.scale.category20b = function() {
2560  return d3.scale.ordinal().range(d3_category20b);
2561};
2562
2563d3.scale.category20c = function() {
2564  return d3.scale.ordinal().range(d3_category20c);
2565};
2566
2567var d3_category10 = [
2568  "#1f77b4", "#ff7f0e", "#2ca02c", "#d62728", "#9467bd",
2569  "#8c564b", "#e377c2", "#7f7f7f", "#bcbd22", "#17becf"
2570];
2571
2572var d3_category20 = [
2573  "#1f77b4", "#aec7e8",
2574  "#ff7f0e", "#ffbb78",
2575  "#2ca02c", "#98df8a",
2576  "#d62728", "#ff9896",
2577  "#9467bd", "#c5b0d5",
2578  "#8c564b", "#c49c94",
2579  "#e377c2", "#f7b6d2",
2580  "#7f7f7f", "#c7c7c7",
2581  "#bcbd22", "#dbdb8d",
2582  "#17becf", "#9edae5"
2583];
2584
2585var d3_category20b = [
2586  "#393b79", "#5254a3", "#6b6ecf", "#9c9ede",
2587  "#637939", "#8ca252", "#b5cf6b", "#cedb9c",
2588  "#8c6d31", "#bd9e39", "#e7ba52", "#e7cb94",
2589  "#843c39", "#ad494a", "#d6616b", "#e7969c",
2590  "#7b4173", "#a55194", "#ce6dbd", "#de9ed6"
2591];
2592
2593var d3_category20c = [
2594  "#3182bd", "#6baed6", "#9ecae1", "#c6dbef",
2595  "#e6550d", "#fd8d3c", "#fdae6b", "#fdd0a2",
2596  "#31a354", "#74c476", "#a1d99b", "#c7e9c0",
2597  "#756bb1", "#9e9ac8", "#bcbddc", "#dadaeb",
2598  "#636363", "#969696", "#bdbdbd", "#d9d9d9"
2599];
2600d3.scale.quantile = function() {
2601  var domain = [],
2602      range = [],
2603      thresholds = [];
2604
2605  function rescale() {
2606    var k = 0,
2607        n = domain.length,
2608        q = range.length;
2609    thresholds.length = Math.max(0, q - 1);
2610    while (++k < q) thresholds[k - 1] = d3.quantile(domain, k / q);
2611  }
2612
2613  function scale(x) {
2614    if (isNaN(x = +x)) return NaN;
2615    return range[d3.bisect(thresholds, x)];
2616  }
2617
2618  scale.domain = function(x) {
2619    if (!arguments.length) return domain;
2620    domain = x.filter(function(d) { return !isNaN(d); }).sort(d3.ascending);
2621    rescale();
2622    return scale;
2623  };
2624
2625  scale.range = function(x) {
2626    if (!arguments.length) return range;
2627    range = x;
2628    rescale();
2629    return scale;
2630  };
2631
2632  scale.quantiles = function() {
2633    return thresholds;
2634  };
2635
2636  return scale;
2637};
2638d3.scale.quantize = function() {
2639  var x0 = 0,
2640      x1 = 1,
2641      kx = 2,
2642      i = 1,
2643      range = [0, 1];
2644
2645  function scale(x) {
2646    return range[Math.max(0, Math.min(i, Math.floor(kx * (x - x0))))];
2647  }
2648
2649  scale.domain = function(x) {
2650    if (!arguments.length) return [x0, x1];
2651    x0 = x[0];
2652    x1 = x[1];
2653    kx = range.length / (x1 - x0);
2654    return scale;
2655  };
2656
2657  scale.range = function(x) {
2658    if (!arguments.length) return range;
2659    range = x;
2660    kx = range.length / (x1 - x0);
2661    i = range.length - 1;
2662    return scale;
2663  };
2664
2665  return scale;
2666};
2667d3.svg = {};
2668d3.svg.arc = function() {
2669  var innerRadius = d3_svg_arcInnerRadius,
2670      outerRadius = d3_svg_arcOuterRadius,
2671      startAngle = d3_svg_arcStartAngle,
2672      endAngle = d3_svg_arcEndAngle;
2673
2674  function arc() {
2675    var r0 = innerRadius.apply(this, arguments),
2676        r1 = outerRadius.apply(this, arguments),
2677        a0 = startAngle.apply(this, arguments) + d3_svg_arcOffset,
2678        a1 = endAngle.apply(this, arguments) + d3_svg_arcOffset,
2679        da = a1 - a0,
2680        df = da < Math.PI ? "0" : "1",
2681        c0 = Math.cos(a0),
2682        s0 = Math.sin(a0),
2683        c1 = Math.cos(a1),
2684        s1 = Math.sin(a1);
2685    return da >= d3_svg_arcMax
2686      ? (r0
2687      ? "M0," + r1
2688      + "A" + r1 + "," + r1 + " 0 1,1 0," + (-r1)
2689      + "A" + r1 + "," + r1 + " 0 1,1 0," + r1
2690      + "M0," + r0
2691      + "A" + r0 + "," + r0 + " 0 1,1 0," + (-r0)
2692      + "A" + r0 + "," + r0 + " 0 1,1 0," + r0
2693      + "Z"
2694      : "M0," + r1
2695      + "A" + r1 + "," + r1 + " 0 1,1 0," + (-r1)
2696      + "A" + r1 + "," + r1 + " 0 1,1 0," + r1
2697      + "Z")
2698      : (r0
2699      ? "M" + r1 * c0 + "," + r1 * s0
2700      + "A" + r1 + "," + r1 + " 0 " + df + ",1 " + r1 * c1 + "," + r1 * s1
2701      + "L" + r0 * c1 + "," + r0 * s1
2702      + "A" + r0 + "," + r0 + " 0 " + df + ",0 " + r0 * c0 + "," + r0 * s0
2703      + "Z"
2704      : "M" + r1 * c0 + "," + r1 * s0
2705      + "A" + r1 + "," + r1 + " 0 " + df + ",1 " + r1 * c1 + "," + r1 * s1
2706      + "L0,0"
2707      + "Z");
2708  }
2709
2710  arc.innerRadius = function(v) {
2711    if (!arguments.length) return innerRadius;
2712    innerRadius = d3.functor(v);
2713    return arc;
2714  };
2715
2716  arc.outerRadius = function(v) {
2717    if (!arguments.length) return outerRadius;
2718    outerRadius = d3.functor(v);
2719    return arc;
2720  };
2721
2722  arc.startAngle = function(v) {
2723    if (!arguments.length) return startAngle;
2724    startAngle = d3.functor(v);
2725    return arc;
2726  };
2727
2728  arc.endAngle = function(v) {
2729    if (!arguments.length) return endAngle;
2730    endAngle = d3.functor(v);
2731    return arc;
2732  };
2733
2734  arc.centroid = function() {
2735    var r = (innerRadius.apply(this, arguments)
2736        + outerRadius.apply(this, arguments)) / 2,
2737        a = (startAngle.apply(this, arguments)
2738        + endAngle.apply(this, arguments)) / 2 + d3_svg_arcOffset;
2739    return [Math.cos(a) * r, Math.sin(a) * r];
2740  };
2741
2742  return arc;
2743};
2744
2745var d3_svg_arcOffset = -Math.PI / 2,
2746    d3_svg_arcMax = 2 * Math.PI - 1e-6;
2747
2748function d3_svg_arcInnerRadius(d) {
2749  return d.innerRadius;
2750}
2751
2752function d3_svg_arcOuterRadius(d) {
2753  return d.outerRadius;
2754}
2755
2756function d3_svg_arcStartAngle(d) {
2757  return d.startAngle;
2758}
2759
2760function d3_svg_arcEndAngle(d) {
2761  return d.endAngle;
2762}
2763function d3_svg_line(projection) {
2764  var x = d3_svg_lineX,
2765      y = d3_svg_lineY,
2766      interpolate = "linear",
2767      interpolator = d3_svg_lineInterpolators[interpolate],
2768      tension = .7;
2769
2770  function line(d) {
2771    return d.length < 1 ? null : "M" + interpolator(projection(d3_svg_linePoints(this, d, x, y)), tension);
2772  }
2773
2774  line.x = function(v) {
2775    if (!arguments.length) return x;
2776    x = v;
2777    return line;
2778  };
2779
2780  line.y = function(v) {
2781    if (!arguments.length) return y;
2782    y = v;
2783    return line;
2784  };
2785
2786  line.interpolate = function(v) {
2787    if (!arguments.length) return interpolate;
2788    interpolator = d3_svg_lineInterpolators[interpolate = v];
2789    return line;
2790  };
2791
2792  line.tension = function(v) {
2793    if (!arguments.length) return tension;
2794    tension = v;
2795    return line;
2796  };
2797
2798  return line;
2799}
2800
2801d3.svg.line = function() {
2802  return d3_svg_line(Object);
2803};
2804
2805// Converts the specified array of data into an array of points
2806// (x-y tuples), by evaluating the specified `x` and `y` functions on each
2807// data point. The `this` context of the evaluated functions is the specified
2808// "self" object; each function is passed the current datum and index.
2809function d3_svg_linePoints(self, d, x, y) {
2810  var points = [],
2811      i = -1,
2812      n = d.length,
2813      fx = typeof x === "function",
2814      fy = typeof y === "function",
2815      value;
2816  if (fx && fy) {
2817    while (++i < n) points.push([
2818      x.call(self, value = d[i], i),
2819      y.call(self, value, i)
2820    ]);
2821  } else if (fx) {
2822    while (++i < n) points.push([x.call(self, d[i], i), y]);
2823  } else if (fy) {
2824    while (++i < n) points.push([x, y.call(self, d[i], i)]);
2825  } else {
2826    while (++i < n) points.push([x, y]);
2827  }
2828  return points;
2829}
2830
2831// The default `x` property, which references d[0].
2832function d3_svg_lineX(d) {
2833  return d[0];
2834}
2835
2836// The default `y` property, which references d[1].
2837function d3_svg_lineY(d) {
2838  return d[1];
2839}
2840
2841// The various interpolators supported by the `line` class.
2842var d3_svg_lineInterpolators = {
2843  "linear": d3_svg_lineLinear,
2844  "step-before": d3_svg_lineStepBefore,
2845  "step-after": d3_svg_lineStepAfter,
2846  "basis": d3_svg_lineBasis,
2847  "basis-open": d3_svg_lineBasisOpen,
2848  "basis-closed": d3_svg_lineBasisClosed,
2849  "bundle": d3_svg_lineBundle,
2850  "cardinal": d3_svg_lineCardinal,
2851  "cardinal-open": d3_svg_lineCardinalOpen,
2852  "cardinal-closed": d3_svg_lineCardinalClosed,
2853  "monotone": d3_svg_lineMonotone
2854};
2855
2856// Linear interpolation; generates "L" commands.
2857function d3_svg_lineLinear(points) {
2858  var path = [],
2859      i = 0,
2860      n = points.length,
2861      p = points[0];
2862  path.push(p[0], ",", p[1]);
2863  while (++i < n) path.push("L", (p = points[i])[0], ",", p[1]);
2864  return path.join("");
2865}
2866
2867// Step interpolation; generates "H" and "V" commands.
2868function d3_svg_lineStepBefore(points) {
2869  var path = [],
2870      i = 0,
2871      n = points.length,
2872      p = points[0];
2873  path.push(p[0], ",", p[1]);
2874  while (++i < n) path.push("V", (p = points[i])[1], "H", p[0]);
2875  return path.join("");
2876}
2877
2878// Step interpolation; generates "H" and "V" commands.
2879function d3_svg_lineStepAfter(points) {
2880  var path = [],
2881      i = 0,
2882      n = points.length,
2883      p = points[0];
2884  path.push(p[0], ",", p[1]);
2885  while (++i < n) path.push("H", (p = points[i])[0], "V", p[1]);
2886  return path.join("");
2887}
2888
2889// Open cardinal spline interpolation; generates "C" commands.
2890function d3_svg_lineCardinalOpen(points, tension) {
2891  return points.length < 4
2892      ? d3_svg_lineLinear(points)
2893      : points[1] + d3_svg_lineHermite(points.slice(1, points.length - 1),
2894        d3_svg_lineCardinalTangents(points, tension));
2895}
2896
2897// Closed cardinal spline interpolation; generates "C" commands.
2898function d3_svg_lineCardinalClosed(points, tension) {
2899  return points.length < 3
2900      ? d3_svg_lineLinear(points)
2901      : points[0] + d3_svg_lineHermite((points.push(points[0]), points),
2902        d3_svg_lineCardinalTangents([points[points.length - 2]]
2903        .concat(points, [points[1]]), tension));
2904}
2905
2906// Cardinal spline interpolation; generates "C" commands.
2907function d3_svg_lineCardinal(points, tension, closed) {
2908  return points.length < 3
2909      ? d3_svg_lineLinear(points)
2910      : points[0] + d3_svg_lineHermite(points,
2911        d3_svg_lineCardinalTangents(points, tension));
2912}
2913
2914// Hermite spline construction; generates "C" commands.
2915function d3_svg_lineHermite(points, tangents) {
2916  if (tangents.length < 1
2917      || (points.length != tangents.length
2918      && points.length != tangents.length + 2)) {
2919    return d3_svg_lineLinear(points);
2920  }
2921
2922  var quad = points.length != tangents.length,
2923      path = "",
2924      p0 = points[0],
2925      p = points[1],
2926      t0 = tangents[0],
2927      t = t0,
2928      pi = 1;
2929
2930  if (quad) {
2931    path += "Q" + (p[0] - t0[0] * 2 / 3) + "," + (p[1] - t0[1] * 2 / 3)
2932        + "," + p[0] + "," + p[1];
2933    p0 = points[1];
2934    pi = 2;
2935  }
2936
2937  if (tangents.length > 1) {
2938    t = tangents[1];
2939    p = points[pi];
2940    pi++;
2941    path += "C" + (p0[0] + t0[0]) + "," + (p0[1] + t0[1])
2942        + "," + (p[0] - t[0]) + "," + (p[1] - t[1])
2943        + "," + p[0] + "," + p[1];
2944    for (var i = 2; i < tangents.length; i++, pi++) {
2945      p = points[pi];
2946      t = tangents[i];
2947      path += "S" + (p[0] - t[0]) + "," + (p[1] - t[1])
2948          + "," + p[0] + "," + p[1];
2949    }
2950  }
2951
2952  if (quad) {
2953    var lp = points[pi];
2954    path += "Q" + (p[0] + t[0] * 2 / 3) + "," + (p[1] + t[1] * 2 / 3)
2955        + "," + lp[0] + "," + lp[1];
2956  }
2957
2958  return path;
2959}
2960
2961// Generates tangents for a cardinal spline.
2962function d3_svg_lineCardinalTangents(points, tension) {
2963  var tangents = [],
2964      a = (1 - tension) / 2,
2965      p0,
2966      p1 = points[0],
2967      p2 = points[1],
2968      i = 1,
2969      n = points.length;
2970  while (++i < n) {
2971    p0 = p1;
2972    p1 = p2;
2973    p2 = points[i];
2974    tangents.push([a * (p2[0] - p0[0]), a * (p2[1] - p0[1])]);
2975  }
2976  return tangents;
2977}
2978
2979// B-spline interpolation; generates "C" commands.
2980function d3_svg_lineBasis(points) {
2981  if (points.length < 3) return d3_svg_lineLinear(points);
2982  var path = [],
2983      i = 1,
2984      n = points.length,
2985      pi = points[0],
2986      x0 = pi[0],
2987      y0 = pi[1],
2988      px = [x0, x0, x0, (pi = points[1])[0]],
2989      py = [y0, y0, y0, pi[1]];
2990  path.push(x0, ",", y0);
2991  d3_svg_lineBasisBezier(path, px, py);
2992  while (++i < n) {
2993    pi = points[i];
2994    px.shift(); px.push(pi[0]);
2995    py.shift(); py.push(pi[1]);
2996    d3_svg_lineBasisBezier(path, px, py);
2997  }
2998  i = -1;
2999  while (++i < 2) {
3000    px.shift(); px.push(pi[0]);
3001    py.shift(); py.push(pi[1]);
3002    d3_svg_lineBasisBezier(path, px, py);
3003  }
3004  return path.join("");
3005}
3006
3007// Open B-spline interpolation; generates "C" commands.
3008function d3_svg_lineBasisOpen(points) {
3009  if (points.length < 4) return d3_svg_lineLinear(points);
3010  var path = [],
3011      i = -1,
3012      n = points.length,
3013      pi,
3014      px = [0],
3015      py = [0];
3016  while (++i < 3) {
3017    pi = points[i];
3018    px.push(pi[0]);
3019    py.push(pi[1]);
3020  }
3021  path.push(d3_svg_lineDot4(d3_svg_lineBasisBezier3, px)
3022    + "," + d3_svg_lineDot4(d3_svg_lineBasisBezier3, py));
3023  --i; while (++i < n) {
3024    pi = points[i];
3025    px.shift(); px.push(pi[0]);
3026    py.shift(); py.push(pi[1]);
3027    d3_svg_lineBasisBezier(path, px, py);
3028  }
3029  return path.join("");
3030}
3031
3032// Closed B-spline interpolation; generates "C" commands.
3033function d3_svg_lineBasisClosed(points) {
3034  var path,
3035      i = -1,
3036      n = points.length,
3037      m = n + 4,
3038      pi,
3039      px = [],
3040      py = [];
3041  while (++i < 4) {
3042    pi = points[i % n];
3043    px.push(pi[0]);
3044    py.push(pi[1]);
3045  }
3046  path = [
3047    d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",",
3048    d3_svg_lineDot4(d3_svg_lineBasisBezier3, py)
3049  ];
3050  --i; while (++i < m) {
3051    pi = points[i % n];
3052    px.shift(); px.push(pi[0]);
3053    py.shift(); py.push(pi[1]);
3054    d3_svg_lineBasisBezier(path, px, py);
3055  }
3056  return path.join("");
3057}
3058
3059function d3_svg_lineBundle(points, tension) {
3060  var n = points.length - 1,
3061      x0 = points[0][0],
3062      y0 = points[0][1],
3063      dx = points[n][0] - x0,
3064      dy = points[n][1] - y0,
3065      i = -1,
3066      p,
3067      t;
3068  while (++i <= n) {
3069    p = points[i];
3070    t = i / n;
3071    p[0] = tension * p[0] + (1 - tension) * (x0 + t * dx);
3072    p[1] = tension * p[1] + (1 - tension) * (y0 + t * dy);
3073  }
3074  return d3_svg_lineBasis(points);
3075}
3076
3077// Returns the dot product of the given four-element vectors.
3078function d3_svg_lineDot4(a, b) {
3079  return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
3080}
3081
3082// Matrix to transform basis (b-spline) control points to bezier
3083// control points. Derived from FvD 11.2.8.
3084var d3_svg_lineBasisBezier1 = [0, 2/3, 1/3, 0],
3085    d3_svg_lineBasisBezier2 = [0, 1/3, 2/3, 0],
3086    d3_svg_lineBasisBezier3 = [0, 1/6, 2/3, 1/6];
3087
3088// Pushes a "C" Bézier curve onto the specified path array, given the
3089// two specified four-element arrays which define the control points.
3090function d3_svg_lineBasisBezier(path, x, y) {
3091  path.push(
3092      "C", d3_svg_lineDot4(d3_svg_lineBasisBezier1, x),
3093      ",", d3_svg_lineDot4(d3_svg_lineBasisBezier1, y),
3094      ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, x),
3095      ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, y),
3096      ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, x),
3097      ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, y));
3098}
3099
3100// Computes the slope from points p0 to p1.
3101function d3_svg_lineSlope(p0, p1) {
3102  return (p1[1] - p0[1]) / (p1[0] - p0[0]);
3103}
3104
3105// Compute three-point differences for the given points.
3106// http://en.wikipedia.org/wiki/Cubic_Hermite_spline#Finite_difference
3107function d3_svg_lineFiniteDifferences(points) {
3108  var i = 0,
3109      j = points.length - 1,
3110      m = [],
3111      p0 = points[0],
3112      p1 = points[1],
3113      d = m[0] = d3_svg_lineSlope(p0, p1);
3114  while (++i < j) {
3115    m[i] = d + (d = d3_svg_lineSlope(p0 = p1, p1 = points[i + 1]));
3116  }
3117  m[i] = d;
3118  return m;
3119}
3120
3121// Interpolates the given points using Fritsch-Carlson Monotone cubic Hermite
3122// interpolation. Returns an array of tangent vectors. For details, see
3123// http://en.wikipedia.org/wiki/Monotone_cubic_interpolation
3124function d3_svg_lineMonotoneTangents(points) {
3125  var tangents = [],
3126      d,
3127      a,
3128      b,
3129      s,
3130      m = d3_svg_lineFiniteDifferences(points),
3131      i = -1,
3132      j = points.length - 1;
3133
3134  // The first two steps are done by computing finite-differences:
3135  // 1. Compute the slopes of the secant lines between successive points.
3136  // 2. Initialize the tangents at every point as the average of the secants.
3137
3138  // Then, for each segment

3139  while (++i < j) {
3140    d = d3_svg_lineSlope(points[i], points[i + 1]);
3141
3142    // 3. If two successive yk = y{k + 1} are equal (i.e., d is zero), then set
3143    // mk = m{k + 1} = 0 as the spline connecting these points must be flat to
3144    // preserve monotonicity. Ignore step 4 and 5 for those k.
3145
3146    if (Math.abs(d) < 1e-6) {
3147      m[i] = m[i + 1] = 0;
3148    } else {
3149      // 4. Let ak = mk / dk and bk = m{k + 1} / dk.
3150      a = m[i] / d;
3151      b = m[i + 1] / d;
3152
3153      // 5. Prevent overshoot and ensure monotonicity by restricting the
3154      // magnitude of vector <ak, bk> to a circle of radius 3.
3155      s = a * a + b * b;
3156      if (s > 9) {
3157        s = d * 3 / Math.sqrt(s);
3158        m[i] = s * a;
3159        m[i + 1] = s * b;
3160      }
3161    }
3162  }
3163
3164  // Compute the normalized tangent vector from the slopes. Note that if x is
3165  // not monotonic, it's possible that the slope will be infinite, so we protect
3166  // against NaN by setting the coordinate to zero.
3167  i = -1; while (++i <= j) {
3168    s = (points[Math.min(j, i + 1)][0] - points[Math.max(0, i - 1)][0])
3169      / (6 * (1 + m[i] * m[i]));
3170    tangents.push([s || 0, m[i] * s || 0]);
3171  }
3172
3173  return tangents;
3174}
3175
3176function d3_svg_lineMonotone(points) {
3177  return points.length < 3
3178      ? d3_svg_lineLinear(points)
3179      : points[0] +
3180        d3_svg_lineHermite(points, d3_svg_lineMonotoneTangents(points));
3181}
3182d3.svg.line.radial = function() {
3183  var line = d3_svg_line(d3_svg_lineRadial);
3184  line.radius = line.x, delete line.x;
3185  line.angle = line.y, delete line.y;
3186  return line;
3187};
3188
3189function d3_svg_lineRadial(points) {
3190  var point,
3191      i = -1,
3192      n = points.length,
3193      r,
3194      a;
3195  while (++i < n) {
3196    point = points[i];
3197    r = point[0];
3198    a = point[1] + d3_svg_arcOffset;
3199    point[0] = r * Math.cos(a);
3200    point[1] = r * Math.sin(a);
3201  }
3202  return points;
3203}
3204function d3_svg_area(projection) {
3205  var x0 = d3_svg_lineX,
3206      x1 = d3_svg_lineX,
3207      y0 = 0,
3208      y1 = d3_svg_lineY,
3209      interpolate = "linear",
3210      interpolator = d3_svg_lineInterpolators[interpolate],
3211      tension = .7;
3212
3213  function area(d) {
3214    if (d.length < 1) return null;
3215    var points0 = d3_svg_linePoints(this, d, x0, y0),
3216        points1 = d3_svg_linePoints(this, d, x0 === x1 ? d3_svg_areaX(points0) : x1, y0 === y1 ? d3_svg_areaY(points0) : y1);
3217    return "M" + interpolator(projection(points1), tension)
3218         + "L" + interpolator(projection(points0.reverse()), tension)
3219         + "Z";
3220  }
3221
3222  area.x = function(x) {
3223    if (!arguments.length) return x1;
3224    x0 = x1 = x;
3225    return area;
3226  };
3227
3228  area.x0 = function(x) {
3229    if (!arguments.length) return x0;
3230    x0 = x;
3231    return area;
3232  };
3233
3234  area.x1 = function(x) {
3235    if (!arguments.length) return x1;
3236    x1 = x;
3237    return area;
3238  };
3239
3240  area.y = function(y) {
3241    if (!arguments.length) return y1;
3242    y0 = y1 = y;
3243    return area;
3244  };
3245
3246  area.y0 = function(y) {
3247    if (!arguments.length) return y0;
3248    y0 = y;
3249    return area;
3250  };
3251
3252  area.y1 = function(y) {
3253    if (!arguments.length) return y1;
3254    y1 = y;
3255    return area;
3256  };
3257
3258  area.interpolate = function(x) {
3259    if (!arguments.length) return interpolate;
3260    interpolator = d3_svg_lineInterpolators[interpolate = x];
3261    return area;
3262  };
3263
3264  area.tension = function(x) {
3265    if (!arguments.length) return tension;
3266    tension = x;
3267    return area;
3268  };
3269
3270  return area;
3271}
3272
3273d3.svg.area = function() {
3274  return d3_svg_area(Object);
3275};
3276
3277function d3_svg_areaX(points) {
3278  return function(d, i) {
3279    return points[i][0];
3280  };
3281}
3282
3283function d3_svg_areaY(points) {
3284  return function(d, i) {
3285    return points[i][1];
3286  };
3287}
3288d3.svg.area.radial = function() {
3289  var area = d3_svg_area(d3_svg_lineRadial);
3290  area.radius = area.x, delete area.x;
3291  area.innerRadius = area.x0, delete area.x0;
3292  area.outerRadius = area.x1, delete area.x1;
3293  area.angle = area.y, delete area.y;
3294  area.startAngle = area.y0, delete area.y0;
3295  area.endAngle = area.y1, delete area.y1;
3296  return area;
3297};
3298d3.svg.chord = function() {
3299  var source = d3_svg_chordSource,
3300      target = d3_svg_chordTarget,
3301      radius = d3_svg_chordRadius,
3302      startAngle = d3_svg_arcStartAngle,
3303      endAngle = d3_svg_arcEndAngle;
3304
3305  // TODO Allow control point to be customized.
3306
3307  function chord(d, i) {
3308    var s = subgroup(this, source, d, i),
3309        t = subgroup(this, target, d, i);
3310    return "M" + s.p0
3311      + arc(s.r, s.p1) + (equals(s, t)
3312      ? curve(s.r, s.p1, s.r, s.p0)
3313      : curve(s.r, s.p1, t.r, t.p0)
3314      + arc(t.r, t.p1)
3315      + curve(t.r, t.p1, s.r, s.p0))
3316      + "Z";
3317  }
3318
3319  function subgroup(self, f, d, i) {
3320    var subgroup = f.call(self, d, i),
3321        r = radius.call(self, subgroup, i),
3322        a0 = startAngle.call(self, subgroup, i) + d3_svg_arcOffset,
3323        a1 = endAngle.call(self, subgroup, i) + d3_svg_arcOffset;
3324    return {
3325      r: r,
3326      a0: a0,
3327      a1: a1,
3328      p0: [r * Math.cos(a0), r * Math.sin(a0)],
3329      p1: [r * Math.cos(a1), r * Math.sin(a1)]
3330    };
3331  }
3332
3333  function equals(a, b) {
3334    return a.a0 == b.a0 && a.a1 == b.a1;
3335  }
3336
3337  function arc(r, p) {
3338    return "A" + r + "," + r + " 0 0,1 " + p;
3339  }
3340
3341  function curve(r0, p0, r1, p1) {
3342    return "Q 0,0 " + p1;
3343  }
3344
3345  chord.radius = function(v) {
3346    if (!arguments.length) return radius;
3347    radius = d3.functor(v);
3348    return chord;
3349  };
3350
3351  chord.source = function(v) {
3352    if (!arguments.length) return source;
3353    source = d3.functor(v);
3354    return chord;
3355  };
3356
3357  chord.target = function(v) {
3358    if (!arguments.length) return target;
3359    target = d3.functor(v);
3360    return chord;
3361  };
3362
3363  chord.startAngle = function(v) {
3364    if (!arguments.length) return startAngle;
3365    startAngle = d3.functor(v);
3366    return chord;
3367  };
3368
3369  chord.endAngle = function(v) {
3370    if (!arguments.length) return endAngle;
3371    endAngle = d3.functor(v);
3372    return chord;
3373  };
3374
3375  return chord;
3376};
3377
3378function d3_svg_chordSource(d) {
3379  return d.source;
3380}
3381
3382function d3_svg_chordTarget(d) {
3383  return d.target;
3384}
3385
3386function d3_svg_chordRadius(d) {
3387  return d.radius;
3388}
3389
3390function d3_svg_chordStartAngle(d) {
3391  return d.startAngle;
3392}
3393
3394function d3_svg_chordEndAngle(d) {
3395  return d.endAngle;
3396}
3397d3.svg.diagonal = function() {
3398  var source = d3_svg_chordSource,
3399      target = d3_svg_chordTarget,
3400      projection = d3_svg_diagonalProjection;
3401
3402  function diagonal(d, i) {
3403    var p0 = source.call(this, d, i),
3404        p3 = target.call(this, d, i),
3405        m = (p0.y + p3.y) / 2,
3406        p = [p0, {x: p0.x, y: m}, {x: p3.x, y: m}, p3];
3407    p = p.map(projection);
3408    return "M" + p[0] + "C" + p[1] + " " + p[2] + " " + p[3];
3409  }
3410
3411  diagonal.source = function(x) {
3412    if (!arguments.length) return source;
3413    source = d3.functor(x);
3414    return diagonal;
3415  };
3416
3417  diagonal.target = function(x) {
3418    if (!arguments.length) return target;
3419    target = d3.functor(x);
3420    return diagonal;
3421  };
3422
3423  diagonal.projection = function(x) {
3424    if (!arguments.length) return projection;
3425    projection = x;
3426    return diagonal;
3427  };
3428
3429  return diagonal;
3430};
3431
3432function d3_svg_diagonalProjection(d) {
3433  return [d.x, d.y];
3434}
3435d3.svg.diagonal.radial = function() {
3436  var diagonal = d3.svg.diagonal(),
3437      projection = d3_svg_diagonalProjection,
3438      projection_ = diagonal.projection;
3439
3440  diagonal.projection = function(x) {
3441    return arguments.length
3442        ? projection_(d3_svg_diagonalRadialProjection(projection = x))
3443        : projection;
3444  };
3445
3446  return diagonal;
3447};
3448
3449function d3_svg_diagonalRadialProjection(projection) {
3450  return function() {
3451    var d = projection.apply(this, arguments),
3452        r = d[0],
3453        a = d[1] + d3_svg_arcOffset;
3454    return [r * Math.cos(a), r * Math.sin(a)];
3455  };
3456}
3457d3.svg.mouse = function(container) {
3458  return d3_svg_mousePoint(container, d3.event);
3459};
3460
3461// https://bugs.webkit.org/show_bug.cgi?id=44083
3462var d3_mouse_bug44083 = /WebKit/.test(navigator.userAgent) ? -1 : 0;
3463
3464function d3_svg_mousePoint(container, e) {
3465  var point = (container.ownerSVGElement || container).createSVGPoint();
3466  if ((d3_mouse_bug44083 < 0) && (window.scrollX || window.scrollY)) {
3467    var svg = d3.select(document.body)
3468      .append("svg:svg")
3469        .style("position", "absolute")
3470        .style("top", 0)
3471        .style("left", 0);
3472    var ctm = svg[0][0].getScreenCTM();
3473    d3_mouse_bug44083 = !(ctm.f || ctm.e);
3474    svg.remove();
3475  }
3476  if (d3_mouse_bug44083) {
3477    point.x = e.pageX;
3478    point.y = e.pageY;
3479  } else {
3480    point.x = e.clientX;
3481    point.y = e.clientY;
3482  }
3483  point = point.matrixTransform(container.getScreenCTM().inverse());
3484  return [point.x, point.y];
3485};
3486d3.svg.touches = function(container) {
3487  var touches = d3.event.touches;
3488  return touches ? d3_array(touches).map(function(touch) {
3489    var point = d3_svg_mousePoint(container, touch);
3490    point.identifier = touch.identifier;
3491    return point;
3492  }) : [];
3493};
3494d3.svg.symbol = function() {
3495  var type = d3_svg_symbolType,
3496      size = d3_svg_symbolSize;
3497
3498  function symbol(d, i) {
3499    return (d3_svg_symbols[type.call(this, d, i)]
3500        || d3_svg_symbols.circle)
3501        (size.call(this, d, i));
3502  }
3503
3504  symbol.type = function(x) {
3505    if (!arguments.length) return type;
3506    type = d3.functor(x);
3507    return symbol;
3508  };
3509
3510  // size of symbol in square pixels
3511  symbol.size = function(x) {
3512    if (!arguments.length) return size;
3513    size = d3.functor(x);
3514    return symbol;
3515  };
3516
3517  return symbol;
3518};
3519
3520function d3_svg_symbolSize() {
3521  return 64;
3522}
3523
3524function d3_svg_symbolType() {
3525  return "circle";
3526}
3527
3528// TODO cross-diagonal?
3529var d3_svg_symbols = {
3530  "circle": function(size) {
3531    var r = Math.sqrt(size / Math.PI);
3532    return "M0," + r
3533        + "A" + r + "," + r + " 0 1,1 0," + (-r)
3534        + "A" + r + "," + r + " 0 1,1 0," + r
3535        + "Z";
3536  },
3537  "cross": function(size) {
3538    var r = Math.sqrt(size / 5) / 2;
3539    return "M" + -3 * r + "," + -r
3540        + "H" + -r
3541        + "V" + -3 * r
3542        + "H" + r
3543        + "V" + -r
3544        + "H" + 3 * r
3545        + "V" + r
3546        + "H" + r
3547        + "V" + 3 * r
3548        + "H" + -r
3549        + "V" + r
3550        + "H" + -3 * r
3551        + "Z";
3552  },
3553  "diamond": function(size) {
3554    var ry = Math.sqrt(size / (2 * d3_svg_symbolTan30)),
3555        rx = ry * d3_svg_symbolTan30;
3556    return "M0," + -ry
3557        + "L" + rx + ",0"
3558        + " 0," + ry
3559        + " " + -rx + ",0"
3560        + "Z";
3561  },
3562  "square": function(size) {
3563    var r = Math.sqrt(size) / 2;
3564    return "M" + -r + "," + -r
3565        + "L" + r + "," + -r
3566        + " " + r + "," + r
3567        + " " + -r + "," + r
3568        + "Z";
3569  },
3570  "triangle-down": function(size) {
3571    var rx = Math.sqrt(size / d3_svg_symbolSqrt3),
3572        ry = rx * d3_svg_symbolSqrt3 / 2;
3573    return "M0," + ry
3574        + "L" + rx +"," + -ry
3575        + " " + -rx + "," + -ry
3576        + "Z";
3577  },
3578  "triangle-up": function(size) {
3579    var rx = Math.sqrt(size / d3_svg_symbolSqrt3),
3580        ry = rx * d3_svg_symbolSqrt3 / 2;
3581    return "M0," + -ry
3582        + "L" + rx +"," + ry
3583        + " " + -rx + "," + ry
3584        + "Z";
3585  }
3586};
3587
3588d3.svg.symbolTypes = d3.keys(d3_svg_symbols);
3589
3590var d3_svg_symbolSqrt3 = Math.sqrt(3),
3591    d3_svg_symbolTan30 = Math.tan(30 * Math.PI / 180);
3592})();
Note: See TracBrowser for help on using the repository browser.