Bar
Столбчатая серия. Категории — по xField, значения растут от нуля.
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 },
};
}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 и т.д. — внутри бара цвет подбирается автоконтрастом с ореолом цвета бара:
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' },
},
],
};
}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, своя заливка с прозрачностью и обводка:
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 },
};
}export function getData() {
return [
{ quarter: 'Q1', revenue: 54 },
{ quarter: 'Q2', revenue: 71 },
{ quarter: 'Q3', revenue: 62 },
{ quarter: 'Q4', revenue: 89 },
];
}Группировка
Несколько bar-серий автоматически делят бэнд категории:
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' },
],
};
}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 позволяет вести несколько независимых стеков. Отрицательные значения копятся вниз от нуля.
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 },
],
};
}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 складываются в общий стек):
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' },
],
};
}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 приводит итог каждой категории к заданному значению:
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}%` } },
],
};
}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:
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' },
],
};
}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' разворачивает чарт: категории уходят на вертикальную ось.
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 },
};
}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, …) — в разделе Общие опции серий.
| Опция | Тип | По умолчанию | Описание |
|---|---|---|---|
xField | string | — | ключи данных (обязательны) |
yField | string | — | ключи данных (обязательны) |
name | string | yField | имя для легенды и тултипа |
direction | 'vertical' | 'horizontal' | 'vertical' | направление баров |
stacked | boolean | false | стекинг |
normalizedTo | number | — | нормализация итога стека (100 — процентный стек) |
stackGroup | string | 'default' | независимые группы стека |
fill | ColorValue | палитра темы | заливка |
fillOpacity | Fraction | 1 | прозрачность заливки |
stroke | ColorValue | — | обводка |
strokeWidth | Pixels | — | обводка |
cornerRadius | Pixels | 0 | скругление углов |
label.enabled | boolean | false | показать подписи значений |
label.placement | внешние/center/inner-* (17 позиций) | 'top' | позиция подписи |
label.formatter | ({ value, datum }) => string | значение | содержимое подписи |
label.fontSize | Pixels | 11 | размер шрифта подписи |
label.fontWeight | string | number | normal | насыщенность |
label.fontFamily | string | шрифт темы | гарнитура |
label.color | ColorValue | foreground; внутри — автоконтраст | цвет текста |