Оси
Типы осей: category (бэнды), number, time, log. Связка по position: bottom/top — ось X, left/right — ось Y.
Временная ось
time принимает Date, timestamp или ISO-строку; тики встают на календарные границы, формат подписи зависит от шага (часы → дни → месяцы → годы).
import { getData } from './data';
import type { ChartOptions } from 'grafit-charts';
export function createOptions(): ChartOptions {
return {
data: getData(),
title: { text: 'Metric over Time' },
series: [{ type: 'line', xField: 'date', yField: 'value', name: 'Value', marker: { enabled: false } }],
axes: [
{ type: 'time', position: 'bottom' },
{ type: 'number', position: 'left' },
],
legend: { enabled: false },
};
}export function getData() {
const start = Date.UTC(2025, 0, 1);
const day = 24 * 60 * 60 * 1000;
const values = [41, 43, 47, 45, 49, 53, 51, 56, 58, 55, 61, 64, 62, 67, 70, 68, 73, 71, 76, 79, 77, 82, 85, 83, 88, 86, 91, 94, 92, 97];
return values.map((value, index) => ({ date: new Date(start + index * 3 * day), value }));
}Логарифмическая ось
log — для данных, растущих на порядки; тики на степенях base (по умолчанию 10).
import { getData } from './data';
import type { ChartOptions } from 'grafit-charts';
export function createOptions(): ChartOptions {
return {
data: getData(),
title: { text: 'Exponential Growth' },
subtitle: { text: 'logarithmic Y axis' },
series: [{ type: 'line', xField: 'year', yField: 'users', name: 'Users' }],
axes: [
{ type: 'category', position: 'bottom' },
{ type: 'log', position: 'left' },
],
legend: { enabled: false },
};
}export function getData() {
return [
{ year: '2018', users: 120 },
{ year: '2019', users: 540 },
{ year: '2020', users: 2400 },
{ year: '2021', users: 9800 },
{ year: '2022', users: 41000 },
{ year: '2023', users: 165000 },
{ year: '2024', users: 720000 },
{ year: '2025', users: 2900000 },
];
}Иерархические категории
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 },
];
}CrossLines
Опорные линии и диапазоны в координатах оси — с подписями:
import { getData } from './data';
import type { ChartOptions } from 'grafit-charts';
export function createOptions(): ChartOptions {
return {
data: getData(),
title: { text: 'Latency p95' },
series: [{ type: 'line', xField: 'month', yField: 'latency', name: 'p95, ms' }],
axes: [
{
type: 'category',
position: 'bottom',
crossLines: [{ type: 'range', range: ['Apr', 'May'], label: { text: 'incident' } }],
},
{
type: 'number',
position: 'left',
crossLines: [{ value: 200, stroke: '#e5484d', label: { text: 'SLO 200 ms', color: '#e5484d' } }],
},
],
legend: { enabled: false },
};
}export function getData() {
return [
{ month: 'Jan', latency: 182 },
{ month: 'Feb', latency: 174 },
{ month: 'Mar', latency: 196 },
{ month: 'Apr', latency: 230 },
{ month: 'May', latency: 218 },
{ month: 'Jun', latency: 187 },
{ month: 'Jul', latency: 171 },
{ month: 'Aug', latency: 165 },
];
}Опции оси
| Блок | Опции |
|---|---|
| number/log | min, max, nice, base (log) |
| time | min, max (Date/timestamp) |
| category | paddingInner, paddingOuter |
Полный список опций
| Опция | Тип | По умолчанию | Описание |
|---|---|---|---|
type | 'number' | 'category' | 'time' | 'log' | 'ordinal-time' | 'grouped-category' | по сериям | тип оси |
position | 'bottom' | 'left' | 'top' | 'right' | по типу | сторона оси |
title.enabled | boolean | true при text | заголовок оси |
title.text | string | — | текст заголовка |
title.fontSize | Pixels | 12 | шрифт заголовка |
title.color | ColorValue | foreground | цвет заголовка |
line.enabled | boolean | true (heatmap — выкл.) | линия оси |
line.stroke | ColorValue | muted темы | цвет линии |
line.width | Pixels | 1 | толщина линии |
tick.enabled | boolean | true (heatmap — выкл.) | тики |
tick.size | Pixels | 6 | длина тика |
tick.width | Pixels | 1 | толщина тика |
tick.stroke | ColorValue | muted темы | цвет тика |
label.enabled | boolean | true | подписи делений |
label.fontSize | Pixels | 11 | шрифт подписей |
label.fontFamily | string | шрифт темы | гарнитура |
label.color | ColorValue | muted темы | цвет подписей |
label.spacing | Pixels | 4 | отступ подписи от тика |
label.format | string | — | format-строка (',.2f', '.0%', '%d %b') |
label.formatter | ({ value, index }) => string | — | программный формат |
label.avoidCollisions | boolean | true | пропуск пересекающихся подписей |
gridLine.enabled | boolean | true (heatmap — выкл.) | линии сетки |
gridLine.stroke | ColorValue | сетка темы | цвет сетки |
gridLine.width | Pixels | 1 | толщина |
gridLine.lineDash | Pixels[] | — | пунктир сетки |
interval.values | unknown[] | авто | явные значения тиков |
interval.minSpacing | Pixels | 8 | мин. расстояние подписей |
crossLines[].type | 'line' | 'range' | 'line' | линия или диапазон |
crossLines[].value | значение | — | координата линии |
crossLines[].range | [от, до] | — | диапазон заливки |
crossLines[].stroke | ColorValue | muted темы | цвет линии |
crossLines[].strokeWidth | Pixels | 1 | толщина линии |
crossLines[].lineDash | Pixels[] | — | пунктир |
crossLines[].fill | ColorValue | muted темы | заливка диапазона |
crossLines[].fillOpacity | Fraction | 0.12 | прозрачность заливки |
crossLines[].label.text | string | — | текст подписи |
crossLines[].label.color | ColorValue | muted темы | цвет подписи |
crossLines[].label.fontSize | Pixels | 11 | шрифт подписи |
min (number, log) | number | домен данных | нижняя граница |
max (number, log) | number | домен данных | верхняя граница |
nice (number) | boolean | true | округление домена до «красивых» границ |
base (log) | number | 10 | основание логарифма |
paddingInner (category, grouped-category) | Fraction | 0.2 (ordinal-time 0.25) | внутренний band-отступ |
paddingOuter (category, ordinal-time, grouped-category) | Fraction | 0.1 | внешний band-отступ |
Подписи горизонтальных осей автоматически прореживаются при тесноте (label.avoidCollisions: false отключает).
Overlays
Состояния «нет данных» и «загрузка» включены по умолчанию: пустой data показывает overlays.noData.text, а loading: true — overlays.loading.text.