Skip to content

Range Bar and Range Area

Range series: instead of yField, a yLowField / yHighField pair.

Range Area

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

export function createOptions(): ChartOptions {
  return {
    data: getData(),
    title: { text: 'Temperature range' },
    series: [{ type: 'range-area', xField: 'month', yLowField: 'min', yHighField: 'max', name: 'Min–Max, °C' }],
    legend: { enabled: false },
  };
}
ts
export function getData() {
  return [
    { month: 'Jan', min: -12, max: -2 },
    { month: 'Feb', min: -10, max: 0 },
    { month: 'Mar', min: -4, max: 6 },
    { month: 'Apr', min: 2, max: 14 },
    { month: 'May', min: 8, max: 21 },
    { month: 'Jun', min: 13, max: 26 },
    { month: 'Jul', min: 15, max: 29 },
    { month: 'Aug', min: 13, max: 27 },
    { month: 'Sep', min: 8, max: 20 },
    { month: 'Oct', min: 2, max: 11 },
    { month: 'Nov', min: -4, max: 4 },
    { month: 'Dec', min: -9, max: -1 },
  ];
}

Range Bar

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

export function createOptions(): ChartOptions {
  return {
    data: getData(),
    title: { text: 'Salary ranges' },
    subtitle: { text: 'thousand ₽ per month' },
    series: [{ type: 'range-bar', xField: 'role', yLowField: 'from', yHighField: 'to', name: 'Range' }],
    legend: { enabled: false },
  };
}
ts
export function getData() {
  return [
    { role: 'Junior', from: 80, to: 150 },
    { role: 'Middle', from: 160, to: 260 },
    { role: 'Senior', from: 250, to: 400 },
    { role: 'Lead', from: 320, to: 480 },
  ];
}

Horizontal range bars

direction: 'horizontal' flips the chart: categories move to the vertical axis.

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

export function createOptions(): ChartOptions {
  return {
    data: getData(),
    title: { text: 'Salary ranges' },
    subtitle: { text: 'thousand ₽ per month' },
    series: [
      {
        type: 'range-bar',
        xField: 'role',
        yLowField: 'from',
        yHighField: 'to',
        name: 'Range',
        direction: 'horizontal',
      },
    ],
    legend: { enabled: false },
  };
}
ts
export function getData() {
  return [
    { role: 'Junior', from: 80, to: 150 },
    { role: 'Middle', from: 160, to: 260 },
    { role: 'Senior', from: 250, to: 400 },
    { role: 'Lead', from: 320, to: 480 },
  ];
}

Per-bar colour (Gantt)

fill accepts a callback ({ low, high, datum, index }) => color — colour each bar individually, e.g. a Gantt timeline painted by task status from a single series:

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

// Colour each task bar by its status — a Gantt-style timeline from a single range-bar series.
const STATUS_COLORS: Record<string, string> = {
  done: '#22c55e',
  running: '#3b82f6',
  failed: '#ef4444',
  queued: '#94a3b8',
};

export function createOptions(): ChartOptions {
  return {
    data: getData(),
    title: { text: 'Pipeline run' },
    subtitle: { text: 'task timeline, hours' },
    series: [
      {
        type: 'range-bar',
        xField: 'task',
        yLowField: 'start',
        yHighField: 'end',
        direction: 'horizontal',
        cornerRadius: 3,
        fill: ({ datum }) => STATUS_COLORS[String(datum.status)] ?? '#94a3b8',
      },
    ],
    legend: { enabled: false },
  };
}
ts
export function getData() {
  return [
    { task: 'extract', start: 0, end: 3, status: 'done' },
    { task: 'validate', start: 3, end: 5, status: 'done' },
    { task: 'transform', start: 5, end: 11, status: 'running' },
    { task: 'notify', start: 8, end: 10, status: 'failed' },
    { task: 'load', start: 11, end: 14, status: 'queued' },
    { task: 'report', start: 14, end: 16, status: 'queued' },
  ];
}

Range labels

label.formatter({ low, high, datum }); placements are the same as for bar — here center inside the bar with auto contrast:

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

export function createOptions(): ChartOptions {
  return {
    data: getData(),
    title: { text: 'Ranges with labels' },
    series: [
      {
        type: 'range-bar',
        xField: 'city',
        yLowField: 'min',
        yHighField: 'max',
        name: 'Temperature, °C',
        label: {
          enabled: true,
          placement: 'center',
          formatter: ({ low, high }) => `${low}…${high}`,
        },
      },
    ],
    legend: { enabled: false },
  };
}
ts
export function getData() {
  return [
    { city: 'Moscow', min: -8, max: 2 },
    { city: 'Sochi', min: 4, max: 12 },
    { city: 'Novosibirsk', min: -16, max: -6 },
    { city: 'Kazan', min: -10, max: 0 },
    { city: 'Vladivostok', min: -7, max: 1 },
  ];
}

Combining with a mean line

Range-area as the background + line on top, with a shared tooltip:

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

export function createOptions(): ChartOptions {
  return {
    data: getData(),
    title: { text: 'Range + average line' },
    series: [
      {
        type: 'range-area',
        xField: 'month',
        yLowField: 'min',
        yHighField: 'max',
        name: 'Range, °C',
        fillOpacity: 0.25,
      },
      { type: 'line', xField: 'month', yField: 'avg', name: 'Average', strokeWidth: 2.5 },
    ],
    tooltip: { mode: 'shared', range: 'nearest' },
  };
}
ts
export function getData() {
  const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
  return months.map((month, i) => {
    const mid = 8 + 14 * Math.sin(((i - 3) / 12) * Math.PI * 2);
    return {
      month,
      min: Math.round(mid - 5 - (i % 3)),
      max: Math.round(mid + 6 + ((i + 1) % 3)),
      avg: Math.round(mid),
    };
  });
}
OptionTypeDescription
yLowFieldstringrange bounds
yHighFieldstringrange bounds
direction (bar)'vertical' | 'horizontal'bar direction (vertical)
fillColorValue | (params) => ColorValuefill; callback colours per datum
fillstylesfill
fillOpacitystylesfill
stroke (area)stylesoutline lines
strokeWidth (area)stylesoutline lines
cornerRadius (bar)Pixelscorner rounding

Full list of options

OptionTypeDefaultDescription
label.enabledbooleanfalseshow value labels
label.placementouter/center/inner-* (17 placements)'top'label placement
label.formatter({ low, high, datum }) => stringvaluelabel content
label.fontSizePixels11label font size
label.fontWeightstring | numbernormalfont weight
label.fontFamilystringtheme fontfont family
label.colorColorValueforeground; inside — auto contrasttext color

Options

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