Skip to content

Bar

Столбчатая серия. Категории — по xField, значения растут от нуля.

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

export function createOptions(): ChartOptions {
  return {
    data: getData(),
    title: { text: 'City Population' },
    subtitle: { text: 'million people' },
    series: [{ type: 'bar', xField: 'city', yField: 'population', name: 'Population', cornerRadius: 4 }],
    legend: { enabled: false },
  };
}
ts
export function getData() {
  return [
    { city: 'Moscow', population: 13.1 },
    { city: 'Saint Petersburg', population: 5.6 },
    { city: 'Novosibirsk', population: 1.6 },
    { city: 'Yekaterinburg', population: 1.5 },
    { city: 'Kazan', population: 1.3 },
  ];
}

Подписи значений

label.placement: внешние позиции top/bottom/left/right и углы (top-left, …), center и внутренние inner-top, inner-top-left и т.д. — внутри бара цвет подбирается автоконтрастом с ореолом цвета бара:

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

export function createOptions(): ChartOptions {
  return {
    data: getData(),
    title: { text: 'Value Labels on Bars' },
    subtitle: { text: "outer ('top') and inner ('inner-top') placements" },
    series: [
      {
        type: 'bar',
        xField: 'team',
        yField: 'done',
        name: 'Done',
        label: { enabled: true, placement: 'inner-top', fontWeight: 'bold' },
      },
      {
        type: 'bar',
        xField: 'team',
        yField: 'planned',
        name: 'Plan',
        label: { enabled: true, placement: 'top' },
      },
    ],
  };
}
ts
export function getData() {
  return [
    { team: 'Alpha', done: 34, planned: 42 },
    { team: 'Beta', done: 27, planned: 30 },
    { team: 'Gamma', done: 41, planned: 38 },
    { team: 'Delta', done: 22, planned: 35 },
  ];
}

Стилизация

cornerRadius, своя заливка с прозрачностью и обводка:

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

export function createOptions(): ChartOptions {
  return {
    data: getData(),
    title: { text: 'Bar Corner Radius and Stroke' },
    series: [
      {
        type: 'bar',
        xField: 'quarter',
        yField: 'revenue',
        name: 'Revenue',
        cornerRadius: 8,
        fill: '#6f5bd7',
        fillOpacity: 0.85,
        stroke: '#4a3aa8',
        strokeWidth: 1.5,
      },
    ],
    legend: { enabled: false },
  };
}
ts
export function getData() {
  return [
    { quarter: 'Q1', revenue: 54 },
    { quarter: 'Q2', revenue: 71 },
    { quarter: 'Q3', revenue: 62 },
    { quarter: 'Q4', revenue: 89 },
  ];
}

Группировка

Несколько bar-серий автоматически делят бэнд категории:

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

export function createOptions(): ChartOptions {
  return {
    data: getData(),
    title: { text: 'Plan vs Actual by Team' },
    series: [
      { type: 'bar', xField: 'team', yField: 'plan', name: 'Plan' },
      { type: 'bar', xField: 'team', yField: 'fact', name: 'Actual' },
    ],
  };
}
ts
export function getData() {
  return [
    { team: 'Search', plan: 120, fact: 134 },
    { team: 'Ads', plan: 90, fact: 81 },
    { team: 'Maps', plan: 75, fact: 79 },
    { team: 'Cloud', plan: 60, fact: 72 },
  ];
}

Стекинг

stacked: true складывает серии друг на друга; stackGroup позволяет вести несколько независимых стеков. Отрицательные значения копятся вниз от нуля.

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

export function createOptions(): ChartOptions {
  return {
    data: getData(),
    title: { text: 'Traffic Sources' },
    subtitle: { text: 'thousands of visits, stacked' },
    series: [
      { type: 'bar', xField: 'year', yField: 'organic', name: 'Organic', stacked: true },
      { type: 'bar', xField: 'year', yField: 'ads', name: 'Ads', stacked: true },
      { type: 'bar', xField: 'year', yField: 'referral', name: 'Referrals', stacked: true },
    ],
  };
}
ts
export function getData() {
  return [
    { year: '2022', organic: 480, ads: 310, referral: 140 },
    { year: '2023', organic: 560, ads: 365, referral: 178 },
    { year: '2024', organic: 640, ads: 402, referral: 210 },
    { year: '2025', organic: 735, ads: 458, referral: 246 },
  ];
}

Группированные стеки

stackGroup собирает серии в независимые стеки: группы стоят рядом внутри категории (серии со stacked: true без stackGroup складываются в общий стек):

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

export function createOptions(): ChartOptions {
  return {
    data: getData(),
    title: { text: 'Revenue by Product Category' },
    subtitle: { text: '$B; two stacks per category' },
    series: [
      { type: 'bar', xField: 'quarter', yField: 'iphone', name: 'iPhone', stacked: true, stackGroup: 'Devices' },
      { type: 'bar', xField: 'quarter', yField: 'mac', name: 'Mac', stacked: true, stackGroup: 'Devices' },
      { type: 'bar', xField: 'quarter', yField: 'ipad', name: 'iPad', stacked: true, stackGroup: 'Devices' },
      { type: 'bar', xField: 'quarter', yField: 'wearables', name: 'Wearables', stacked: true, stackGroup: 'Other' },
      { type: 'bar', xField: 'quarter', yField: 'services', name: 'Services', stacked: true, stackGroup: 'Other' },
    ],
  };
}
ts
export function getData() {
  return [
    { quarter: "Q1'18", iphone: 140, mac: 16, ipad: 14, wearables: 12, services: 20 },
    { quarter: "Q2'18", iphone: 124, mac: 20, ipad: 14, wearables: 12, services: 30 },
    { quarter: "Q3'18", iphone: 112, mac: 20, ipad: 18, wearables: 14, services: 36 },
    { quarter: "Q4'18", iphone: 118, mac: 24, ipad: 14, wearables: 14, services: 36 },
    { quarter: "Q1'19", iphone: 124, mac: 18, ipad: 16, wearables: 18, services: 26 },
    { quarter: "Q2'19", iphone: 108, mac: 20, ipad: 16, wearables: 18, services: 40 },
    { quarter: "Q3'19", iphone: 96, mac: 22, ipad: 18, wearables: 24, services: 42 },
    { quarter: "Q4'19", iphone: 104, mac: 22, ipad: 14, wearables: 20, services: 40 },
  ];
}

