|
import {range as sequence} from "d3-array"; |
|
import {initRange} from "./init.js"; |
|
import ordinal from "./ordinal.js"; |
|
|
|
export default function band() { |
|
var scale = ordinal().unknown(undefined), |
|
domain = scale.domain, |
|
ordinalRange = scale.range, |
|
r0 = 0, |
|
r1 = 1, |
|
step, |
|
bandwidth, |
|
round = false, |
|
paddingInner = 0, |
|
paddingOuter = 0, |
|
align = 0.5; |
|
|
|
delete scale.unknown; |
|
|
|
function rescale() { |
|
var n = domain().length, |
|
reverse = r1 < r0, |
|
start = reverse ? r1 : r0, |
|
stop = reverse ? r0 : r1; |
|
step = (stop - start) / Math.max(1, n - paddingInner + paddingOuter * 2); |
|
if (round) step = Math.floor(step); |
|
start += (stop - start - step * (n - paddingInner)) * align; |
|
bandwidth = step * (1 - paddingInner); |
|
if (round) start = Math.round(start), bandwidth = Math.round(bandwidth); |
|
var values = sequence(n).map(function(i) { return start + step * i; }); |
|
return ordinalRange(reverse ? values.reverse() : values); |
|
} |
|
|
|
scale.domain = function(_) { |
|
return arguments.length ? (domain(_), rescale()) : domain(); |
|
}; |
|
|
|
scale.range = function(_) { |
|
return arguments.length ? ([r0, r1] = _, r0 = +r0, r1 = +r1, rescale()) : [r0, r1]; |
|
}; |
|
|
|
scale.rangeRound = function(_) { |
|
return [r0, r1] = _, r0 = +r0, r1 = +r1, round = true, rescale(); |
|
}; |
|
|
|
scale.bandwidth = function() { |
|
return bandwidth; |
|
}; |
|
|
|
scale.step = function() { |
|
return step; |
|
}; |
|
|
|
scale.round = function(_) { |
|
return arguments.length ? (round = !!_, rescale()) : round; |
|
}; |
|
|
|
scale.padding = function(_) { |
|
return arguments.length ? (paddingInner = Math.min(1, paddingOuter = +_), rescale()) : paddingInner; |
|
}; |
|
|
|
scale.paddingInner = function(_) { |
|
return arguments.length ? (paddingInner = Math.min(1, _), rescale()) : paddingInner; |
|
}; |
|
|
|
scale.paddingOuter = function(_) { |
|
return arguments.length ? (paddingOuter = +_, rescale()) : paddingOuter; |
|
}; |
|
|
|
scale.align = function(_) { |
|
return arguments.length ? (align = Math.max(0, Math.min(1, _)), rescale()) : align; |
|
}; |
|
|
|
scale.copy = function() { |
|
return band(domain(), [r0, r1]) |
|
.round(round) |
|
.paddingInner(paddingInner) |
|
.paddingOuter(paddingOuter) |
|
.align(align); |
|
}; |
|
|
|
return initRange.apply(rescale(), arguments); |
|
} |
|
|
|
function pointish(scale) { |
|
var copy = scale.copy; |
|
|
|
scale.padding = scale.paddingOuter; |
|
delete scale.paddingInner; |
|
delete scale.paddingOuter; |
|
|
|
scale.copy = function() { |
|
return pointish(copy()); |
|
}; |
|
|
|
return scale; |
|
} |
|
|
|
export function point() { |
|
return pointish(band.apply(null, arguments).paddingInner(1)); |
|
} |
|
|