Skip to content

Histogram

The createHistogram helper bins a plain array of numbers and returns chart-ready rows plus the config fragments that make the bars read as a histogram — contiguous, one bar per bin.

ts
// createHistogram bins raw values (Sturges' count, round edges) and returns
// chart-ready rows plus config fragments to spread into a chart config.
import { createHistogram } from '@mochart/core';
import type { MochartInputConfig } from '@mochart/core';

// 60 response-time samples (ms).
const samples = [
  62, 71, 78, 84, 91, 97,
  102, 104, 108, 111, 114, 117, 119, 121, 124, 126,
  128, 131, 133, 136, 138, 141, 143, 145, 147, 149,
  151, 153, 156, 158, 161, 164, 167, 170, 173, 176,
  179, 183, 186, 190, 193, 196, 199,
  202, 206, 211, 217, 222, 228, 233, 239, 244, 249,
  254, 261, 270, 281, 293, 305, 318
];

const histogram = createHistogram(samples, { seriesTitle: 'Requests' });

export const config: MochartInputConfig = {
  version: '1.0.0',
  title: { text: 'Response Time Distribution' },
  categoryAxis: { ...histogram.categoryAxis, title: 'Response time (ms)' },
  valueAxes: [{ min: 0 }],
  series: [histogram.seriesConfig]
};

export const data = histogram.data;

How it works

  • createHistogram(values, options) picks the bins for you: roughly Sturges' count by default, with edges rounded to 1/2/5-style numbers. Override with binCount (approximate), binWidth (exact, wins over binCount), or domain to bin over a fixed range; nice: false divides the domain exactly instead of rounding.
  • The returned categoryAxis fragment uses an ordinal axis with categoryPaddingFraction zeroed so the bars touch, which is what visually separates a histogram from a bar chart. (Bins are contiguous and equal width, so an ordinal axis positions them identically to a linear one — and on a linear category axis a bar always spans a single category value, which would leave multi-unit-wide bins as slivers.)
  • normalize switches each bin's value from the raw 'count' to 'probability' (sums to 1) or 'density' (integrates to 1), and cumulative: true accumulates the bins left to right. The default series title follows the mode; set seriesTitle to override it.
  • Each row stores its bin's value under the property named by valueProperty (default 'value') — the returned series fragment points at it. Rows also carry binStart, binEnd, binCenter and count, and the raw bin descriptions come back under bins — useful for custom tick labels via binLabel or annotations built alongside the chart.
  • The lower-level binValues(values, options) returns just the bins with no chart fragments, for when you want the binning without the charting.

Released under the BSD-3-Clause License.