Нормализованный стек (100%)

normalizedTo приводит итог каждой категории к заданному значению:

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

export function createOptions(): ChartOptions {
  return {
    data: getData(),
    title: { text: 'Traffic Breakdown' },
    subtitle: { text: '100%-stacked: normalizedTo: 100' },
    series: [
      { type: 'bar', xField: 'quarter', yField: 'search', name: 'Search', stacked: true, normalizedTo: 100 },
      { type: 'bar', xField: 'quarter', yField: 'social', name: 'Social', stacked: true, normalizedTo: 100 },
      { type: 'bar', xField: 'quarter', yField: 'direct', name: 'Direct', stacked: true, normalizedTo: 100 },
    ],
    axes: [
      { type: 'category', position: 'bottom' },
      { type: 'number', position: 'left', label: { formatter: ({ value }) => `${value}%` } },
    ],
  };
}
ts
export function getData() {
  return [
    { quarter: 'Q1', search: 420, social: 180, direct: 95 },
    { quarter: 'Q2', search: 460, social: 240, direct: 88 },
    { quarter: 'Q3', search: 405, social: 310, direct: 102 },
    { quarter: 'Q4', search: 480, social: 405, direct: 97 },
  ];
}

Группированные категории

Для иерархических категорий (год → квартал) используйте ось grouped-category:

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

export function createOptions(): ChartOptions {
  return {
    data: getData(),
    title: { text: 'Revenue by Product Category' },
    subtitle: { text: '$B, grouped categories year → quarter' },
    series: [
      { type: 'bar', xField: 'period', yField: 'iphone', name: 'iPhone' },
      { type: 'bar', xField: 'period', yField: 'mac', name: 'Mac' },
      { type: 'bar', xField: 'period', yField: 'services', name: 'Services' },
    ],
    axes: [
      { type: 'grouped-category', position: 'bottom' },
      { type: 'number', position: 'left' },
    ],
  };
}
ts
export function getData() {
  return [
    { period: ['2018', 'Q1'], iphone: 140, mac: 16, services: 20 },
    { period: ['2018', 'Q2'], iphone: 124, mac: 20, services: 30 },
    { period: ['2018', 'Q3'], iphone: 112, mac: 20, services: 36 },
    { period: ['2018', 'Q4'], iphone: 118, mac: 24, services: 36 },
    { period: ['2019', 'Q1'], iphone: 124, mac: 18, services: 26 },
    { period: ['2019', 'Q2'], iphone: 108, mac: 20, services: 40 },
    { period: ['2019', 'Q3'], iphone: 96, mac: 22, services: 42 },
    { period: ['2019', 'Q4'], iphone: 104, mac: 22, services: 40 },
  ];
}

Горизонтальные бары

direction: 'horizontal' разворачивает чарт: категории уходят на вертикальную ось.

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

export function createOptions(): ChartOptions {
  return {
    data: getData(),
    title: { text: 'Languages in New Services' },
    subtitle: { text: '% of repositories' },
    series: [
      {
        type: 'bar',
        xField: 'language',
        yField: 'share',
        name: 'Share',
        direction: 'horizontal',
        cornerRadius: 3,
      },
    ],
    legend: { enabled: false },
  };
}
ts
export function getData() {
  return [
    { language: 'TypeScript', share: 38 },
    { language: 'Python', share: 31 },
    { language: 'Go', share: 14 },
    { language: 'Rust', share: 9 },
    { language: 'Kotlin', share: 8 },
  ];
}

Опции

Общие опции всех серий (name, showInLegend, tooltip.renderer, …) — в разделе Общие опции серий.

ОпцияТипПо умолчаниюОписание
xFieldstringключи данных (обязательны)
yFieldstringключи данных (обязательны)
namestringyFieldимя для легенды и тултипа
direction'vertical' | 'horizontal''vertical'направление баров
stackedbooleanfalseстекинг
normalizedTonumberнормализация итога стека (100 — процентный стек)
stackGroupstring'default'независимые группы стека
fillColorValueпалитра темызаливка
fillOpacityFraction1прозрачность заливки
strokeColorValueобводка
strokeWidthPixelsобводка
cornerRadiusPixels0скругление углов
label.enabledbooleanfalseпоказать подписи значений
label.placementвнешние/center/inner-* (17 позиций)'top'позиция подписи
label.formatter({ value, datum }) => stringзначениесодержимое подписи
label.fontSizePixels11размер шрифта подписи
label.fontWeightstring | numbernormalнасыщенность
label.fontFamilystringшрифт темыгарнитура
label.colorColorValueforeground; внутри — автоконтрастцвет текста