| import "../arrays/map"; | |
| import "../arrays/range"; | |
| import "scale"; | |
| d3.scale.ordinal = function() { | |
| return d3_scale_ordinal([], {t: "range", a: [[]]}); | |
| }; | |
| function d3_scale_ordinal(domain, ranger) { | |
| var index, | |
| range, | |
| rangeBand; | |
| function scale(x) { | |
| return range[((index.get(x) || ranger.t === "range" && index.set(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 = new d3_Map; | |
| var i = -1, n = x.length, xi; | |
| while (++i < n) if (!index.has(xi = x[i])) index.set(xi, domain.push(xi)); | |
| return scale[ranger.t].apply(scale, ranger.a); | |
| }; | |
| scale.range = function(x) { | |
| if (!arguments.length) return range; | |
| range = x; | |
| rangeBand = 0; | |
| ranger = {t: "range", a: arguments}; | |
| return scale; | |
| }; | |
| scale.rangePoints = function(x, padding) { | |
| if (arguments.length < 2) padding = 0; | |
| var start = x[0], | |
| stop = x[1], | |
| step = (stop - start) / (Math.max(1, domain.length - 1) + padding); | |
| range = steps(domain.length < 2 ? (start + stop) / 2 : start + step * padding / 2, step); | |
| rangeBand = 0; | |
| ranger = {t: "rangePoints", a: arguments}; | |
| return scale; | |
| }; | |
| scale.rangeBands = function(x, padding, outerPadding) { | |
| if (arguments.length < 2) padding = 0; | |
| if (arguments.length < 3) outerPadding = padding; | |
| var reverse = x[1] < x[0], | |
| start = x[reverse - 0], | |
| stop = x[1 - reverse], | |
| step = (stop - start) / (domain.length - padding + 2 * outerPadding); | |
| range = steps(start + step * outerPadding, step); | |
| if (reverse) range.reverse(); | |
| rangeBand = step * (1 - padding); | |
| ranger = {t: "rangeBands", a: arguments}; | |
| return scale; | |
| }; | |
| scale.rangeRoundBands = function(x, padding, outerPadding) { | |
| if (arguments.length < 2) padding = 0; | |
| if (arguments.length < 3) outerPadding = padding; | |
| var reverse = x[1] < x[0], | |
| start = x[reverse - 0], | |
| stop = x[1 - reverse], | |
| step = Math.floor((stop - start) / (domain.length - padding + 2 * outerPadding)), | |
| error = stop - start - (domain.length - padding) * step; | |
| range = steps(start + Math.round(error / 2), step); | |
| if (reverse) range.reverse(); | |
| rangeBand = Math.round(step * (1 - padding)); | |
| ranger = {t: "rangeRoundBands", a: arguments}; | |
| return scale; | |
| }; | |
| scale.rangeBand = function() { | |
| return rangeBand; | |
| }; | |
| scale.rangeExtent = function() { | |
| return d3_scaleExtent(ranger.a[0]); | |
| }; | |
| scale.copy = function() { | |
| return d3_scale_ordinal(domain, ranger); | |
| }; | |
| return scale.domain(domain); | |
| } |