diff --git a/client/__tests__/util/range.test.js b/client/__tests__/util/range.test.js index 0567c9eb..fac1ade3 100644 --- a/client/__tests__/util/range.test.js +++ b/client/__tests__/util/range.test.js @@ -1,4 +1,4 @@ -import { range, rangeFill } from "../../src/util/range"; +import { range, rangeFill, linspace } from "../../src/util/range"; describe("range", () => { test("no defaults", () => { @@ -40,3 +40,11 @@ describe("rangefill", () => { ); }); }); + +describe("linspace", () => { + test("linspace(arr, start, step)", () => { + expect(linspace(0.0, 2.0, 5)).toMatchObject( + [0.0, 0.5, 1.0, 1.5, 2.0] + ); + }); +}); diff --git a/client/src/components/brushableHistogram/index.js b/client/src/components/brushableHistogram/index.js index fc7732fc..1b5b1a29 100644 --- a/client/src/components/brushableHistogram/index.js +++ b/client/src/components/brushableHistogram/index.js @@ -12,6 +12,7 @@ import * as d3 from "d3"; import memoize from "memoize-one"; import * as globals from "../../globals"; import actions from "../../actions"; +import { linspace } from "../../util/range"; import { makeContinuousDimensionName } from "../../util/nameCreators"; @connect((state, ownProps) => { @@ -53,15 +54,20 @@ class HistogramBrush extends React.PureComponent { const values = col.asArray(); const summary = col.summarize(); const { min: domainMin, max: domainMax } = summary; + const numBins = 40; + histogramCache.x = d3 .scaleLinear() .domain([domainMin, domainMax]) .range([this.marginLeft, this.marginLeft + this.width]); + const [xStart, xStop] = histogramCache.x.domain(); + const histThresholds = linspace(xStart, xStop, numBins + 1); + histogramCache.bins = d3 .histogram() .domain(histogramCache.x.domain()) - .thresholds(40)(values); + .thresholds(histThresholds)(values); const yMax = histogramCache.bins .map(b => b.length) diff --git a/client/src/util/range.js b/client/src/util/range.js index 972a6276..01ac931b 100644 --- a/client/src/util/range.js +++ b/client/src/util/range.js @@ -43,3 +43,8 @@ export function range(start, stop, step) { const len = Math.max(Math.ceil((stop - start) / step), 0); return _doFill(new Array(len), start, step, len); } + +export function linspace(start, stop, nsteps) { + const delta = (stop - start) / (nsteps - 1).toFixed(); + return range(0, nsteps, 1).map(i => start + i * delta); +} \ No newline at end of file