Skip to content

Histogram

Distribution of a numeric field across bins. xField is a numeric field; without yField, the number of records is counted.

ts
import { getData } from './data';
import type { ChartOptions } from 'grafit-charts';

export function createOptions(): ChartOptions {
  return {
    data: getData(),
    title: { text: 'Session duration' },
    subtitle: { text: 'distribution, minutes' },
    series: [{ type: 'histogram', xField: 'duration', name: 'Sessions', binCount: 8 }],
    legend: { enabled: false },
  };
}
ts
export function getData() {
  const durations = [
    12, 18, 22, 25, 28, 31, 33, 35, 38, 41, 42, 44, 47, 48, 51, 53, 54, 56, 58, 61, 63, 64, 67, 71, 74, 78, 82, 87, 93, 104, 36, 45, 52, 59,
    49, 39, 29, 57, 66, 73,
  ];
  return durations.map((duration) => ({ duration }));
}

Bin count

binCount controls the granularity (or set bin boundaries explicitly via bins):

ts
import { getData } from './data';
import type { ChartOptions } from 'grafit-charts';

export function createOptions(): ChartOptions {
  return {
    data: getData(),
    title: { text: 'Bin count' },
    subtitle: { text: 'binCount: 24 vs default auto' },
    series: [{ type: 'histogram', xField: 'response', name: 'Response time, ms', binCount: 24, fillOpacity: 0.8 }],
    legend: { enabled: false },
  };
}
ts
export function getData() {
  const values: Array<{ response: number }> = [];
  for (let i = 0; i < 400; i++) {
    const u = ((i * 9301 + 49297) % 233280) / 233280;
    const v = ((i * 7621 + 1) % 233280) / 233280;
    values.push({ response: Math.round(120 + 55 * (Math.sqrt(-2 * Math.log(u + 1e-6)) * Math.cos(2 * Math.PI * v))) });
  }
  return values.filter((d) => d.response > 0 && d.response < 320);
}

Bin labels

label — placements are the same as for bar (top, inner-top, center, …), formatter({ value, x0, x1 }):

ts
import { getData } from './data';
import type { ChartOptions } from 'grafit-charts';

export function createOptions(): ChartOptions {
  return {
    data: getData(),
    title: { text: 'Histogram with bin labels' },
    series: [
      {
        type: 'histogram',
        xField: 'score',
        name: 'Scores',
        binCount: 8,
        label: { enabled: true, placement: 'top', fontWeight: 'bold' },
      },
    ],
    legend: { enabled: false },
  };
}
ts
export function getData() {
  const values: Array<{ score: number }> = [];
  for (let i = 0; i < 120; i++) {
    const u = ((i * 9301 + 49297) % 233280) / 233280;
    values.push({ score: Math.round(35 + 50 * u + 15 * Math.sin(i) ** 2) });
  }
  return values;
}

Options

Options common to all series (name, showInLegend, tooltip.renderer, …) are covered in Common series options.

OptionTypeDefaultDescription
xFieldstringnumeric field to bin
yFieldstringaggregation field (optional)
aggregation'count' | 'sum' | 'mean'count / sumaggregation method (sum with yField)
binCountnumber10number of bins
bins[number, number][]explicit bin boundaries
fillstylespalettebar styling
strokestylespalettebar styling
fillOpacitystylespalettebar styling
strokeWidthstyles1bin stroke width
label.enabledbooleanfalseshow value labels
label.placementouter/center/inner-* (17 placements)'top'label placement
label.formatter({ value, x0, x1 }) => stringvaluelabel content
label.fontSizePixels11label font size
label.fontWeightstring | numbernormalfont weight
label.fontFamilystringtheme fontfont family
label.colorColorValueforeground; inside — auto contrasttext color