Funnel and Pyramid
Stage-based series without axes: flat data with stageField/valueField.
Funnel
Stages run top to bottom, width is proportional to the value. funnel — rectangular stages, cone-funnel — trapezoids tapering to the next stage.
import { getData } from './data';
import type { ChartOptions } from 'grafit-charts';
export function createOptions(): ChartOptions {
return {
data: getData(),
title: { text: 'Activation funnel' },
series: [{ type: 'cone-funnel', stageField: 'stage', valueField: 'value', name: 'Users' }],
legend: { enabled: false },
};
}export function getData() {
return [
{ stage: 'Visits', value: 12400 },
{ stage: 'Sign-ups', value: 5300 },
{ stage: 'Activations', value: 2900 },
{ stage: 'Subscriptions', value: 1150 },
{ stage: 'Renewals', value: 780 },
];
}Spacing and outside labels
itemSpacing — the gap between segments; label.placement: 'outside' moves labels out to the right. The shape geometry does not depend on labels — the width is set by widthRatio:
import { getData } from './data';
import type { ChartOptions } from 'grafit-charts';
export function createOptions(): ChartOptions {
return {
data: getData(),
title: { text: 'Funnel: spacing and outside labels' },
series: [
{
type: 'funnel',
stageField: 'stage',
valueField: 'count',
itemSpacing: 10,
label: {
placement: 'outside',
formatter: ({ stage, value }) => `${stage} — ${value.toLocaleString('en-US')}`,
},
},
],
legend: { enabled: false },
};
}export function getData() {
return [
{ stage: 'Visits', count: 12500 },
{ stage: 'Sign-ups', count: 6400 },
{ stage: 'Activations', count: 3100 },
{ stage: 'Subscriptions', count: 1400 },
{ stage: 'Renewals', count: 900 },
];
}Cone funnel with outside labels
Trapezoidal stages; the callout line starts at the slanted edge. Inside labels get an outline in the background color (readable on any segment):
import { getData } from './data';
import type { ChartOptions } from 'grafit-charts';
export function createOptions(): ChartOptions {
return {
data: getData(),
title: { text: 'Cone funnel: outside labels' },
series: [
{
type: 'cone-funnel',
stageField: 'stage',
valueField: 'count',
itemSpacing: 2,
label: {
placement: 'outside',
formatter: ({ stage, value }) => `${stage} — ${value.toLocaleString('en-US')}`,
},
},
],
legend: { enabled: false },
};
}export function getData() {
return [
{ stage: 'Leads', count: 8200 },
{ stage: 'Qualified', count: 4900 },
{ stage: 'Demo', count: 2300 },
{ stage: 'Contract', count: 1100 },
{ stage: 'Payment', count: 750 },
];
}Pyramid
Layer height is proportional to the value; reverse flips the apex downward.
import { getData } from './data';
import type { ChartOptions } from 'grafit-charts';
export function createOptions(): ChartOptions {
return {
data: getData(),
title: { text: 'Company structure' },
series: [{ type: 'pyramid', stageField: 'level', valueField: 'count', name: 'People' }],
legend: { enabled: false },
};
}export function getData() {
return [
{ level: 'C-level', count: 6 },
{ level: 'Managers', count: 28 },
{ level: 'Team leads', count: 90 },
{ level: 'Engineers', count: 420 },
{ level: 'Interns', count: 160 },
];
}Spacing and inside labels
itemSpacing slices the pyramid into layers; label.placement: 'inside' — labels in the segments with an auto-contrast color:
import { getData } from './data';
import type { ChartOptions } from 'grafit-charts';
export function createOptions(): ChartOptions {
return {
data: getData(),
title: { text: 'Pyramid: spacing and inside labels' },
series: [
{
type: 'pyramid',
stageField: 'level',
valueField: 'people',
itemSpacing: 6,
label: { placement: 'inside', fontWeight: 'bold' },
},
],
legend: { enabled: false },
};
}export function getData() {
return [
{ level: 'CEO', people: 2 },
{ level: 'Directors', people: 9 },
{ level: 'Managers', people: 34 },
{ level: 'Engineers', people: 120 },
{ level: 'Interns', people: 45 },
];
}Options
Options common to all series (name, showInLegend, tooltip.renderer, …) are covered in Common series options.
| Option | Series | Default | Description |
|---|---|---|---|
stageField | all | — | stage name and value |
valueField | all | — | stage name and value |
fills | all | palette | stage colors |
itemSpacing | all | funnel 4, pyramid 0 | gap between segments |
widthRatio | all | 0.62 | fraction of the area width given to the shape (independent of labels) |
reverse | pyramid | false | apex at the bottom |
label.enabled | boolean | true | stage labels |
label.placement | 'inside' | 'outside' | funnel 'inside'; pyramid 'outside' | position (shared by all segments) |
label.formatter | ({ datum, stage, value }) => string | stage · value | content |
label.fontSize | Pixels | 12 | font |
label.fontWeight | string | number | normal | font weight |
label.color | ColorValue | inside — auto-contrast; outside — foreground | color |
calloutLine.enabled | boolean | true when outside | line to the outside label |
calloutLine.length | Pixels | 14 | line length |
calloutLine.stroke | ColorValue | segment color | line color |
calloutLine.strokeWidth | Pixels | 1 | line width |