toolkit/javascript/d3/src/scale/ordinal.js
changeset 47 c0b4a8b5a012
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/toolkit/javascript/d3/src/scale/ordinal.js	Thu Apr 10 14:20:23 2014 +0200
@@ -0,0 +1,77 @@
+d3.scale.ordinal = function() {
+  return d3_scale_ordinal([], {t: "range", x: []});
+};
+
+function d3_scale_ordinal(domain, ranger) {
+  var index,
+      range,
+      rangeBand;
+
+  function scale(x) {
+    return range[((index[x] || (index[x] = domain.push(x))) - 1) % range.length];
+  }
+
+  function steps(start, step) {
+    return d3.range(domain.length).map(function(i) { return start + step * i; });
+  }
+
+  scale.domain = function(x) {
+    if (!arguments.length) return domain;
+    domain = [];
+    index = {};
+    var i = -1, n = x.length, xi;
+    while (++i < n) if (!index[xi = x[i]]) index[xi] = domain.push(xi);
+    return scale[ranger.t](ranger.x, ranger.p);
+  };
+
+  scale.range = function(x) {
+    if (!arguments.length) return range;
+    range = x;
+    rangeBand = 0;
+    ranger = {t: "range", x: x};
+    return scale;
+  };
+
+  scale.rangePoints = function(x, padding) {
+    if (arguments.length < 2) padding = 0;
+    var start = x[0],
+        stop = x[1],
+        step = (stop - start) / (domain.length - 1 + padding);
+    range = steps(domain.length < 2 ? (start + stop) / 2 : start + step * padding / 2, step);
+    rangeBand = 0;
+    ranger = {t: "rangePoints", x: x, p: padding};
+    return scale;
+  };
+
+  scale.rangeBands = function(x, padding) {
+    if (arguments.length < 2) padding = 0;
+    var start = x[0],
+        stop = x[1],
+        step = (stop - start) / (domain.length + padding);
+    range = steps(start + step * padding, step);
+    rangeBand = step * (1 - padding);
+    ranger = {t: "rangeBands", x: x, p: padding};
+    return scale;
+  };
+
+  scale.rangeRoundBands = function(x, padding) {
+    if (arguments.length < 2) padding = 0;
+    var start = x[0],
+        stop = x[1],
+        step = Math.floor((stop - start) / (domain.length + padding));
+    range = steps(start + Math.round((stop - start - (domain.length - padding) * step) / 2), step);
+    rangeBand = Math.round(step * (1 - padding));
+    ranger = {t: "rangeRoundBands", x: x, p: padding};
+    return scale;
+  };
+
+  scale.rangeBand = function() {
+    return rangeBand;
+  };
+
+  scale.copy = function() {
+    return d3_scale_ordinal(domain, ranger);
+  };
+
+  return scale.domain(domain);
+};