Funnel & Pyramid

Pro

Stage funnel and hierarchy pyramid. Width is the value and every band is the same height, which the chart states under the plot — the area of a band is not its value. Pure SVG.

</>sv-funnel-chart chartfunnelpyramidconversionstages
import { SvFunnelChartComponent } from '@styloviz-pro/charts';

Demo & usage

Basic usage

Pro

Usage example — open the gallery for the full interactive demo.

Pro

An interactive demo for this component lives in the gallery.

Open live demo

More examples

Conversion funnel

Pro

Hierarchy pyramid

Pro

When to use

  • An ordered sequence of stages where each is a subset of the one before it.
  • A ranked hierarchy where the ordering is the point and the exact widths are secondary.
  • For stage counts you want compared precisely, a bar chart is read faster and more accurately.

Async states

  • loading
  • empty
  • error
  • retry

Inputs

NameTypeDefaultDescription
loadingbooleanfalseTrue while the series are being fetched.
errorSvDataError | string | nullnullLoad failure. Use `toSvDataError()` from `@styloviz/core` to normalize an `HttpErrorResponse`.
emptyMessagestring'No data to plot'Copy for the empty state.
filteredbooleanfalseWhether a filter, not an absence of data, is why the chart is empty.
slicesFunnelSlice[][]Funnel stages, top to bottom; each band's width is its value relative to the largest stage. Negative or non-finite values are omitted and disclosed under the plot.
titlestring''Chart title rendered above the plot; also the accessible name when `ariaLabel` is empty.
ariaLabelstring''Accessible name for the plot. Falls back to `title`, then to a generated summary of the funnel — the chart is a `role="group"`, so without one a screen-reader user reaches it and is told only "Funnel chart". Every other chart in the kit takes this; the funnel was the exception.
heightnumber380Chart height in pixels.
optionsFunnelChartOptions{}Display options: value and percentage labels, legend, `gapRatio` (gap between stages as a fraction of a stage's height; a fixed 3 px when omitted), neck ratio (the narrowest band width as a fraction of its stage) and animation duration.
customClassstring''Extra CSS classes applied to the root wrapper.

Outputs

EventPayload typeDescription
retryvoidThe host should re-run the failed load.
sliceHoverFunnelSliceEventEmitted when a slice is hovered or keyboard-focused.
sliceSelectFunnelSliceEventEmitted when a slice is clicked or activated via keyboard (Enter/Space).

<sv-pyramid-chart>

Also in this family — SvPyramidChartComponent from @styloviz-pro/charts.

Async states

  • loading
  • empty
  • error
  • retry

Inputs

NameTypeDefaultDescription
loadingbooleanfalseTrue while the series are being fetched.
errorSvDataError | string | nullnullLoad failure. Use `toSvDataError()` from `@styloviz/core` to normalize an `HttpErrorResponse`.
emptyMessagestring'No data to plot'Copy for the empty state.
filteredbooleanfalseWhether a filter, not an absence of data, is why the chart is empty.
slicesPyramidSlice[][]Pyramid tiers in any order; they are sorted so the smallest sits at the top, and each band's width is proportional to its value. Negative or non-finite values are omitted and disclosed under the plot.
titlestring''Chart title rendered above the plot; also used as the plot's accessible name.
heightnumber380Chart height in pixels.
optionsPyramidChartOptions{}Display options: value and percentage labels, legend and animation duration.
customClassstring''Extra CSS classes applied to the root wrapper.

Outputs

EventPayload typeDescription
retryvoidThe host should re-run the failed load.
sliceHoverPyramidSliceEventEmitted when a tier is hovered or keyboard-focused.
sliceSelectPyramidSliceEventEmitted when a tier is clicked or activated via keyboard (Enter/Space).

Wire it to your API

This component is headless about transport: it renders what you give it and reports what the user asks for. Nothing below requires @styloviz/data — drive it from whatever you already use.

Template

Pro

Bound to the names this component actually exposes.

Host class

Pro

Drive the three async inputs from your own fetch.

  • This component does not emit a query, so it renders what you give it. Fetch on your own trigger and bind `slices`, `loading` and `error`.
  • Set `filtered` when a search or filter is active. It is the difference between "you have no orders" and "no orders match this filter" — telling a customer with 4,000 orders the first one reads as a bug.
  • Normalize failures with `toSvDataError()` from `@styloviz/core`. It derives `retryable` from the status, so a 404 does not get a "Try again" button that can only fail again.

Full walkthrough: Connecting to a backend.

Customization & theming

  • Percentage and value annotations per band.
  • neckRatio floors the funnel's base so a stage that drops to zero still has something to stand on.
  • Per-slice colour, with a shared palette fallback.

Best practices

  • Don't: Do not read area off either chart. Width is the value and every band is the same height, so a band's area is closer to the average of its own value and the next one — a quantity that means nothing. A stage that halves looks far more than half gone, because the eye integrates a trapezoid. Both charts say what they encode under the plot.
  • Do: Order funnel stages by the process, not by value. A funnel whose stages are sorted largest-first is a bar chart wearing a funnel's shape, and the taper stops meaning progression.
  • Tip: Keep the stage labels short — they sit inside the band, and a long one is the first thing to overflow at a narrow width.

Accessibility

  • Every band is a keyboard-focusable `role="button"` named with its label, value and share.
  • What the geometry encodes is stated in the rendered output rather than left to the convention: width is the value, the bands are equal height, and the taper between two bands is not a rate.

Feedback on Funnel & Pyramid

Spotted a gap in this page, or something that didn't work as described? Comments are GitHub Discussions in the public styloviz/community repo, so posting needs a GitHub account.

Loads giscus.app and GitHub — nothing is fetched until you click.