diff --git a/src/transforms/bin.js b/src/transforms/bin.js index 2687d4184f..b9bd1a5b9e 100644 --- a/src/transforms/bin.js +++ b/src/transforms/bin.js @@ -4,31 +4,28 @@ import {valueof, first, second, maybeValue, range, offsetRange} from "../mark.js export function bin1(options = {}) { let {value, domain, thresholds, cumulative} = maybeValue(options); const bin = binof({value, domain, thresholds}); - return (data, facets) => { - let bins = bin(data); - if (facets !== undefined) return binfacets(bins, facets, subset1, cumulative); - if (cumulative) bins = accumulate(cumulative < 0 ? bins.reverse() : bins); - bins = bins.filter(nonempty); - return {index: range(bins), data: bins}; - }; + return (data, facets) => rebin(bin(data), facets, subset1, cumulative); } export function bin2({x = {}, y = {}, domain, thresholds} = {}) { const binX = binof({domain, thresholds, value: first, ...maybeValue(x)}); const binY = binof({domain, thresholds, value: second, ...maybeValue(y)}); - return (data, facets) => { - let bins = cross(binX(data).filter(nonempty), binY(data).filter(nonempty).map(binset), (x, y) => { - const subbin = x.filter(i => y.has(i)); - subbin.x0 = x.x0; - subbin.x1 = x.x1; - subbin.y0 = y.x0; - subbin.y1 = y.x1; - return subbin; - }); - if (facets !== undefined) return binfacets(bins, facets, subset2); - bins = bins.filter(nonempty); - return {index: range(bins), data: bins}; - }; + return (data, facets) => rebin( + cross( + binX(data).filter(nonempty), + binY(data).filter(nonempty).map(binset), + (x, y) => { + const subbin = x.filter(i => y.has(i)); + subbin.x0 = x.x0; + subbin.x1 = x.x1; + subbin.y0 = y.x0; + subbin.y1 = y.x1; + return subbin; + } + ), + facets, + subset2 + ); } function binof({value, domain, thresholds}) { @@ -41,13 +38,19 @@ function binof({value, domain, thresholds}) { }; } -function binfacets(bins, facets, subset, cumulative) { +// When faceting, subdivides the given bins according to the facet indexes. +function rebin(bins, facets, subset, cumulative) { + if (facets === undefined) { + if (cumulative) bins = accumulate(cumulative < 0 ? bins.reverse() : bins); + bins = bins.filter(nonempty); + return {index: range(bins), data: bins}; + } const index = []; const data = []; let k = 0; for (const facet of facets.map(subset)) { let b = bins.map(facet); - b = cumulative ? accumulate(cumulative < 0 ? b.reverse() : b) : b; + if (cumulative) b = accumulate(cumulative < 0 ? b.reverse() : b); b = b.filter(nonempty); index.push(offsetRange(b, k)); data.push(b);