Funnel & Pyramid
ProStage 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.
import { SvFunnelChartComponent } from '@styloviz-pro/charts';Demo & usage
Basic usage
ProUsage example — open the gallery for the full interactive demo.
An interactive demo for this component lives in the gallery.
Open live demoMore examples
Conversion funnel
ProHierarchy pyramid
ProWhen 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
| Name | Type | Default | Description |
|---|---|---|---|
| loading | boolean | false | True while the series are being fetched. |
| error | SvDataError | string | null | null | Load failure. Use `toSvDataError()` from `@styloviz/core` to normalize an `HttpErrorResponse`. |
| emptyMessage | string | 'No data to plot' | Copy for the empty state. |
| filtered | boolean | false | Whether a filter, not an absence of data, is why the chart is empty. |
| slices | FunnelSlice[] | [] | 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. |
| title | string | '' | Chart title rendered above the plot; also the accessible name when `ariaLabel` is empty. |
| ariaLabel | string | '' | 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. |
| height | number | 380 | Chart height in pixels. |
| options | FunnelChartOptions | {} | 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. |
| customClass | string | '' | Extra CSS classes applied to the root wrapper. |
Outputs
| Event | Payload type | Description |
|---|---|---|
| retry | void | The host should re-run the failed load. |
| sliceHover | FunnelSliceEvent | Emitted when a slice is hovered or keyboard-focused. |
| sliceSelect | FunnelSliceEvent | Emitted 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
| Name | Type | Default | Description |
|---|---|---|---|
| loading | boolean | false | True while the series are being fetched. |
| error | SvDataError | string | null | null | Load failure. Use `toSvDataError()` from `@styloviz/core` to normalize an `HttpErrorResponse`. |
| emptyMessage | string | 'No data to plot' | Copy for the empty state. |
| filtered | boolean | false | Whether a filter, not an absence of data, is why the chart is empty. |
| slices | PyramidSlice[] | [] | 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. |
| title | string | '' | Chart title rendered above the plot; also used as the plot's accessible name. |
| height | number | 380 | Chart height in pixels. |
| options | PyramidChartOptions | {} | Display options: value and percentage labels, legend and animation duration. |
| customClass | string | '' | Extra CSS classes applied to the root wrapper. |
Outputs
| Event | Payload type | Description |
|---|---|---|
| retry | void | The host should re-run the failed load. |
| sliceHover | PyramidSliceEvent | Emitted when a tier is hovered or keyboard-focused. |
| sliceSelect | PyramidSliceEvent | Emitted 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
ProBound to the names this component actually exposes.
Host class
ProDrive 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.