Pie и Donut
Полярные серии долей. angleField задаёт значение сектора, labelField — имя (легенда, выносные подписи, тултип).
import { getData } from './data';
import type { ChartOptions } from 'grafit-charts';
export function createOptions(): ChartOptions {
return {
data: getData(),
title: { text: 'Browser share' },
series: [
{
type: 'pie',
angleField: 'share',
angleName: 'Share, %',
labelField: 'browser',
sectorLabel: { enabled: true },
},
],
};
}export function getData() {
return [
{ browser: 'Chrome', share: 64 },
{ browser: 'Safari', share: 19 },
{ browser: 'Edge', share: 6 },
{ browser: 'Firefox', share: 5 },
{ browser: 'Other', share: 6 },
];
}Отступы и скругление у pie
Те же sectorSpacing и cornerRadius работают и без кольца:
import { getData } from './data';
import type { ChartOptions } from 'grafit-charts';
export function createOptions(): ChartOptions {
return {
data: getData(),
title: { text: 'Pie with spacing and rounded corners' },
series: [
{
type: 'pie',
angleField: 'share',
angleName: 'Share, %',
labelField: 'device',
sectorSpacing: 3,
cornerRadius: 7,
sectorLabel: { enabled: true },
},
],
};
}export function getData() {
return [
{ device: 'Smartphones', share: 48 },
{ device: 'Laptops', share: 24 },
{ device: 'Tablets', share: 14 },
{ device: 'Desktops', share: 9 },
{ device: 'Other', share: 5 },
];
}Donut
innerRadiusRatio создаёт кольцо; innerLabels — текст в центре.
import { getData } from './data';
import type { ChartOptions } from 'grafit-charts';
export function createOptions(): ChartOptions {
return {
data: getData(),
title: { text: 'Order statuses' },
series: [
{
type: 'donut',
angleField: 'count',
angleName: 'Orders',
labelField: 'status',
innerRadiusRatio: 0.62,
// callout lines: length and style of each segment are configured separately
calloutLine: {
radial: { length: 10, strokeWidth: 1 },
horizontal: { length: 14, strokeWidth: 1 },
},
innerLabels: [
{ text: '2193', fontSize: 22, fontWeight: 'bold' },
{ text: 'orders', fontSize: 12 },
],
},
],
legend: { position: 'right' },
};
}export function getData() {
return [
{ status: 'Completed', count: 1840 },
{ status: 'Cancelled', count: 215 },
{ status: 'Refunded', count: 96 },
{ status: 'Failed', count: 42 },
];
}Поворот, цвета, подписи долей
import { getData } from './data';
import type { ChartOptions } from 'grafit-charts';
export function createOptions(): ChartOptions {
return {
data: getData(),
title: { text: 'Rotation and sector labels' },
subtitle: { text: 'rotation: -90, sectorLabel + custom colors' },
series: [
{
type: 'pie',
angleField: 'amount',
angleName: 'Share, %',
labelField: 'source',
rotation: -90,
fills: ['#1d4fd7', '#27c08d', '#f4a236', '#9a7bff'],
sectorLabel: { enabled: true },
calloutLabel: { enabled: false },
},
],
legend: { position: 'right' },
};
}export function getData() {
return [
{ source: 'Organization', amount: 46 },
{ source: 'Grants', amount: 28 },
{ source: 'Partners', amount: 16 },
{ source: 'Other', amount: 10 },
];
}Кастомный тултип
tooltip.renderer серии получает datum целиком — в тултип можно выводить любые поля:
import { getData } from './data';
import type { ChartOptions } from 'grafit-charts';
export function createOptions(): ChartOptions {
return {
data: getData(),
title: { text: 'Custom sector tooltip' },
series: [
{
type: 'donut',
angleField: 'visits',
labelField: 'channel',
innerRadiusRatio: 0.55,
tooltip: {
renderer: ({ datum, color }) => ({
heading: String(datum.channel),
rows: [
{ label: 'Visits', value: String(datum.visits), color },
{ label: 'Conversion', value: `${datum.conversion}%` },
],
}),
},
},
],
legend: { enabled: false },
};
}export function getData() {
return [
{ channel: 'Organic', visits: 18200, conversion: 4.1 },
{ channel: 'Ads', visits: 9400, conversion: 2.6 },
{ channel: 'Social', visits: 6100, conversion: 1.9 },
{ channel: 'Email', visits: 2800, conversion: 6.4 },
];
}Отступы и скругление
sectorSpacing — зазор между секторами (px), cornerRadius — скругление углов:
import { getData } from './data';
import type { ChartOptions } from 'grafit-charts';
const money = new Intl.NumberFormat('en-US');
export function createOptions(): ChartOptions {
return {
data: getData(),
title: { text: 'Sector spacing and corner radius' },
series: [
{
type: 'donut',
angleField: 'amount',
labelField: 'fund',
innerRadiusRatio: 0.55,
sectorSpacing: 6,
cornerRadius: 8,
calloutLabel: { enabled: true },
calloutLine: {
radial: { length: 12, strokeWidth: 1 },
horizontal: { length: 16, stroke: '#9aa1ad', strokeWidth: 1 },
},
tooltip: {
renderer: ({ label, value, color }) => ({
heading: label,
rows: [{ label: 'Amount', value: money.format(Number(value)), color }],
}),
},
},
],
legend: { enabled: false },
};
}export function getData() {
return [
{ fund: 'Stocks', amount: 32129675 },
{ fund: 'Bonds', amount: 9196461 },
{ fund: 'Funds', amount: 5248310 },
{ fund: 'Deposits', amount: 3933726 },
{ fund: 'Currency', amount: 3354246 },
];
}Значения в легенде
legendValue выводит значение сектора справа от подписи; тултип здесь привязан к курсору (tooltip.position.anchorTo: 'pointer'):
import { getData } from './data';
import type { ChartOptions } from 'grafit-charts';
export function createOptions(): ChartOptions {
return {
data: getData(),
title: { text: 'Values in the legend' },
series: [
{
type: 'donut',
angleField: 'amount',
labelField: 'source',
innerRadiusRatio: 0.62,
sectorSpacing: 3,
cornerRadius: 4,
calloutLabel: { enabled: false },
innerLabels: [
{ text: 'Total', fontSize: 13 },
{ text: '$86K', fontSize: 24, fontWeight: 'bold' },
],
legendValue: {
enabled: true,
formatter: ({ value }) => `$${value}K`,
},
},
],
legend: { position: 'right' },
tooltip: { position: { anchorTo: 'pointer', yOffset: -8 } },
};
}export function getData() {
return [
{ source: 'Equipment sales', amount: 35 },
{ source: 'Online training', amount: 12 },
{ source: 'Athlete contracts', amount: 5 },
{ source: 'Merchandise', amount: 21 },
{ source: 'Sponsored events', amount: 13 },
];
}Donut-прогресс
Тонкое кольцо + innerLabels — компактный индикатор:
import { getData } from './data';
import type { ChartOptions } from 'grafit-charts';
export function createOptions(): ChartOptions {
return {
data: getData(),
title: { text: 'Year progress' },
series: [
{
type: 'donut',
angleField: 'value',
labelField: 'state',
innerRadiusRatio: 0.78,
rotation: 0,
fills: ['#21a06c', '#e8eaee'],
calloutLabel: { enabled: false },
innerLabels: [
{ text: '68%', fontSize: 26, fontWeight: 'bold' },
{ text: 'of plan complete', fontSize: 12 },
],
},
],
legend: { enabled: false },
};
}export function getData() {
return [
{ state: 'Done', value: 68 },
{ state: 'Remaining', value: 32 },
];
}Опции
Общие опции всех серий (name, showInLegend, tooltip.renderer, …) — в разделе Общие опции серий.
| Опция | Тип | По умолчанию | Описание |
|---|---|---|---|
angleField | string | — | значение сектора (обязательно) |
labelField | string | — | имя сектора |
fills | ColorValue[] | палитра темы | цвета секторов по кругу |
strokes | ColorValue[] | палитра темы | цвета секторов по кругу |
rotation | Degrees | 0 | начальный угол |
outerRadiusRatio | Fraction | 0.85 | доля свободного радиуса под чарт (подписи выносятся в оставшееся место) |
innerRadiusRatio (donut) | Fraction | 0.6 | внутренний радиус |
angleName | string | имя angleField | подпись значения в тултипе |
sectorSpacing | Pixels | 0 | зазор постоянной ширины между секторами |
cornerRadius | Pixels | 0 | скругление углов секторов |
calloutLabel.enabled | boolean | вкл. при labelField | выносные подписи |
calloutLabel.fontSize | Pixels | 11 | шрифт выносной подписи |
calloutLabel.fontFamily | string | шрифт темы | гарнитура |
calloutLabel.color | ColorValue | foreground | цвет текста |
calloutLine.radial.length | Pixels | 20 | длина радиального отрезка |
calloutLine.radial.stroke | ColorValue | цвет сектора | цвет радиального отрезка |
calloutLine.radial.strokeWidth | Pixels | 1 | толщина |
calloutLine.horizontal.length | Pixels | 20 | длина хвоста к подписи |
calloutLine.horizontal.stroke | ColorValue | как radial | цвет хвоста |
calloutLine.horizontal.strokeWidth | Pixels | как radial | толщина хвоста |
sectorLabel.enabled | boolean | false | доля в % внутри сектора |
sectorLabel.positionRatio | Fraction | 0.7 | позиция вдоль радиуса |
sectorLabel.fontSize | Pixels | 11 | шрифт |
sectorLabel.color | ColorValue | автоконтраст | цвет (ореол цвета сектора) |
legendValue.enabled | boolean | false | значение сектора в легенде |
legendValue.formatter | ({ datum, label, value, color }) => string | значение | формат значения |
tooltip.renderer | ({ datum, label, value, color }) => … | — | кастомный тултип |
innerLabels[] | { text, fontSize?, fontWeight?, color? } | — | строки в центре donut |
innerCircle.fill | ColorValue | — | заливка центра donut |
innerRadiusRatio | Fraction | 0.6 | внутренний радиус donut |
Клик по элементу легенды скрывает сектор (доли пересчитываются); непоместившиеся элементы легенды пагинируются стрелками.