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.rangeExtent = function() { return ranger.x; }; scale.copy = function() { return d3_scale_ordinal(domain, ranger); }; return scale.domain(domain); };