Multiple Axis
ProIndependent left and right y-axes with bars and lines on either. Both scales and their ranges are stated under the plot, because each axis fills the full height and the crossing point is an artefact of that. Pure SVG.
import { SvMultiAxisChartComponent } 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
Revenue against a rate
ProWhen to use
- Two measures on the same categories whose units genuinely differ — a total and a rate, a count and a percentage.
- When the shapes over time are the comparison, not the levels.
- For two measures in the same unit, use one axis: a second scale invents a relationship.
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. |
| categories | string[] | [] | Shared X-axis category labels; each series' `data` is indexed by position against these. |
| series | MultiAxisSeries[] | [] | Series to plot; each sets `type` (`'bar'` default or `'line'`) and `axis` (`'primary'` left, default, or `'secondary'` right) and is scaled to its own axis. |
| title | string | '' | Chart title rendered above the plot; also used as the plot's accessible name. |
| height | number | 340 | Chart height in pixels. |
| options | MultiAxisChartOptions | {} | Display options: grid, legend, primary/secondary axis titles, bar gap ratio 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. |
| pointHover | MultiAxisPointEvent | Emitted when a bar or line point is hovered or keyboard-focused. |
| pointSelect | MultiAxisPointEvent | Emitted when a bar or line point is clicked or activated via keyboard. |
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 `series`, `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
- Bar or line per series, on either axis.
- Named axes, configurable grid, legend and bar gap.
- The two-scale disclosure is always on — there is no input to hide it, on the same rule as the bullet chart's scale note.
Best practices
- Don't: Do not read a relationship off this chart. Each axis is scaled to its own maximum, so BOTH series always fill the full plot height whatever their magnitudes — revenue in millions and a growth rate in single percent are drawn at the same amplitude, and the point where they cross is an artefact of two independent divisions rather than an event. Slide either axis and the apparent relationship changes shape without one number changing.
- Do: Prefer two small charts stacked on a shared x-axis whenever the reader only needs to compare shapes over time. Two panels cannot imply a crossing that is not there.
- Do: Fill in primaryLabel and secondaryLabel. The chart names both ranges under the plot, and a range with no unit beside it is half a disclosure.
Accessibility
- The legend marks each series "(left)" or "(right)", and the ranges of both axes are stated in text under the plot — a reader who cannot compare two line positions by eye otherwise has no way to know the two are measured on different rulers.
- Bars and line points are keyboard-focusable with descriptive names; Enter/Space emits `pointSelect`.
Feedback on Multiple Axis
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.